sha3 0.2.2 → 1.0.2
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.
- checksums.yaml +7 -0
- data/.gitignore +232 -17
- data/.travis.yml +21 -12
- data/.yardopts +1 -1
- data/ChangeLog.rdoc +16 -0
- data/Gemfile +1 -1
- data/Gemfile.ci +5 -5
- data/LICENSE.txt +1 -1
- data/README.md +120 -0
- data/Rakefile +15 -18
- data/ext/sha3/KeccakF-1600-interface.h +28 -34
- data/ext/sha3/KeccakHash.c +80 -0
- data/ext/sha3/KeccakHash.h +110 -0
- data/ext/sha3/KeccakSponge.c +127 -201
- data/ext/sha3/KeccakSponge.h +74 -37
- data/ext/sha3/Optimized64/KeccakF-1600-64.macros +2199 -0
- data/ext/sha3/Optimized64/KeccakF-1600-opt64-settings.h +3 -0
- data/ext/sha3/Optimized64/KeccakF-1600-opt64.c +508 -0
- data/ext/sha3/{KeccakF-1600-unrolling.macros → Optimized64/KeccakF-1600-unrolling.macros} +16 -14
- data/ext/sha3/Optimized64/SnP-interface.h +47 -0
- data/ext/sha3/Reference/KeccakF-1600-reference.c +311 -0
- data/ext/sha3/Reference/KeccakF-reference.h +26 -0
- data/ext/sha3/Reference/SnP-FBWL-default.c +96 -0
- data/ext/sha3/Reference/SnP-FBWL-default.h +26 -0
- data/ext/sha3/Reference/SnP-interface.h +42 -0
- data/ext/sha3/{displayIntermediateValues.c → Reference/displayIntermediateValues.c} +52 -11
- data/ext/sha3/{displayIntermediateValues.h → Reference/displayIntermediateValues.h} +11 -6
- data/ext/sha3/SnP-Relaned.h +249 -0
- data/ext/sha3/brg_endian.h +0 -0
- data/ext/sha3/digest.c +270 -0
- data/ext/sha3/digest.h +48 -0
- data/ext/sha3/extconf.rb +16 -9
- data/ext/sha3/sha3.c +62 -0
- data/ext/sha3/sha3.h +26 -0
- data/lib/sha3.rb +1 -1
- data/lib/sha3/doc.rb +121 -0
- data/lib/sha3/version.rb +6 -5
- data/sha3.gemspec +13 -15
- data/spec/generate_tests.rb +22 -56
- data/spec/sha3_core_spec.rb +113 -133
- data/spec/spec_helper.rb +2 -2
- data/tests.sh +11 -9
- metadata +53 -65
- data/README.rdoc +0 -133
- data/ext/sha3/KeccakF-1600-32-rvk.macros +0 -555
- data/ext/sha3/KeccakF-1600-32-s1.macros +0 -1187
- data/ext/sha3/KeccakF-1600-32-s2.macros +0 -1187
- data/ext/sha3/KeccakF-1600-32.macros +0 -26
- data/ext/sha3/KeccakF-1600-64.macros +0 -728
- data/ext/sha3/KeccakF-1600-int-set.h +0 -6
- data/ext/sha3/KeccakF-1600-opt.c +0 -504
- data/ext/sha3/KeccakF-1600-opt32-settings.h +0 -4
- data/ext/sha3/KeccakF-1600-opt32.c-arch +0 -524
- data/ext/sha3/KeccakF-1600-opt64-settings.h +0 -7
- data/ext/sha3/KeccakF-1600-opt64.c-arch +0 -504
- data/ext/sha3/KeccakF-1600-reference.c-arch +0 -300
- data/ext/sha3/KeccakF-1600-x86-64-gas.s +0 -766
- data/ext/sha3/KeccakF-1600-x86-64-shld-gas.s +0 -766
- data/ext/sha3/KeccakNISTInterface.c +0 -81
- data/ext/sha3/KeccakNISTInterface.h +0 -70
- data/ext/sha3/_sha3.c +0 -309
- data/ext/sha3/_sha3.h +0 -32
data/Rakefile
CHANGED
@@ -1,43 +1,41 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
1
|
require 'rubygems'
|
4
2
|
require 'rake'
|
5
3
|
|
6
4
|
begin
|
7
|
-
gem 'rubygems-tasks'
|
5
|
+
gem 'rubygems-tasks'
|
8
6
|
require 'rubygems/tasks'
|
9
7
|
|
10
8
|
Gem::Tasks.new
|
11
9
|
rescue LoadError => e
|
12
10
|
warn e.message
|
13
|
-
warn
|
11
|
+
warn 'Run `gem install rubygems-tasks` to install Gem::Tasks.'
|
14
12
|
end
|
15
13
|
|
16
14
|
begin
|
17
|
-
gem 'rspec'
|
15
|
+
gem 'rspec'
|
18
16
|
require 'rspec/core/rake_task'
|
19
17
|
|
20
18
|
RSpec::Core::RakeTask.new
|
21
|
-
rescue LoadError
|
19
|
+
rescue LoadError
|
22
20
|
task :spec do
|
23
|
-
abort
|
21
|
+
abort 'Please run `gem install rspec` to install RSpec.'
|
24
22
|
end
|
25
23
|
end
|
26
24
|
|
27
|
-
task :
|
28
|
-
task :
|
25
|
+
task test: :spec
|
26
|
+
task default: %i[compile spec]
|
29
27
|
|
30
28
|
begin
|
31
|
-
gem 'yard'
|
29
|
+
gem 'yard'
|
32
30
|
require 'yard'
|
33
31
|
|
34
|
-
YARD::Rake::YardocTask.new
|
35
|
-
rescue LoadError
|
32
|
+
YARD::Rake::YardocTask.new
|
33
|
+
rescue LoadError
|
36
34
|
task :yard do
|
37
|
-
abort
|
35
|
+
abort 'Please run `gem install yard` to install YARD.'
|
38
36
|
end
|
39
37
|
end
|
40
|
-
task :
|
38
|
+
task doc: :yard
|
41
39
|
|
42
40
|
begin
|
43
41
|
gem 'rake-compiler'
|
@@ -47,11 +45,10 @@ begin
|
|
47
45
|
ext.name = 'sha3_n'
|
48
46
|
ext.ext_dir = 'ext/sha3'
|
49
47
|
ext.tmp_dir = 'tmp'
|
50
|
-
ext.source_pattern =
|
48
|
+
ext.source_pattern = '*.{c}'
|
51
49
|
end
|
52
|
-
rescue LoadError
|
50
|
+
rescue LoadError
|
53
51
|
task :compile do
|
54
|
-
abort
|
52
|
+
abort 'Please run `gem install rake-compiler` to install Rake-Compiler.'
|
55
53
|
end
|
56
54
|
end
|
57
|
-
|
@@ -1,46 +1,40 @@
|
|
1
1
|
/*
|
2
|
-
|
3
|
-
Michaël Peeters
|
4
|
-
|
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
5
|
|
6
|
-
|
7
|
-
|
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/
|
8
10
|
|
9
11
|
To the extent possible under law, the implementer has waived all copyright
|
10
12
|
and related or neighboring rights to the source code in this file.
|
11
13
|
http://creativecommons.org/publicdomain/zero/1.0/
|
12
14
|
*/
|
13
15
|
|
14
|
-
#ifndef
|
15
|
-
#define
|
16
|
+
#ifndef _KeccakF1600Interface_h_
|
17
|
+
#define _KeccakF1600Interface_h_
|
16
18
|
|
17
|
-
#include
|
19
|
+
#include <string.h>
|
18
20
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
#
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
void
|
27
|
-
|
28
|
-
|
29
|
-
void
|
30
|
-
|
31
|
-
|
32
|
-
void
|
33
|
-
|
34
|
-
|
35
|
-
void
|
36
|
-
|
37
|
-
#ifdef ProvideFast1344
|
38
|
-
void KeccakAbsorb1344bits(unsigned char *state, const unsigned char *data);
|
39
|
-
#endif
|
40
|
-
void KeccakAbsorb(unsigned char *state, const unsigned char *data, unsigned int laneCount);
|
41
|
-
#ifdef ProvideFast1024
|
42
|
-
void KeccakExtract1024bits(const unsigned char *state, unsigned char *data);
|
43
|
-
#endif
|
44
|
-
void KeccakExtract(const unsigned char *state, unsigned char *data, unsigned int laneCount);
|
21
|
+
#define KeccakF_width 1600
|
22
|
+
#define KeccakF_laneInBytes 8
|
23
|
+
#define KeccakF_stateSizeInBytes (KeccakF_width/8)
|
24
|
+
#define KeccakF_1600
|
25
|
+
|
26
|
+
void KeccakF1600_Initialize( void );
|
27
|
+
void KeccakF1600_StateInitialize(void *state);
|
28
|
+
void KeccakF1600_StateXORBytes(void *state, const unsigned char *data, unsigned int offset, unsigned int length);
|
29
|
+
void KeccakF1600_StateOverwriteBytes(void *state, const unsigned char *data, unsigned int offset, unsigned int length);
|
30
|
+
void KeccakF1600_StateOverwriteWithZeroes(void *state, unsigned int byteCount);
|
31
|
+
void KeccakF1600_StateComplementBit(void *state, unsigned int position);
|
32
|
+
void KeccakF1600_StatePermute(void *state);
|
33
|
+
void KeccakF1600_StateExtractBytes(const void *state, unsigned char *data, unsigned int offset, unsigned int length);
|
34
|
+
void KeccakF1600_StateExtractAndXORBytes(const void *state, unsigned char *data, unsigned int offset, unsigned int length);
|
35
|
+
size_t KeccakF1600_FBWL_Absorb(void *state, unsigned int laneCount, const unsigned char *data, size_t dataByteLen, unsigned char trailingBits);
|
36
|
+
size_t KeccakF1600_FBWL_Squeeze(void *state, unsigned int laneCount, unsigned char *data, size_t dataByteLen);
|
37
|
+
size_t KeccakF1600_FBWL_Wrap(void *state, unsigned int laneCount, const unsigned char *dataIn, unsigned char *dataOut, size_t dataByteLen, unsigned char trailingBits);
|
38
|
+
size_t KeccakF1600_FBWL_Unwrap(void *state, unsigned int laneCount, const unsigned char *dataIn, unsigned char *dataOut, size_t dataByteLen, unsigned char trailingBits);
|
45
39
|
|
46
40
|
#endif
|
@@ -0,0 +1,80 @@
|
|
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 "KeccakHash.h"
|
18
|
+
|
19
|
+
/* ---------------------------------------------------------------- */
|
20
|
+
|
21
|
+
HashReturn Keccak_HashInitialize(Keccak_HashInstance *instance, unsigned int rate, unsigned int capacity, unsigned int hashbitlen, unsigned char delimitedSuffix)
|
22
|
+
{
|
23
|
+
HashReturn result;
|
24
|
+
|
25
|
+
if (delimitedSuffix == 0)
|
26
|
+
return FAIL;
|
27
|
+
result = (HashReturn)Keccak_SpongeInitialize(&instance->sponge, rate, capacity);
|
28
|
+
if (result != SUCCESS)
|
29
|
+
return result;
|
30
|
+
instance->fixedOutputLength = hashbitlen;
|
31
|
+
instance->delimitedSuffix = delimitedSuffix;
|
32
|
+
return SUCCESS;
|
33
|
+
}
|
34
|
+
|
35
|
+
/* ---------------------------------------------------------------- */
|
36
|
+
|
37
|
+
HashReturn Keccak_HashUpdate(Keccak_HashInstance *instance, const BitSequence *data, DataLength databitlen)
|
38
|
+
{
|
39
|
+
if ((databitlen % 8) == 0)
|
40
|
+
return (HashReturn)Keccak_SpongeAbsorb(&instance->sponge, data, databitlen/8);
|
41
|
+
else {
|
42
|
+
HashReturn ret = (HashReturn)Keccak_SpongeAbsorb(&instance->sponge, data, databitlen/8);
|
43
|
+
if (ret == SUCCESS) {
|
44
|
+
// The last partial byte is assumed to be aligned on the least significant bits
|
45
|
+
unsigned char lastByte = data[databitlen/8];
|
46
|
+
// Concatenate the last few bits provided here with those of the suffix
|
47
|
+
unsigned short delimitedLastBytes = (unsigned short)lastByte | ((unsigned short)instance->delimitedSuffix << (databitlen % 8));
|
48
|
+
if ((delimitedLastBytes & 0xFF00) == 0x0000) {
|
49
|
+
instance->delimitedSuffix = delimitedLastBytes & 0xFF;
|
50
|
+
}
|
51
|
+
else {
|
52
|
+
unsigned char oneByte[1];
|
53
|
+
oneByte[0] = delimitedLastBytes & 0xFF;
|
54
|
+
ret = (HashReturn)Keccak_SpongeAbsorb(&instance->sponge, oneByte, 1);
|
55
|
+
instance->delimitedSuffix = (delimitedLastBytes >> 8) & 0xFF;
|
56
|
+
}
|
57
|
+
}
|
58
|
+
return ret;
|
59
|
+
}
|
60
|
+
}
|
61
|
+
|
62
|
+
/* ---------------------------------------------------------------- */
|
63
|
+
|
64
|
+
HashReturn Keccak_HashFinal(Keccak_HashInstance *instance, BitSequence *hashval)
|
65
|
+
{
|
66
|
+
HashReturn ret = (HashReturn)Keccak_SpongeAbsorbLastFewBits(&instance->sponge, instance->delimitedSuffix);
|
67
|
+
if (ret == SUCCESS)
|
68
|
+
return (HashReturn)Keccak_SpongeSqueeze(&instance->sponge, hashval, instance->fixedOutputLength/8);
|
69
|
+
else
|
70
|
+
return ret;
|
71
|
+
}
|
72
|
+
|
73
|
+
/* ---------------------------------------------------------------- */
|
74
|
+
|
75
|
+
HashReturn Keccak_HashSqueeze(Keccak_HashInstance *instance, BitSequence *data, DataLength databitlen)
|
76
|
+
{
|
77
|
+
if ((databitlen % 8) != 0)
|
78
|
+
return FAIL;
|
79
|
+
return (HashReturn)Keccak_SpongeSqueeze(&instance->sponge, data, databitlen/8);
|
80
|
+
}
|
@@ -0,0 +1,110 @@
|
|
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
|
+
#ifndef _KeccakHashInterface_h_
|
17
|
+
#define _KeccakHashInterface_h_
|
18
|
+
|
19
|
+
#include "KeccakSponge.h"
|
20
|
+
#include <string.h>
|
21
|
+
|
22
|
+
typedef unsigned char BitSequence;
|
23
|
+
typedef size_t DataLength;
|
24
|
+
typedef enum { SUCCESS = 0, FAIL = 1, BAD_HASHLEN = 2 } HashReturn;
|
25
|
+
|
26
|
+
typedef struct {
|
27
|
+
Keccak_SpongeInstance sponge;
|
28
|
+
unsigned int fixedOutputLength;
|
29
|
+
unsigned char delimitedSuffix;
|
30
|
+
} Keccak_HashInstance;
|
31
|
+
|
32
|
+
/**
|
33
|
+
* Function to initialize the Keccak[r, c] sponge function instance used in sequential hashing mode.
|
34
|
+
* @param hashInstance Pointer to the hash instance to be initialized.
|
35
|
+
* @param rate The value of the rate r.
|
36
|
+
* @param capacity The value of the capacity c.
|
37
|
+
* @param hashbitlen The desired number of output bits,
|
38
|
+
* or 0 for an arbitrarily-long output.
|
39
|
+
* @param delimitedSuffix Bits that will be automatically appended to the end
|
40
|
+
* of the input message, as in domain separation.
|
41
|
+
* This is a byte containing from 0 to 7 bits
|
42
|
+
* formatted like the @a delimitedData parameter of
|
43
|
+
* the Keccak_SpongeAbsorbLastFewBits() function.
|
44
|
+
* @pre One must have r+c=1600 and the rate a multiple of 8 bits in this implementation.
|
45
|
+
* @return SUCCESS if successful, FAIL otherwise.
|
46
|
+
*/
|
47
|
+
HashReturn Keccak_HashInitialize(Keccak_HashInstance *hashInstance, unsigned int rate, unsigned int capacity, unsigned int hashbitlen, unsigned char delimitedSuffix);
|
48
|
+
|
49
|
+
/** Macro to initialize a SHAKE128 instance as specified in the FIPS 202 standard.
|
50
|
+
*/
|
51
|
+
#define Keccak_HashInitialize_SHAKE128(hashInstance) Keccak_HashInitialize(hashInstance, 1344, 256, 0, 0x1F)
|
52
|
+
|
53
|
+
/** Macro to initialize a SHAKE256 instance as specified in the FIPS 202 standard.
|
54
|
+
*/
|
55
|
+
#define Keccak_HashInitialize_SHAKE256(hashInstance) Keccak_HashInitialize(hashInstance, 1088, 512, 0, 0x1F)
|
56
|
+
|
57
|
+
/** Macro to initialize a SHA3-224 instance as specified in the FIPS 202 standard.
|
58
|
+
*/
|
59
|
+
#define Keccak_HashInitialize_SHA3_224(hashInstance) Keccak_HashInitialize(hashInstance, 1152, 448, 224, 0x06)
|
60
|
+
|
61
|
+
/** Macro to initialize a SHA3-256 instance as specified in the FIPS 202 standard.
|
62
|
+
*/
|
63
|
+
#define Keccak_HashInitialize_SHA3_256(hashInstance) Keccak_HashInitialize(hashInstance, 1088, 512, 256, 0x06)
|
64
|
+
|
65
|
+
/** Macro to initialize a SHA3-384 instance as specified in the FIPS 202 standard.
|
66
|
+
*/
|
67
|
+
#define Keccak_HashInitialize_SHA3_384(hashInstance) Keccak_HashInitialize(hashInstance, 832, 768, 384, 0x06)
|
68
|
+
|
69
|
+
/** Macro to initialize a SHA3-512 instance as specified in the FIPS 202 standard.
|
70
|
+
*/
|
71
|
+
#define Keccak_HashInitialize_SHA3_512(hashInstance) Keccak_HashInitialize(hashInstance, 576, 1024, 512, 0x06)
|
72
|
+
|
73
|
+
/**
|
74
|
+
* Function to give input data to be absorbed.
|
75
|
+
* @param hashInstance Pointer to the hash instance initialized by Keccak_HashInitialize().
|
76
|
+
* @param data Pointer to the input data.
|
77
|
+
* When @a databitLen is not a multiple of 8, the last bits of data must be
|
78
|
+
* in the least significant bits of the last byte (little-endian convention).
|
79
|
+
* @param databitLen The number of input bits provided in the input data.
|
80
|
+
* @pre In the previous call to Keccak_HashUpdate(), databitlen was a multiple of 8.
|
81
|
+
* @return SUCCESS if successful, FAIL otherwise.
|
82
|
+
*/
|
83
|
+
HashReturn Keccak_HashUpdate(Keccak_HashInstance *hashInstance, const BitSequence *data, DataLength databitlen);
|
84
|
+
|
85
|
+
/**
|
86
|
+
* Function to call after all input blocks have been input and to get
|
87
|
+
* output bits if the length was specified when calling Keccak_HashInitialize().
|
88
|
+
* @param hashInstance Pointer to the hash instance initialized by Keccak_HashInitialize().
|
89
|
+
* If @a hashbitlen was not 0 in the call to Keccak_HashInitialize(), the number of
|
90
|
+
* output bits is equal to @a hashbitlen.
|
91
|
+
* If @a hashbitlen was 0 in the call to Keccak_HashInitialize(), the output bits
|
92
|
+
* must be extracted using the Keccak_HashSqueeze() function.
|
93
|
+
* @param state Pointer to the state of the sponge function initialized by Init().
|
94
|
+
* @param hashval Pointer to the buffer where to store the output data.
|
95
|
+
* @return SUCCESS if successful, FAIL otherwise.
|
96
|
+
*/
|
97
|
+
HashReturn Keccak_HashFinal(Keccak_HashInstance *hashInstance, BitSequence *hashval);
|
98
|
+
|
99
|
+
/**
|
100
|
+
* Function to squeeze output data.
|
101
|
+
* @param hashInstance Pointer to the hash instance initialized by Keccak_HashInitialize().
|
102
|
+
* @param data Pointer to the buffer where to store the output data.
|
103
|
+
* @param databitlen The number of output bits desired (must be a multiple of 8).
|
104
|
+
* @pre Keccak_HashFinal() must have been already called.
|
105
|
+
* @pre @a databitlen is a multiple of 8.
|
106
|
+
* @return SUCCESS if successful, FAIL otherwise.
|
107
|
+
*/
|
108
|
+
HashReturn Keccak_HashSqueeze(Keccak_HashInstance *hashInstance, BitSequence *data, DataLength databitlen);
|
109
|
+
|
110
|
+
#endif
|
data/ext/sha3/KeccakSponge.c
CHANGED
@@ -1,10 +1,12 @@
|
|
1
1
|
/*
|
2
|
-
|
3
|
-
Michaël Peeters
|
4
|
-
|
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
5
|
|
6
|
-
|
7
|
-
|
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/
|
8
10
|
|
9
11
|
To the extent possible under law, the implementer has waived all copyright
|
10
12
|
and related or neighboring rights to the source code in this file.
|
@@ -13,254 +15,178 @@ http://creativecommons.org/publicdomain/zero/1.0/
|
|
13
15
|
|
14
16
|
#include <string.h>
|
15
17
|
#include "KeccakSponge.h"
|
16
|
-
#include "
|
18
|
+
#include "SnP-interface.h"
|
17
19
|
#ifdef KeccakReference
|
18
20
|
#include "displayIntermediateValues.h"
|
19
21
|
#endif
|
20
22
|
|
21
|
-
|
23
|
+
/* ---------------------------------------------------------------- */
|
24
|
+
|
25
|
+
int Keccak_SpongeInitialize(Keccak_SpongeInstance *instance, unsigned int rate, unsigned int capacity)
|
22
26
|
{
|
23
|
-
if (rate+capacity !=
|
27
|
+
if (rate+capacity != SnP_width)
|
24
28
|
return 1;
|
25
|
-
if ((rate <= 0) || (rate
|
29
|
+
if ((rate <= 0) || (rate > SnP_width) || ((rate % 8) != 0))
|
26
30
|
return 1;
|
27
|
-
|
28
|
-
state
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
memset(state->dataQueue, 0, KeccakMaximumRateInBytes);
|
33
|
-
state->bitsInQueue = 0;
|
34
|
-
state->squeezing = 0;
|
35
|
-
state->bitsAvailableForSqueezing = 0;
|
31
|
+
SnP_StaticInitialize();
|
32
|
+
SnP_Initialize(instance->state);
|
33
|
+
instance->rate = rate;
|
34
|
+
instance->byteIOIndex = 0;
|
35
|
+
instance->squeezing = 0;
|
36
36
|
|
37
37
|
return 0;
|
38
38
|
}
|
39
39
|
|
40
|
-
|
41
|
-
{
|
42
|
-
// state->bitsInQueue is assumed to be equal to state->rate
|
43
|
-
#ifdef KeccakReference
|
44
|
-
displayBytes(1, "Block to be absorbed", state->dataQueue, state->rate/8);
|
45
|
-
#endif
|
46
|
-
#ifdef ProvideFast576
|
47
|
-
if (state->rate == 576)
|
48
|
-
KeccakAbsorb576bits(state->state, state->dataQueue);
|
49
|
-
else
|
50
|
-
#endif
|
51
|
-
#ifdef ProvideFast832
|
52
|
-
if (state->rate == 832)
|
53
|
-
KeccakAbsorb832bits(state->state, state->dataQueue);
|
54
|
-
else
|
55
|
-
#endif
|
56
|
-
#ifdef ProvideFast1024
|
57
|
-
if (state->rate == 1024)
|
58
|
-
KeccakAbsorb1024bits(state->state, state->dataQueue);
|
59
|
-
else
|
60
|
-
#endif
|
61
|
-
#ifdef ProvideFast1088
|
62
|
-
if (state->rate == 1088)
|
63
|
-
KeccakAbsorb1088bits(state->state, state->dataQueue);
|
64
|
-
else
|
65
|
-
#endif
|
66
|
-
#ifdef ProvideFast1152
|
67
|
-
if (state->rate == 1152)
|
68
|
-
KeccakAbsorb1152bits(state->state, state->dataQueue);
|
69
|
-
else
|
70
|
-
#endif
|
71
|
-
#ifdef ProvideFast1344
|
72
|
-
if (state->rate == 1344)
|
73
|
-
KeccakAbsorb1344bits(state->state, state->dataQueue);
|
74
|
-
else
|
75
|
-
#endif
|
76
|
-
KeccakAbsorb(state->state, state->dataQueue, state->rate/64);
|
77
|
-
state->bitsInQueue = 0;
|
78
|
-
}
|
40
|
+
/* ---------------------------------------------------------------- */
|
79
41
|
|
80
|
-
int
|
42
|
+
int Keccak_SpongeAbsorb(Keccak_SpongeInstance *instance, const unsigned char *data, size_t dataByteLen)
|
81
43
|
{
|
82
|
-
|
83
|
-
unsigned int partialBlock
|
44
|
+
size_t i, j;
|
45
|
+
unsigned int partialBlock;
|
84
46
|
const unsigned char *curData;
|
47
|
+
unsigned int rateInBytes = instance->rate/8;
|
85
48
|
|
86
|
-
if (
|
87
|
-
return 1; // Only the last call may contain a partial byte
|
88
|
-
if (state->squeezing)
|
49
|
+
if (instance->squeezing)
|
89
50
|
return 1; // Too late for additional input
|
90
51
|
|
91
52
|
i = 0;
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
#endif
|
102
|
-
KeccakAbsorb576bits(state->state, curData);
|
103
|
-
}
|
104
|
-
}
|
105
|
-
else
|
106
|
-
#endif
|
107
|
-
#ifdef ProvideFast832
|
108
|
-
if (state->rate == 832) {
|
109
|
-
for(j=0; j<wholeBlocks; j++, curData+=832/8) {
|
110
|
-
#ifdef KeccakReference
|
111
|
-
displayBytes(1, "Block to be absorbed", curData, state->rate/8);
|
112
|
-
#endif
|
113
|
-
KeccakAbsorb832bits(state->state, curData);
|
114
|
-
}
|
53
|
+
curData = data;
|
54
|
+
while(i < dataByteLen) {
|
55
|
+
if ((instance->byteIOIndex == 0) && (dataByteLen >= (i + rateInBytes))) {
|
56
|
+
// processing full blocks first
|
57
|
+
if ((rateInBytes % SnP_laneLengthInBytes) == 0) {
|
58
|
+
// fast lane: whole lane rate
|
59
|
+
j = SnP_FBWL_Absorb(instance->state, rateInBytes/SnP_laneLengthInBytes, curData, dataByteLen - i, 0);
|
60
|
+
i += j;
|
61
|
+
curData += j;
|
115
62
|
}
|
116
|
-
else
|
117
|
-
|
118
|
-
#ifdef ProvideFast1024
|
119
|
-
if (state->rate == 1024) {
|
120
|
-
for(j=0; j<wholeBlocks; j++, curData+=1024/8) {
|
121
|
-
#ifdef KeccakReference
|
122
|
-
displayBytes(1, "Block to be absorbed", curData, state->rate/8);
|
123
|
-
#endif
|
124
|
-
KeccakAbsorb1024bits(state->state, curData);
|
125
|
-
}
|
126
|
-
}
|
127
|
-
else
|
128
|
-
#endif
|
129
|
-
#ifdef ProvideFast1088
|
130
|
-
if (state->rate == 1088) {
|
131
|
-
for(j=0; j<wholeBlocks; j++, curData+=1088/8) {
|
63
|
+
else {
|
64
|
+
for(j=dataByteLen-i; j>=rateInBytes; j-=rateInBytes) {
|
132
65
|
#ifdef KeccakReference
|
133
|
-
displayBytes(1, "Block to be absorbed", curData,
|
66
|
+
displayBytes(1, "Block to be absorbed", curData, rateInBytes);
|
134
67
|
#endif
|
135
|
-
|
68
|
+
SnP_XORBytes(instance->state, curData, 0, rateInBytes);
|
69
|
+
SnP_Permute(instance->state);
|
70
|
+
curData+=rateInBytes;
|
136
71
|
}
|
72
|
+
i = dataByteLen - j;
|
137
73
|
}
|
138
|
-
else
|
139
|
-
#endif
|
140
|
-
#ifdef ProvideFast1152
|
141
|
-
if (state->rate == 1152) {
|
142
|
-
for(j=0; j<wholeBlocks; j++, curData+=1152/8) {
|
143
|
-
#ifdef KeccakReference
|
144
|
-
displayBytes(1, "Block to be absorbed", curData, state->rate/8);
|
145
|
-
#endif
|
146
|
-
KeccakAbsorb1152bits(state->state, curData);
|
147
|
-
}
|
148
|
-
}
|
149
|
-
else
|
150
|
-
#endif
|
151
|
-
#ifdef ProvideFast1344
|
152
|
-
if (state->rate == 1344) {
|
153
|
-
for(j=0; j<wholeBlocks; j++, curData+=1344/8) {
|
154
|
-
#ifdef KeccakReference
|
155
|
-
displayBytes(1, "Block to be absorbed", curData, state->rate/8);
|
156
|
-
#endif
|
157
|
-
KeccakAbsorb1344bits(state->state, curData);
|
158
|
-
}
|
159
|
-
}
|
160
|
-
else
|
161
|
-
#endif
|
162
|
-
{
|
163
|
-
for(j=0; j<wholeBlocks; j++, curData+=state->rate/8) {
|
164
|
-
#ifdef KeccakReference
|
165
|
-
displayBytes(1, "Block to be absorbed", curData, state->rate/8);
|
166
|
-
#endif
|
167
|
-
KeccakAbsorb(state->state, curData, state->rate/64);
|
168
|
-
}
|
169
|
-
}
|
170
|
-
i += wholeBlocks*state->rate;
|
171
74
|
}
|
172
75
|
else {
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
76
|
+
// normal lane: using the message queue
|
77
|
+
partialBlock = (unsigned int)(dataByteLen - i);
|
78
|
+
if (partialBlock+instance->byteIOIndex > rateInBytes)
|
79
|
+
partialBlock = rateInBytes-instance->byteIOIndex;
|
80
|
+
#ifdef KeccakReference
|
81
|
+
displayBytes(1, "Block to be absorbed (part)", curData, partialBlock);
|
82
|
+
#endif
|
180
83
|
i += partialBlock;
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
state
|
187
|
-
|
84
|
+
|
85
|
+
SnP_XORBytes(instance->state, curData, instance->byteIOIndex, partialBlock);
|
86
|
+
curData += partialBlock;
|
87
|
+
instance->byteIOIndex += partialBlock;
|
88
|
+
if (instance->byteIOIndex == rateInBytes) {
|
89
|
+
SnP_Permute(instance->state);
|
90
|
+
instance->byteIOIndex = 0;
|
188
91
|
}
|
189
92
|
}
|
190
93
|
}
|
191
94
|
return 0;
|
192
95
|
}
|
193
96
|
|
194
|
-
|
97
|
+
/* ---------------------------------------------------------------- */
|
98
|
+
|
99
|
+
int Keccak_SpongeAbsorbLastFewBits(Keccak_SpongeInstance *instance, unsigned char delimitedData)
|
195
100
|
{
|
196
|
-
|
197
|
-
|
198
|
-
state->dataQueue[state->bitsInQueue/8 ] |= 1 << (state->bitsInQueue % 8);
|
199
|
-
AbsorbQueue(state);
|
200
|
-
memset(state->dataQueue, 0, state->rate/8);
|
201
|
-
}
|
202
|
-
else {
|
203
|
-
memset(state->dataQueue + (state->bitsInQueue+7)/8, 0, state->rate/8 - (state->bitsInQueue+7)/8);
|
204
|
-
state->dataQueue[state->bitsInQueue/8 ] |= 1 << (state->bitsInQueue % 8);
|
205
|
-
}
|
206
|
-
state->dataQueue[(state->rate-1)/8] |= 1 << ((state->rate-1) % 8);
|
207
|
-
AbsorbQueue(state);
|
101
|
+
unsigned char delimitedData1[1];
|
102
|
+
unsigned int rateInBytes = instance->rate/8;
|
208
103
|
|
104
|
+
if (delimitedData == 0)
|
105
|
+
return 1;
|
106
|
+
if (instance->squeezing)
|
107
|
+
return 1; // Too late for additional input
|
108
|
+
|
109
|
+
delimitedData1[0] = delimitedData;
|
209
110
|
#ifdef KeccakReference
|
210
|
-
|
111
|
+
displayBytes(1, "Block to be absorbed (last few bits + first bit of padding)", delimitedData1, 1);
|
211
112
|
#endif
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
113
|
+
// Last few bits, whose delimiter coincides with first bit of padding
|
114
|
+
SnP_XORBytes(instance->state, delimitedData1, instance->byteIOIndex, 1);
|
115
|
+
// If the first bit of padding is at position rate-1, we need a whole new block for the second bit of padding
|
116
|
+
if ((delimitedData >= 0x80) && (instance->byteIOIndex == (rateInBytes-1)))
|
117
|
+
SnP_Permute(instance->state);
|
118
|
+
// Second bit of padding
|
119
|
+
SnP_ComplementBit(instance->state, rateInBytes*8-1);
|
120
|
+
#ifdef KeccakReference
|
219
121
|
{
|
220
|
-
|
221
|
-
|
122
|
+
unsigned char block[SnP_width/8];
|
123
|
+
memset(block, 0, SnP_width/8);
|
124
|
+
block[rateInBytes-1] = 0x80;
|
125
|
+
displayBytes(1, "Second bit of padding", block, rateInBytes);
|
222
126
|
}
|
127
|
+
#endif
|
128
|
+
SnP_Permute(instance->state);
|
129
|
+
instance->byteIOIndex = 0;
|
130
|
+
instance->squeezing = 1;
|
223
131
|
#ifdef KeccakReference
|
224
|
-
|
132
|
+
displayText(1, "--- Switching to squeezing phase ---");
|
225
133
|
#endif
|
226
|
-
|
134
|
+
return 0;
|
227
135
|
}
|
228
136
|
|
229
|
-
|
137
|
+
/* ---------------------------------------------------------------- */
|
138
|
+
|
139
|
+
int Keccak_SpongeSqueeze(Keccak_SpongeInstance *instance, unsigned char *data, size_t dataByteLen)
|
230
140
|
{
|
231
|
-
|
141
|
+
size_t i, j;
|
232
142
|
unsigned int partialBlock;
|
143
|
+
unsigned int rateInBytes = instance->rate/8;
|
144
|
+
unsigned char *curData;
|
233
145
|
|
234
|
-
if (!
|
235
|
-
|
236
|
-
if ((outputLength % 8) != 0)
|
237
|
-
return 1; // Only multiple of 8 bits are allowed, truncation can be done at user level
|
146
|
+
if (!instance->squeezing)
|
147
|
+
Keccak_SpongeAbsorbLastFewBits(instance, 0x01);
|
238
148
|
|
239
149
|
i = 0;
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
if (
|
245
|
-
|
246
|
-
|
150
|
+
curData = data;
|
151
|
+
while(i < dataByteLen) {
|
152
|
+
if ((instance->byteIOIndex == rateInBytes) && (dataByteLen >= (i + rateInBytes))) {
|
153
|
+
// processing full blocks first
|
154
|
+
if ((rateInBytes % SnP_laneLengthInBytes) == 0) {
|
155
|
+
// fast lane: whole lane rate
|
156
|
+
j = SnP_FBWL_Squeeze(instance->state, rateInBytes/SnP_laneLengthInBytes, curData, dataByteLen - i);
|
157
|
+
i += j;
|
158
|
+
curData += j;
|
247
159
|
}
|
248
|
-
else
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
160
|
+
else {
|
161
|
+
for(j=dataByteLen-i; j>=rateInBytes; j-=rateInBytes) {
|
162
|
+
SnP_Permute(instance->state);
|
163
|
+
SnP_ExtractBytes(instance->state, curData, 0, rateInBytes);
|
164
|
+
#ifdef KeccakReference
|
165
|
+
displayBytes(1, "Squeezed block", curData, rateInBytes);
|
166
|
+
#endif
|
167
|
+
curData+=rateInBytes;
|
168
|
+
}
|
169
|
+
i = dataByteLen - j;
|
170
|
+
}
|
171
|
+
}
|
172
|
+
else {
|
173
|
+
// normal lane: using the message queue
|
174
|
+
if (instance->byteIOIndex == rateInBytes) {
|
175
|
+
SnP_Permute(instance->state);
|
176
|
+
instance->byteIOIndex = 0;
|
253
177
|
}
|
178
|
+
partialBlock = (unsigned int)(dataByteLen - i);
|
179
|
+
if (partialBlock+instance->byteIOIndex > rateInBytes)
|
180
|
+
partialBlock = rateInBytes-instance->byteIOIndex;
|
181
|
+
i += partialBlock;
|
182
|
+
|
183
|
+
SnP_ExtractBytes(instance->state, curData, instance->byteIOIndex, partialBlock);
|
254
184
|
#ifdef KeccakReference
|
255
|
-
displayBytes(1, "
|
185
|
+
displayBytes(1, "Squeezed block (part)", curData, partialBlock);
|
256
186
|
#endif
|
187
|
+
curData += partialBlock;
|
188
|
+
instance->byteIOIndex += partialBlock;
|
257
189
|
}
|
258
|
-
partialBlock = state->bitsAvailableForSqueezing;
|
259
|
-
if ((unsigned long long)partialBlock > outputLength - i)
|
260
|
-
partialBlock = (unsigned int)(outputLength - i);
|
261
|
-
memcpy(output+i/8, state->dataQueue+(state->rate-state->bitsAvailableForSqueezing)/8, partialBlock/8);
|
262
|
-
state->bitsAvailableForSqueezing -= partialBlock;
|
263
|
-
i += partialBlock;
|
264
190
|
}
|
265
191
|
return 0;
|
266
192
|
}
|