digest-kangarootwelve 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d71e89ddf0629c43ac51a05492c19ae291007522
4
+ data.tar.gz: 605df33fb6c7b786262604f294aaae5269bc5ec9
5
+ SHA512:
6
+ metadata.gz: 1b7fc73a0210dbcc229a767daf6f90c4fefc269a608cc87001af9c59017732abac18c03d43c2e6588076aef3bac5f92d60ebb4e559ba3055c687269cf335803b
7
+ data.tar.gz: 4b488488ea6306425388fd69f6f9a56444feb584c86df1cea3d412746569f443cd88f32a37b02f43c23efccd7d71688a074575c4f7a56299a947e239bb72519e
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2017 konsolebox
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,84 @@
1
+ # digest-kangarootwelve-ruby
2
+
3
+ An implementation of KangarooTwelve for Ruby that works on top of Digest::Base.
4
+
5
+ It allows hashing with different digest lengths and different customization
6
+ strings.
7
+
8
+ See http://kangarootwelve.org/ to know more about the hashing algorithm.
9
+
10
+ The core implementation was extracted/generated from the KCP
11
+ (https://github.com/gvanas/KeccakCodePackage). The extension currently utilizes
12
+ the compact version, but I'll try to use a more optimized version in the future,
13
+ and also consider adding a capability to use an external library that can be
14
+ natively optimized (e.g. libkeccak.a), without compromisations.
15
+
16
+ ## Installation
17
+
18
+ Add this line to your application's Gemfile:
19
+
20
+ gem 'digest-kangarootwelve'
21
+
22
+ And then execute:
23
+
24
+ $ bundle
25
+
26
+ Or install it yourself as:
27
+
28
+ $ gem install digest-kangarootwelve
29
+
30
+ ## Example Usage
31
+
32
+ require 'digest/kangarootwelve'
33
+
34
+ klass = Digest::KangarooTwelve[32]
35
+ => Digest::KangarooTwelve_32
36
+
37
+ hash = klass.new
38
+ => #<Digest::KangarooTwelve_32|32|65536||1ac2d450fc3b4205d19da7bfca1b37513c0803577ac7167f06fe2ce1f0ef39e5>
39
+
40
+ hash.hexdigest("abc")
41
+ => "ab174f328c55a5510b0b209791bf8b60e801a7cfc2aa42042dcb8f547fbe3a7d"
42
+
43
+ Digest::KangarooTwelve[32].new.hexdigest("abc")
44
+ => "ab174f328c55a5510b0b209791bf8b60e801a7cfc2aa42042dcb8f547fbe3a7d"
45
+
46
+ Digest::KangarooTwelve.default
47
+ => Digest::KangarooTwelve_64
48
+
49
+ Digest::KangarooTwelve.implement(digest_length: 32, customization: "secret")
50
+ => Digest::KangarooTwelve_32_65536_736563726574
51
+
52
+ Digest::KangarooTwelve.implement(name: "SecretHash", digest_length: 32, customization: "secret")
53
+ => Digest::SecretHash
54
+
55
+ Digest::KangarooTwelve.implement(n: "SecretHash", d: 32, c: "secret")
56
+ => Digest::SecretHash
57
+
58
+ Digest::SecretHash.new.hexdigest("abc")
59
+ => "dc1fd53f85402e2b34fa92bd87593dd9c3fe6cc49d9db6c05dc0cf26c6a7e03f"
60
+
61
+ Digest::KangarooTwelve.implement(name: nil, digest_length: 48)
62
+ => #<Class:0x000000015fe8e8>
63
+
64
+ ## Details
65
+
66
+ For details on how to use the methods, please examine the comments in
67
+ `ext/digest/kangarootwelve/ext.c`, or try to run
68
+ `ri 'Digest::KangarooTwelve'` or
69
+ `ri 'Digest::KangarooTwelve::<method_name>'`. I'll try to provide a more
70
+ readable format of the documentation for the API soon.
71
+
72
+ You can use the implementation classes produced by `[]`, `default` or
73
+ `implement`, just like any other implementation class in `Digest`
74
+ (e.g. `Digest::SHA1`, `Digest::SHA512`), since they are also derived from
75
+ `Digest::Base`, and are programmed to work the way an implementation class
76
+ that's based on the `Digest` framework should.
77
+
78
+ ## Contributing
79
+
80
+ 1. Fork it ( https://github.com/konsolebox/digest-kangarootwelve-ruby/fork ).
81
+ 2. Create your feature branch (`git checkout -b my-new-feature`).
82
+ 3. Commit your changes (`git commit -am 'Add some feature'`).
83
+ 4. Push to the branch (`git push origin my-new-feature`).
84
+ 5. Create a new Pull Request.
data/Rakefile ADDED
@@ -0,0 +1,20 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rake/testtask'
3
+
4
+ # clean, clobber, compile, and compile:digest/kangarootwelve
5
+ require 'rake/extensiontask'
6
+ Rake::ExtensionTask.new('digest/kangarootwelve', Bundler::GemHelper.gemspec)
7
+
8
+ # test
9
+ Rake::TestTask.new(:test => :compile) do |t|
10
+ t.test_files = FileList['test/test.rb']
11
+ t.verbose = true
12
+ end
13
+
14
+ # clean
15
+ task :clean do
16
+ list = FileList.new('test/*.tmp', 'test/*.temp')
17
+ rm_f list unless list.empty?
18
+ end
19
+
20
+ # Run `rake --tasks` for a list of tasks.
@@ -0,0 +1,29 @@
1
+ # coding: utf-8
2
+
3
+ lib = File.expand_path('../lib', __FILE__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require 'digest/kangarootwelve/version'
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = "digest-kangarootwelve"
9
+ spec.version = Digest::KangarooTwelve::VERSION
10
+ spec.authors = ["konsolebox"]
11
+ spec.email = ["konsolebox@gmail.com"]
12
+ spec.summary = "KangarooTwelve for Ruby"
13
+ spec.description = "An implementation of KangarooTwelve for Ruby that works on top of Digest::Base."
14
+ spec.homepage = "https://github.com/konsolebox/digest-kangaootwelve-ruby"
15
+ spec.license = "MIT"
16
+
17
+ spec.required_ruby_version = '>= 2.2'
18
+
19
+ spec.files = `git ls-files -z`.split("\x0")
20
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
21
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
22
+ spec.require_paths = ["lib"]
23
+
24
+ spec.add_development_dependency "rake"
25
+ spec.add_development_dependency "rake-compiler", "~> 1.0"
26
+ spec.add_development_dependency "minitest", "~> 5.8"
27
+
28
+ spec.extensions = %w[ext/digest/kangarootwelve/extconf.rb]
29
+ end
@@ -0,0 +1,275 @@
1
+ /*
2
+ Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni,
3
+ Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby
4
+ denoted as "the implementer".
5
+
6
+ For more information, feedback or questions, please refer to our websites:
7
+ http://keccak.noekeon.org/
8
+ http://keyak.noekeon.org/
9
+ http://ketje.noekeon.org/
10
+
11
+ To the extent possible under law, the implementer has waived all copyright
12
+ and related or neighboring rights to the source code in this file.
13
+ http://creativecommons.org/publicdomain/zero/1.0/
14
+ */
15
+
16
+ #include <string.h>
17
+ #include "KangarooTwelve.h"
18
+ #ifndef KeccakP1600timesN_excluded
19
+ #include "KeccakP-1600-times2-SnP.h"
20
+ #include "KeccakP-1600-times4-SnP.h"
21
+ #include "KeccakP-1600-times8-SnP.h"
22
+ #endif
23
+
24
+ #define chunkSize 8192
25
+ #define laneSize 8
26
+ #define suffixLeaf 0x0B /* '110': message hop, simple padding, inner node */
27
+
28
+ #define security 128
29
+ #define capacity (2*security)
30
+ #define capacityInBytes (capacity/8)
31
+ #define capacityInLanes (capacityInBytes/laneSize)
32
+ #define rate (1600-capacity)
33
+ #define rateInBytes (rate/8)
34
+ #define rateInLanes (rateInBytes/laneSize)
35
+
36
+ #define ParallelSpongeFastLoop( Parallellism ) \
37
+ while ( inLen >= Parallellism * chunkSize ) { \
38
+ ALIGN(KeccakP1600times##Parallellism##_statesAlignment) unsigned char states[KeccakP1600times##Parallellism##_statesSizeInBytes]; \
39
+ unsigned char intermediate[Parallellism*capacityInBytes]; \
40
+ unsigned int localBlockLen = chunkSize; \
41
+ const unsigned char * localInput = input; \
42
+ unsigned int i; \
43
+ unsigned int fastLoopOffset; \
44
+ \
45
+ KeccakP1600times##Parallellism##_StaticInitialize(); \
46
+ KeccakP1600times##Parallellism##_InitializeAll(states); \
47
+ fastLoopOffset = KeccakP1600times##Parallellism##_12rounds_FastLoop_Absorb(states, rateInLanes, chunkSize / laneSize, rateInLanes, localInput, Parallellism * chunkSize); \
48
+ localBlockLen -= fastLoopOffset; \
49
+ localInput += fastLoopOffset; \
50
+ for ( i = 0; i < Parallellism; ++i, localInput += chunkSize ) { \
51
+ KeccakP1600times##Parallellism##_AddBytes(states, i, localInput, 0, localBlockLen); \
52
+ KeccakP1600times##Parallellism##_AddByte(states, i, suffixLeaf, localBlockLen); \
53
+ KeccakP1600times##Parallellism##_AddByte(states, i, 0x80, rateInBytes-1); \
54
+ } \
55
+ KeccakP1600times##Parallellism##_PermuteAll_12rounds(states); \
56
+ input += Parallellism * chunkSize; \
57
+ inLen -= Parallellism * chunkSize; \
58
+ ktInstance->blockNumber += Parallellism; \
59
+ KeccakP1600times##Parallellism##_ExtractLanesAll(states, intermediate, capacityInLanes, capacityInLanes ); \
60
+ if (KeccakWidth1600_12rounds_SpongeAbsorb(&ktInstance->finalNode, intermediate, Parallellism * capacityInBytes) != 0) return 1; \
61
+ }
62
+
63
+ #define ParallelSpongeLoop( Parallellism ) \
64
+ while ( inLen >= Parallellism * chunkSize ) { \
65
+ ALIGN(KeccakP1600times##Parallellism##_statesAlignment) unsigned char states[KeccakP1600times##Parallellism##_statesSizeInBytes]; \
66
+ unsigned char intermediate[Parallellism*capacityInBytes]; \
67
+ unsigned int localBlockLen = chunkSize; \
68
+ const unsigned char * localInput = input; \
69
+ unsigned int i; \
70
+ \
71
+ KeccakP1600times##Parallellism##_StaticInitialize(); \
72
+ KeccakP1600times##Parallellism##_InitializeAll(states); \
73
+ while(localBlockLen >= rateInBytes) { \
74
+ KeccakP1600times##Parallellism##_AddLanesAll(states, localInput, rateInLanes, chunkSize / laneSize); \
75
+ KeccakP1600times##Parallellism##_PermuteAll_12rounds(states); \
76
+ localBlockLen -= rateInBytes; \
77
+ localInput += rateInBytes; \
78
+ } \
79
+ for ( i = 0; i < Parallellism; ++i, localInput += chunkSize ) { \
80
+ KeccakP1600times##Parallellism##_AddBytes(states, i, localInput, 0, localBlockLen); \
81
+ KeccakP1600times##Parallellism##_AddByte(states, i, suffixLeaf, localBlockLen); \
82
+ KeccakP1600times##Parallellism##_AddByte(states, i, 0x80, rateInBytes-1); \
83
+ } \
84
+ KeccakP1600times##Parallellism##_PermuteAll_12rounds(states); \
85
+ input += Parallellism * chunkSize; \
86
+ inLen -= Parallellism * chunkSize; \
87
+ ktInstance->blockNumber += Parallellism; \
88
+ KeccakP1600times##Parallellism##_ExtractLanesAll(states, intermediate, capacityInLanes, capacityInLanes ); \
89
+ if (KeccakWidth1600_12rounds_SpongeAbsorb(&ktInstance->finalNode, intermediate, Parallellism * capacityInBytes) != 0) return 1; \
90
+ }
91
+
92
+ static unsigned int right_encode( unsigned char * encbuf, size_t value )
93
+ {
94
+ unsigned int n, i;
95
+ size_t v;
96
+
97
+ for ( v = value, n = 0; v && (n < sizeof(size_t)); ++n, v >>= 8 )
98
+ ; /* empty */
99
+ for ( i = 1; i <= n; ++i )
100
+ encbuf[i-1] = (unsigned char)(value >> (8 * (n-i)));
101
+ encbuf[n] = (unsigned char)n;
102
+ return n + 1;
103
+ }
104
+
105
+ int KangarooTwelve_Initialize(KangarooTwelve_Instance *ktInstance, size_t outputLen)
106
+ {
107
+ ktInstance->fixedOutputLength = outputLen;
108
+ ktInstance->queueAbsorbedLen = 0;
109
+ ktInstance->blockNumber = 0;
110
+ ktInstance->phase = ABSORBING;
111
+ return KeccakWidth1600_12rounds_SpongeInitialize(&ktInstance->finalNode, rate, capacity);
112
+ }
113
+
114
+ int KangarooTwelve_Update(KangarooTwelve_Instance *ktInstance, const unsigned char *input, size_t inLen)
115
+ {
116
+ if (ktInstance->phase != ABSORBING)
117
+ return 1;
118
+
119
+ if ( ktInstance->blockNumber == 0 ) {
120
+ /* First block, absorb in final node */
121
+ unsigned int len = (inLen < (chunkSize - ktInstance->queueAbsorbedLen)) ? inLen : (chunkSize - ktInstance->queueAbsorbedLen);
122
+ if (KeccakWidth1600_12rounds_SpongeAbsorb(&ktInstance->finalNode, input, len) != 0)
123
+ return 1;
124
+ input += len;
125
+ inLen -= len;
126
+ ktInstance->queueAbsorbedLen += len;
127
+ if ( (ktInstance->queueAbsorbedLen == chunkSize) && (inLen != 0) ) {
128
+ /* First block complete and more input data available, finalize it */
129
+ const unsigned char padding = 0x03; /* '110^6': message hop, simple padding */
130
+ ktInstance->queueAbsorbedLen = 0;
131
+ ktInstance->blockNumber = 1;
132
+ if (KeccakWidth1600_12rounds_SpongeAbsorb(&ktInstance->finalNode, &padding, 1) != 0)
133
+ return 1;
134
+ ktInstance->finalNode.byteIOIndex = (ktInstance->finalNode.byteIOIndex + 7) & ~7; /* Zero padding up to 64 bits */
135
+ }
136
+ }
137
+ else if ( ktInstance->queueAbsorbedLen != 0 ) {
138
+ /* There is data in the queue, absorb further in queue until block complete */
139
+ unsigned int len = (inLen < (chunkSize - ktInstance->queueAbsorbedLen)) ? inLen : (chunkSize - ktInstance->queueAbsorbedLen);
140
+ if (KeccakWidth1600_12rounds_SpongeAbsorb(&ktInstance->queueNode, input, len) != 0)
141
+ return 1;
142
+ input += len;
143
+ inLen -= len;
144
+ ktInstance->queueAbsorbedLen += len;
145
+ if ( ktInstance->queueAbsorbedLen == chunkSize ) {
146
+ unsigned char intermediate[capacityInBytes];
147
+ ktInstance->queueAbsorbedLen = 0;
148
+ ++ktInstance->blockNumber;
149
+ if (KeccakWidth1600_12rounds_SpongeAbsorbLastFewBits(&ktInstance->queueNode, suffixLeaf) != 0)
150
+ return 1;
151
+ if (KeccakWidth1600_12rounds_SpongeSqueeze(&ktInstance->queueNode, intermediate, capacityInBytes) != 0)
152
+ return 1;
153
+ if (KeccakWidth1600_12rounds_SpongeAbsorb(&ktInstance->finalNode, intermediate, capacityInBytes) != 0)
154
+ return 1;
155
+ }
156
+ }
157
+
158
+ #if defined(KeccakP1600times8_implementation)
159
+ #if defined(KeccakP1600times8_12rounds_FastLoop_supported)
160
+ ParallelSpongeFastLoop( 8 )
161
+ #else
162
+ ParallelSpongeLoop( 8 )
163
+ #endif
164
+ #endif
165
+
166
+ #if defined(KeccakP1600times4_implementation)
167
+ #if defined(KeccakP1600times4_12rounds_FastLoop_supported)
168
+ ParallelSpongeFastLoop( 4 )
169
+ #else
170
+ ParallelSpongeLoop( 4 )
171
+ #endif
172
+ #endif
173
+
174
+ #if defined(KeccakP1600times2_implementation)
175
+ #if defined(KeccakP1600times2_12rounds_FastLoop_supported)
176
+ ParallelSpongeFastLoop( 2 )
177
+ #else
178
+ ParallelSpongeLoop( 2 )
179
+ #endif
180
+ #endif
181
+
182
+ while ( inLen > 0 ) {
183
+ unsigned int len = (inLen < chunkSize) ? inLen : chunkSize;
184
+ if (KeccakWidth1600_12rounds_SpongeInitialize(&ktInstance->queueNode, rate, capacity) != 0)
185
+ return 1;
186
+ if (KeccakWidth1600_12rounds_SpongeAbsorb(&ktInstance->queueNode, input, len) != 0)
187
+ return 1;
188
+ input += len;
189
+ inLen -= len;
190
+ if ( len == chunkSize ) {
191
+ unsigned char intermediate[capacityInBytes];
192
+ ++ktInstance->blockNumber;
193
+ if (KeccakWidth1600_12rounds_SpongeAbsorbLastFewBits(&ktInstance->queueNode, suffixLeaf) != 0)
194
+ return 1;
195
+ if (KeccakWidth1600_12rounds_SpongeSqueeze(&ktInstance->queueNode, intermediate, capacityInBytes) != 0)
196
+ return 1;
197
+ if (KeccakWidth1600_12rounds_SpongeAbsorb(&ktInstance->finalNode, intermediate, capacityInBytes) != 0)
198
+ return 1;
199
+ }
200
+ else
201
+ ktInstance->queueAbsorbedLen = len;
202
+ }
203
+
204
+ return 0;
205
+ }
206
+
207
+ int KangarooTwelve_Final(KangarooTwelve_Instance *ktInstance, unsigned char * output, const unsigned char * customization, size_t customLen)
208
+ {
209
+ unsigned char encbuf[sizeof(size_t)+1+2];
210
+ unsigned char padding;
211
+
212
+ if (ktInstance->phase != ABSORBING)
213
+ return 1;
214
+
215
+ /* Absorb customization | right_encode(customLen) */
216
+ if ((customLen != 0) && (KangarooTwelve_Update(ktInstance, customization, customLen) != 0))
217
+ return 1;
218
+ if (KangarooTwelve_Update(ktInstance, encbuf, right_encode(encbuf, customLen)) != 0)
219
+ return 1;
220
+
221
+ if ( ktInstance->blockNumber == 0 ) {
222
+ /* Non complete first block in final node, pad it */
223
+ padding = 0x07; /* '11': message hop, final node */
224
+ }
225
+ else {
226
+ unsigned int n;
227
+
228
+ if ( ktInstance->queueAbsorbedLen != 0 ) {
229
+ /* There is data in the queue node */
230
+ unsigned char intermediate[capacityInBytes];
231
+ ++ktInstance->blockNumber;
232
+ if (KeccakWidth1600_12rounds_SpongeAbsorbLastFewBits(&ktInstance->queueNode, suffixLeaf) != 0)
233
+ return 1;
234
+ if (KeccakWidth1600_12rounds_SpongeSqueeze(&ktInstance->queueNode, intermediate, capacityInBytes) != 0)
235
+ return 1;
236
+ if (KeccakWidth1600_12rounds_SpongeAbsorb(&ktInstance->finalNode, intermediate, capacityInBytes) != 0)
237
+ return 1;
238
+ }
239
+ --ktInstance->blockNumber; /* Absorb right_encode(number of Chaining Values) || 0xFF || 0xFF */
240
+ n = right_encode(encbuf, ktInstance->blockNumber);
241
+ encbuf[n++] = 0xFF;
242
+ encbuf[n++] = 0xFF;
243
+ if (KeccakWidth1600_12rounds_SpongeAbsorb(&ktInstance->finalNode, encbuf, n) != 0)
244
+ return 1;
245
+ padding = 0x06; /* '01': chaining hop, final node */
246
+ }
247
+ if (KeccakWidth1600_12rounds_SpongeAbsorbLastFewBits(&ktInstance->finalNode, padding) != 0)
248
+ return 1;
249
+ if ( ktInstance->fixedOutputLength != 0 ) {
250
+ ktInstance->phase = FINAL;
251
+ return KeccakWidth1600_12rounds_SpongeSqueeze(&ktInstance->finalNode, output, ktInstance->fixedOutputLength);
252
+ }
253
+ ktInstance->phase = SQUEEZING;
254
+ return 0;
255
+ }
256
+
257
+ int KangarooTwelve_Squeeze(KangarooTwelve_Instance *ktInstance, unsigned char * output, size_t outputLen)
258
+ {
259
+ if (ktInstance->phase != SQUEEZING)
260
+ return 1;
261
+ return KeccakWidth1600_12rounds_SpongeSqueeze(&ktInstance->finalNode, output, outputLen);
262
+ }
263
+
264
+ int KangarooTwelve( const unsigned char * input, size_t inLen, unsigned char * output, size_t outLen, const unsigned char * customization, size_t customLen )
265
+ {
266
+ KangarooTwelve_Instance ktInstance;
267
+
268
+ if (outLen == 0)
269
+ return 1;
270
+ if (KangarooTwelve_Initialize(&ktInstance, outLen) != 0)
271
+ return 1;
272
+ if (KangarooTwelve_Update(&ktInstance, input, inLen) != 0)
273
+ return 1;
274
+ return KangarooTwelve_Final(&ktInstance, output, customization, customLen);
275
+ }