Intended for use as part of the olalonde/blind-solvency-proof scheme.
NEW: web UI
Beer fund: 1ECyyu39RtDNAuk3HRCRWwD4syBF2ZGzdx
npm install -g blproof
Simple usage:
# Generate a partial tree for all users in accounts.json.
# Partial trees will be saved to partial_trees/ directory.
# complete_tree.json and root.json will be saved to current directory.
# For a sample accounts file, refer to test/accounts.json.
$ blproof generate -f accounts.json
# Verify a partial tree
$ blproof verify --root root.json -f partial_trees/satoshi.json
# or (where hash is the root hash and value is the root value)
$ blproof verify --hash "SLpDal8kYJNdLwczp6wrU68FOFrpoHT3w5nd15HOpwU=" --value 37618 -f mark.json
Advanced usage:
# Create complete proof tree from an accounts file (see
# test/account.json for format)
$ blproof completetree -f test/accounts.json --human
$ blproof completetree -f test/accounts.json > complete.out.json
# Extract partial tree for user mark.
$ blproof partialtree mark -f complete.out.json --human
$ blproof partialtree mark -f complete.out.json > mark.out.json
# Display root node hash and value
$ blproof root -f complete.out.json --human
# Verify partial tree
$ blproof verify --hash "SLpDal8kYJNdLwczp6wrU68FOFrpoHT3w5nd15HOpwU=" --value 37618 -f mark.out.json
See cli.js
.
Browser build: browserify index.js --standalone blproof > build/blproof.js
.
Clojure:
https://github.com/zw/PoLtree/blob/master/src/uk/me/iwilcox/poltree.clj
Python:
https://github.com/ConceptPending/proveit
C++:
https://github.com/bifubao/proof_of_reserves
The complete proof tree is a binary tree where the leaf nodes represent all the user accounts and the interior nodes generated using the NodeCombiner function described below.
The complete tree should be kept private by the operator in order to protect the privacy of its users. Only the root node should be puslished publicly and each individual user should have private access to their own partial proof tree.
Interior nodes are generated using the NodeCombiner function described below.
The node's value is equal to the sum of its two child node's values.
The node's hash is equal to the sha256 of its value concatenated with its child's hashes.
function NodeCombiner (left_node, right_node) {
var n = {};
n.value = left_node.value + right_node.value;
n.hash = sha256((left_node.value + right_node.value) + '' + left_node.hash + '' + right_node.hash);
return n;
}
Leaf nodes represent user accounts. They possess the following values:
user
: A unique identifier for the user. It is necessary for a user to assess the uniqueness of this value so it is recommended to use their username or email.nonce
: A random number to prevent its neighboor node from discovering itsuser
valuevalue
: The user's balance.hash
: sha256(user + '|' + value + '|' + nonce)
The root node of the tree like all interior nodes possesses a hash and a value. This data must be published publicly as a way to prove that all users are part of the same proof tree.
A partial proof contains only the nodes from the complete root a given user needs to verify he was included in the tree.
It can be generated by starting from the user's leaf node and moving up the tree until reaching the root node. Then the sibblings of each selected node on the path must be added to the tree.
-
All internal nodes should be completely stripped of their
data
since they need to be computed during verification. -
All leaf nodes should be stripped of their
user
andnonce
properties except for the leaf representing the current user. -
The leaf representing the current
user
should be stripped of its hash property since it needs to be computed during verification.
Partial trees should be disclosed privately to each individual users so they can verify the proof.
This section is intended to standardize the way root nodes and trees are distributed in order to make implementations compatible.
All formats are based on JSON.
{
"root": {
"value": 37618,
"hash": "2evVTMS8wbF2p5aq1qFETanO24BsnP/eshJxxPHJcug="
}
}
Hash is the sha256 hash in base64 encoding. Value is a number (float or integer).
Partial trees are represented as a node
object graph. Nodes have the following format:
{
"left": <node>,
"right": <node>,
"data": <node_data>
}
<node_data>
is an object which must contain the following keys:
value
numberhash
string SHA256 hash in base64 encodinguser
string (optional) Only the node belonging to the user this partial tree was generated for should have this key set.nonce
number (optional) Only the node belonging to the user this partial tree was generated for should have this key set.