-
Notifications
You must be signed in to change notification settings - Fork 48
/
tree.h
68 lines (61 loc) · 3.35 KB
/
tree.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
/*! @file tree.h
* @brief This file has part of the tree implementation used to generate
* random seeds and commit to multiple values with a Merkle tree.
*
* This file is part of the reference implementation of the Picnic signature scheme.
* See the accompanying documentation for complete details.
*
* The code is provided under the MIT license, see LICENSE for
* more details.
* SPDX-License-Identifier: MIT
*/
/*
* Represents a (nearly) complete binary tree, stored in memory as an array.
* The root is at nodes[0], and the left child of node k is 2k + 1, the right
* child is at 2k + 2
*/
typedef struct tree_t {
size_t depth; /* The depth of the tree */
uint8_t** nodes; /* The data for each node */
size_t dataSize; /* The size data at each node, in bytes */
uint8_t* haveNode; /* If we have the data (seed or hash) for node i, haveSeed[i] is 1 */
uint8_t* exists; /* Since the tree is not always complete, nodes marked 0 don't exist */
size_t numNodes; /* The total number of nodes in the tree */
size_t numLeaves; /* The total number of leaves in the tree */
} tree_t;
/* The largest seed size is 256 bits, for the Picnic3-L5-FS parameter set. */
#define MAX_SEED_SIZE_BYTES (32)
tree_t* createTree(size_t numLeaves, size_t dataSize);
void freeTree(tree_t* tree);
uint8_t** getLeaves(tree_t* tree);
/* Get one leaf, leafIndex must be in [0, tree->numLeaves -1] */
uint8_t* getLeaf(tree_t* tree, size_t leafIndex);
void printLeaves(tree_t* tree);
/* Functions for trees used to derive seeds.
* Signer's usage: generateSeeds -> revealSeeds -> freeTree
* Verifier's usage: createTree -> reconstructSeeds -> freeTree
*/
/* Returns the number of bytes written to output. A safe number of bytes for
* callers to allocate is numLeaves*params->seedSizeBytes, or call revealSeedsSize. */
tree_t* generateSeeds(size_t nSeeds, uint8_t* rootSeed, uint8_t* salt, size_t repIndex, paramset_t* params);
size_t revealSeeds(tree_t* tree, uint16_t* hideList, size_t hideListSize, uint8_t* output, size_t outputLen, paramset_t* params);
size_t revealSeedsSize(size_t numNodes, uint16_t* hideList, size_t hideListSize, paramset_t* params);
int reconstructSeeds(tree_t* tree, uint16_t* hideList, size_t hideListSize, uint8_t* input, size_t inputLen, uint8_t* salt, size_t repIndex, paramset_t* params);
/* Functions for Merkle hash trees used for commitments.
*
* Signer call sequence:
* 1. createTree
* 2. buildMerkleTree with all commitments as leaf nodes
* 3. openMerkleTree with missingLeaves - list of commitments the verifier won't recompute
* 4. freeTree
* Verifier call sequence
* 1. createTree
* 2. addMerkleNodes with the output of the signer
* 3. verifyMerkleTree Checks that all leaf nodes present are correct commitments
* 4. freeTree
*/
void buildMerkleTree(tree_t* tree, uint8_t** leafData, uint8_t* salt, paramset_t* params);
uint8_t* openMerkleTree(tree_t* tree, uint16_t* missingLeaves, size_t missingLeavesSize, size_t* outputSizeBytes);
size_t openMerkleTreeSize(size_t numNodes, uint16_t* notMissingLeaves, size_t notMissingLeavesSize, paramset_t* params);
int addMerkleNodes(tree_t* tree, uint16_t* missingLeaves, size_t missingLeavesSize, uint8_t* input, size_t inputSize);
int verifyMerkleTree(tree_t* tree, uint8_t** leafData, uint8_t* salt, paramset_t* params);