krypt 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. data/LICENSE +20 -0
  2. data/README.md +82 -0
  3. data/lib/krypt.rb +49 -0
  4. data/lib/krypt/asn1.rb +3 -0
  5. data/lib/krypt/asn1/common.rb +96 -0
  6. data/lib/krypt/asn1/template.rb +257 -0
  7. data/lib/krypt/codec.rb +57 -0
  8. data/lib/krypt/codec/base64.rb +140 -0
  9. data/lib/krypt/codec/base_codec.rb +36 -0
  10. data/lib/krypt/codec/hex.rb +122 -0
  11. data/lib/krypt/digest.rb +112 -0
  12. data/lib/krypt/hmac.rb +69 -0
  13. data/lib/krypt/pkcs5.rb +1 -0
  14. data/lib/krypt/pkcs5/pbkdf2.rb +41 -0
  15. data/lib/krypt/provider.rb +35 -0
  16. data/lib/krypt/x509.rb +3 -0
  17. data/lib/krypt/x509/certificate.rb +36 -0
  18. data/lib/krypt/x509/common.rb +41 -0
  19. data/lib/krypt/x509/crl.rb +33 -0
  20. data/lib/krypt_missing.rb +32 -0
  21. data/spec/krypt-core/MEMO.txt +85 -0
  22. data/spec/krypt-core/asn1/asn1_bit_string_spec.rb +475 -0
  23. data/spec/krypt-core/asn1/asn1_boolean_spec.rb +392 -0
  24. data/spec/krypt-core/asn1/asn1_constants_spec.rb +71 -0
  25. data/spec/krypt-core/asn1/asn1_data_spec.rb +1153 -0
  26. data/spec/krypt-core/asn1/asn1_end_of_contents_spec.rb +133 -0
  27. data/spec/krypt-core/asn1/asn1_enumerated_spec.rb +458 -0
  28. data/spec/krypt-core/asn1/asn1_generalized_time_spec.rb +492 -0
  29. data/spec/krypt-core/asn1/asn1_integer_spec.rb +557 -0
  30. data/spec/krypt-core/asn1/asn1_null_spec.rb +360 -0
  31. data/spec/krypt-core/asn1/asn1_object_id_spec.rb +495 -0
  32. data/spec/krypt-core/asn1/asn1_octet_string_spec.rb +456 -0
  33. data/spec/krypt-core/asn1/asn1_parser_spec.rb +503 -0
  34. data/spec/krypt-core/asn1/asn1_pem_spec.rb +282 -0
  35. data/spec/krypt-core/asn1/asn1_sequence_spec.rb +637 -0
  36. data/spec/krypt-core/asn1/asn1_set_spec.rb +795 -0
  37. data/spec/krypt-core/asn1/asn1_utc_time_spec.rb +495 -0
  38. data/spec/krypt-core/asn1/asn1_utf8_string_spec.rb +404 -0
  39. data/spec/krypt-core/asn1/resources.rb +53 -0
  40. data/spec/krypt-core/base64/base64_spec.rb +97 -0
  41. data/spec/krypt-core/digest/digest_spec.rb +707 -0
  42. data/spec/krypt-core/hex/hex_spec.rb +102 -0
  43. data/spec/krypt-core/pem/pem_decode_spec.rb +235 -0
  44. data/spec/krypt-core/resources.rb +1 -0
  45. data/spec/krypt-core/template/template_choice_parse_spec.rb +289 -0
  46. data/spec/krypt-core/template/template_dsl_spec.rb +351 -0
  47. data/spec/krypt-core/template/template_seq_of_parse_spec.rb +64 -0
  48. data/spec/krypt-core/template/template_seq_parse_spec.rb +1241 -0
  49. data/spec/krypt/codec/base64_decoder_spec.rb +94 -0
  50. data/spec/krypt/codec/base64_encoder_spec.rb +94 -0
  51. data/spec/krypt/codec/base64_mixed_spec.rb +16 -0
  52. data/spec/krypt/codec/hex_decoder_spec.rb +94 -0
  53. data/spec/krypt/codec/hex_encoder_spec.rb +94 -0
  54. data/spec/krypt/codec/hex_mixed_spec.rb +17 -0
  55. data/spec/krypt/codec/identity_shared.rb +119 -0
  56. data/spec/krypt/hmac/hmac_spec.rb +311 -0
  57. data/spec/krypt/pkcs5/pbkdf2_spec.rb +79 -0
  58. data/spec/krypt/provider/provider_spec.rb +83 -0
  59. data/spec/res/ca-bundle.crt +11758 -0
  60. data/spec/res/certificate.cer +0 -0
  61. data/spec/res/certificate.pem +20 -0
  62. data/spec/res/multiple_certs.pem +60 -0
  63. data/spec/resources.rb +66 -0
  64. data/test/helper.rb +8 -0
  65. data/test/res/certificate.cer +0 -0
  66. data/test/resources.rb +48 -0
  67. data/test/scratch.rb +28 -0
  68. data/test/test_krypt_asn1.rb +119 -0
  69. data/test/test_krypt_parser.rb +331 -0
  70. metadata +134 -0
@@ -0,0 +1,97 @@
1
+ require 'rspec'
2
+ require 'krypt'
3
+
4
+ describe Krypt::Base64 do
5
+
6
+ let(:mod) { Krypt::Base64 }
7
+
8
+ describe "encode" do
9
+ context "single parameter data" do
10
+ context "RFC 4648 test vectors" do
11
+ specify "empty string" do
12
+ mod.encode("").should == ""
13
+ end
14
+
15
+ specify "f" do
16
+ mod.encode("f").should == "Zg=="
17
+ end
18
+
19
+ specify "fo" do
20
+ mod.encode("fo").should == "Zm8="
21
+ end
22
+
23
+ specify "foo" do
24
+ mod.encode("foo").should == "Zm9v"
25
+ end
26
+
27
+ specify "foob" do
28
+ mod.encode("foob").should == "Zm9vYg=="
29
+ end
30
+
31
+ specify "fooba" do
32
+ mod.encode("fooba").should == "Zm9vYmE="
33
+ end
34
+
35
+ specify "foobar" do
36
+ mod.encode("foobar").should == "Zm9vYmFy"
37
+ end
38
+ end
39
+ end
40
+
41
+ it "should return a string with US-ASCII encoding" do
42
+ mod.encode("test").encoding.should == Encoding::US_ASCII
43
+ end
44
+
45
+ it "should return a string with US-ASCII encoding even if
46
+ the underlying encoding is not" do
47
+ auml = [%w{ C3 A4 }.join('')].pack('H*')
48
+ auml.force_encoding(Encoding::UTF_8)
49
+ mod.encode(auml).encoding.should == Encoding::US_ASCII
50
+ end
51
+ end
52
+
53
+ describe "decode" do
54
+ context "RFC 4648 test vectors" do
55
+ specify "empty string" do
56
+ mod.decode("").should == ""
57
+ end
58
+
59
+ specify "f" do
60
+ mod.decode("Zg==").should == "f"
61
+ end
62
+
63
+ specify "fo" do
64
+ mod.decode("Zm8=").should == "fo"
65
+ end
66
+
67
+ specify "foo" do
68
+ mod.decode("Zm9v").should == "foo"
69
+ end
70
+
71
+ specify "foob" do
72
+ mod.decode("Zm9vYg==").should == "foob"
73
+ end
74
+
75
+ specify "fooba" do
76
+ mod.decode("Zm9vYmE=").should == "fooba"
77
+ end
78
+
79
+ specify "foobar" do
80
+ mod.decode("Zm9vYmFy").should == "foobar"
81
+ end
82
+ end
83
+
84
+ it "should return a string with binary encoding" do
85
+ mod.decode("Zm9vYmE=").encoding.should == Encoding::BINARY
86
+ end
87
+
88
+ it "should return a string with binary encoding even if
89
+ the underlying encoding is not" do
90
+ auml = [%w{ C3 A4 }.join('')].pack('H*')
91
+ auml.force_encoding(Encoding::UTF_8)
92
+ mod.decode(auml).encoding.should == Encoding::BINARY
93
+ end
94
+ end
95
+
96
+ end
97
+
@@ -0,0 +1,707 @@
1
+ require 'rspec'
2
+ require 'krypt'
3
+ require 'stringio'
4
+ require 'base64'
5
+ require_relative '../resources'
6
+
7
+ RSpec::Matchers.define :be_a_hex_string do
8
+ match do |value|
9
+ value.each_byte do |b|
10
+ unless (("0".ord)..("9".ord)).include?(b) || (("a".ord)..("f".ord)).include?(b) || (("A".ord)..("F".ord)).include?(b)
11
+ false
12
+ else
13
+ true
14
+ end
15
+ end
16
+ end
17
+ end
18
+
19
+ describe Krypt::Digest do
20
+ let(:klass) { Krypt::Digest }
21
+ let(:digesterror) { Krypt::Digest::DigestError }
22
+
23
+ describe "#new" do
24
+ context "accepts a String representing an algorithm" do
25
+ subject { klass.new(algo) }
26
+
27
+ context "SHA1" do
28
+ context "uppercase" do
29
+ let(:algo) { "SHA1" }
30
+ its(:name) { should == algo }
31
+ end
32
+
33
+ describe "although algorithms can be requested in lowercase, the name
34
+ will always be returned in uppercase" do
35
+ context "lowercase" do
36
+ let(:algo) { "sha1" }
37
+ its(:name) { should == "SHA1" }
38
+ end
39
+ end
40
+ end
41
+
42
+ context "SHA224" do
43
+ context "uppercase" do
44
+ let(:algo) { "SHA224" }
45
+ its(:name) { should == algo }
46
+ end
47
+
48
+ context "lowercase" do
49
+ let(:algo) { "sha224" }
50
+ its(:name) { should == "SHA224" }
51
+ end
52
+ end
53
+
54
+ context "SHA256" do
55
+ context "uppercase" do
56
+ let(:algo) { "SHA256" }
57
+ its(:name) { should == algo }
58
+ end
59
+
60
+ context "lowercase" do
61
+ let(:algo) { "sha256" }
62
+ its(:name) { should == "SHA256" }
63
+ end
64
+ end
65
+
66
+ context "SHA384" do
67
+ context "uppercase" do
68
+ let(:algo) { "SHA384" }
69
+ its(:name) { should == algo }
70
+ end
71
+
72
+ context "lowercase" do
73
+ let(:algo) { "sha384" }
74
+ its(:name) { should == "SHA384" }
75
+ end
76
+ end
77
+
78
+ context "SHA512" do
79
+ context "uppercase" do
80
+ let(:algo) { "SHA512" }
81
+ its(:name) { should == algo }
82
+ end
83
+
84
+ context "lowercase" do
85
+ let(:algo) { "sha512" }
86
+ its(:name) { should == "SHA512" }
87
+ end
88
+ end
89
+
90
+ context "RIPEMD160" do
91
+ context "uppercase" do
92
+ let(:algo) { "RIPEMD160" }
93
+ its(:name) { should == algo }
94
+ end
95
+
96
+ context "lowercase" do
97
+ let(:algo) { "ripemd160" }
98
+ its(:name) { should == "RIPEMD160" }
99
+ end
100
+ end
101
+
102
+ context "MD5" do
103
+ context "uppercase" do
104
+ let(:algo) { "MD5" }
105
+ its(:name) { should == algo }
106
+ end
107
+
108
+ context "lowercase" do
109
+ let(:algo) { "md5" }
110
+ its(:name) { should == "MD5" }
111
+ end
112
+ end
113
+ end
114
+
115
+ it "rejects an unknown algorithm" do
116
+ -> { klass.new("HAS1") }.should raise_error Krypt::Provider::ServiceNotAvailableError
117
+ end
118
+
119
+ context "accepts an algorithm oid String" do
120
+ subject { klass.new(oid) }
121
+
122
+ context "SHA-1" do
123
+ let(:oid) { "1.3.14.3.2.26" }
124
+ its(:name) { should == "SHA1" }
125
+ end
126
+
127
+ context "SHA-224" do
128
+ let(:oid) { "2.16.840.1.101.3.4.2.4" }
129
+ its(:name) { should == "SHA224" }
130
+ end
131
+
132
+ context "SHA-256" do
133
+ let(:oid) { "2.16.840.1.101.3.4.2.1" }
134
+ its(:name) { should == "SHA256" }
135
+ end
136
+
137
+ context "SHA-384" do
138
+ let(:oid) { "2.16.840.1.101.3.4.2.2" }
139
+ its(:name) { should == "SHA384" }
140
+ end
141
+
142
+ context "SHA-512" do
143
+ let(:oid) { "2.16.840.1.101.3.4.2.3" }
144
+ its(:name) { should == "SHA512" }
145
+ end
146
+
147
+ context "RIPEMD-160" do
148
+ let(:oid) { "1.3.36.3.2.1" }
149
+ its(:name) { should == "RIPEMD160" }
150
+ end
151
+
152
+ context "MD5" do
153
+ let(:oid) { "1.2.840.113549.2.5" }
154
+ its(:name) { should == "MD5" }
155
+ end
156
+ end
157
+
158
+ it "rejects an unknown oid" do
159
+ -> { klass.new("1.2.3.4.5") }.should raise_error Krypt::Provider::ServiceNotAvailableError
160
+ end
161
+ end
162
+
163
+ describe "#update" do
164
+ it "takes a String as an argument and returns self" do
165
+ md = klass.new("SHA1")
166
+ md.update("test").should be_equal md
167
+ end
168
+
169
+ it "<< is an alias" do
170
+ algo = "SHA1"
171
+ md = klass.new(algo)
172
+ md.update("test")
173
+ digest = md.digest
174
+
175
+ md = klass.new(algo)
176
+ md << "test"
177
+ md.digest.should == digest
178
+ end
179
+
180
+ it "treats multiple updates equivalently to one single call to #digest" do
181
+ algo = "SHA1"
182
+ data = "a" * 64
183
+ n = 3
184
+ h1 = klass.new(algo)
185
+ h2 = klass.new(algo)
186
+ n.times { h1 << data }
187
+ h2 << (data * n)
188
+ h1.digest.should == h2.digest
189
+ end
190
+ end
191
+
192
+ describe "#digest" do
193
+ subject { klass.new("SHA1") }
194
+
195
+ it "outputs the digest of everything hashed so far when given no
196
+ arguments" do
197
+ subject.update("test").digest.should be_an_instance_of String
198
+ end
199
+
200
+ it "updates itself with a given String argument and returns the
201
+ final digest" do
202
+ h = klass.new("SHA1")
203
+ h << "test"
204
+ subject.digest("test").should == h.digest
205
+ end
206
+
207
+ it "resets its internal state after no-args call" do
208
+ data = "test"
209
+ digest = subject.digest(data)
210
+ h = klass.new("SHA1")
211
+ h << data
212
+ h.digest
213
+ h << data
214
+ digest.should == h.digest
215
+ # in case we found a collision ;)
216
+ digest.should_not == klass.new("SHA1").<<(data).<<(data).digest
217
+ end
218
+
219
+ it "doesn't alter internal state when called with argument" do
220
+ data = "test"
221
+ digest = subject.digest(data)
222
+ h = klass.new("SHA1")
223
+ h.digest(data)
224
+ h << data
225
+ digest.should == h.digest
226
+ end
227
+ end
228
+
229
+ describe "#hexdigest" do
230
+ subject { klass.new("SHA1") }
231
+
232
+ it "outputs a hex string of the digest of everything hashed so far when
233
+ given no arguments" do
234
+ subject.update("test").hexdigest.should be_a_hex_string
235
+ end
236
+
237
+ it "updates itself with a given String argument and returns the
238
+ final digest" do
239
+ h = klass.new("SHA1")
240
+ h << "test"
241
+ subject.hexdigest("test").should == h.hexdigest
242
+ end
243
+
244
+ it "resets its internal state after no-args call" do
245
+ data = "test"
246
+ digest = subject.hexdigest(data)
247
+ h = klass.new("SHA1")
248
+ h << data
249
+ h.hexdigest
250
+ h << data
251
+ digest.should == h.hexdigest
252
+ end
253
+
254
+ it "doesn't alter internal state when called with argument" do
255
+ data = "test"
256
+ digest = subject.hexdigest(data)
257
+ h = klass.new("SHA1")
258
+ h.hexdigest(data)
259
+ h << data
260
+ digest.should == h.hexdigest
261
+ end
262
+ end
263
+
264
+ describe "#reset" do
265
+ it "takes no arguments and returns self" do
266
+ h = klass.new("SHA1")
267
+ h.reset.should be_equal h
268
+ end
269
+
270
+ it "resets the internal state of an instance" do
271
+ algo = "SHA1"
272
+ data = "test"
273
+ noise = "abcd"
274
+ h = klass.new(algo)
275
+ h << noise
276
+ digest = h.reset.digest(data)
277
+ digest.should == klass.new(algo).digest(data)
278
+ # in case we found a collision ;)
279
+ digest.should_not == klass.new(algo).update(noise).digest(data)
280
+ end
281
+ end
282
+
283
+ context "#name" do
284
+ subject { klass.new(value) }
285
+
286
+ context "returns the algorithm name of an instance in uppercase letters" do
287
+ context "when created from uppercase algorithm" do
288
+ let(:value) { "SHA1" }
289
+ its(:name) { should == value }
290
+ end
291
+
292
+ context "when created from lowercase algorithm" do
293
+ let(:value) { "sha1" }
294
+ its(:name) { should == "SHA1" }
295
+ end
296
+
297
+ context "when created from an OID" do
298
+ let(:value) { "1.3.14.3.2.26" }
299
+ its(:name) { should == "SHA1" }
300
+ end
301
+ end
302
+ end
303
+
304
+ describe "#digest_length" do
305
+ context "returns the size of the final digest in bytes" do
306
+ subject { klass.new(algo) }
307
+
308
+ context "SHA1" do
309
+ let(:algo) { "SHA1" }
310
+ its(:digest_length) { should == 20 }
311
+ end
312
+
313
+ context "SHA224" do
314
+ let(:algo) { "SHA224" }
315
+ its(:digest_length) { should == 28 }
316
+ end
317
+
318
+ context "SHA256" do
319
+ let(:algo) { "SHA256" }
320
+ its(:digest_length) { should == 32 }
321
+ end
322
+
323
+ context "SHA384" do
324
+ let(:algo) { "SHA384" }
325
+ its(:digest_length) { should == 48 }
326
+ end
327
+
328
+ context "SHA512" do
329
+ let(:algo) { "SHA512" }
330
+ its(:digest_length) { should == 64 }
331
+ end
332
+
333
+ context "RIPEMD160" do
334
+ let(:algo) { "RIPEMD160" }
335
+ its(:digest_length) { should == 20 }
336
+ end
337
+
338
+ context "MD5" do
339
+ let(:algo) { "MD5" }
340
+ its(:digest_length) { should == 16 }
341
+ end
342
+ end
343
+ end
344
+
345
+ describe "#block_length" do
346
+ context "returns the size of one input message block in bytes" do
347
+ subject { klass.new(algo) }
348
+
349
+ context "SHA1" do
350
+ let(:algo) { "SHA1" }
351
+ its(:block_length) { should == 64 }
352
+ end
353
+
354
+ context "SHA224" do
355
+ let(:algo) { "SHA224" }
356
+ its(:block_length) { should == 64 }
357
+ end
358
+
359
+ context "SHA256" do
360
+ let(:algo) { "SHA256" }
361
+ its(:block_length) { should == 64 }
362
+ end
363
+
364
+ context "SHA384" do
365
+ let(:algo) { "SHA384" }
366
+ its(:block_length) { should == 128 }
367
+ end
368
+
369
+ context "SHA512" do
370
+ let(:algo) { "SHA512" }
371
+ its(:block_length) { should == 128 }
372
+ end
373
+
374
+ context "RIPEMD160" do
375
+ let(:algo) { "RIPEMD160" }
376
+ its(:block_length) { should == 64 }
377
+ end
378
+
379
+ context "MD5" do
380
+ let(:algo) { "MD5" }
381
+ its(:block_length) { should == 64 }
382
+ end
383
+ end
384
+ end
385
+
386
+ describe "explicit constructors" do
387
+ context "behave exactly like the equivalent Digest instance" do
388
+ let(:data) { "test" }
389
+ let(:expected) { klass.new(algo).digest(data) }
390
+
391
+ context "SHA1" do
392
+ let(:algo) { "SHA1" }
393
+ it { klass::SHA1.new.digest(data).should == expected }
394
+ end
395
+
396
+ context "SHA224" do
397
+ let(:algo) { "SHA224" }
398
+ it { klass::SHA224.new.digest(data).should == expected }
399
+ end
400
+
401
+ context "SHA256" do
402
+ let(:algo) { "SHA256" }
403
+ it { klass::SHA256.new.digest(data).should == expected }
404
+ end
405
+
406
+ context "SHA384" do
407
+ let(:algo) { "SHA384" }
408
+ it { klass::SHA384.new.digest(data).should == expected }
409
+ end
410
+
411
+ context "SHA512" do
412
+ let(:algo) { "SHA512" }
413
+ it { klass::SHA512.new.digest(data).should == expected }
414
+ end
415
+
416
+ context "RIPEMD160" do
417
+ let(:algo) { "RIPEMD160" }
418
+ it { klass::RIPEMD160.new.digest(data).should == expected }
419
+ end
420
+
421
+ context "MD5" do
422
+ let(:algo) { "MD5" }
423
+ it { klass::MD5.new.digest(data).should == expected }
424
+ end
425
+ end
426
+ end
427
+
428
+ # taken from FIPS 180-2
429
+ # empty string vectors taken from http://www.febooti.com/products/filetweak/members/hash-and-crc/test-vectors/
430
+ context "conforms to NIST test vectors" do
431
+ context "SHA-1" do
432
+ let(:instance) { klass::SHA1.new }
433
+ let(:binary) { instance.digest(data) }
434
+ let(:hex) { instance.hexdigest(data) }
435
+
436
+ context "one block message sample" do
437
+ let(:data) { "abc" }
438
+ let(:expected) { "A9993E364706816ABA3E25717850C26C9CD0D89D" }
439
+ it { binary.should == [expected].pack("H*") }
440
+ it { hex.upcase.should == expected }
441
+ end
442
+
443
+ context "two block message sample" do
444
+ let(:data) { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" }
445
+ let(:expected) { "84983E441C3BD26EBAAE4AA1F95129E5E54670F1" }
446
+ it { binary.should == [expected].pack("H*") }
447
+ it { hex.upcase.should == expected }
448
+ end
449
+
450
+ context "multi-block message sample" do
451
+ let(:data) { "a" * 10**6 }
452
+ let(:expected) { "34AA973CD4C4DAA4F61EEB2BDBAD27316534016F" }
453
+ it { binary.should == [expected].pack("H*") }
454
+ it { hex.upcase.should == expected }
455
+ end
456
+
457
+ context "empty string" do
458
+ let(:data) { "" }
459
+ let(:expected) { "DA39A3EE5E6B4B0D3255BFEF95601890AFD80709" }
460
+ it { binary.should == [expected].pack("H*") }
461
+ it { hex.upcase.should == expected }
462
+ end
463
+ end
464
+
465
+ context "SHA-256" do
466
+ let(:instance) { klass::SHA256.new }
467
+ let(:binary) { instance.digest(data) }
468
+ let(:hex) { instance.hexdigest(data) }
469
+
470
+ context "one block message sample" do
471
+ let(:data) { "abc" }
472
+ let(:expected) { "BA7816BF8F01CFEA414140DE5DAE2223B00361A396177A9CB410FF61F20015AD" }
473
+ it { binary.should == [expected].pack("H*") }
474
+ it { hex.upcase.should == expected }
475
+ end
476
+
477
+ context "two block message sample" do
478
+ let(:data) { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" }
479
+ let(:expected) { "248D6A61D20638B8E5C026930C3E6039A33CE45964FF2167F6ECEDD419DB06C1" }
480
+ it { binary.should == [expected].pack("H*") }
481
+ it { hex.upcase.should == expected }
482
+ end
483
+
484
+ context "multi-block message sample" do
485
+ let(:data) { "a" * 10**6 }
486
+ let(:expected) { "CDC76E5C9914FB9281A1C7E284D73E67F1809A48A497200E046D39CCC7112CD0" }
487
+ it { binary.should == [expected].pack("H*") }
488
+ it { hex.upcase.should == expected }
489
+ end
490
+
491
+ context "empty string" do
492
+ let(:data) { "" }
493
+ let(:expected) { "E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855" }
494
+ it { binary.should == [expected].pack("H*") }
495
+ it { hex.upcase.should == expected }
496
+ end
497
+ end
498
+
499
+ context "SHA-512" do
500
+ let(:instance) { klass::SHA512.new }
501
+ let(:binary) { instance.digest(data) }
502
+ let(:hex) { instance.hexdigest(data) }
503
+
504
+ context "one block message sample" do
505
+ let(:data) { "abc" }
506
+ let(:expected) { "DDAF35A193617ABACC417349AE20413112E6FA4E89A97EA20A9EEEE64B55D39A2192992A274FC1A836BA3C23A3FEEBBD454D4423643CE80E2A9AC94FA54CA49F" }
507
+ it { binary.should == [expected].pack("H*") }
508
+ it { hex.upcase.should == expected }
509
+ end
510
+
511
+ context "two block message sample" do
512
+ let(:data) { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" }
513
+ let(:expected) { "8E959B75DAE313DA8CF4F72814FC143F8F7779C6EB9F7FA17299AEADB6889018501D289E4900F7E4331B99DEC4B5433AC7D329EEB6DD26545E96E55B874BE909" }
514
+ it { binary.should == [expected].pack("H*") }
515
+ it { hex.upcase.should == expected }
516
+ end
517
+
518
+ context "multi-block message sample" do
519
+ let(:data) { "a" * 10**6 }
520
+ let(:expected) { "E718483D0CE769644E2E42C7BC15B4638E1F98B13B2044285632A803AFA973EBDE0FF244877EA60A4CB0432CE577C31BEB009C5C2C49AA2E4EADB217AD8CC09B" }
521
+ it { binary.should == [expected].pack("H*") }
522
+ it { hex.upcase.should == expected }
523
+ end
524
+
525
+ context "empty string" do
526
+ let(:data) { "" }
527
+ let(:expected) { "CF83E1357EEFB8BDF1542850D66D8007D620E4050B5715DC83F4A921D36CE9CE47D0D13C5D85F2B0FF8318D2877EEC2F63B931BD47417A81A538327AF927DA3E" }
528
+ it { binary.should == [expected].pack("H*") }
529
+ it { hex.upcase.should == expected }
530
+ end
531
+ end
532
+
533
+ context "SHA-384" do
534
+ let(:instance) { klass::SHA384.new }
535
+ let(:binary) { instance.digest(data) }
536
+ let(:hex) { instance.hexdigest(data) }
537
+
538
+ context "one block message sample" do
539
+ let(:data) { "abc" }
540
+ let(:expected) { "CB00753F45A35E8BB5A03D699AC65007272C32AB0EDED1631A8B605A43FF5BED8086072BA1E7CC2358BAECA134C825A7" }
541
+ it { binary.should == [expected].pack("H*") }
542
+ it { hex.upcase.should == expected }
543
+ end
544
+
545
+ context "two block message sample" do
546
+ let(:data) { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" }
547
+ let(:expected) { "09330C33F71147E83D192FC782CD1B4753111B173B3B05D22FA08086E3B0F712FCC7C71A557E2DB966C3E9FA91746039" }
548
+ it { binary.should == [expected].pack("H*") }
549
+ it { hex.upcase.should == expected }
550
+ end
551
+
552
+ context "multi-block message sample" do
553
+ let(:data) { "a" * 10**6 }
554
+ let(:expected) { "9D0E1809716474CB086E834E310A4A1CED149E9C00F248527972CEC5704C2A5B07B8B3DC38ECC4EBAE97DDD87F3D8985" }
555
+ it { binary.should == [expected].pack("H*") }
556
+ it { hex.upcase.should == expected }
557
+ end
558
+
559
+ context "empty string" do
560
+ let(:data) { "" }
561
+ let(:expected) { "38B060A751AC96384CD9327EB1B1E36A21FDB71114BE07434C0CC7BF63F6E1DA274EDEBFE76F65FBD51AD2F14898B95B" }
562
+ it { binary.should == [expected].pack("H*") }
563
+ it { hex.upcase.should == expected }
564
+ end
565
+ end
566
+
567
+ context "SHA-224" do
568
+ let(:instance) { klass::SHA224.new }
569
+ let(:binary) { instance.digest(data) }
570
+ let(:hex) { instance.hexdigest(data) }
571
+
572
+ context "one block message sample" do
573
+ let(:data) { "abc" }
574
+ let(:expected) { "23097D223405D8228642A477BDA255B32AADBCE4BDA0B3F7E36C9DA7" }
575
+ it { binary.should == [expected].pack("H*") }
576
+ it { hex.upcase.should == expected }
577
+ end
578
+
579
+ context "two block message sample" do
580
+ let(:data) { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" }
581
+ let(:expected) { "75388B16512776CC5DBA5DA1FD890150B0C6455CB4F58B1952522525" }
582
+ it { binary.should == [expected].pack("H*") }
583
+ it { hex.upcase.should == expected }
584
+ end
585
+
586
+ context "multi-block message sample" do
587
+ let(:data) { "a" * 10**6 }
588
+ let(:expected) { "20794655980C91D8BBB4C1EA97618A4BF03F42581948B2EE4EE7AD67" }
589
+ it { binary.should == [expected].pack("H*") }
590
+ it { hex.upcase.should == expected }
591
+ end
592
+
593
+ context "empty string" do
594
+ let(:data) { "" }
595
+ let(:expected) { "D14A028C2A3A2BC9476102BB288234C415A2B01F828EA62AC5B3E42F" }
596
+ it { binary.should == [expected].pack("H*") }
597
+ it { hex.upcase.should == expected }
598
+ end
599
+ end
600
+ end
601
+
602
+ # taken from http://homes.esat.kuleuven.be/~bosselae/ripemd160.html
603
+ context "RIPEMD-160 implementation conforms to test vectors" do
604
+ let(:instance) { klass::RIPEMD160.new }
605
+ let(:binary) { instance.digest(data) }
606
+ let(:hex) { instance.hexdigest(data) }
607
+
608
+ context "empty string" do
609
+ let(:data) { "" }
610
+ let(:expected) { "9C1185A5C5E9FC54612808977EE8F548B2258D31" }
611
+ it { binary.should == [expected].pack("H*") }
612
+ it { hex.upcase.should == expected }
613
+ end
614
+
615
+ context "a" do
616
+ let(:data) { "a" }
617
+ let(:expected) { "0BDC9D2D256B3EE9DAAE347BE6F4DC835A467FFE" }
618
+ it { binary.should == [expected].pack("H*") }
619
+ it { hex.upcase.should == expected }
620
+ end
621
+
622
+ context "abc" do
623
+ let(:data) { "abc" }
624
+ let(:expected) { "8EB208F7E05D987A9B044A8E98C6B087F15A0BFC" }
625
+ it { binary.should == [expected].pack("H*") }
626
+ it { hex.upcase.should == expected }
627
+ end
628
+
629
+ context "message digest" do
630
+ let(:data) { "message digest" }
631
+ let(:expected) { "5D0689EF49D2FAE572B881B123A85FFA21595F36" }
632
+ it { binary.should == [expected].pack("H*") }
633
+ it { hex.upcase.should == expected }
634
+ end
635
+
636
+ context "a to z" do
637
+ let(:data) { "abcdefghijklmnopqrstuvwxyz" }
638
+ let(:expected) { "F71C27109C692C1B56BBDCEB5B9D2865B3708DBC" }
639
+ it { binary.should == [expected].pack("H*") }
640
+ it { hex.upcase.should == expected }
641
+ end
642
+
643
+ context "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" do
644
+ let(:data) { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" }
645
+ let(:expected) { "12A053384A9C0C88E405A06C27DCF49ADA62EB2B" }
646
+ it { binary.should == [expected].pack("H*") }
647
+ it { hex.upcase.should == expected }
648
+ end
649
+
650
+ context "A...Za...z0...9" do
651
+ let(:data) { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" }
652
+ let(:expected) { "B0E20B6E3116640286ED3A87A5713079B21F5189" }
653
+ it { binary.should == [expected].pack("H*") }
654
+ it { hex.upcase.should == expected }
655
+ end
656
+
657
+ context "8 times 1 to 0" do
658
+ let(:data) { "1234567890" * 8 }
659
+ let(:expected) { "9B752E45573D4B39F4DBD3323CAB82BF63326BFB" }
660
+ it { binary.should == [expected].pack("H*") }
661
+ it { hex.upcase.should == expected }
662
+ end
663
+
664
+ context "million times 'a'" do
665
+ let(:data) { "a" * 10**6 }
666
+ let(:expected) { "52783243C1697BDBE16D37F97F68F08325DC1528" }
667
+ it { binary.should == [expected].pack("H*") }
668
+ it { hex.upcase.should == expected }
669
+ end
670
+ end
671
+
672
+ # taken from http://www.nsrl.nist.gov/testdata/
673
+ context "MD5 implementation conforms to test vectors" do
674
+ let(:instance) { klass::MD5.new }
675
+ let(:binary) { instance.digest(data) }
676
+ let(:hex) { instance.hexdigest(data) }
677
+
678
+ context "one block message sample" do
679
+ let(:data) { "abc" }
680
+ let(:expected) { "900150983CD24FB0D6963F7D28E17F72" }
681
+ it { binary.should == [expected].pack("H*") }
682
+ it { hex.upcase.should == expected }
683
+ end
684
+
685
+ context "two block message sample" do
686
+ let(:data) { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" }
687
+ let(:expected) { "8215EF0796A20BCAAAE116D3876C664A" }
688
+ it { binary.should == [expected].pack("H*") }
689
+ it { hex.upcase.should == expected }
690
+ end
691
+
692
+ context "multi-block message sample" do
693
+ let(:data) { "a" * 10**6 }
694
+ let(:expected) { "7707D6AE4E027C70EEA2A935C2296F21" }
695
+ it { binary.should == [expected].pack("H*") }
696
+ it { hex.upcase.should == expected }
697
+ end
698
+
699
+ context "empty string" do
700
+ let(:data) { "" }
701
+ let(:expected) { "D41D8CD98F00B204E9800998ECF8427E" }
702
+ it { binary.should == [expected].pack("H*") }
703
+ it { hex.upcase.should == expected }
704
+ end
705
+ end
706
+ end
707
+