2025-10-02 14:08:56 -04:00
|
|
|
/*
|
|
|
|
|
Merkle tree
|
|
|
|
|
derived from flat-tree implementation DEP-0002, datrs
|
|
|
|
|
*/
|
|
|
|
|
#include "sleep.h"
|
|
|
|
|
|
|
|
|
|
#ifdef SLEEP_SALT
|
|
|
|
|
#include <sodium.h>
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#include <stdint.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include <errno.h>
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
|
|
|
|
|
// count trailing zeros
|
|
|
|
|
static inline unsigned int _ctzll_fallback(uint64_t x) {
|
|
|
|
|
if (x == 0) return 64;
|
|
|
|
|
unsigned int n = 0;
|
|
|
|
|
while ((x & 1ULL) == 0ULL) {
|
|
|
|
|
n++;
|
|
|
|
|
x >>= 1;
|
|
|
|
|
}
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
static inline unsigned int flattree_ctzll(uint64_t x) {
|
|
|
|
|
#if defined(__GNUC__) || defined(__clang__) || define(__MUSL__)
|
|
|
|
|
if (x == 0) return 64;
|
|
|
|
|
return (unsigned int)__builtin_ctzll(x);
|
|
|
|
|
#else
|
|
|
|
|
return _ctzll_fallback(x);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// भव न सन हृदयं
|
|
|
|
|
int sleep_tree_hash_block(const uint8_t *data, size_t len, uint8_t out_hash[32]) {
|
|
|
|
|
#ifndef SLEEP_SALT
|
|
|
|
|
errno = ENOSYS;
|
|
|
|
|
return -1;
|
|
|
|
|
#else
|
|
|
|
|
if (crypto_generichash(out_hash, 32, data, len, NULL, 0) != 0)
|
|
|
|
|
return -1;
|
|
|
|
|
return 0;
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int sleep_tree_hash_parent(const uint8_t left[32], const uint8_t right[32], uint8_t out_hash[32]) {
|
|
|
|
|
#ifndef SLEEP_SALT
|
|
|
|
|
errno = ENOSYS;
|
|
|
|
|
return -1;
|
|
|
|
|
#else
|
|
|
|
|
uint8_t buf[64];
|
|
|
|
|
memcpy(buf, left, 32);
|
|
|
|
|
memcpy(buf + 32, right, 32);
|
|
|
|
|
if (crypto_generichash(out_hash, 32, buf, sizeof(buf), NULL, 0) != 0)
|
|
|
|
|
return -1;
|
|
|
|
|
return 0;
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int sleep_tree_build(const uint8_t **blocks, size_t *block_lens, size_t nblocks, /*FIXME*/, size_t *out_count){
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|