sha512t 0.0.1

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.
Files changed (4) hide show
  1. checksums.yaml +7 -0
  2. data/lib/sha512.rb +173 -0
  3. data/lib/sha512t.rb +90 -0
  4. metadata +46 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: fc5405f22e2bfc683bc70da75ffc58cb3a0bce83
4
+ data.tar.gz: 60ce990bf63935afa00266c5d038b81d1056d3f5
5
+ SHA512:
6
+ metadata.gz: 42d3338109350f052f21f15d23ecc897160826fa258a2d5f35f387c95f9b5227187942f8191b8e4f50469415890e13c667c2db811b60f0f733028ba9c5ef8dc5
7
+ data.tar.gz: abcf6e5211d4d20ec5c9cede9209229acc2b5f6de5b0605afd8e49dad6f2825a319b5cc0f17edfd1355f7394fcd825e125e3bbd7f9f2de81038a0cc6c85a392d
data/lib/sha512.rb ADDED
@@ -0,0 +1,173 @@
1
+ # FIPS PUB 180-4 SHA512 hashing
2
+ # written by Frederic Walch
3
+
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software.
9
+
10
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
11
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
12
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
13
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
14
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
15
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
16
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
17
+
18
+ class Sha512
19
+ def initialize
20
+ # SHA-384, SHA-512, SHA-512/224 and SHA-512/256 Constants
21
+ @constants = [ 0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f, 0xe9b5dba58189dbbc,
22
+ 0x3956c25bf348b538, 0x59f111f1b605d019, 0x923f82a4af194f9b, 0xab1c5ed5da6d8118,
23
+ 0xd807aa98a3030242, 0x12835b0145706fbe, 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2,
24
+ 0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x9bdc06a725c71235, 0xc19bf174cf692694,
25
+ 0xe49b69c19ef14ad2, 0xefbe4786384f25e3, 0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65,
26
+ 0x2de92c6f592b0275, 0x4a7484aa6ea6e483, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5,
27
+ 0x983e5152ee66dfab, 0xa831c66d2db43210, 0xb00327c898fb213f, 0xbf597fc7beef0ee4,
28
+ 0xc6e00bf33da88fc2, 0xd5a79147930aa725, 0x06ca6351e003826f, 0x142929670a0e6e70,
29
+ 0x27b70a8546d22ffc, 0x2e1b21385c26c926, 0x4d2c6dfc5ac42aed, 0x53380d139d95b3df,
30
+ 0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x81c2c92e47edaee6, 0x92722c851482353b,
31
+ 0xa2bfe8a14cf10364, 0xa81a664bbc423001, 0xc24b8b70d0f89791, 0xc76c51a30654be30,
32
+ 0xd192e819d6ef5218, 0xd69906245565a910, 0xf40e35855771202a, 0x106aa07032bbd1b8,
33
+ 0x19a4c116b8d2d0c8, 0x1e376c085141ab53, 0x2748774cdf8eeb99, 0x34b0bcb5e19b48a8,
34
+ 0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb, 0x5b9cca4f7763e373, 0x682e6ff3d6b2b8a3,
35
+ 0x748f82ee5defb2fc, 0x78a5636f43172f60, 0x84c87814a1f0ab72, 0x8cc702081a6439ec,
36
+ 0x90befffa23631e28, 0xa4506cebde82bde9, 0xbef9a3f7b2c67915, 0xc67178f2e372532b,
37
+ 0xca273eceea26619c, 0xd186b8c721c0c207, 0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178,
38
+ 0x06f067aa72176fba, 0x0a637dc5a2c898a6, 0x113f9804bef90dae, 0x1b710b35131c471b,
39
+ 0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc, 0x431d67c49c100d4c,
40
+ 0x4cc5d4becb3e42b6, 0x597f299cfc657e2a, 0x5fcb6fab3ad6faec, 0x6c44198c4a475817 ]
41
+ end
42
+
43
+ def preprocessing(message)
44
+ # Preprocessing Step 1: Padding the message
45
+ bytes = message.bytes.to_a
46
+ l = bytes.size * 8
47
+ padded_message = ""
48
+ zero = "0"
49
+
50
+ bytes.each do |byte|
51
+ bit = byte.to_s(2)
52
+ if bit.length < 8
53
+ bit = (zero * (8 - bit.length)) + bit
54
+ end
55
+ padded_message += bit
56
+ end
57
+
58
+ # padding with a one bit
59
+ padded_message += "1"
60
+
61
+ # add k zero bits, where k is the smallest non-negative solution to the equation l+1+k = 896 mod 1024
62
+ blocks = (896-(l+1))
63
+ while blocks < 0 do
64
+ blocks += 1024
65
+ end
66
+ padded_message += zero * blocks
67
+
68
+ # append 128-bit block that is equal to the number of l expressed using a binary representation
69
+ last_bit_block = l.to_s(2)
70
+ if last_bit_block.length < 128
71
+ last_bit_block = (zero * (128 - last_bit_block.length)) + last_bit_block
72
+ end
73
+ padded_message += last_bit_block
74
+
75
+ # Preprocessing Step 2: Parsing the message
76
+ parsed_message = []
77
+ for block in 0..padded_message.size/64-1
78
+ parsed_message.push(padded_message[(64*block)..(64*block)+63])
79
+ end
80
+
81
+ return parsed_message
82
+ end
83
+
84
+ def hash_computation(p, iv)
85
+ # initial hash value
86
+ h0 = iv[0]
87
+ h1 = iv[1]
88
+ h2 = iv[2]
89
+ h3 = iv[3]
90
+ h4 = iv[4]
91
+ h5 = iv[5]
92
+ h6 = iv[6]
93
+ h7 = iv[7]
94
+
95
+ for i in 1..p.size/15
96
+
97
+ # Initialize the eight working variables, a, b, c, d, e, f, g, and h, with the (i-1)-st hash value:
98
+ a, b, c, d, e, f, g, h = h0, h1, h2, h3, h4, h5, h6, h7
99
+ w = []
100
+
101
+ for t in 0..79
102
+ if t < 16
103
+ w[t] = p[((i-1)*16) + t].to_i(2)
104
+ else
105
+ v1 = w[t-2]
106
+ t1 = (v1>>19 | v1<<(64-19)) ^ (v1>>61 | v1<<(64-61)) ^ (v1 >> 6)
107
+ v2 = w[t-15]
108
+ t2 = (v2>>1 | v2<<(64-1)) ^ (v2>>8 | v2<<(64-8)) ^ (v2 >> 7)
109
+
110
+ w[t] = (t1 + w[t-7] + t2 + w[t-16]) % (2**64)
111
+ end
112
+
113
+ t1 = h + ((e>>14 | e<<(64-14)) ^ (e>>18 | e<<(64-18)) ^ (e>>41 | e<<(64-41))) + ((e & f) ^ (~e & g)) + @constants[t] + w[t]
114
+ t2 = ((a>>28 | a<<(64-28)) ^ (a>>34 | a<<(64-34)) ^ (a>>39 | a<<(64-39))) + ((a & b) ^ (a & c) ^ (b & c))
115
+
116
+ h = g
117
+ g = f
118
+ f = e
119
+ e = (d + t1) % (2**64)
120
+ d = c
121
+ c = b
122
+ b = a
123
+ a = (t1 + t2) % (2**64)
124
+ end
125
+
126
+ # Compute the i-th intermediate hash value H(i)
127
+ h0 = (a + h0) % (2**64)
128
+ h1 = (b + h1) % (2**64)
129
+ h2 = (c + h2) % (2**64)
130
+ h3 = (d + h3) % (2**64)
131
+ h4 = (e + h4) % (2**64)
132
+ h5 = (f + h5) % (2**64)
133
+ h6 = (g + h6) % (2**64)
134
+ h7 = (h + h7) % (2**64)
135
+ end
136
+
137
+ hash = [ h0, h1, h2, h3, h4, h5, h6, h7 ]
138
+
139
+ # Convert hash to hex-String
140
+ hash_string = ""
141
+ hash.each do |h|
142
+ temp = h.to_s(16)
143
+ if temp.length < 16
144
+ temp = "0" * (16 - temp.length) + temp
145
+ end
146
+ hash_string += temp
147
+ end
148
+ return hash_string
149
+ end
150
+
151
+
152
+ def self.hash(message)
153
+ # SHA512 initial hash value from FIPS-180
154
+ sha512_initial_hash_value = [ 0x6a09e667f3bcc908,
155
+ 0xbb67ae8584caa73b,
156
+ 0x3c6ef372fe94f82b,
157
+ 0xa54ff53a5f1d36f1,
158
+ 0x510e527fade682d1,
159
+ 0x9b05688c2b3e6c1f,
160
+ 0x1f83d9abfb41bd6b,
161
+ 0x5be0cd19137e2179 ]
162
+
163
+ # Preprocessing
164
+ #
165
+ # consists of two steps:
166
+ # 1. padding the message,
167
+ # 2. parsing the message into message blocks
168
+ parsed_message = Sha512.new.preprocessing(message)
169
+
170
+ # Hash Computation
171
+ return Sha512.new.hash_computation(parsed_message, sha512_initial_hash_value)
172
+ end
173
+ end
data/lib/sha512t.rb ADDED
@@ -0,0 +1,90 @@
1
+ # FIPS PUB 180-4 SHA512 hashing
2
+ # written by Frederic Walch
3
+
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software.
9
+
10
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
11
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
12
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
13
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
14
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
15
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
16
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
17
+
18
+ require_relative 'sha512'
19
+
20
+ class Sha512t
21
+ def digest(t)
22
+ if t < 0
23
+ abort("bitLength cannot be less than 0.")
24
+ end
25
+
26
+ if t > 511
27
+ abort("bitLength cannot be >= 512.")
28
+ end
29
+
30
+ if t % 8 != 0
31
+ abort("bitLength needs to be a multiple of 8.")
32
+ end
33
+
34
+ if t == 384
35
+ abort("bitLength cannot be 384 use SHA384 instead.")
36
+ end
37
+
38
+ if t == 256
39
+ abort("bitLength cannot be 256 use SHA256 instead.")
40
+ end
41
+
42
+ if t == 512
43
+ abort("bitLength cannot be 512 use SHA512 instead.")
44
+ end
45
+ end
46
+
47
+ def generate_iv(iv)
48
+ generated_iv = []
49
+ for i in 0..7
50
+ generated_iv.push(iv[i*16..(i*16)+15].to_i(16))
51
+ end
52
+ return generated_iv
53
+ end
54
+
55
+ def sha512t_truncate(hash, t)
56
+ hash = hash.to_i(16).to_s(2)
57
+ if hash.length < 512
58
+ hash = "0" * (512 - hash.length) + hash
59
+ end
60
+ hash = hash[0..t-1].to_i(2).to_s(16)
61
+
62
+ if hash.length < t/4
63
+ hash = "0" * (t/4 - hash.length) + hash
64
+ end
65
+ return hash
66
+ end
67
+
68
+ def self.hash(message, t)
69
+ # SHA512/t initial hash value from FIPS-180
70
+ sha512t_initial_iv = [ 0x6a09e667f3bcc908 ^ 0xa5a5a5a5a5a5a5a5,
71
+ 0xbb67ae8584caa73b ^ 0xa5a5a5a5a5a5a5a5,
72
+ 0x3c6ef372fe94f82b ^ 0xa5a5a5a5a5a5a5a5,
73
+ 0xa54ff53a5f1d36f1 ^ 0xa5a5a5a5a5a5a5a5,
74
+ 0x510e527fade682d1 ^ 0xa5a5a5a5a5a5a5a5,
75
+ 0x9b05688c2b3e6c1f ^ 0xa5a5a5a5a5a5a5a5,
76
+ 0x1f83d9abfb41bd6b ^ 0xa5a5a5a5a5a5a5a5,
77
+ 0x5be0cd19137e2179 ^ 0xa5a5a5a5a5a5a5a5 ]
78
+
79
+ Sha512t.new.digest(t)
80
+ # Generate SHA-512/t IV
81
+ preprocessed_massage = Sha512.new.preprocessing("SHA-512/#{t}")
82
+ computed_iv = Sha512.new.hash_computation(preprocessed_massage, sha512t_initial_iv)
83
+ sha512t_iv = Sha512t.new.generate_iv(computed_iv)
84
+
85
+ # Hash with SHA-512/t IV and truncate t-bits
86
+ preprocessed_massage = Sha512.new.preprocessing(message)
87
+ sha512t_untruncated = Sha512.new.hash_computation(preprocessed_massage, sha512t_iv)
88
+ return Sha512t.new.sha512t_truncate(sha512t_untruncated, t)
89
+ end
90
+ end
metadata ADDED
@@ -0,0 +1,46 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sha512t
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Frederic Walch
8
+ - Maximilian Bielefeld
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2015-06-18 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: A simple gem to generate sha512/t hashes.
15
+ email: fredericwalch@informatik.hu-berlin.de
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - lib/sha512.rb
21
+ - lib/sha512t.rb
22
+ homepage: ''
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
+ rubyforge_project:
42
+ rubygems_version: 2.0.14
43
+ signing_key:
44
+ specification_version: 4
45
+ summary: sha512/t hashing
46
+ test_files: []