krypt 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+