mssmt 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/mssmt/branch_node.rb +6 -2
- data/lib/mssmt/computed_node.rb +22 -0
- data/lib/mssmt/leaf_node.rb +2 -1
- data/lib/mssmt/proof.rb +59 -2
- data/lib/mssmt/version.rb +1 -1
- data/lib/mssmt.rb +1 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e99668bb044c1670cee5d94e301f8113321c04ce9ac06b697fcfa8eabf1668f9
|
4
|
+
data.tar.gz: 7928cf9abd46c85c505dc770c2cbcce33e82ce98c2f7f772872792366bcd6eaa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1b0b1648a73caed3a29c764c688b8077dea1beaa65da3772429470fc1ca1eab352b11128538e0e3b4daa2e8c578452360a562a08bd69bebe3bebadd228070f74
|
7
|
+
data.tar.gz: 653ad3b9270105b25a9dfea42414918cc0640cdc9359a7c9c01c712ee503f6689d81ee74796510099c3827fae53209fd2a7325392a36541f64b39447482d6e30
|
data/lib/mssmt/branch_node.rb
CHANGED
@@ -16,15 +16,19 @@ module MSSMT
|
|
16
16
|
@left = left
|
17
17
|
@right = right
|
18
18
|
@sum = left.sum + right.sum
|
19
|
+
warn("sum:#{@sum} cause overflow.") if @sum > 0xffffffffffffffff # TODO
|
20
|
+
@sum = (@sum & 0xffffffffffffffff)
|
19
21
|
@node_hash =
|
20
22
|
Digest::SHA256.digest(
|
21
23
|
"#{left.node_hash}#{right.node_hash}#{[@sum].pack("Q>")}"
|
22
24
|
)
|
23
25
|
end
|
24
26
|
|
27
|
+
# Check whether same branch|computed node or not.
|
28
|
+
# @return [Boolean]
|
25
29
|
def ==(other)
|
26
|
-
return false unless
|
27
|
-
node_hash == other.node_hash
|
30
|
+
return false unless [BranchNode, ComputedNode].include?(other.class)
|
31
|
+
node_hash == other.node_hash && sum == other.sum
|
28
32
|
end
|
29
33
|
end
|
30
34
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MSSMT
|
4
|
+
# Node within a MS-SMT that has already had its node_hash and sum computed, i.e., its preimage is not available.
|
5
|
+
class ComputedNode
|
6
|
+
attr_reader :node_hash, :sum
|
7
|
+
|
8
|
+
# Constructor
|
9
|
+
# @param [String] node_hash node hash with binary fomat.
|
10
|
+
# @param [Integer] sum
|
11
|
+
def initialize(node_hash, sum)
|
12
|
+
@node_hash = node_hash
|
13
|
+
warn("sum: #{sum} cause overflow.") if sum > 0xffffffffffffffff # TODO
|
14
|
+
@sum = sum
|
15
|
+
end
|
16
|
+
|
17
|
+
def ==(other)
|
18
|
+
return false unless [BranchNode, ComputedNode].include?(other.class)
|
19
|
+
node_hash == other.node_hash && sum == other.sum
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/mssmt/leaf_node.rb
CHANGED
@@ -10,7 +10,8 @@ module MSSMT
|
|
10
10
|
# @param [Integer] sum integer value associated with the value
|
11
11
|
def initialize(value, sum)
|
12
12
|
@value = value
|
13
|
-
|
13
|
+
warn("sum: #{sum} cause overflow.") if sum > 0xffffffffffffffff # TODO
|
14
|
+
@sum = sum & 0xffffffffffffffff
|
14
15
|
end
|
15
16
|
|
16
17
|
# Generate empty leaf node.
|
data/lib/mssmt/proof.rb
CHANGED
@@ -17,8 +17,7 @@ module MSSMT
|
|
17
17
|
bits = Array.new(nodes.length, false)
|
18
18
|
compact_nodes = []
|
19
19
|
nodes.each.each_with_index do |node, i|
|
20
|
-
|
21
|
-
if node.node_hash == Tree.empty_tree[Tree::MAX_LEVEL - 1].node_hash
|
20
|
+
if node.node_hash == Tree.empty_tree[Tree::MAX_LEVEL - i].node_hash
|
22
21
|
bits[i] = true
|
23
22
|
else
|
24
23
|
compact_nodes << node
|
@@ -49,6 +48,21 @@ module MSSMT
|
|
49
48
|
@bits = bits
|
50
49
|
end
|
51
50
|
|
51
|
+
# Decode compressed proof.
|
52
|
+
# @param [String] compressed proof with binary fomat.
|
53
|
+
# @return [MSSMT::CompressedProof]
|
54
|
+
def self.decode(data)
|
55
|
+
buf = data.is_a?(StringIO) ? data : StringIO.new(data)
|
56
|
+
nodes_len = buf.read(2).unpack1("n")
|
57
|
+
nodes =
|
58
|
+
nodes_len.times.map do
|
59
|
+
ComputedNode.new(buf.read(32), buf.read(8).unpack1("Q>"))
|
60
|
+
end
|
61
|
+
bytes = buf.read(MSSMT::Tree::MAX_LEVEL / 8)
|
62
|
+
bits = unpack_bits(bytes.unpack("C*"))
|
63
|
+
CompressedProof.new(nodes, bits)
|
64
|
+
end
|
65
|
+
|
52
66
|
# Decompress a compressed merkle proof by replacing its bit vector with the empty nodes it represents.
|
53
67
|
# @return [MSSMT::Proof]
|
54
68
|
def decompress
|
@@ -64,5 +78,48 @@ module MSSMT
|
|
64
78
|
end
|
65
79
|
Proof.new(full_nodes)
|
66
80
|
end
|
81
|
+
|
82
|
+
# Encode the compressed proof.
|
83
|
+
# @return [String] encoded string.
|
84
|
+
def encode
|
85
|
+
buf = [nodes.length].pack("n")
|
86
|
+
nodes.each do |node|
|
87
|
+
buf << node.node_hash
|
88
|
+
buf << [node.sum].pack("Q>")
|
89
|
+
end
|
90
|
+
buf << pack_bits.pack("C*")
|
91
|
+
buf
|
92
|
+
end
|
93
|
+
|
94
|
+
def ==(other)
|
95
|
+
return false unless other.is_a?(CompressedProof)
|
96
|
+
bits == other.bits && nodes == other.nodes
|
97
|
+
end
|
98
|
+
|
99
|
+
private
|
100
|
+
|
101
|
+
def pack_bits
|
102
|
+
bytes = Array.new((bits.length + 8 - 1) / 8, 0)
|
103
|
+
bits.each_with_index do |b, i|
|
104
|
+
next unless b
|
105
|
+
byte_index = i / 8
|
106
|
+
bit_index = i % 8
|
107
|
+
bytes[byte_index] |= (1 << bit_index)
|
108
|
+
end
|
109
|
+
bytes
|
110
|
+
end
|
111
|
+
|
112
|
+
def self.unpack_bits(bytes)
|
113
|
+
bit_len = bytes.length * 8
|
114
|
+
bits = Array.new(bit_len, false)
|
115
|
+
bit_len.times do |i|
|
116
|
+
byte_index = i / 8
|
117
|
+
bit_index = i % 8
|
118
|
+
bits[i] = ((bytes[byte_index] >> bit_index) & 1) == 1
|
119
|
+
end
|
120
|
+
bits
|
121
|
+
end
|
122
|
+
|
123
|
+
private_class_method :unpack_bits
|
67
124
|
end
|
68
125
|
end
|
data/lib/mssmt/version.rb
CHANGED
data/lib/mssmt.rb
CHANGED
@@ -11,6 +11,7 @@ module MSSMT
|
|
11
11
|
autoload :Store, "mssmt/store"
|
12
12
|
autoload :LeafNode, "mssmt/leaf_node"
|
13
13
|
autoload :BranchNode, "mssmt/branch_node"
|
14
|
+
autoload :ComputedNode, "mssmt/computed_node"
|
14
15
|
autoload :Tree, "mssmt/tree"
|
15
16
|
autoload :Proof, "mssmt/proof"
|
16
17
|
autoload :CompressedProof, "mssmt/proof"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mssmt
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- azuchi
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-10-
|
11
|
+
date: 2022-10-29 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Ruby implementation of Merkle Sum Sparse Merkle Tree
|
14
14
|
email:
|
@@ -32,6 +32,7 @@ files:
|
|
32
32
|
- bin/setup
|
33
33
|
- lib/mssmt.rb
|
34
34
|
- lib/mssmt/branch_node.rb
|
35
|
+
- lib/mssmt/computed_node.rb
|
35
36
|
- lib/mssmt/leaf_node.rb
|
36
37
|
- lib/mssmt/proof.rb
|
37
38
|
- lib/mssmt/store.rb
|