poseidon_hash 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,123 @@
1
+ module Poseidon
2
+ class Hash
3
+ include Constant
4
+
5
+ def s_box(x)
6
+ p = 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001
7
+ a = (x * x) % p
8
+ b = (a * a) % p
9
+ (x * b) % p
10
+ end
11
+
12
+ def dotprod(a, b)
13
+ p = 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001
14
+ raise 'Length of a and b must be equal' unless a.length == b.length
15
+
16
+ res = 0
17
+ for i in 0...a.length
18
+ res += ((a[i] * b[i]) % p)
19
+ end
20
+ res % p
21
+ end
22
+
23
+ def matrix_multiply(m, x)
24
+ b = []
25
+ raise 'M must be a square matrix' unless m.length == m[0].length
26
+ raise 'Length of M and x must be equal' unless m.length == x.length
27
+
28
+ for i in 0...x.length
29
+ b << dotprod(m[i], x)
30
+ end
31
+ b
32
+ end
33
+
34
+ def perm(input_words, t)
35
+ p = 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001
36
+ raise 'Length of input_words must be equal to t' unless input_words.length == t
37
+
38
+ rp = get_RP(t)
39
+ rf = 4
40
+ m = get_mds(t)
41
+ rc = get_round_constants(t)
42
+ state_words = input_words.dup
43
+
44
+ rc_counter = 0
45
+ # First full rounds
46
+ for r in 0...rf
47
+ # Round constants, nonlinear layer, matrix multiplication
48
+ for i in 0...t
49
+ state_words[i] = (state_words[i] + rc[rc_counter]) % p
50
+ rc_counter += 1
51
+ end
52
+ for i in 0...t
53
+ state_words[i] = s_box(state_words[i])
54
+ end
55
+ state_words = matrix_multiply(m, state_words)
56
+ end
57
+
58
+ # Middle partial rounds
59
+ for r in 0...rp
60
+ # Round constants, nonlinear layer, matrix multiplication
61
+ for i in 0...t
62
+ state_words[i] = (state_words[i] + rc[rc_counter]) % p
63
+ rc_counter += 1
64
+ end
65
+ state_words[0] = s_box(state_words[0])
66
+ state_words = matrix_multiply(m, state_words)
67
+ end
68
+
69
+ # Last full rounds
70
+ for r in 0...rf
71
+ # Round constants, nonlinear layer, matrix multiplication
72
+ for i in 0...t
73
+ state_words[i] = (state_words[i] + rc[rc_counter]) % p
74
+ rc_counter += 1
75
+ end
76
+ for i in 0...t
77
+ state_words[i] = s_box(state_words[i])
78
+ end
79
+ state_words = matrix_multiply(m, state_words)
80
+ end
81
+
82
+ raise 'rc_counter must be equal to length of RC' unless rc_counter == rc.length
83
+
84
+ state_words
85
+ end
86
+
87
+ def hash(input, arity)
88
+ raise 'The length of the input must be equal to the arity' unless input.length == arity
89
+
90
+ copied_input = input.dup
91
+ state = [0] + copied_input
92
+ output = perm(state, arity + 1)
93
+ output[0]
94
+ end
95
+
96
+ def linear_hash_many(inputs, arity = 16)
97
+ # base case
98
+ if inputs.length <= arity
99
+ base_hash_inputs = inputs + ([0] * (arity - inputs.length))
100
+ current_hash = hash(base_hash_inputs, arity)
101
+ remaining_inputs = []
102
+ else
103
+ base_hash_inputs = inputs[0...arity]
104
+ remaining_inputs = inputs[arity..-1]
105
+ current_hash = hash(base_hash_inputs, arity)
106
+ end
107
+
108
+ while remaining_inputs.length > 0
109
+ if remaining_inputs.length <= arity - 1
110
+ hash_inputs = [current_hash] + remaining_inputs + ([0] * (arity - remaining_inputs.length - 1))
111
+ remaining_inputs = []
112
+ current_hash = hash(hash_inputs, arity)
113
+ else
114
+ hash_inputs = [current_hash] + remaining_inputs[0...arity - 1]
115
+ remaining_inputs = remaining_inputs[arity - 1..-1]
116
+ current_hash = hash(hash_inputs, arity)
117
+ end
118
+ end
119
+
120
+ current_hash
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,2 @@
1
+ require 'poseidon/constant'
2
+ require 'poseidon/hash'
metadata ADDED
@@ -0,0 +1,45 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: poseidon_hash
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Nhan Vu
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2023-06-29 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Ruby implementation of Poseidon hash function
14
+ email: nhannvu.19@gmail.com
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - lib/poseidon/constant.rb
20
+ - lib/poseidon/hash.rb
21
+ - lib/poseidon_hash.rb
22
+ homepage: https://rubygems.org/gems/poseidon_hash
23
+ licenses:
24
+ - MIT
25
+ metadata: {}
26
+ post_install_message:
27
+ rdoc_options: []
28
+ require_paths:
29
+ - lib
30
+ required_ruby_version: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ required_rubygems_version: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ requirements: []
41
+ rubygems_version: 3.2.33
42
+ signing_key:
43
+ specification_version: 4
44
+ summary: Poseidon hash function
45
+ test_files: []