amduat/src/near_core/fps.c
Carl Niklas Rydberg 3473b19425 trow AI at it.
2026-02-22 00:25:56 +01:00

203 lines
5.7 KiB
C

#include "amduat/fps.h"
#include <stdlib.h>
#include <string.h>
static const char k_amduat_fps_domain_sep[] = "CAS:OBJ\0";
static uint8_t amduat_fps_reverse_bits8(uint8_t value) {
value = (uint8_t)(((value & 0xf0u) >> 4) | ((value & 0x0fu) << 4));
value = (uint8_t)(((value & 0xccu) >> 2) | ((value & 0x33u) << 2));
value = (uint8_t)(((value & 0xaau) >> 1) | ((value & 0x55u) << 1));
return value;
}
static bool amduat_fps_alloc_output(size_t len, amduat_octets_t *out) {
uint8_t *buf;
if (out == NULL) {
return false;
}
*out = amduat_octets(NULL, 0u);
if (len == 0u) {
return true;
}
buf = (uint8_t *)malloc(len);
if (buf == NULL) {
return false;
}
*out = amduat_octets(buf, len);
return true;
}
amduat_fps_error_t amduat_fps_slice(amduat_octets_t input,
size_t offset,
size_t length,
amduat_octets_t *out) {
if (out == NULL || (input.len != 0u && input.data == NULL)) {
return AMDUAT_FPS_ERR_INVALID;
}
if (offset > input.len || length > input.len - offset) {
return AMDUAT_FPS_ERR_SLICE_RANGE;
}
if (!amduat_fps_alloc_output(length, out)) {
return AMDUAT_FPS_ERR_IO_FAILURE;
}
if (length != 0u) {
memcpy((void *)out->data, input.data + offset, length);
}
return AMDUAT_FPS_OK;
}
amduat_fps_error_t amduat_fps_concat(const amduat_octets_t *inputs,
size_t input_count,
amduat_octets_t *out) {
size_t total = 0u;
size_t i;
uint8_t *cursor;
if (out == NULL) {
return AMDUAT_FPS_ERR_INVALID;
}
if (input_count == 0u) {
return AMDUAT_FPS_ERR_EMPTY_INPUTS;
}
if (inputs == NULL) {
return AMDUAT_FPS_ERR_INVALID;
}
for (i = 0u; i < input_count; ++i) {
if (inputs[i].len != 0u && inputs[i].data == NULL) {
return AMDUAT_FPS_ERR_INVALID;
}
if (SIZE_MAX - total < inputs[i].len) {
return AMDUAT_FPS_ERR_IO_FAILURE;
}
total += inputs[i].len;
}
if (!amduat_fps_alloc_output(total, out)) {
return AMDUAT_FPS_ERR_IO_FAILURE;
}
cursor = (uint8_t *)out->data;
for (i = 0u; i < input_count; ++i) {
if (inputs[i].len != 0u) {
memcpy(cursor, inputs[i].data, inputs[i].len);
cursor += inputs[i].len;
}
}
return AMDUAT_FPS_OK;
}
amduat_fps_error_t amduat_fps_reverse(amduat_octets_t input,
amduat_fps_reverse_level_t level,
amduat_octets_t *out) {
size_t unit_size;
size_t i;
size_t unit_count;
if (out == NULL || (input.len != 0u && input.data == NULL)) {
return AMDUAT_FPS_ERR_INVALID;
}
if (level == AMDUAT_FPS_REVERSE_BITS) {
if (!amduat_fps_alloc_output(input.len, out)) {
return AMDUAT_FPS_ERR_IO_FAILURE;
}
for (i = 0u; i < input.len; ++i) {
size_t dst = input.len - 1u - i;
((uint8_t *)out->data)[dst] = amduat_fps_reverse_bits8(input.data[i]);
}
return AMDUAT_FPS_OK;
}
if (level == AMDUAT_FPS_REVERSE_BYTES) {
unit_size = 1u;
} else if (level == AMDUAT_FPS_REVERSE_WORDS) {
unit_size = 2u;
} else if (level == AMDUAT_FPS_REVERSE_LONGS) {
unit_size = 4u;
} else {
return AMDUAT_FPS_ERR_INVALID_LEVEL;
}
if (unit_size != 0u && input.len % unit_size != 0u) {
return AMDUAT_FPS_ERR_REV_ALIGNMENT;
}
if (!amduat_fps_alloc_output(input.len, out)) {
return AMDUAT_FPS_ERR_IO_FAILURE;
}
unit_count = unit_size == 0u ? 0u : input.len / unit_size;
for (i = 0u; i < unit_count; ++i) {
size_t src_offset = i * unit_size;
size_t dst_offset = (unit_count - 1u - i) * unit_size;
memcpy((uint8_t *)out->data + dst_offset,
input.data + src_offset,
unit_size);
}
return AMDUAT_FPS_OK;
}
amduat_fps_error_t amduat_fps_splice(amduat_octets_t a,
size_t offset,
amduat_octets_t b,
amduat_octets_t *out) {
size_t total;
if (out == NULL ||
(a.len != 0u && a.data == NULL) ||
(b.len != 0u && b.data == NULL)) {
return AMDUAT_FPS_ERR_INVALID;
}
if (offset > a.len) {
return AMDUAT_FPS_ERR_SPLICE_RANGE;
}
if (SIZE_MAX - a.len < b.len) {
return AMDUAT_FPS_ERR_IO_FAILURE;
}
total = a.len + b.len;
if (!amduat_fps_alloc_output(total, out)) {
return AMDUAT_FPS_ERR_IO_FAILURE;
}
if (offset != 0u) {
memcpy((uint8_t *)out->data, a.data, offset);
}
if (b.len != 0u) {
memcpy((uint8_t *)out->data + offset, b.data, b.len);
}
if (a.len > offset) {
memcpy((uint8_t *)out->data + offset + b.len,
a.data + offset,
a.len - offset);
}
return AMDUAT_FPS_OK;
}
bool amduat_fps_cid_for_payload(amduat_hash_id_t hash_id,
amduat_octets_t payload,
amduat_reference_t *out_cid) {
const amduat_hash_asl1_desc_t *desc;
amduat_octets_t domain_sep;
uint8_t *digest;
if (out_cid == NULL) {
return false;
}
*out_cid = amduat_reference(0, amduat_octets(NULL, 0u));
desc = amduat_hash_asl1_desc_lookup(hash_id);
if (desc == NULL || desc->digest_len == 0u) {
return false;
}
digest = (uint8_t *)malloc(desc->digest_len);
if (digest == NULL) {
return false;
}
domain_sep = amduat_octets(k_amduat_fps_domain_sep,
sizeof(k_amduat_fps_domain_sep) - 1u);
if (!amduat_hash_asl1_digest_domain(hash_id, domain_sep, payload, digest,
desc->digest_len)) {
free(digest);
return false;
}
*out_cid = amduat_reference(hash_id, amduat_octets(digest, desc->digest_len));
return true;
}