sha3 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of sha3 might be problematic. Click here for more details.

data/.document CHANGED
@@ -1,3 +1,4 @@
1
- -
1
+ -
2
+ README.rdoc
2
3
  ChangeLog.rdoc
3
4
  LICENSE.txt
data/.gitignore CHANGED
@@ -1,5 +1,6 @@
1
1
  *.gem
2
2
  *.rbc
3
+ *.rbx
3
4
  .bundle
4
5
  .config
5
6
  coverage
@@ -17,10 +18,6 @@ tmp/
17
18
  _yardoc
18
19
  doc/
19
20
 
20
- install.sh
21
21
  *.lock
22
-
23
- *.bundle
24
-
25
- spec/bench.rb
26
- .rbx/
22
+ *.so
23
+ Makefile
data/.travis.yml CHANGED
@@ -2,8 +2,14 @@ language: ruby
2
2
  rvm:
3
3
  - 1.9.3
4
4
  - 1.9.2
5
+ - 1.8.7
6
+ - ruby-head
5
7
  - rbx-18mode
6
8
  - rbx-19mode
7
- - 1.8.7
9
+ - ree
10
+
11
+ gemfile: Gemfile.ci
8
12
 
9
- gemfile: Gemfile.ci
13
+ branches:
14
+ only:
15
+ - master
data/.yardopts CHANGED
@@ -1 +1 @@
1
- --markup rdoc --title "sha3 Documentation" --protected
1
+ lib/**/*.rb ext/**/_sha3.c --markup rdoc --title "sha3 Documentation" --protected
data/ChangeLog.rdoc CHANGED
@@ -6,3 +6,6 @@
6
6
 
7
7
  * Replaced Keccak reference code with optimized (~10x faster)
8
8
 
9
+ === 0.2.0 / 2012-11-1
10
+
11
+ * SHA3::Digest: A proper ::Digest subclass.
data/README.rdoc CHANGED
@@ -1,44 +1,105 @@
1
- = sha3 {<img src="https://secure.travis-ci.org/johanns/sha3.png" alt="Build Status" />}[http://travis-ci.org/johanns/sha3]
1
+ = sha3
2
2
 
3
- * {Homepage}[https://github.com/johanns/sha3#readme]
4
- * {Issues}[https://github.com/johanns/sha3/issues]
5
- * {Documentation}[http://rubydoc.info/gems/sha3/frames]
3
+ {<img src="https://secure.travis-ci.org/johanns/sha3.png" alt="Build Status" />}[http://travis-ci.org/johanns/sha3]
4
+ Home :: https://github.com/johanns/sha3#readme
5
+ Issues :: https://github.com/johanns/sha3/issues
6
+ Documentation :: http://rubydoc.info/gems/sha3/frames
6
7
 
7
8
  == Description
8
9
 
9
- A native SHA3 Ruby gem.
10
+ <em>SHA3 for Ruby</em> is a native (C) implementation of Keccak (SHA3) cryptographic hashing algorithm.
10
11
 
11
- == Features/Status/Etc.
12
+ +SHA3::Digest+ is a *Digest*[http://www.ruby-doc.org/stdlib-1.9.3/libdoc/digest/rdoc/Digest.html] compliant _subclass_ with complete interface support.
12
13
 
13
- 4th Oct. 2012: This is very alpha quality code, and not suitable for production.
14
+ +SHA3::Digest.compute()+ method provides support for bit-length hashing.
14
15
 
15
- == Install
16
+ == Releases
17
+
18
+ *0.1.x* :: Alpha code, and not suitable for production.
19
+ *0.2.0* :: Production worthy, but breaks API compatibility with 0.1.x. Backward-compatibility will be maintained henceforth.
20
+
21
+ == Installation
16
22
 
17
23
  $ gem install sha3
18
24
 
19
- == Examples
25
+ == Usage
20
26
 
21
27
  require 'sha3'
22
28
 
23
- # Basic usage
24
- SHA3::digest_224("Crazy Man's Utopia")
25
- => "\xF8\x1A4\xACW6\v\x01A \x99\x11i\x91\xB3q\xB5\xF5\x04\xD4\x88fn\xC6\xA7\xEA\xBBb"
29
+ Valid hash bit-lengths are: *224*, *256*, *384*, *512*. You may also use corresponding symbols when instantiating a new instance or calling the +compute()+ method:
30
+
31
+ :sha224
32
+ :sha256
33
+ :sha384
34
+ :sha512
35
+
36
+ === Basics
37
+
38
+ # Instantiate a new SHA3::Digest class with 256 bit length
39
+ s = SHA3::Digest.new(:sha256)
40
+ # => #<SHA3::Digest: c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470>
41
+
42
+ # Update hash state, and compute new value
43
+ s.update "Compute Me"
44
+ # => #<SHA3::Digest: c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470>
45
+
46
+ # << is an .update() alias
47
+ s << "Me too"
48
+ # => #<SHA3::Digest: e26f539eee3a05c52eb1f9439652d23343adea9764f011da232d24cd6d19924a>
49
+
50
+ # Print digest bytes string
51
+ puts s.digest
52
+
53
+ # Print digest hex string
54
+ puts s.hexdigest
55
+
56
+ === Hashing a file
57
+
58
+ # Compute the hash value for given file, and return the result as hex
59
+ s = SHA3::Digest.new(224).file("my_fantastical_file.bin").hexdigest
60
+
61
+ === Bit-length hashing
62
+
63
+ # Compute hash of "011"
64
+ SHA3::Digest.compute(:sha224, "\xC0", 3).unpack("H*")
65
+ # => ["2b695a6fd92a2b3f3ce9cfca617d22c9bb52815dd59a9719b01bad25"]
66
+
67
+ == Development
26
68
 
27
- # A bit more advanced
28
- SHA3::digest("Crazy Man's Utopia", 36, 512).unpack("H*")
29
- => ["bc9d6cea2083c219c80d2f3...884059103313040bcf73562"]
69
+ * Native build tools (e.g., GCC, Minigw, etc.)
70
+ * Gems: rubygems-tasks, rake, rspec, yard
30
71
 
31
- == Requirements
72
+ == RSpec
32
73
 
33
- Native build environment (GCC 4.x).
74
+ Call +rake+ to run the included RSpec tests.
34
75
 
35
- Tested with Rubies (see build status up-top):
76
+ Please note that only a small subset of test vectors are included in this source repository; however, the complete test vectors suite is available for download. Simply run the +test.sh+ shell script (available in the root of source directory) to generate full bit-length RSpec test files.
36
77
 
37
- - 1.9.3
38
- - 1.9.2
39
- - 1.8.7
78
+ sh test.sh
79
+
80
+ == Rubies
81
+
82
+ Tested with Rubies:
83
+
84
+ - MRI 1.9.3
85
+ - MRI 1.9.2
86
+ - MRI 1.8.7
87
+ - MRI Ruby-Head
40
88
  - Rubinius (18mode)
41
89
  - Rubinius (19mode)
90
+ - ree
91
+
92
+ On:
93
+
94
+ - Ubuntu 12.04, 12.10
95
+ - Windows 7, 8
96
+ - Mac OS X 10.8
97
+
98
+ == TO DO:
99
+
100
+ * Documentation (resolve order issue with Yard)!
101
+ * Add support for arbitrary length hashes.
102
+ * Add hex output support to compute method.
42
103
 
43
104
  == Copyright
44
105
 
data/Rakefile CHANGED
@@ -47,7 +47,7 @@ begin
47
47
  ext.name = 'sha3_n'
48
48
  ext.ext_dir = 'ext/sha3'
49
49
  ext.tmp_dir = 'tmp'
50
- ext.source_pattern = "*.{c,cpp}"
50
+ ext.source_pattern = "*.{c}"
51
51
  end
52
52
  rescue LoadError => e
53
53
  task :compile do
@@ -0,0 +1,300 @@
1
+ /*
2
+ The Keccak sponge function, designed by Guido Bertoni, Joan Daemen,
3
+ Michaël Peeters and Gilles Van Assche. For more information, feedback or
4
+ questions, please refer to our website: http://keccak.noekeon.org/
5
+
6
+ Implementation by the designers,
7
+ hereby denoted as "the implementer".
8
+
9
+ To the extent possible under law, the implementer has waived all copyright
10
+ and related or neighboring rights to the source code in this file.
11
+ http://creativecommons.org/publicdomain/zero/1.0/
12
+ */
13
+
14
+ #include <stdio.h>
15
+ #include <string.h>
16
+ #include "brg_endian.h"
17
+ #include "displayIntermediateValues.h"
18
+ #include "KeccakNISTInterface.h"
19
+ #include "KeccakF-1600-interface.h"
20
+
21
+ typedef unsigned char UINT8;
22
+ typedef unsigned long long int UINT64;
23
+
24
+ #define nrRounds 24
25
+ UINT64 KeccakRoundConstants[nrRounds];
26
+ #define nrLanes 25
27
+ unsigned int KeccakRhoOffsets[nrLanes];
28
+
29
+ void KeccakPermutationOnWords(UINT64 *state);
30
+ void theta(UINT64 *A);
31
+ void rho(UINT64 *A);
32
+ void pi(UINT64 *A);
33
+ void chi(UINT64 *A);
34
+ void iota(UINT64 *A, unsigned int indexRound);
35
+
36
+ void fromBytesToWords(UINT64 *stateAsWords, const unsigned char *state)
37
+ {
38
+ unsigned int i, j;
39
+
40
+ for(i=0; i<(KeccakPermutationSize/64); i++) {
41
+ stateAsWords[i] = 0;
42
+ for(j=0; j<(64/8); j++)
43
+ stateAsWords[i] |= (UINT64)(state[i*(64/8)+j]) << (8*j);
44
+ }
45
+ }
46
+
47
+ void fromWordsToBytes(unsigned char *state, const UINT64 *stateAsWords)
48
+ {
49
+ unsigned int i, j;
50
+
51
+ for(i=0; i<(KeccakPermutationSize/64); i++)
52
+ for(j=0; j<(64/8); j++)
53
+ state[i*(64/8)+j] = (stateAsWords[i] >> (8*j)) & 0xFF;
54
+ }
55
+
56
+ void KeccakPermutation(unsigned char *state)
57
+ {
58
+ #if (PLATFORM_BYTE_ORDER != IS_LITTLE_ENDIAN)
59
+ UINT64 stateAsWords[KeccakPermutationSize/64];
60
+ #endif
61
+
62
+ displayStateAsBytes(1, "Input of permutation", state);
63
+ #if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN)
64
+ KeccakPermutationOnWords((UINT64*)state);
65
+ #else
66
+ fromBytesToWords(stateAsWords, state);
67
+ KeccakPermutationOnWords(stateAsWords);
68
+ fromWordsToBytes(state, stateAsWords);
69
+ #endif
70
+ displayStateAsBytes(1, "State after permutation", state);
71
+ }
72
+
73
+ void KeccakPermutationAfterXor(unsigned char *state, const unsigned char *data, unsigned int dataLengthInBytes)
74
+ {
75
+ unsigned int i;
76
+
77
+ for(i=0; i<dataLengthInBytes; i++)
78
+ state[i] ^= data[i];
79
+ KeccakPermutation(state);
80
+ }
81
+
82
+ void KeccakPermutationOnWords(UINT64 *state)
83
+ {
84
+ unsigned int i;
85
+
86
+ displayStateAs64bitWords(3, "Same, with lanes as 64-bit words", state);
87
+
88
+ for(i=0; i<nrRounds; i++) {
89
+ displayRoundNumber(3, i);
90
+
91
+ theta(state);
92
+ displayStateAs64bitWords(3, "After theta", state);
93
+
94
+ rho(state);
95
+ displayStateAs64bitWords(3, "After rho", state);
96
+
97
+ pi(state);
98
+ displayStateAs64bitWords(3, "After pi", state);
99
+
100
+ chi(state);
101
+ displayStateAs64bitWords(3, "After chi", state);
102
+
103
+ iota(state, i);
104
+ displayStateAs64bitWords(3, "After iota", state);
105
+ }
106
+ }
107
+
108
+ #define index(x, y) (((x)%5)+5*((y)%5))
109
+ #define ROL64(a, offset) ((offset != 0) ? ((((UINT64)a) << offset) ^ (((UINT64)a) >> (64-offset))) : a)
110
+
111
+ void theta(UINT64 *A)
112
+ {
113
+ unsigned int x, y;
114
+ UINT64 C[5], D[5];
115
+
116
+ for(x=0; x<5; x++) {
117
+ C[x] = 0;
118
+ for(y=0; y<5; y++)
119
+ C[x] ^= A[index(x, y)];
120
+ }
121
+ for(x=0; x<5; x++)
122
+ D[x] = ROL64(C[(x+1)%5], 1) ^ C[(x+4)%5];
123
+ for(x=0; x<5; x++)
124
+ for(y=0; y<5; y++)
125
+ A[index(x, y)] ^= D[x];
126
+ }
127
+
128
+ void rho(UINT64 *A)
129
+ {
130
+ unsigned int x, y;
131
+
132
+ for(x=0; x<5; x++) for(y=0; y<5; y++)
133
+ A[index(x, y)] = ROL64(A[index(x, y)], KeccakRhoOffsets[index(x, y)]);
134
+ }
135
+
136
+ void pi(UINT64 *A)
137
+ {
138
+ unsigned int x, y;
139
+ UINT64 tempA[25];
140
+
141
+ for(x=0; x<5; x++) for(y=0; y<5; y++)
142
+ tempA[index(x, y)] = A[index(x, y)];
143
+ for(x=0; x<5; x++) for(y=0; y<5; y++)
144
+ A[index(0*x+1*y, 2*x+3*y)] = tempA[index(x, y)];
145
+ }
146
+
147
+ void chi(UINT64 *A)
148
+ {
149
+ unsigned int x, y;
150
+ UINT64 C[5];
151
+
152
+ for(y=0; y<5; y++) {
153
+ for(x=0; x<5; x++)
154
+ C[x] = A[index(x, y)] ^ ((~A[index(x+1, y)]) & A[index(x+2, y)]);
155
+ for(x=0; x<5; x++)
156
+ A[index(x, y)] = C[x];
157
+ }
158
+ }
159
+
160
+ void iota(UINT64 *A, unsigned int indexRound)
161
+ {
162
+ A[index(0, 0)] ^= KeccakRoundConstants[indexRound];
163
+ }
164
+
165
+ int LFSR86540(UINT8 *LFSR)
166
+ {
167
+ int result = ((*LFSR) & 0x01) != 0;
168
+ if (((*LFSR) & 0x80) != 0)
169
+ // Primitive polynomial over GF(2): x^8+x^6+x^5+x^4+1
170
+ (*LFSR) = ((*LFSR) << 1) ^ 0x71;
171
+ else
172
+ (*LFSR) <<= 1;
173
+ return result;
174
+ }
175
+
176
+ void KeccakInitializeRoundConstants()
177
+ {
178
+ UINT8 LFSRstate = 0x01;
179
+ unsigned int i, j, bitPosition;
180
+
181
+ for(i=0; i<nrRounds; i++) {
182
+ KeccakRoundConstants[i] = 0;
183
+ for(j=0; j<7; j++) {
184
+ bitPosition = (1<<j)-1; //2^j-1
185
+ if (LFSR86540(&LFSRstate))
186
+ KeccakRoundConstants[i] ^= (UINT64)1<<bitPosition;
187
+ }
188
+ }
189
+ }
190
+
191
+ void KeccakInitializeRhoOffsets()
192
+ {
193
+ unsigned int x, y, t, newX, newY;
194
+
195
+ KeccakRhoOffsets[index(0, 0)] = 0;
196
+ x = 1;
197
+ y = 0;
198
+ for(t=0; t<24; t++) {
199
+ KeccakRhoOffsets[index(x, y)] = ((t+1)*(t+2)/2) % 64;
200
+ newX = (0*x+1*y) % 5;
201
+ newY = (2*x+3*y) % 5;
202
+ x = newX;
203
+ y = newY;
204
+ }
205
+ }
206
+
207
+ void KeccakInitialize()
208
+ {
209
+ KeccakInitializeRoundConstants();
210
+ KeccakInitializeRhoOffsets();
211
+ }
212
+
213
+ void displayRoundConstants(FILE *f)
214
+ {
215
+ unsigned int i;
216
+
217
+ for(i=0; i<nrRounds; i++) {
218
+ fprintf(f, "RC[%02i][0][0] = ", i);
219
+ fprintf(f, "%08X", (unsigned int)(KeccakRoundConstants[i] >> 32));
220
+ fprintf(f, "%08X", (unsigned int)(KeccakRoundConstants[i] & 0xFFFFFFFFULL));
221
+ fprintf(f, "\n");
222
+ }
223
+ fprintf(f, "\n");
224
+ }
225
+
226
+ void displayRhoOffsets(FILE *f)
227
+ {
228
+ unsigned int x, y;
229
+
230
+ for(y=0; y<5; y++) for(x=0; x<5; x++) {
231
+ fprintf(f, "RhoOffset[%i][%i] = ", x, y);
232
+ fprintf(f, "%2i", KeccakRhoOffsets[index(x, y)]);
233
+ fprintf(f, "\n");
234
+ }
235
+ fprintf(f, "\n");
236
+ }
237
+
238
+ void KeccakInitializeState(unsigned char *state)
239
+ {
240
+ memset(state, 0, KeccakPermutationSizeInBytes);
241
+ }
242
+
243
+ #ifdef ProvideFast576
244
+ void KeccakAbsorb576bits(unsigned char *state, const unsigned char *data)
245
+ {
246
+ KeccakPermutationAfterXor(state, data, 72);
247
+ }
248
+ #endif
249
+
250
+ #ifdef ProvideFast832
251
+ void KeccakAbsorb832bits(unsigned char *state, const unsigned char *data)
252
+ {
253
+ KeccakPermutationAfterXor(state, data, 104);
254
+ }
255
+ #endif
256
+
257
+ #ifdef ProvideFast1024
258
+ void KeccakAbsorb1024bits(unsigned char *state, const unsigned char *data)
259
+ {
260
+ KeccakPermutationAfterXor(state, data, 128);
261
+ }
262
+ #endif
263
+
264
+ #ifdef ProvideFast1088
265
+ void KeccakAbsorb1088bits(unsigned char *state, const unsigned char *data)
266
+ {
267
+ KeccakPermutationAfterXor(state, data, 136);
268
+ }
269
+ #endif
270
+
271
+ #ifdef ProvideFast1152
272
+ void KeccakAbsorb1152bits(unsigned char *state, const unsigned char *data)
273
+ {
274
+ KeccakPermutationAfterXor(state, data, 144);
275
+ }
276
+ #endif
277
+
278
+ #ifdef ProvideFast1344
279
+ void KeccakAbsorb1344bits(unsigned char *state, const unsigned char *data)
280
+ {
281
+ KeccakPermutationAfterXor(state, data, 168);
282
+ }
283
+ #endif
284
+
285
+ void KeccakAbsorb(unsigned char *state, const unsigned char *data, unsigned int laneCount)
286
+ {
287
+ KeccakPermutationAfterXor(state, data, laneCount*8);
288
+ }
289
+
290
+ #ifdef ProvideFast1024
291
+ void KeccakExtract1024bits(const unsigned char *state, unsigned char *data)
292
+ {
293
+ memcpy(data, state, 128);
294
+ }
295
+ #endif
296
+
297
+ void KeccakExtract(const unsigned char *state, unsigned char *data, unsigned int laneCount)
298
+ {
299
+ memcpy(data, state, laneCount*8);
300
+ }