Skip to content

Commit e02e6b6

Browse files
committed
wip proof
1 parent 69e8b2a commit e02e6b6

4 files changed

Lines changed: 154 additions & 36 deletions

File tree

app/src/metadata_proof.c

Lines changed: 151 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,29 @@ static uint8_t log2i(uint32_t input) {
7070
return log2;
7171
}
7272

73+
/**
74+
* @brief Calculate the largest power of two which is strictly less than the argument.
75+
*
76+
* @param n The input value.
77+
* @return The largest power of two which is strictly less than the argument.
78+
*/
79+
static uint32_t next_smaller_po2(uint32_t n) {
80+
if ((n & (n - 1)) == 0) {
81+
return n >> 1;
82+
}
83+
// Find the next power of two greater than or equal to n
84+
n |= n >> 1;
85+
n |= n >> 2;
86+
n |= n >> 4;
87+
n |= n >> 8;
88+
n |= n >> 16;
89+
n += 1;
90+
91+
// Return the next smaller power of two
92+
return n >> 1;
93+
}
94+
95+
7396
/**
7497
* @brief Compute the number of left siblings needed for a given node index.
7598
*
@@ -82,14 +105,42 @@ static uint32_t compute_num_left_siblings(uint32_t node_idx) {
82105
uint32_t num_left_siblings = 0;
83106
uint32_t start_idx = node_idx;
84107
while (start_idx != 0) {
85-
if (start_idx & 1 != 0) {
108+
if ((start_idx & 1) != 0) {
86109
num_left_siblings += 1;
87110
}
88111
start_idx >>= 1;
89112
}
90113
return num_left_siblings;
91114
}
92115

116+
/**
117+
* @brief Compute the size of the tree needed to prove a given index.
118+
*
119+
* @param num_right_siblings The number of right siblings needed.
120+
* @param index_of_last_included_leaf The index of the last included leaf.
121+
* @param tree_size The output buffer for the computed tree size.
122+
* @return parser_error_t Error code indicating the result of the operation.
123+
*/
124+
parser_error_t compute_tree_size(uint32_t num_right_siblings, uint32_t index_of_last_included_leaf, uint32_t* tree_size) {
125+
uint32_t index_of_final_node = index_of_last_included_leaf;
126+
uint32_t mask = 1;
127+
uint32_t remaining_right_siblings = num_right_siblings;
128+
129+
while (remaining_right_siblings > 0) {
130+
if ((index_of_final_node & mask) == 0) {
131+
index_of_final_node |= mask;
132+
remaining_right_siblings--;
133+
}
134+
mask <<= 1;
135+
if (index_of_final_node == UINT32_MAX) {
136+
return parser_value_out_of_range;
137+
}
138+
}
139+
140+
*tree_size = index_of_final_node + 1;
141+
return parser_ok;
142+
}
143+
93144
/**
94145
* @brief Check if a given index is a descendant of a leaf in a binary tree.
95146
*
@@ -141,6 +192,7 @@ static bool isLemma(uint32_t index, uint32_t leaf) {
141192
* @return parser_error_t Error code indicating the result of the operation.
142193
*/
143194
static parser_error_t hash_leaf(proof_t *proof) {
195+
CHECK_INPUT(proof);
144196
// const uint16_t initialOffset = proof->registry.registry.offset;
145197
// CHECK_ERROR(readType(&proof->registry.registry, &proof->lastEntry));
146198

@@ -149,12 +201,7 @@ static parser_error_t hash_leaf(proof_t *proof) {
149201
crypto_sha256_init();
150202
crypto_sha256_update(&LEAF_PREFIX, 1);
151203
crypto_sha256_update(proof->registry.registry.buffer.ptr, proof->registry.registry.buffer.len);
152-
crypto_sha256_final(proof->hash, CX_SHA256_SIZE);
153-
154-
bytes_t buffer = {0};
155-
buffer.ptr = proof->hash;
156-
buffer.len = CX_SHA256_SIZE;
157-
print_buffer(&buffer, "hash leaf");
204+
crypto_sha256_final(proof->hash_leaf, CX_SHA256_SIZE);
158205

159206
return parser_ok;
160207
}
@@ -266,6 +313,80 @@ static parser_error_t get_hash(uint32_t index, proof_t *proof) {
266313
return freeStack();
267314
}
268315

316+
static parser_error_t check_range_proof_inner(proof_t *proof, uint32_t start_index, uint32_t subtrie_size, uint32_t offset) {
317+
CHECK_INPUT(proof);
318+
319+
uint32_t split_index = next_smaller_po2(subtrie_size);
320+
print_u32("split_point:", split_index);
321+
322+
uint32_t leaves_end_idx = (proof->indices.entries + start_index) - 1;
323+
print_u32("leaves_end_idx:", leaves_end_idx);
324+
325+
// Check right subtree
326+
bytes_t right = {0};
327+
if (leaves_end_idx >= (split_index + offset)) {
328+
uint32_t right_subtrie_size = subtrie_size - split_index;
329+
if (right_subtrie_size == 1) {
330+
right.ptr = proof->hash_leaf;
331+
right.len = CX_SHA256_SIZE;
332+
print_buffer(&right, "right inside if true");
333+
} else {
334+
print_u32("right inside else:", right_subtrie_size);
335+
CHECK_ERROR(check_range_proof_inner(
336+
proof,
337+
start_index,
338+
right_subtrie_size,
339+
offset + split_index
340+
));
341+
right.ptr = proof->hash;
342+
right.len = CX_SHA256_SIZE;
343+
}
344+
} else {
345+
if (proof->lemmas.last_index == 0) {
346+
return parser_value_out_of_range;
347+
}
348+
right.ptr = proof->lemmas.lemmas.buffer.ptr + CX_SHA256_SIZE * proof->lemmas.last_index;
349+
right.len = CX_SHA256_SIZE;
350+
proof->lemmas.last_index--;
351+
print_buffer(&right, "proof right outside if else");
352+
}
353+
354+
// Check left subtree
355+
bytes_t left = {0};
356+
if (start_index < (split_index + offset)) {
357+
uint32_t left_subtrie_size = split_index;
358+
if (left_subtrie_size == 1) {
359+
left.ptr = proof->hash_leaf;
360+
left.len = CX_SHA256_SIZE;
361+
print_buffer(&left, "left inside if true");
362+
} else {
363+
print_u32("left inside else:", left_subtrie_size);
364+
CHECK_ERROR(check_range_proof_inner(
365+
proof,
366+
start_index,
367+
left_subtrie_size,
368+
offset
369+
));
370+
left.ptr = proof->hash;
371+
left.len = CX_SHA256_SIZE;
372+
}
373+
} else {
374+
left.ptr = proof->lemmas.lemmas.buffer.ptr + CX_SHA256_SIZE * proof->lemmas.last_index;
375+
left.len = CX_SHA256_SIZE;
376+
if (proof->lemmas.last_index > 0) {
377+
proof->lemmas.last_index--;
378+
}
379+
print_buffer(&left, "proof left outside if else");
380+
}
381+
382+
print_string("MERGING LEFT AND RIGHT");
383+
print_buffer(&left, "left outside if else");
384+
print_buffer(&right, "right outside if else");
385+
merge_branches(left.ptr, right.ptr, proof->hash);
386+
387+
return parser_ok;
388+
}
389+
269390
/**
270391
* @brief Compute the hash for a given index in the proof.
271392
*
@@ -274,42 +395,33 @@ static parser_error_t get_hash(uint32_t index, proof_t *proof) {
274395
* @return parser_error_t Error code indicating the result of the operation.
275396
*/
276397
static parser_error_t get_hash_single_proof(uint32_t index, proof_t *proof) {
277-
const uint16_t tmpOffset = proof->indices.indices.offset;
278-
uint32_t nextIndex = 0;
279-
CHECK_ERROR(get_next_index(&proof->indices.indices, &nextIndex));
398+
CHECK_INPUT(proof);
280399

281-
// Check if this index is used
282-
if (index == nextIndex) {
283-
CHECK_ERROR(hash_leaf(proof));
284-
return parser_ok;
285-
}
400+
// Compute hash of leaf data
401+
CHECK_ERROR(hash_leaf(proof));
402+
bytes_t buffer = {0};
403+
buffer.ptr = proof->hash_leaf;
404+
buffer.len = CX_SHA256_SIZE;
405+
print_buffer(&buffer, "hash leaf");
286406

287-
// If nextIndex doesn't match the requested, restore the offset
288-
proof->indices.indices.offset = tmpOffset;
407+
// Get the number of left siblings needed
408+
uint32_t num_left_siblings = compute_num_left_siblings(index);
289409

290-
// Check if this index is a lemma
291-
if (isLemma(index, nextIndex)) {
292-
CTX_CHECK(&proof->lemmas.lemmas, CX_SHA256_SIZE);
293-
memcpy(proof->hash, proof->lemmas.lemmas.buffer.ptr + proof->lemmas.lemmas.offset, CX_SHA256_SIZE);
294-
proof->lemmas.lemmas.offset += CX_SHA256_SIZE;
295-
return parser_ok;
410+
// Get the number of right siblings needed
411+
if (num_left_siblings > proof->lemmas.entries) {
412+
return parser_value_out_of_range;
296413
}
414+
uint32_t num_right_siblings = proof->lemmas.entries - num_left_siblings;
415+
print_u32("num_left_siblings:", num_left_siblings);
416+
print_u32("num_right_siblings:", num_right_siblings);
297417

298-
CHECK_ERROR(checkStack());
418+
uint32_t tree_size = 0;
419+
CHECK_ERROR(compute_tree_size(num_right_siblings, index, &tree_size));
420+
print_u32("tree_size:", tree_size);
299421

300-
// Go and find left and right children
301-
uint8_t leftHash[CX_SHA256_SIZE] = {0};
302-
uint8_t rightHash[CX_SHA256_SIZE] = {0};
303-
304-
CHECK_ERROR(get_hash(get_left_child(index), proof));
305-
memcpy(leftHash, proof->hash, CX_SHA256_SIZE);
422+
CHECK_ERROR(check_range_proof_inner(proof, index, tree_size, 0));
306423

307-
CHECK_ERROR(get_hash(get_right_child(index), proof));
308-
memcpy(rightHash, proof->hash, CX_SHA256_SIZE);
309-
310-
merge_branches(leftHash, rightHash, proof->hash);
311-
312-
return freeStack();
424+
return parser_ok;
313425
}
314426

315427
/**
@@ -336,6 +448,9 @@ parser_error_t get_metadata_digest(metadata_t *metadata, uint8_t metadataDigest[
336448
CHECK_ERROR(read_u32(&proof.indices.indices, &leaves_start));
337449
print_u32("leaves_start:", leaves_start);
338450

451+
CHECK_ERROR(get_hash_single_proof(leaves_start, &proof));
452+
memcpy(metadataDigest, proof.hash, CX_SHA256_SIZE);
453+
339454
// // CHECK_ERROR(setInitialConditions(&proof));
340455
// const uint8_t MAX_ONE_BYTE_COMPACT = 0x3F;
341456

app/src/metadata_proof.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ extern "C" {
2929

3030
typedef struct {
3131
uint8_t hash[CX_SHA256_SIZE];
32+
uint8_t hash_leaf[CX_SHA256_SIZE];
3233
short_registry_t registry;
3334
merkle_indices_t indices;
3435
merkle_lemmas_t lemmas;

app/src/metadata_reader.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -974,6 +974,7 @@ parser_error_t merkle_proofs_read(parser_context_t *ctx, parser_tx_t *txObj) {
974974

975975
CHECK_ERROR(read_u32(ctx, &txObj->merkle_proofs.shortMetadata.lemmas.entries));
976976
print_u32("registry_qty:", txObj->merkle_proofs.shortMetadata.lemmas.entries);
977+
txObj->merkle_proofs.shortMetadata.lemmas.last_index = txObj->merkle_proofs.shortMetadata.lemmas.entries - 1;
977978

978979
// read short_registry
979980
txObj->merkle_proofs.shortMetadata.lemmas.lemmas.buffer.ptr = ctx->buffer.ptr + ctx->offset;

app/src/txdefs/merkle_txdef.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ typedef struct {
3434

3535
typedef struct {
3636
uint32_t entries;
37+
uint32_t last_index;
3738
parser_context_t lemmas;
3839
} merkle_lemmas_t;
3940

0 commit comments

Comments
 (0)