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.

Files changed (62) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +232 -17
  3. data/.travis.yml +21 -12
  4. data/.yardopts +1 -1
  5. data/ChangeLog.rdoc +16 -0
  6. data/Gemfile +1 -1
  7. data/Gemfile.ci +5 -5
  8. data/LICENSE.txt +1 -1
  9. data/README.md +120 -0
  10. data/Rakefile +15 -18
  11. data/ext/sha3/KeccakF-1600-interface.h +28 -34
  12. data/ext/sha3/KeccakHash.c +80 -0
  13. data/ext/sha3/KeccakHash.h +110 -0
  14. data/ext/sha3/KeccakSponge.c +127 -201
  15. data/ext/sha3/KeccakSponge.h +74 -37
  16. data/ext/sha3/Optimized64/KeccakF-1600-64.macros +2199 -0
  17. data/ext/sha3/Optimized64/KeccakF-1600-opt64-settings.h +3 -0
  18. data/ext/sha3/Optimized64/KeccakF-1600-opt64.c +508 -0
  19. data/ext/sha3/{KeccakF-1600-unrolling.macros → Optimized64/KeccakF-1600-unrolling.macros} +16 -14
  20. data/ext/sha3/Optimized64/SnP-interface.h +47 -0
  21. data/ext/sha3/Reference/KeccakF-1600-reference.c +311 -0
  22. data/ext/sha3/Reference/KeccakF-reference.h +26 -0
  23. data/ext/sha3/Reference/SnP-FBWL-default.c +96 -0
  24. data/ext/sha3/Reference/SnP-FBWL-default.h +26 -0
  25. data/ext/sha3/Reference/SnP-interface.h +42 -0
  26. data/ext/sha3/{displayIntermediateValues.c → Reference/displayIntermediateValues.c} +52 -11
  27. data/ext/sha3/{displayIntermediateValues.h → Reference/displayIntermediateValues.h} +11 -6
  28. data/ext/sha3/SnP-Relaned.h +249 -0
  29. data/ext/sha3/brg_endian.h +0 -0
  30. data/ext/sha3/digest.c +270 -0
  31. data/ext/sha3/digest.h +48 -0
  32. data/ext/sha3/extconf.rb +16 -9
  33. data/ext/sha3/sha3.c +62 -0
  34. data/ext/sha3/sha3.h +26 -0
  35. data/lib/sha3.rb +1 -1
  36. data/lib/sha3/doc.rb +121 -0
  37. data/lib/sha3/version.rb +6 -5
  38. data/sha3.gemspec +13 -15
  39. data/spec/generate_tests.rb +22 -56
  40. data/spec/sha3_core_spec.rb +113 -133
  41. data/spec/spec_helper.rb +2 -2
  42. data/tests.sh +11 -9
  43. metadata +53 -65
  44. data/README.rdoc +0 -133
  45. data/ext/sha3/KeccakF-1600-32-rvk.macros +0 -555
  46. data/ext/sha3/KeccakF-1600-32-s1.macros +0 -1187
  47. data/ext/sha3/KeccakF-1600-32-s2.macros +0 -1187
  48. data/ext/sha3/KeccakF-1600-32.macros +0 -26
  49. data/ext/sha3/KeccakF-1600-64.macros +0 -728
  50. data/ext/sha3/KeccakF-1600-int-set.h +0 -6
  51. data/ext/sha3/KeccakF-1600-opt.c +0 -504
  52. data/ext/sha3/KeccakF-1600-opt32-settings.h +0 -4
  53. data/ext/sha3/KeccakF-1600-opt32.c-arch +0 -524
  54. data/ext/sha3/KeccakF-1600-opt64-settings.h +0 -7
  55. data/ext/sha3/KeccakF-1600-opt64.c-arch +0 -504
  56. data/ext/sha3/KeccakF-1600-reference.c-arch +0 -300
  57. data/ext/sha3/KeccakF-1600-x86-64-gas.s +0 -766
  58. data/ext/sha3/KeccakF-1600-x86-64-shld-gas.s +0 -766
  59. data/ext/sha3/KeccakNISTInterface.c +0 -81
  60. data/ext/sha3/KeccakNISTInterface.h +0 -70
  61. data/ext/sha3/_sha3.c +0 -309
  62. 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', '~> 0.2'
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 "Run `gem install rubygems-tasks` to install Gem::Tasks."
11
+ warn 'Run `gem install rubygems-tasks` to install Gem::Tasks.'
14
12
  end
15
13
 
16
14
  begin
17
- gem 'rspec', '~> 2.4'
15
+ gem 'rspec'
18
16
  require 'rspec/core/rake_task'
19
17
 
20
18
  RSpec::Core::RakeTask.new
21
- rescue LoadError => e
19
+ rescue LoadError
22
20
  task :spec do
23
- abort "Please run `gem install rspec` to install RSpec."
21
+ abort 'Please run `gem install rspec` to install RSpec.'
24
22
  end
25
23
  end
26
24
 
27
- task :test => :spec
28
- task :default => [:compile, :spec]
25
+ task test: :spec
26
+ task default: %i[compile spec]
29
27
 
30
28
  begin
31
- gem 'yard', '~> 0.8'
29
+ gem 'yard'
32
30
  require 'yard'
33
31
 
34
- YARD::Rake::YardocTask.new
35
- rescue LoadError => e
32
+ YARD::Rake::YardocTask.new
33
+ rescue LoadError
36
34
  task :yard do
37
- abort "Please run `gem install yard` to install YARD."
35
+ abort 'Please run `gem install yard` to install YARD.'
38
36
  end
39
37
  end
40
- task :doc => :yard
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 = "*.{c}"
48
+ ext.source_pattern = '*.{c}'
51
49
  end
52
- rescue LoadError => e
50
+ rescue LoadError
53
51
  task :compile do
54
- abort "Please run `gem install rake-compiler` to install Rake-Compiler."
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
- 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/
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
- Implementation by the designers,
7
- hereby denoted as "the implementer".
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 _KeccakPermutationInterface_h_
15
- #define _KeccakPermutationInterface_h_
16
+ #ifndef _KeccakF1600Interface_h_
17
+ #define _KeccakF1600Interface_h_
16
18
 
17
- #include "KeccakF-1600-int-set.h"
19
+ #include <string.h>
18
20
 
19
- void KeccakInitialize( void );
20
- void KeccakInitializeState(unsigned char *state);
21
- void KeccakPermutation(unsigned char *state);
22
- #ifdef ProvideFast576
23
- void KeccakAbsorb576bits(unsigned char *state, const unsigned char *data);
24
- #endif
25
- #ifdef ProvideFast832
26
- void KeccakAbsorb832bits(unsigned char *state, const unsigned char *data);
27
- #endif
28
- #ifdef ProvideFast1024
29
- void KeccakAbsorb1024bits(unsigned char *state, const unsigned char *data);
30
- #endif
31
- #ifdef ProvideFast1088
32
- void KeccakAbsorb1088bits(unsigned char *state, const unsigned char *data);
33
- #endif
34
- #ifdef ProvideFast1152
35
- void KeccakAbsorb1152bits(unsigned char *state, const unsigned char *data);
36
- #endif
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
@@ -1,10 +1,12 @@
1
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/
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
- Implementation by the designers,
7
- hereby denoted as "the implementer".
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 "KeccakF-1600-interface.h"
18
+ #include "SnP-interface.h"
17
19
  #ifdef KeccakReference
18
20
  #include "displayIntermediateValues.h"
19
21
  #endif
20
22
 
21
- int InitSponge(spongeState *state, unsigned int rate, unsigned int capacity)
23
+ /* ---------------------------------------------------------------- */
24
+
25
+ int Keccak_SpongeInitialize(Keccak_SpongeInstance *instance, unsigned int rate, unsigned int capacity)
22
26
  {
23
- if (rate+capacity != 1600)
27
+ if (rate+capacity != SnP_width)
24
28
  return 1;
25
- if ((rate <= 0) || (rate >= 1600) || ((rate % 64) != 0))
29
+ if ((rate <= 0) || (rate > SnP_width) || ((rate % 8) != 0))
26
30
  return 1;
27
- KeccakInitialize();
28
- state->rate = rate;
29
- state->capacity = capacity;
30
- state->fixedOutputLength = 0;
31
- KeccakInitializeState(state->state);
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
- void AbsorbQueue(spongeState *state)
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 Absorb(spongeState *state, const unsigned char *data, unsigned long long databitlen)
42
+ int Keccak_SpongeAbsorb(Keccak_SpongeInstance *instance, const unsigned char *data, size_t dataByteLen)
81
43
  {
82
- unsigned long long i, j, wholeBlocks;
83
- unsigned int partialBlock, partialByte;
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 ((state->bitsInQueue % 8) != 0)
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
- while(i < databitlen) {
93
- if ((state->bitsInQueue == 0) && (databitlen >= state->rate) && (i <= (databitlen-state->rate))) {
94
- wholeBlocks = (databitlen-i)/state->rate;
95
- curData = data+i/8;
96
- #ifdef ProvideFast576
97
- if (state->rate == 576) {
98
- for(j=0; j<wholeBlocks; j++, curData+=576/8) {
99
- #ifdef KeccakReference
100
- displayBytes(1, "Block to be absorbed", curData, state->rate/8);
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
- #endif
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, state->rate/8);
66
+ displayBytes(1, "Block to be absorbed", curData, rateInBytes);
134
67
  #endif
135
- KeccakAbsorb1088bits(state->state, curData);
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
- partialBlock = (unsigned int)(databitlen - i);
174
- if (partialBlock+state->bitsInQueue > state->rate)
175
- partialBlock = state->rate-state->bitsInQueue;
176
- partialByte = partialBlock % 8;
177
- partialBlock -= partialByte;
178
- memcpy(state->dataQueue+state->bitsInQueue/8, data+i/8, partialBlock/8);
179
- state->bitsInQueue += partialBlock;
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
- if (state->bitsInQueue == state->rate)
182
- AbsorbQueue(state);
183
- if (partialByte > 0) {
184
- unsigned char mask = (1 << partialByte)-1;
185
- state->dataQueue[state->bitsInQueue/8] = data[i/8] & mask;
186
- state->bitsInQueue += partialByte;
187
- i += partialByte;
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
- void PadAndSwitchToSqueezingPhase(spongeState *state)
97
+ /* ---------------------------------------------------------------- */
98
+
99
+ int Keccak_SpongeAbsorbLastFewBits(Keccak_SpongeInstance *instance, unsigned char delimitedData)
195
100
  {
196
- // Note: the bits are numbered from 0=LSB to 7=MSB
197
- if (state->bitsInQueue + 1 == state->rate) {
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
- displayText(1, "--- Switching to squeezing phase ---");
111
+ displayBytes(1, "Block to be absorbed (last few bits + first bit of padding)", delimitedData1, 1);
211
112
  #endif
212
- #ifdef ProvideFast1024
213
- if (state->rate == 1024) {
214
- KeccakExtract1024bits(state->state, state->dataQueue);
215
- state->bitsAvailableForSqueezing = 1024;
216
- }
217
- else
218
- #endif
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
- KeccakExtract(state->state, state->dataQueue, state->rate/64);
221
- state->bitsAvailableForSqueezing = state->rate;
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
- displayBytes(1, "Block available for squeezing", state->dataQueue, state->bitsAvailableForSqueezing/8);
132
+ displayText(1, "--- Switching to squeezing phase ---");
225
133
  #endif
226
- state->squeezing = 1;
134
+ return 0;
227
135
  }
228
136
 
229
- int Squeeze(spongeState *state, unsigned char *output, unsigned long long outputLength)
137
+ /* ---------------------------------------------------------------- */
138
+
139
+ int Keccak_SpongeSqueeze(Keccak_SpongeInstance *instance, unsigned char *data, size_t dataByteLen)
230
140
  {
231
- unsigned long long i;
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 (!state->squeezing)
235
- PadAndSwitchToSqueezingPhase(state);
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
- while(i < outputLength) {
241
- if (state->bitsAvailableForSqueezing == 0) {
242
- KeccakPermutation(state->state);
243
- #ifdef ProvideFast1024
244
- if (state->rate == 1024) {
245
- KeccakExtract1024bits(state->state, state->dataQueue);
246
- state->bitsAvailableForSqueezing = 1024;
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
- #endif
250
- {
251
- KeccakExtract(state->state, state->dataQueue, state->rate/64);
252
- state->bitsAvailableForSqueezing = state->rate;
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, "Block available for squeezing", state->dataQueue, state->bitsAvailableForSqueezing/8);
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
  }