sha3 0.2.6 → 1.0.1

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 (55) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.travis.yml +9 -1
  4. data/Gemfile.ci +4 -4
  5. data/LICENSE.txt +1 -1
  6. data/README.md +145 -0
  7. data/Rakefile +4 -5
  8. data/ext/sha3/KeccakF-1600-interface.h +28 -34
  9. data/ext/sha3/KeccakHash.c +80 -0
  10. data/ext/sha3/KeccakHash.h +110 -0
  11. data/ext/sha3/KeccakSponge.c +127 -201
  12. data/ext/sha3/KeccakSponge.h +74 -37
  13. data/ext/sha3/Optimized64/KeccakF-1600-64.macros +2199 -0
  14. data/ext/sha3/Optimized64/KeccakF-1600-opt64-settings.h +3 -0
  15. data/ext/sha3/Optimized64/KeccakF-1600-opt64.c +508 -0
  16. data/ext/sha3/{KeccakF-1600-unrolling.macros → Optimized64/KeccakF-1600-unrolling.macros} +16 -14
  17. data/ext/sha3/Optimized64/SnP-interface.h +47 -0
  18. data/ext/sha3/Reference/KeccakF-1600-reference.c +311 -0
  19. data/ext/sha3/Reference/KeccakF-reference.h +26 -0
  20. data/ext/sha3/Reference/SnP-FBWL-default.c +96 -0
  21. data/ext/sha3/Reference/SnP-FBWL-default.h +26 -0
  22. data/ext/sha3/Reference/SnP-interface.h +42 -0
  23. data/ext/sha3/{displayIntermediateValues.c → Reference/displayIntermediateValues.c} +52 -11
  24. data/ext/sha3/{displayIntermediateValues.h → Reference/displayIntermediateValues.h} +11 -6
  25. data/ext/sha3/SnP-Relaned.h +249 -0
  26. data/ext/sha3/brg_endian.h +0 -0
  27. data/ext/sha3/digest.c +67 -70
  28. data/ext/sha3/digest.h +2 -2
  29. data/ext/sha3/extconf.rb +7 -12
  30. data/ext/sha3/sha3.h +2 -2
  31. data/lib/sha3/doc.rb +26 -39
  32. data/lib/sha3/version.rb +2 -2
  33. data/sha3.gemspec +6 -6
  34. data/spec/generate_tests.rb +6 -41
  35. data/spec/sha3_core_spec.rb +111 -133
  36. data/spec/spec_helper.rb +2 -2
  37. data/tests.sh +9 -7
  38. metadata +33 -36
  39. data/README.rdoc +0 -131
  40. data/ext/sha3/KeccakF-1600-32-rvk.macros +0 -555
  41. data/ext/sha3/KeccakF-1600-32-s1.macros +0 -1187
  42. data/ext/sha3/KeccakF-1600-32-s2.macros +0 -1187
  43. data/ext/sha3/KeccakF-1600-32.macros +0 -26
  44. data/ext/sha3/KeccakF-1600-64.macros +0 -728
  45. data/ext/sha3/KeccakF-1600-int-set.h +0 -6
  46. data/ext/sha3/KeccakF-1600-opt.c +0 -504
  47. data/ext/sha3/KeccakF-1600-opt32-settings.h +0 -4
  48. data/ext/sha3/KeccakF-1600-opt32.c-arch +0 -524
  49. data/ext/sha3/KeccakF-1600-opt64-settings.h +0 -7
  50. data/ext/sha3/KeccakF-1600-opt64.c-arch +0 -504
  51. data/ext/sha3/KeccakF-1600-reference.c-arch +0 -300
  52. data/ext/sha3/KeccakF-1600-x86-64-gas.s +0 -766
  53. data/ext/sha3/KeccakF-1600-x86-64-shld-gas.s +0 -766
  54. data/ext/sha3/KeccakNISTInterface.c +0 -81
  55. data/ext/sha3/KeccakNISTInterface.h +0 -70
File without changes
@@ -7,7 +7,7 @@ VALUE eSHA3DigestError;
7
7
 
8
8
  /*
9
9
  * == Notes
10
- *
10
+ *
11
11
  * ::Digest::Class call sequence ->
12
12
  * | .alloc() ->
13
13
  * | .new() ->
@@ -16,31 +16,33 @@ VALUE eSHA3DigestError;
16
16
  * --| .alloc() ->
17
17
  * | .copy() ->
18
18
  * | .finish() ->
19
- *
19
+ *
20
20
  */
21
21
 
22
- static void free_allox(MDX *mdx)
22
+ static void free_allox(MDX *mdx)
23
23
  {
24
24
  if (mdx) {
25
- if (mdx->state)
25
+ if (mdx->state) {
26
26
  free(mdx->state);
27
+ }
27
28
 
28
29
  free(mdx);
29
- }
30
+ }
30
31
 
31
32
  return;
32
33
  }
33
34
 
34
- static VALUE c_digest_alloc(VALUE klass)
35
- {
35
+ static VALUE c_digest_alloc(VALUE klass)
36
+ {
36
37
  MDX *mdx;
37
38
  VALUE obj;
38
39
 
39
40
  mdx = (MDX *) malloc(sizeof(MDX));
40
- if (!mdx)
41
+ if (!mdx) {
41
42
  rb_raise(eSHA3DigestError, "failed to allocate object memory");
43
+ }
42
44
 
43
- mdx->state = (hashState *) malloc(sizeof(hashState));
45
+ mdx->state = (Keccak_HashInstance *) malloc(sizeof(Keccak_HashInstance));
44
46
  if (!mdx->state) {
45
47
  free_allox(mdx);
46
48
  rb_raise(eSHA3DigestError, "failed to allocate state memory");
@@ -48,7 +50,7 @@ static VALUE c_digest_alloc(VALUE klass)
48
50
 
49
51
  obj = Data_Wrap_Struct(klass, 0, free_allox, mdx);
50
52
 
51
- memset(mdx->state, 0, sizeof(hashState));
53
+ memset(mdx->state, 0, sizeof(Keccak_HashInstance));
52
54
  mdx->hashbitlen = 0;
53
55
 
54
56
  return obj;
@@ -56,31 +58,56 @@ static VALUE c_digest_alloc(VALUE klass)
56
58
 
57
59
  static VALUE c_digest_update(VALUE, VALUE);
58
60
 
61
+ HashReturn c_keccak_hash_initialize(MDX *mdx)
62
+ {
63
+ HashReturn r = FAIL;
64
+
65
+ switch (mdx->hashbitlen) {
66
+ case 224:
67
+ r = Keccak_HashInitialize_SHA3_224(mdx->state);
68
+ break;
69
+ case 256:
70
+ r = Keccak_HashInitialize_SHA3_256(mdx->state);
71
+ break;
72
+ case 384:
73
+ r = Keccak_HashInitialize_SHA3_384(mdx->state);
74
+ break;
75
+ case 512:
76
+ r = Keccak_HashInitialize_SHA3_512(mdx->state);
77
+ break;
78
+ }
79
+
80
+ return r;
81
+ }
82
+
59
83
  // SHA3::Digest.new(type, [data]) -> self
60
84
  static VALUE c_digest_init(int argc, VALUE *argv, VALUE self)
61
- {
85
+ {
62
86
  MDX *mdx;
63
87
  VALUE hlen, data;
64
88
 
65
89
  rb_scan_args(argc, argv, "02", &hlen, &data);
66
90
  GETMDX(self, mdx);
67
91
 
68
- if (!NIL_P(hlen))
92
+ if (!NIL_P(hlen)) {
69
93
  mdx->hashbitlen = get_hlen(hlen);
70
- else
94
+ } else {
71
95
  mdx->hashbitlen = 256;
96
+ }
72
97
 
73
- if (Init(mdx->state, mdx->hashbitlen) != SUCCESS)
98
+ if (c_keccak_hash_initialize(mdx) != SUCCESS) {
74
99
  rb_raise(eSHA3DigestError, "failed to initialize algorithm state");
100
+ }
75
101
 
76
- if (!NIL_P(data))
102
+ if (!NIL_P(data)) {
77
103
  return c_digest_update(self, data);
104
+ }
78
105
 
79
106
  return self;
80
107
  }
81
108
 
82
109
  // SHA3::Digest.update(data) -> self
83
- static VALUE c_digest_update(VALUE self, VALUE data)
110
+ static VALUE c_digest_update(VALUE self, VALUE data)
84
111
  {
85
112
  MDX *mdx;
86
113
  DataLength dlen;
@@ -90,41 +117,39 @@ static VALUE c_digest_update(VALUE self, VALUE data)
90
117
 
91
118
  dlen = (RSTRING_LEN(data) * 8);
92
119
 
93
- if (Update(mdx->state, RSTRING_PTR(data), dlen) != SUCCESS)
120
+ if (Keccak_HashUpdate(mdx->state, (BitSequence *) RSTRING_PTR(data), dlen) != SUCCESS) {
94
121
  rb_raise(eSHA3DigestError, "failed to update hash data");
122
+ }
95
123
 
96
124
  return self;
97
125
  }
98
126
 
99
127
  // SHA3::Digest.reset() -> self
100
- static VALUE c_digest_reset(VALUE self)
128
+ static VALUE c_digest_reset(VALUE self)
101
129
  {
102
130
  MDX *mdx;
103
131
 
104
132
  GETMDX(self, mdx);
105
133
 
106
- memset(mdx->state, 0, sizeof(hashState));
134
+ memset(mdx->state, 0, sizeof(Keccak_HashInstance));
107
135
 
108
- if (Init(mdx->state, mdx->hashbitlen) != SUCCESS)
136
+ if (c_keccak_hash_initialize(mdx) != SUCCESS) {
109
137
  rb_raise(eSHA3DigestError, "failed to reset internal state");
138
+ }
110
139
 
111
140
  return self;
112
141
  }
113
142
 
114
- // Fix: And, permanent reminder of a rookie mistake in c_digest_copy, comparing structs with ==/!= op
115
- // Fix: Woke-up after 2-hours of sleep, and for good reason. Fixed string comparison. Need to re-read K&R!
116
143
  static int cmp_states(MDX *mdx1, MDX *mdx2)
117
144
  {
118
145
  return (
119
146
  (mdx1->hashbitlen == mdx2->hashbitlen) &&
120
- (strcmp((const char *) mdx1->state->state, (const char *)mdx2->state->state) == 0) &&
121
- (strcmp((const char *) mdx1->state->dataQueue, (const char *) mdx2->state->dataQueue) == 0) &&
122
- (mdx1->state->rate == mdx2->state->rate) &&
123
- (mdx1->state->capacity == mdx2->state->capacity) &&
124
- (mdx1->state->bitsInQueue == mdx2->state->bitsInQueue) &&
147
+ (strcmp((const char *) mdx1->state->sponge.state, (const char *)mdx2->state->sponge.state) == 0) &&
148
+ (mdx1->state->sponge.rate == mdx2->state->sponge.rate) &&
149
+ (mdx1->state->sponge.byteIOIndex == mdx2->state->sponge.byteIOIndex) &&
150
+ (mdx1->state->sponge.squeezing == mdx2->state->sponge.squeezing) &&
125
151
  (mdx1->state->fixedOutputLength == mdx2->state->fixedOutputLength) &&
126
- (mdx1->state->squeezing == mdx2->state->squeezing) &&
127
- (mdx1->state->bitsAvailableForSqueezing == mdx2->state->bitsAvailableForSqueezing)
152
+ (mdx1->state->delimitedSuffix == mdx2->state->delimitedSuffix)
128
153
  );
129
154
  }
130
155
 
@@ -134,20 +159,22 @@ static VALUE c_digest_copy(VALUE self, VALUE obj)
134
159
  MDX *mdx1, *mdx2;
135
160
 
136
161
  rb_check_frozen(self);
137
- if (self == obj)
162
+ if (self == obj) {
138
163
  return self;
164
+ }
139
165
 
140
166
  GETMDX(self, mdx1);
141
167
  SAFEGETMDX(obj, mdx2);
142
168
 
143
- memcpy(mdx1->state, mdx2->state, sizeof(hashState));
169
+ memcpy(mdx1->state, mdx2->state, sizeof(Keccak_HashInstance));
144
170
  mdx1->hashbitlen = mdx2->hashbitlen;
145
171
 
146
172
  // Fetch the data again to make sure it was copied
147
173
  GETMDX(self, mdx1);
148
174
  SAFEGETMDX(obj, mdx2);
149
- if (!cmp_states(mdx1, mdx2))
175
+ if (!cmp_states(mdx1, mdx2)) {
150
176
  rb_raise(eSHA3DigestError, "failed to copy state");
177
+ }
151
178
 
152
179
  return self;
153
180
  }
@@ -162,7 +189,7 @@ static VALUE c_digest_length(VALUE self)
162
189
  }
163
190
 
164
191
  // SHA3::Digest.block_length -> Integer
165
- static VALUE c_digest_block_length(VALUE self)
192
+ static VALUE c_digest_block_length(VALUE self)
166
193
  {
167
194
  MDX *mdx;
168
195
  GETMDX(self, mdx);
@@ -171,13 +198,13 @@ static VALUE c_digest_block_length(VALUE self)
171
198
  }
172
199
 
173
200
  // SHA3::Digest.name -> String
174
- static VALUE c_digest_name(VALUE self)
201
+ static VALUE c_digest_name(VALUE self)
175
202
  {
176
203
  return rb_str_new2("SHA3");
177
204
  }
178
205
 
179
206
  // SHA3::Digest.finish() -> String
180
- static VALUE c_digest_finish(int argc, VALUE *argv, VALUE self)
207
+ static VALUE c_digest_finish(int argc, VALUE *argv, VALUE self)
181
208
  {
182
209
  MDX *mdx;
183
210
  VALUE str;
@@ -187,41 +214,14 @@ static VALUE c_digest_finish(int argc, VALUE *argv, VALUE self)
187
214
 
188
215
  if (NIL_P(str)) {
189
216
  str = rb_str_new(0, mdx->hashbitlen / 8);
190
- }
191
- else {
217
+ } else {
192
218
  StringValue(str);
193
219
  rb_str_resize(str, mdx->hashbitlen / 8);
194
220
  }
195
221
 
196
- if (Final(mdx->state, RSTRING_PTR(str)) != SUCCESS)
222
+ if (Keccak_HashFinal(mdx->state, (BitSequence *) RSTRING_PTR(str)) != SUCCESS) {
197
223
  rb_raise(eSHA3DigestError, "failed to finalize digest");
198
-
199
- return str;
200
- }
201
-
202
- // SHA3::Digest.compute(type, data, [datalen]) -> String (bytes)
203
- // TO-DO: styled output (hex)
204
- static VALUE c_digest_compute(int argc, VALUE *argv, VALUE self)
205
- {
206
- VALUE hlen, data, dlen, str;
207
- int hashbitlen;
208
- DataLength datalen;
209
-
210
- rb_scan_args(argc, argv, "21", &hlen, &data, &dlen);
211
-
212
- hashbitlen = get_hlen(hlen);
213
-
214
- StringValue(data);
215
-
216
- if (!NIL_P(dlen))
217
- datalen = NUM2ULL(dlen);
218
- else
219
- datalen = (RSTRING_LEN(data) * 8);
220
-
221
- str = rb_str_new(0, hashbitlen / 8);
222
-
223
- if (Hash(hashbitlen, RSTRING_PTR(data), datalen, RSTRING_PTR(str)) != SUCCESS)
224
- rb_raise(eSHA3DigestError, "failed to generate hash");
224
+ }
225
225
 
226
226
  return str;
227
227
  }
@@ -232,7 +232,7 @@ void Init_sha3_n_digest()
232
232
 
233
233
  /* SHA3::Digest (class) */
234
234
  cSHA3Digest = rb_define_class_under(mSHA3, "Digest", rb_path2class("Digest::Class"));
235
- /* SHA3::Digest::DigestError (class) */
235
+ /* SHA3::Digest::DigestError (class) */
236
236
  eSHA3DigestError = rb_define_class_under(cSHA3Digest, "DigestError", rb_eStandardError);
237
237
 
238
238
  // SHA3::Digest (class) methods
@@ -247,9 +247,6 @@ void Init_sha3_n_digest()
247
247
  rb_define_private_method(cSHA3Digest, "finish", c_digest_finish, -1);
248
248
 
249
249
  rb_define_alias(cSHA3Digest, "<<", "update");
250
-
251
- // SHA3 (module) functions (support bit operations)
252
- rb_define_singleton_method(cSHA3Digest, "compute", c_digest_compute, -1);
253
250
 
254
251
  return;
255
- }
252
+ }
@@ -27,7 +27,7 @@ extern VALUE cSHA3Digest;
27
27
  extern VALUE eSHA3DigestError;
28
28
 
29
29
  typedef struct {
30
- hashState *state;
30
+ Keccak_HashInstance *state;
31
31
  int hashbitlen;
32
32
  } MDX;
33
33
 
@@ -37,4 +37,4 @@ void Init_sha3_n_digest(void);
37
37
  }
38
38
  #endif
39
39
 
40
- #endif
40
+ #endif
@@ -1,24 +1,19 @@
1
1
  require 'mkmf'
2
2
  require 'rbconfig'
3
3
 
4
- FileUtils.rm "#{$srcdir}/KeccakF-1600-opt.c", :force => true
5
-
6
4
  target_cpu = RbConfig::CONFIG['target_cpu']
7
5
 
8
6
  if 1.size == 4 and target_cpu =~ /i386|x86_32/ # x86 32bit optimized code
9
- Logging::message "=== Using i386 optimized Keccak code ===\n"
10
- FileUtils.cp "#{$srcdir}/KeccakF-1600-opt32.c-arch", "#{$srcdir}/KeccakF-1600-opt.c"
7
+ Logging::message "=== Using reference ===\n"
8
+ FileUtils.cp Dir["#{$srcdir}/Reference/*"].collect { |f| File.expand_path(f) }, "#{$srcdir}/"
11
9
  elsif 1.size == 8 and target_cpu =~ /i686|x86_64/
12
- Logging::message "=== Using i686 optimized Keccak code ===\n"
13
- FileUtils.cp "#{$srcdir}/KeccakF-1600-opt64.c-arch", "#{$srcdir}/KeccakF-1600-opt.c"
14
- else # Ha? Use reference code -- slow
15
- Logging::message "=== Using reference Keccak code ===\n"
16
- FileUtils.cp "#{$srcdir}/KeccakF-1600-reference.c-arch", "#{$srcdir}/KeccakF-1600-opt.c"
10
+ Logging::message "=== Using optimized (64-bit) ===\n"
11
+ FileUtils.cp Dir["#{$srcdir}/Optimized64/*"].collect { |f| File.expand_path(f) }, "#{$srcdir}/"
12
+ else
13
+ Logging::message "=== Using reference ===\n"
14
+ FileUtils.cp Dir["#{$srcdir}/Reference/*"].collect { |f| File.expand_path(f) }, "#{$srcdir}/"
17
15
  end
18
16
 
19
- find_header("KeccakF-1600-interface.h")
20
- find_header("KeccakSponge.h")
21
- find_header("KeccakNISTInterface.h")
22
17
  find_header("sha3.h")
23
18
  find_header("digest.h")
24
19
 
@@ -5,7 +5,7 @@
5
5
 
6
6
  #include <ruby.h>
7
7
 
8
- #include "KeccakNISTInterface.h"
8
+ #include "KeccakHash.h"
9
9
  #include "digest.h"
10
10
 
11
11
  #ifdef __cplusplus
@@ -22,4 +22,4 @@ void Init_sha3_n(void);
22
22
  }
23
23
  #endif
24
24
 
25
- #endif
25
+ #endif
@@ -2,10 +2,10 @@ require 'digest'
2
2
 
3
3
  module SHA3
4
4
  # A sub-class of (MRI Ruby based) Digest::Class, it implements SHA3 (Keccak) digest algorithm.
5
- #
5
+ #
6
6
  # @note SHA3::Digest class provides a four sub-classes for the available hash bit lengths (types).
7
7
  # You can instantiate a new instance of Digest sub-class for a given type using the following sub-classes:
8
- #
8
+ #
9
9
  # SHA3::Digest::SHA224([data])
10
10
  # SHA3::Digest::SHA256([data])
11
11
  # SHA3::Digest::SHA384([data])
@@ -14,18 +14,18 @@ module SHA3
14
14
  # The [data] parameter is optional.
15
15
  class Digest < Digest::Class
16
16
  # Creates a Digest instance based on given hash bit length (type).
17
- #
18
- # @param type [Number, Symbol] optional parameter used to set hash bit length (type).
19
- # Valid options are:
20
- #
17
+ #
18
+ # @param type [Number, Symbol] optional parameter used to set hash bit length (type).
19
+ # Valid options are:
20
+ #
21
21
  # Number: 224, 256, 384, or 512
22
22
  # Symobols: :sha224, :sha256, :sha384, or :sha512
23
- #
23
+ #
24
24
  # Default value: 256 (bits)
25
25
  # @param data [String] optional parameter used to update initial instance state.
26
- # #
26
+ # #
27
27
  # @return [Digest] self
28
- #
28
+ #
29
29
  # @example
30
30
  # digest = SHA3::Digest.new # => Defaults to 256 bits
31
31
  # digest = SHA3::Digest.new(224) # => Initialize a new 224 bit digest instance
@@ -34,15 +34,15 @@ module SHA3
34
34
  # See function: c_digest_init(...) in ext/sha3/_digest.c
35
35
  end
36
36
 
37
- # Updates, and recalculates Message Digest (state) with given data. If a message digest
38
- # is to be computed from several subsequent sources, then each may be passed individually
37
+ # Updates, and recalculates Message Digest (state) with given data. If a message digest
38
+ # is to be computed from several subsequent sources, then each may be passed individually
39
39
  # to the Digest instance.
40
- #
40
+ #
41
41
  # @param data [String] data to compute
42
- #
42
+ #
43
43
  # @return [Digest] self
44
- #
45
- # @example
44
+ #
45
+ # @example
46
46
  # digest = SHA3::Digest::SHA256.new
47
47
  # digest.update('hash me')
48
48
  # digest.update('me too')
@@ -61,9 +61,9 @@ module SHA3
61
61
  end
62
62
 
63
63
  # Returns message digest length in bytes.
64
- #
64
+ #
65
65
  # @return [Number] message length in bytes.
66
- #
66
+ #
67
67
  # @example
68
68
  # digest = SHA3::Digest::SHA256.new
69
69
  # digest.length # Result => 32 (or 256 bits)
@@ -72,9 +72,9 @@ module SHA3
72
72
  end
73
73
 
74
74
  # Returns digest block length in bytes.
75
- #
75
+ #
76
76
  # @return [Number] digest block length in bytes.
77
- #
77
+ #
78
78
  # @example
79
79
  # digest = SHA3::Digest::SHA384.new
80
80
  # digest.block_length # Result => 104
@@ -83,19 +83,19 @@ module SHA3
83
83
  end
84
84
 
85
85
  # Returns name of initialized digest
86
- #
86
+ #
87
87
  # @return [String] name
88
88
  def name
89
89
  # See function: c_digest_name(...) in ext/sha3/_digest.c
90
90
  end
91
91
 
92
92
  # Returns computed hash value for given hash type, and data in hex (string).
93
- #
93
+ #
94
94
  # @param type [Number, Symbol] See {#initialize} for valid type values.
95
95
  # @param data [String] data to compute hash value
96
- #
96
+ #
97
97
  # @return (String) computed hash as hex-encoded string
98
- #
98
+ #
99
99
  # @example
100
100
  # SHA3::Digest.hexdigest(256, 'compute me, please')
101
101
  # SHA3::Digest::SHA256.hexdigest('compute me, please') # => Alternate syntax
@@ -103,30 +103,17 @@ module SHA3
103
103
  end
104
104
 
105
105
  # Returns computed hash value for given hash type, and data in bytes.
106
- #
106
+ #
107
107
  # @param type [Number, Symbol] See {#initialize} for valid type values.
108
108
  # @param data [String] data to compute hash value
109
- #
109
+ #
110
110
  # @return [String] computed hash in bytes
111
- #
111
+ #
112
112
  # @example
113
113
  # SHA3::Digest.digest(256, 'compute me, please')
114
114
  # SHA3::Digest::SHA256.digest('compute me, please') # => Alternate syntax
115
115
  def self.digest(type, data)
116
116
  end
117
-
118
- # Returns computed hash value of bit-length data.
119
- #
120
- # @param type [Number, Symbol] See {#initialize} for valid type values.
121
- # @param data [String] data to compute hash value
122
- # @param data_length [Number] data bit length
123
- #
124
- # @return [String] computed hash in bytes
125
- #
126
- # @example
127
- # SHA3::Digest.compute(:sha384, '\0C', 2)
128
- def self.compute(type, data, data_length)
129
- end
130
117
  end
131
118
 
132
119
  class DigestError < StandardError