hashtastic 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8a1e5b44ccfb59de465e29f03e25cb8d4f828b5b09074c0c8b96cbc826b51921
4
- data.tar.gz: a9ccc452b9c6a67861224062c82d48ecc54c8acda26a1285d0696728cac0a886
3
+ metadata.gz: 93a14f1cad9f8acd97b774aff0a17a9645fbe4c58e9ff436b558aaee2bb3ee7c
4
+ data.tar.gz: d503ccccdfe7902945b342e9c95c3d6b84eb1dbc23b9a7087b17904011846eab
5
5
  SHA512:
6
- metadata.gz: 0a0b7f8193c6e48fd2eeee598815ee8aa1c7416f101b3095e1536a96df0014b731e4ddc5a4b93c9f692d5387e59b63d026893bac62b1baff08ad4d990c921349
7
- data.tar.gz: 8504b343d3a157f2d0e66c70393a1a243bf2a128db23485c942f238521ef6290f8e6c543b2c6496ae7309f0f2fa9c6f88767ee139470e30d976e0c5ff3af7c59
6
+ metadata.gz: 212807d96c812105679a1c0f6325a38598202d98c9e2ce2f0ceeafce54a59e41fdb050cc8d864507c09f80719bb120e878aa92c03df3f6cd93a55887ab863890
7
+ data.tar.gz: 809e52a76d93323944578e19db72f9f48a1195438e1bb18ec97cb701c67973e8fadd41ab2bc339df13f7bb38e3ee3fbfb41b4da2653657a43656f15131b16f58
@@ -5,6 +5,10 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
5
5
  and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
6
6
 
7
7
 
8
+ ## [0.3.0] - 2019-08-05
9
+ ### Added:
10
+ - Add merkle-root proof and verifier
11
+
8
12
  ## [0.2.0] - 2019-07-17
9
13
  ### Added:
10
14
  - DictionaryHasher function
@@ -1,24 +1,24 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- hashtastic (0.1.2)
4
+ hashtastic (0.3.0)
5
5
  activesupport (~> 5.0)
6
6
  digest-sha3 (~> 1.1)
7
7
 
8
8
  GEM
9
9
  remote: https://rubygems.org/
10
10
  specs:
11
- activesupport (5.2.0)
11
+ activesupport (5.2.3)
12
12
  concurrent-ruby (~> 1.0, >= 1.0.2)
13
13
  i18n (>= 0.7, < 2)
14
14
  minitest (~> 5.1)
15
15
  tzinfo (~> 1.1)
16
16
  ast (2.4.0)
17
17
  coderay (1.1.2)
18
- concurrent-ruby (1.0.5)
18
+ concurrent-ruby (1.1.5)
19
19
  diff-lcs (1.3)
20
20
  digest-sha3 (1.1.0)
21
- i18n (1.0.1)
21
+ i18n (1.6.0)
22
22
  concurrent-ruby (~> 1.0)
23
23
  jaro_winkler (1.5.1)
24
24
  method_source (0.9.0)
@@ -71,4 +71,4 @@ DEPENDENCIES
71
71
  rubocop (~> 0.58)
72
72
 
73
73
  BUNDLED WITH
74
- 1.16.0
74
+ 1.17.3
@@ -2,11 +2,16 @@
2
2
 
3
3
  require 'hashtastic/version'
4
4
  require 'active_support/all'
5
+ require 'hashtastic/utils'
5
6
  require 'hashtastic/list_hasher'
6
7
  require 'hashtastic/dictionary_values_hasher'
7
8
  require 'hashtastic/ethereum_sha3'
8
9
  require 'hashtastic/dictionary_hasher'
9
10
  require 'hashtastic/digester'
10
11
 
12
+ require 'hashtastic/merkle_tree/layers_creator'
13
+ require 'hashtastic/merkle_tree/merkle_tree'
14
+ require 'hashtastic/merkle_tree/leaf_not_found_error'
15
+
11
16
  module Hashtastic
12
17
  end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hashtastic
4
+ class MerkleTree
5
+ class LayersCreator
6
+ class << self
7
+ def call(leafs, hashfunc = EthereumSHA3)
8
+ @hashfunc = hashfunc
9
+ @leafs = leafs
10
+
11
+ return [['']] if @leafs.empty?
12
+
13
+ layers = []
14
+ layers.push(@leafs)
15
+
16
+ while layers[layers.length - 1].length > 1
17
+ layers.push(next_layer(layers[layers.length - 1]))
18
+ end
19
+
20
+ layers
21
+ end
22
+
23
+ private
24
+
25
+ def combine_hash(first, second)
26
+ return first if second.nil?
27
+ @hashfunc.call(sort_and_concat(first, second))
28
+ end
29
+
30
+ def next_layer(leafs)
31
+ leafs.each_with_object([]).with_index do |(leaf, arr), index|
32
+ arr << combine_hash(leaf, leafs[index + 1]) if index.even?
33
+ end
34
+ end
35
+
36
+ def sort_and_concat(first, second)
37
+ [first, second].map { |leaf| Utils.hex_to_ascii(leaf) }.sort.join
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class LeafNotFoundError < StandardError
4
+ def initialize(leaf)
5
+ super("leaf does not exist in merkle-tree: #{leaf}")
6
+ end
7
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hashtastic
4
+ class MerkleTree
5
+ attr_reader :layers, :leafs
6
+
7
+ def initialize(leafs, hashfunc = EthereumSHA3)
8
+ @hashfunc = hashfunc
9
+ @leafs = leafs.sort.uniq
10
+ @layers = LayersCreator.call(@leafs, hashfunc)
11
+ end
12
+
13
+ def root
14
+ layers[layers.length - 1][0]
15
+ end
16
+
17
+ def proof(leaf)
18
+ index = leafs.index(leaf)
19
+ raise LeafNotFoundError, leaf unless index
20
+
21
+ layers.each_with_object([]) do |layer, accumulator|
22
+ pair_element = pair_element(index, layer)
23
+
24
+ accumulator.push(pair_element) if pair_element
25
+
26
+ index = (index / 2).floor
27
+ end
28
+ end
29
+
30
+ def pair_element(index, layer)
31
+ pair_index = index.even? ? index + 1 : index - 1
32
+
33
+ return layer[pair_index] if pair_index < layer.length
34
+ end
35
+
36
+ def verify(proof:, root:, leaf:)
37
+ computed_hash =
38
+ proof.reduce(leaf) do |acc, element|
39
+ combined = [acc, element].map { |h| Utils.hex_to_ascii(h) }.sort.join
40
+
41
+ @hashfunc.call(combined)
42
+ end
43
+
44
+ computed_hash == root
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hashtastic
4
+ class Utils
5
+ class << self
6
+ def hex_to_ascii(hex)
7
+ value = hex[2..-1] if hex[0..1] == '0x'
8
+
9
+ [value].pack('H*')
10
+ end
11
+ end
12
+ end
13
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Hashtastic
4
- VERSION = '0.2.0'
4
+ VERSION = '0.3.0'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hashtastic
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - lucidity
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-07-17 00:00:00.000000000 Z
11
+ date: 2019-08-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -133,6 +133,10 @@ files:
133
133
  - lib/hashtastic/digester.rb
134
134
  - lib/hashtastic/ethereum_sha3.rb
135
135
  - lib/hashtastic/list_hasher.rb
136
+ - lib/hashtastic/merkle_tree/layers_creator.rb
137
+ - lib/hashtastic/merkle_tree/leaf_not_found_error.rb
138
+ - lib/hashtastic/merkle_tree/merkle_tree.rb
139
+ - lib/hashtastic/utils.rb
136
140
  - lib/hashtastic/version.rb
137
141
  homepage: https://github.com/luciditytech/hashtastic
138
142
  licenses: