First commit, Vystem v0.1
This commit is contained in:
100
Blastproof/initfsgen/utilsx1.c
Normal file
100
Blastproof/initfsgen/utilsx1.c
Normal file
@@ -0,0 +1,100 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "utils.h"
|
||||
#include "utilsx1.h"
|
||||
#include "params.h"
|
||||
#include "thash.h"
|
||||
#include "address.h"
|
||||
|
||||
/*
|
||||
* Generate the entire Merkle tree, computing the authentication path for
|
||||
* leaf_idx, and the resulting root node using Merkle's TreeHash algorithm.
|
||||
* Expects the layer and tree parts of the tree_addr to be set, as well as the
|
||||
* tree type (i.e. SPX_ADDR_TYPE_HASHTREE or SPX_ADDR_TYPE_FORSTREE)
|
||||
*
|
||||
* This expects tree_addr to be initialized to the addr structures for the
|
||||
* Merkle tree nodes
|
||||
*
|
||||
* Applies the offset idx_offset to indices before building addresses, so that
|
||||
* it is possible to continue counting indices across trees.
|
||||
*
|
||||
* This works by using the standard Merkle tree building algorithm,
|
||||
*/
|
||||
void treehashx1(unsigned char *root, unsigned char *auth_path,
|
||||
const spx_ctx* ctx,
|
||||
uint32_t leaf_idx, uint32_t idx_offset,
|
||||
uint32_t tree_height,
|
||||
void (*gen_leaf)(
|
||||
unsigned char* /* Where to write the leaves */,
|
||||
const spx_ctx* /* ctx */,
|
||||
uint32_t idx, void *info),
|
||||
uint32_t tree_addr[8],
|
||||
void *info)
|
||||
{
|
||||
/* This is where we keep the intermediate nodes */
|
||||
SPX_VLA(uint8_t, stack, tree_height*SPX_N);
|
||||
|
||||
uint32_t idx;
|
||||
uint32_t max_idx = (uint32_t)((1 << tree_height) - 1);
|
||||
for (idx = 0;; idx++) {
|
||||
unsigned char current[2*SPX_N]; /* Current logical node is at */
|
||||
/* index[SPX_N]. We do this to minimize the number of copies */
|
||||
/* needed during a thash */
|
||||
gen_leaf( ¤t[SPX_N], ctx, idx + idx_offset,
|
||||
info );
|
||||
|
||||
/* Now combine the freshly generated right node with previously */
|
||||
/* generated left ones */
|
||||
uint32_t internal_idx_offset = idx_offset;
|
||||
uint32_t internal_idx = idx;
|
||||
uint32_t internal_leaf = leaf_idx;
|
||||
uint32_t h; /* The height we are in the Merkle tree */
|
||||
for (h=0;; h++, internal_idx >>= 1, internal_leaf >>= 1) {
|
||||
|
||||
/* Check if we hit the top of the tree */
|
||||
if (h == tree_height) {
|
||||
/* We hit the root; return it */
|
||||
memcpy( root, ¤t[SPX_N], SPX_N );
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if the node we have is a part of the
|
||||
* authentication path; if it is, write it out
|
||||
*/
|
||||
if ((internal_idx ^ internal_leaf) == 0x01) {
|
||||
memcpy( &auth_path[ h * SPX_N ],
|
||||
¤t[SPX_N],
|
||||
SPX_N );
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if we're at a left child; if so, stop going up the stack
|
||||
* Exception: if we've reached the end of the tree, keep on going
|
||||
* (so we combine the last 4 nodes into the one root node in two
|
||||
* more iterations)
|
||||
*/
|
||||
if ((internal_idx & 1) == 0 && idx < max_idx) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* Ok, we're at a right node */
|
||||
/* Now combine the left and right logical nodes together */
|
||||
|
||||
/* Set the address of the node we're creating. */
|
||||
internal_idx_offset >>= 1;
|
||||
set_tree_height(tree_addr, h + 1);
|
||||
set_tree_index(tree_addr, internal_idx/2 + internal_idx_offset );
|
||||
|
||||
unsigned char *left = &stack[h * SPX_N];
|
||||
memcpy( ¤t[0], left, SPX_N );
|
||||
thash( ¤t[1 * SPX_N],
|
||||
¤t[0 * SPX_N],
|
||||
2, ctx, tree_addr);
|
||||
}
|
||||
|
||||
/* We've hit a left child; save the current for when we get the */
|
||||
/* corresponding right right */
|
||||
memcpy( &stack[h * SPX_N], ¤t[SPX_N], SPX_N);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user