rbnacl 1.0.0.pre

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. data/.coveralls.yml +1 -0
  2. data/.gitignore +19 -0
  3. data/.rspec +4 -0
  4. data/.travis.yml +21 -0
  5. data/.yardopts +1 -0
  6. data/CHANGES.md +4 -0
  7. data/Gemfile +9 -0
  8. data/LICENSE.txt +23 -0
  9. data/README.md +179 -0
  10. data/Rakefile +5 -0
  11. data/images/dragons.png +0 -0
  12. data/images/ed25519.png +0 -0
  13. data/images/logo.png +0 -0
  14. data/lib/rbnacl.rb +46 -0
  15. data/lib/rbnacl/auth.rb +78 -0
  16. data/lib/rbnacl/auth/one_time.rb +38 -0
  17. data/lib/rbnacl/box.rb +141 -0
  18. data/lib/rbnacl/encoder.rb +44 -0
  19. data/lib/rbnacl/encoders/base32.rb +33 -0
  20. data/lib/rbnacl/encoders/base64.rb +30 -0
  21. data/lib/rbnacl/encoders/hex.rb +30 -0
  22. data/lib/rbnacl/encoders/raw.rb +12 -0
  23. data/lib/rbnacl/hash.rb +48 -0
  24. data/lib/rbnacl/hmac/sha256.rb +32 -0
  25. data/lib/rbnacl/hmac/sha512256.rb +35 -0
  26. data/lib/rbnacl/keys/key_comparator.rb +59 -0
  27. data/lib/rbnacl/keys/private_key.rb +62 -0
  28. data/lib/rbnacl/keys/public_key.rb +38 -0
  29. data/lib/rbnacl/keys/signing_key.rb +74 -0
  30. data/lib/rbnacl/keys/verify_key.rb +76 -0
  31. data/lib/rbnacl/nacl.rb +132 -0
  32. data/lib/rbnacl/point.rb +67 -0
  33. data/lib/rbnacl/rake_tasks.rb +56 -0
  34. data/lib/rbnacl/random.rb +19 -0
  35. data/lib/rbnacl/random_nonce_box.rb +109 -0
  36. data/lib/rbnacl/secret_box.rb +86 -0
  37. data/lib/rbnacl/self_test.rb +118 -0
  38. data/lib/rbnacl/serializable.rb +23 -0
  39. data/lib/rbnacl/test_vectors.rb +69 -0
  40. data/lib/rbnacl/util.rb +137 -0
  41. data/lib/rbnacl/version.rb +5 -0
  42. data/rbnacl.gemspec +28 -0
  43. data/rbnacl.gpg +30 -0
  44. data/spec/rbnacl/auth/one_time_spec.rb +8 -0
  45. data/spec/rbnacl/box_spec.rb +42 -0
  46. data/spec/rbnacl/encoder_spec.rb +14 -0
  47. data/spec/rbnacl/encoders/base32_spec.rb +16 -0
  48. data/spec/rbnacl/encoders/base64_spec.rb +15 -0
  49. data/spec/rbnacl/encoders/hex_spec.rb +15 -0
  50. data/spec/rbnacl/hash_spec.rb +52 -0
  51. data/spec/rbnacl/hmac/sha256_spec.rb +8 -0
  52. data/spec/rbnacl/hmac/sha512256_spec.rb +8 -0
  53. data/spec/rbnacl/keys/private_key_spec.rb +68 -0
  54. data/spec/rbnacl/keys/public_key_spec.rb +45 -0
  55. data/spec/rbnacl/keys/signing_key_spec.rb +40 -0
  56. data/spec/rbnacl/keys/verify_key_spec.rb +51 -0
  57. data/spec/rbnacl/point_spec.rb +29 -0
  58. data/spec/rbnacl/random_nonce_box_spec.rb +78 -0
  59. data/spec/rbnacl/random_spec.rb +9 -0
  60. data/spec/rbnacl/secret_box_spec.rb +24 -0
  61. data/spec/rbnacl/util_spec.rb +119 -0
  62. data/spec/shared/authenticator.rb +114 -0
  63. data/spec/shared/box.rb +51 -0
  64. data/spec/shared/key_equality.rb +26 -0
  65. data/spec/spec_helper.rb +14 -0
  66. data/tasks/ci.rake +11 -0
  67. data/tasks/rspec.rake +7 -0
  68. metadata +187 -0
@@ -0,0 +1,45 @@
1
+ # encoding: binary
2
+ require 'spec_helper'
3
+
4
+ describe Crypto::PublicKey do
5
+ let(:alicepk) { Crypto::TestVectors[:alice_public] }
6
+ let(:alicepk_raw) { Crypto::Encoder[:hex].decode(alicepk) }
7
+
8
+ subject { Crypto::PublicKey.new(alicepk, :hex) }
9
+
10
+ context "new" do
11
+ it "accepts a valid key" do
12
+ expect { Crypto::PublicKey.new(alicepk_raw) }.not_to raise_error
13
+ end
14
+ it "accepts a valid key in hex" do
15
+ expect { Crypto::PublicKey.new(alicepk, :hex) }.not_to raise_error
16
+ end
17
+ it "rejects a nil key" do
18
+ expect { Crypto::PublicKey.new(nil) }.to raise_error(ArgumentError)
19
+ end
20
+ it "rejects a short key" do
21
+ expect { Crypto::PublicKey.new("short") }.to raise_error(ArgumentError)
22
+ end
23
+ end
24
+
25
+ context "#to_bytes" do
26
+ it "returns the bytes of the key" do
27
+ subject.to_bytes.should eq alicepk_raw
28
+ end
29
+ end
30
+
31
+ context "#to_s" do
32
+ it "returns the bytes of the key" do
33
+ subject.to_s.should eq alicepk_raw
34
+ end
35
+ it "returns the bytes of the key hex encoded" do
36
+ subject.to_s(:hex).should eq alicepk
37
+ end
38
+ end
39
+
40
+ include_examples "key equality" do
41
+ let(:key) { subject }
42
+ let(:key_bytes) { subject.to_bytes }
43
+ let(:other_key) { described_class.new(alicepk_raw.succ) }
44
+ end
45
+ end
@@ -0,0 +1,40 @@
1
+ # encoding: binary
2
+ require 'spec_helper'
3
+
4
+ describe Crypto::SigningKey do
5
+ let(:signing_key) { Crypto::TestVectors[:sign_private] }
6
+ let(:signing_key_raw) { Crypto::Encoder[:hex].decode(signing_key) }
7
+
8
+ let(:message) { Crypto::Encoder[:hex].decode(Crypto::TestVectors[:sign_message]) }
9
+ let(:signature) { Crypto::TestVectors[:sign_signature] }
10
+ let(:signature_raw) { Crypto::Encoder[:hex].decode(signature) }
11
+
12
+ # NOTE: this implicitly covers testing initialization from bytes
13
+ subject { described_class.new(signing_key, :hex) }
14
+
15
+ it "generates keys" do
16
+ described_class.generate.should be_a described_class
17
+ end
18
+
19
+ it "signs messages as bytes" do
20
+ subject.sign(message).should eq signature_raw
21
+ end
22
+
23
+ it "signs messages as hex" do
24
+ subject.sign(message, :hex).should eq signature
25
+ end
26
+
27
+ it "serializes to hex" do
28
+ subject.to_s(:hex).should eq signing_key
29
+ end
30
+
31
+ it "serializes to bytes" do
32
+ subject.to_bytes.should eq signing_key_raw
33
+ end
34
+
35
+ include_examples "key equality" do
36
+ let(:key_bytes) { signing_key_raw }
37
+ let(:key) { described_class.new(key_bytes) }
38
+ let(:other_key) { described_class.new("B"*32) }
39
+ end
40
+ end
@@ -0,0 +1,51 @@
1
+ # encoding: binary
2
+ describe Crypto::VerifyKey do
3
+ let(:signing_key) { Crypto::TestVectors[:sign_private] }
4
+ let(:verify_key) { Crypto::TestVectors[:sign_public] }
5
+ let(:verify_key_raw) { Crypto::Encoder[:hex].decode(verify_key) }
6
+
7
+ let(:message) { Crypto::Encoder[:hex].decode(Crypto::TestVectors[:sign_message]) }
8
+ let(:signature) { Crypto::TestVectors[:sign_signature] }
9
+ let(:signature_raw) { Crypto::Encoder[:hex].decode(signature) }
10
+ let(:bad_signature) { sig = signature.dup; sig[0] = (sig[0].ord + 1).chr; sig }
11
+
12
+ subject { Crypto::SigningKey.new(signing_key, :hex).verify_key }
13
+
14
+ it "verifies correct signatures" do
15
+ subject.verify(message, signature_raw).should be_true
16
+ end
17
+
18
+ it "verifies correct hex signatures" do
19
+ subject.verify(message, signature, :hex).should be_true
20
+ end
21
+
22
+ it "detects bad signatures" do
23
+ subject.verify(message, bad_signature, :hex).should be_false
24
+ end
25
+
26
+ it "raises when asked to verify with a bang" do
27
+ expect { subject.verify!(message, bad_signature, :hex) }.to raise_exception Crypto::BadSignatureError
28
+ end
29
+
30
+ it "serializes to bytes" do
31
+ subject.to_bytes.should eq verify_key_raw
32
+ end
33
+
34
+ it "serializes to hex" do
35
+ subject.to_s(:hex).should eq verify_key
36
+ end
37
+
38
+ it "initializes from bytes" do
39
+ described_class.new(verify_key_raw).to_s(:hex).should eq verify_key
40
+ end
41
+
42
+ it "initializes from hex" do
43
+ described_class.new(verify_key, :hex).to_s(:hex).should eq verify_key
44
+ end
45
+
46
+ include_examples "key equality" do
47
+ let(:key_bytes) { verify_key_raw }
48
+ let(:key) { described_class.new(key_bytes) }
49
+ let(:other_key) { described_class.new("B"*32) }
50
+ end
51
+ end
@@ -0,0 +1,29 @@
1
+ # encoding: binary
2
+ require 'spec_helper'
3
+
4
+ describe Crypto::Point do
5
+ let(:alice_private) { Crypto::TestVectors[:alice_private] }
6
+ let(:alice_public) { Crypto::TestVectors[:alice_public] }
7
+
8
+ let(:bob_public) { Crypto::TestVectors[:bob_public] }
9
+
10
+ let(:alice_mult_bob) { Crypto::TestVectors[:alice_mult_bob] }
11
+
12
+ subject { described_class.new(bob_public, :hex) }
13
+
14
+ it "multiplies integers with the base point" do
15
+ described_class.base.mult(alice_private, :hex).to_s(:hex).should eq alice_public
16
+ end
17
+
18
+ it "multiplies integers with arbitrary points" do
19
+ described_class.new(bob_public, :hex).mult(alice_private, :hex).to_s(:hex).should eq alice_mult_bob
20
+ end
21
+
22
+ it "serializes to bytes" do
23
+ subject.to_bytes.should eq Crypto::Encoder[:hex].decode(bob_public)
24
+ end
25
+
26
+ it "serializes to hex" do
27
+ subject.to_s(:hex).should eq bob_public
28
+ end
29
+ end
@@ -0,0 +1,78 @@
1
+ # encoding: binary
2
+ require 'spec_helper'
3
+
4
+ describe Crypto::RandomNonceBox do
5
+ let (:secret_key) {
6
+ [0x1b,0x27,0x55,0x64,0x73,0xe9,0x85,0xd4,0x62,0xcd,0x51,0x19,0x7a,0x9a,0x46,0xc7,
7
+ 0x60,0x09,0x54,0x9e,0xac,0x64,0x74,0xf2,0x06,0xc4,0xee,0x08,0x44,0xf6,0x83,0x89].pack('c*')
8
+ } # from the nacl distribution
9
+ let(:secret_box) { Crypto::SecretBox.new(secret_key) }
10
+ let (:alicepk) { "\x85 \xF0\t\x890\xA7Tt\x8B}\xDC\xB4>\xF7Z\r\xBF:\r&8\x1A\xF4\xEB\xA4\xA9\x8E\xAA\x9BNj" } # from the nacl distribution
11
+ let (:bobsk) { "]\xAB\b~bJ\x8AKy\xE1\x7F\x8B\x83\x80\x0E\xE6o;\xB1)&\x18\xB6\xFD\x1C/\x8B'\xFF\x88\xE0\xEB" } # from the nacl distribution
12
+
13
+ context "instantiation" do
14
+ it "can be instantiated from an already existing box" do
15
+ expect { Crypto::RandomNonceBox.new(secret_box) }.not_to raise_error
16
+ end
17
+
18
+ it "can be instantiated from a secret key" do
19
+ Crypto::RandomNonceBox.from_secret_key(secret_key).should be_a Crypto::RandomNonceBox
20
+ end
21
+ it "complains on an inappropriate secret key" do
22
+ expect { Crypto::RandomNonceBox.from_secret_key(nil) }.to raise_error(ArgumentError)
23
+ end
24
+ it "can be instantiated from a key-pair" do
25
+ Crypto::RandomNonceBox.from_keypair(alicepk, bobsk).should be_a Crypto::RandomNonceBox
26
+ end
27
+ it "complains on an inappropriate key in the pair" do
28
+ expect { Crypto::RandomNonceBox.from_keypair(nil, bobsk) }.to raise_error(ArgumentError)
29
+ end
30
+ end
31
+
32
+
33
+
34
+ context "cryptography" do
35
+ let(:nonce) { "iin\xE9U\xB6+s\xCDb\xBD\xA8u\xFCs\xD6\x82\x19\xE0\x03kz\v7" } # from nacl distribution
36
+ let(:message) { # from nacl distribution
37
+ [0xbe,0x07,0x5f,0xc5,0x3c,0x81,0xf2,0xd5,0xcf,0x14,0x13,0x16,0xeb,0xeb,0x0c,0x7b,
38
+ 0x52,0x28,0xc5,0x2a,0x4c,0x62,0xcb,0xd4,0x4b,0x66,0x84,0x9b,0x64,0x24,0x4f,0xfc,
39
+ 0xe5,0xec,0xba,0xaf,0x33,0xbd,0x75,0x1a,0x1a,0xc7,0x28,0xd4,0x5e,0x6c,0x61,0x29,
40
+ 0x6c,0xdc,0x3c,0x01,0x23,0x35,0x61,0xf4,0x1d,0xb6,0x6c,0xce,0x31,0x4a,0xdb,0x31,
41
+ 0x0e,0x3b,0xe8,0x25,0x0c,0x46,0xf0,0x6d,0xce,0xea,0x3a,0x7f,0xa1,0x34,0x80,0x57,
42
+ 0xe2,0xf6,0x55,0x6a,0xd6,0xb1,0x31,0x8a,0x02,0x4a,0x83,0x8f,0x21,0xaf,0x1f,0xde,
43
+ 0x04,0x89,0x77,0xeb,0x48,0xf5,0x9f,0xfd,0x49,0x24,0xca,0x1c,0x60,0x90,0x2e,0x52,
44
+ 0xf0,0xa0,0x89,0xbc,0x76,0x89,0x70,0x40,0xe0,0x82,0xf9,0x37,0x76,0x38,0x48,0x64,
45
+ 0x5e,0x07,0x05].pack('c*')
46
+ }
47
+ let(:ciphertext) { # from nacl distribution
48
+ [0xf3,0xff,0xc7,0x70,0x3f,0x94,0x00,0xe5,0x2a,0x7d,0xfb,0x4b,0x3d,0x33,0x05,0xd9,
49
+ 0x8e,0x99,0x3b,0x9f,0x48,0x68,0x12,0x73,0xc2,0x96,0x50,0xba,0x32,0xfc,0x76,0xce,
50
+ 0x48,0x33,0x2e,0xa7,0x16,0x4d,0x96,0xa4,0x47,0x6f,0xb8,0xc5,0x31,0xa1,0x18,0x6a,
51
+ 0xc0,0xdf,0xc1,0x7c,0x98,0xdc,0xe8,0x7b,0x4d,0xa7,0xf0,0x11,0xec,0x48,0xc9,0x72,
52
+ 0x71,0xd2,0xc2,0x0f,0x9b,0x92,0x8f,0xe2,0x27,0x0d,0x6f,0xb8,0x63,0xd5,0x17,0x38,
53
+ 0xb4,0x8e,0xee,0xe3,0x14,0xa7,0xcc,0x8a,0xb9,0x32,0x16,0x45,0x48,0xe5,0x26,0xae,
54
+ 0x90,0x22,0x43,0x68,0x51,0x7a,0xcf,0xea,0xbd,0x6b,0xb3,0x73,0x2b,0xc0,0xe9,0xda,
55
+ 0x99,0x83,0x2b,0x61,0xca,0x01,0xb6,0xde,0x56,0x24,0x4a,0x9e,0x88,0xd5,0xf9,0xb3,
56
+ 0x79,0x73,0xf6,0x22,0xa4,0x3d,0x14,0xa6,0x59,0x9b,0x1f,0x65,0x4c,0xb4,0x5a,0x74,
57
+ 0xe3,0x55,0xa5].pack('c*')
58
+ }
59
+ let(:random_box) { Crypto::RandomNonceBox.from_keypair(alicepk, bobsk) }
60
+ let(:enciphered_message) { random_box.box(message) }
61
+ let(:enciphered_message_hex) { random_box.box(message, :hex) }
62
+
63
+ it "descrypts a message with a 'random' nonce" do
64
+ random_box.open(nonce+ciphertext).should eql message
65
+ end
66
+
67
+ it "can successfully round-trip a message" do
68
+ random_box.open(enciphered_message).should eql message
69
+ end
70
+
71
+ it "can encode a ciphertext as hex" do
72
+ enciphered_message_hex.should match /\A[0-9a-f]+\z/
73
+ end
74
+ it "can roundtrip a message as hex" do
75
+ random_box.open(enciphered_message_hex, :hex).should eql message
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,9 @@
1
+ # encoding: binary
2
+ describe Crypto::Random do
3
+ it "produces random bytes" do
4
+ Crypto::Random.random_bytes(16).bytesize.should == 16
5
+ end
6
+ it "produces different random bytes" do
7
+ Crypto::Random.random_bytes(16).should_not == Crypto::Random.random_bytes(16)
8
+ end
9
+ end
@@ -0,0 +1,24 @@
1
+ # encoding: binary
2
+ require 'spec_helper'
3
+
4
+ describe Crypto::SecretBox do
5
+ let (:key) { Crypto::TestVectors[:secret_key] }
6
+
7
+ context "new" do
8
+ it "accepts strings" do
9
+ expect { Crypto::SecretBox.new(key, :hex) }.to_not raise_error(Exception)
10
+ end
11
+
12
+ it "raises on a nil key" do
13
+ expect { Crypto::SecretBox.new(nil) }.to raise_error(Crypto::LengthError, "Secret key was nil \(Expected #{Crypto::NaCl::SECRETKEYBYTES}\)")
14
+ end
15
+
16
+ it "raises on a short key" do
17
+ expect { Crypto::SecretBox.new("hello") }.to raise_error(Crypto::LengthError, "Secret key was 5 bytes \(Expected #{Crypto::NaCl::SECRETKEYBYTES}\)")
18
+ end
19
+ end
20
+
21
+ include_examples "box" do
22
+ let(:box) { Crypto::SecretBox.new(key, :hex) }
23
+ end
24
+ end
@@ -0,0 +1,119 @@
1
+ # encoding: binary
2
+ describe Crypto::Util do
3
+ context ".verify32!" do
4
+ let (:msg) { Crypto::Util.zeros(32) }
5
+ let (:identical_msg) { Crypto::Util.zeros(32) }
6
+ let (:other_msg) { Crypto::Util.zeros(31) + "\001" }
7
+ let (:short_msg) { Crypto::Util.zeros(31) }
8
+ let (:long_msg) { Crypto::Util.zeros(33) }
9
+
10
+ it "confirms identical messages are identical" do
11
+ Crypto::Util.verify32!(msg, identical_msg).should be true
12
+ end
13
+
14
+ it "confirms non-identical messages are non-identical" do
15
+ Crypto::Util.verify32!(msg, other_msg).should be false
16
+ Crypto::Util.verify32!(other_msg, msg).should be false
17
+ end
18
+
19
+ it "raises descriptively on a short message in position 1" do
20
+ expect { Crypto::Util.verify32!(short_msg, msg) }.to raise_error(Crypto::LengthError)
21
+ end
22
+ it "raises descriptively on a short message in position 2" do
23
+ expect { Crypto::Util.verify32!(msg, short_msg) }.to raise_error(Crypto::LengthError)
24
+ end
25
+ it "raises descriptively on a long message in position 1" do
26
+ expect { Crypto::Util.verify32!(long_msg, msg) }.to raise_error(Crypto::LengthError)
27
+ end
28
+ it "raises descriptively on a long message in position 2" do
29
+ expect { Crypto::Util.verify32!(msg, long_msg) }.to raise_error(Crypto::LengthError)
30
+ end
31
+ end
32
+
33
+ context ".verify32" do
34
+ let (:msg) { Crypto::Util.zeros(32) }
35
+ let (:identical_msg) { Crypto::Util.zeros(32) }
36
+ let (:other_msg) { Crypto::Util.zeros(31) + "\001" }
37
+ let (:short_msg) { Crypto::Util.zeros(31) }
38
+ let (:long_msg) { Crypto::Util.zeros(33) }
39
+
40
+ it "confirms identical messages are identical" do
41
+ Crypto::Util.verify32(msg, identical_msg).should be true
42
+ end
43
+
44
+ it "confirms non-identical messages are non-identical" do
45
+ Crypto::Util.verify32(msg, other_msg).should be false
46
+ Crypto::Util.verify32(other_msg, msg).should be false
47
+ Crypto::Util.verify32(short_msg, msg).should be false
48
+ Crypto::Util.verify32(msg, short_msg).should be false
49
+ Crypto::Util.verify32(long_msg, msg).should be false
50
+ Crypto::Util.verify32(msg, long_msg).should be false
51
+ end
52
+
53
+ end
54
+
55
+ context ".verify16!" do
56
+ let (:msg) { Crypto::Util.zeros(16) }
57
+ let (:identical_msg) { Crypto::Util.zeros(16) }
58
+ let (:other_msg) { Crypto::Util.zeros(15) + "\001" }
59
+ let (:short_msg) { Crypto::Util.zeros(15) }
60
+ let (:long_msg) { Crypto::Util.zeros(17) }
61
+
62
+ it "confirms identical messages are identical" do
63
+ Crypto::Util.verify16!(msg, identical_msg).should be true
64
+ end
65
+
66
+ it "confirms non-identical messages are non-identical" do
67
+ Crypto::Util.verify16!(msg, other_msg).should be false
68
+ Crypto::Util.verify16!(other_msg, msg).should be false
69
+ end
70
+
71
+ it "raises descriptively on a short message in position 1" do
72
+ expect { Crypto::Util.verify16!(short_msg, msg) }.to raise_error(Crypto::LengthError)
73
+ end
74
+ it "raises descriptively on a short message in position 2" do
75
+ expect { Crypto::Util.verify16!(msg, short_msg) }.to raise_error(Crypto::LengthError)
76
+ end
77
+ it "raises descriptively on a long message in position 1" do
78
+ expect { Crypto::Util.verify16!(long_msg, msg) }.to raise_error(Crypto::LengthError)
79
+ end
80
+ it "raises descriptively on a long message in position 2" do
81
+ expect { Crypto::Util.verify16!(msg, long_msg) }.to raise_error(Crypto::LengthError)
82
+ end
83
+ end
84
+
85
+ context ".verify16" do
86
+ let (:msg) { Crypto::Util.zeros(16) }
87
+ let (:identical_msg) { Crypto::Util.zeros(16) }
88
+ let (:other_msg) { Crypto::Util.zeros(15) + "\001" }
89
+ let (:short_msg) { Crypto::Util.zeros(15) }
90
+ let (:long_msg) { Crypto::Util.zeros(17) }
91
+
92
+ it "confirms identical messages are identical" do
93
+ Crypto::Util.verify16(msg, identical_msg).should be true
94
+ end
95
+
96
+ it "confirms non-identical messages are non-identical" do
97
+ Crypto::Util.verify16(msg, other_msg).should be false
98
+ Crypto::Util.verify16(other_msg, msg).should be false
99
+ Crypto::Util.verify16(short_msg, msg).should be false
100
+ Crypto::Util.verify16(msg, short_msg).should be false
101
+ Crypto::Util.verify16(long_msg, msg).should be false
102
+ Crypto::Util.verify16(msg, long_msg).should be false
103
+ end
104
+ end
105
+ context "check_length" do
106
+ it "accepts strings of the correct length" do
107
+ expect { Crypto::Util.check_length("A"*4, 4, "Test String") }.not_to raise_error
108
+ end
109
+ it "rejects strings which are too short" do
110
+ expect { Crypto::Util.check_length("A"*3, 4, "Test String") }.to raise_error(Crypto::LengthError, "Test String was 3 bytes (Expected 4)")
111
+ end
112
+ it "rejects strings which are too long" do
113
+ expect { Crypto::Util.check_length("A"*5, 4, "Test String") }.to raise_error(Crypto::LengthError, "Test String was 5 bytes (Expected 4)")
114
+ end
115
+ it "rejects nil strings" do
116
+ expect { Crypto::Util.check_length(nil, 4, "Test String") }.to raise_error(Crypto::LengthError, "Test String was nil (Expected 4)")
117
+ end
118
+ end
119
+ end
@@ -0,0 +1,114 @@
1
+ # encoding: binary
2
+ shared_examples "authenticator" do
3
+ let (:hex_key) { Crypto::TestVectors[:auth_key] }
4
+ let (:key) { Crypto::Encoder[:hex].decode(hex_key) }
5
+ let (:message) { Crypto::Encoder[:hex].decode(Crypto::TestVectors[:auth_message]) }
6
+ let(:tag) { Crypto::Encoder[:hex].decode(hex_tag) }
7
+
8
+ context ".new" do
9
+ it "accepts a key" do
10
+ expect { described_class.new(key) }.to_not raise_error(ArgumentError)
11
+ end
12
+
13
+ it "requires a key" do
14
+ expect { described_class.new }.to raise_error(ArgumentError)
15
+ end
16
+
17
+ it "raises on a nil key" do
18
+ expect { described_class.new(nil) }.to raise_error(ArgumentError)
19
+ end
20
+
21
+ it "raises on a key which is too long" do
22
+ expect { described_class.new("\0"*33) }.to raise_error(ArgumentError)
23
+ end
24
+
25
+ it "raises on a key which is too short" do
26
+ expect { described_class.new("\0"*31) }.to raise_error(ArgumentError)
27
+ end
28
+ end
29
+
30
+ context ".auth" do
31
+ it "produces an authenticator" do
32
+ described_class.auth(key, message).should eq tag
33
+ end
34
+
35
+ it "raises on a nil key" do
36
+ expect { described_class.auth(nil, message) }.to raise_error(ArgumentError)
37
+ end
38
+
39
+ it "raises on a key which is too long" do
40
+ expect { described_class.auth("\0"*33, message) }.to raise_error(ArgumentError)
41
+ end
42
+ end
43
+
44
+ context ".verify" do
45
+ it "verify an authenticator" do
46
+ described_class.verify(key, message, tag).should eq true
47
+ end
48
+
49
+ it "raises on a nil key" do
50
+ expect { described_class.verify(nil, message, tag) }.to raise_error(ArgumentError)
51
+ end
52
+
53
+ it "raises on a key which is too long" do
54
+ expect { described_class.verify("\0"*33, message, tag) }.to raise_error(ArgumentError)
55
+ end
56
+
57
+ it "fails to validate an invalid authenticator" do
58
+ described_class.verify(key, message+"\0", tag ).should be false
59
+ end
60
+ it "fails to validate a short authenticator" do
61
+ described_class.verify(key, message, tag[0,tag.bytesize - 2]).should be false
62
+ end
63
+ it "fails to validate a long authenticator" do
64
+ described_class.verify(key, message, tag+"\0").should be false
65
+ end
66
+ end
67
+
68
+
69
+ context "Instance methods" do
70
+ let(:authenticator) { described_class.new(key) }
71
+
72
+ context "#auth" do
73
+ it "produces an authenticator" do
74
+ authenticator.auth(message).should eq tag
75
+ end
76
+
77
+ it "produces a hex encoded authenticator" do
78
+ authenticator.auth(message, :hex).should eq hex_tag
79
+ end
80
+ end
81
+
82
+ context "#verify" do
83
+ context "raw bytes" do
84
+ it "verifies an authenticator" do
85
+ authenticator.verify(message, tag).should be true
86
+ end
87
+ it "fails to validate an invalid authenticator" do
88
+ authenticator.verify(tag, message+"\0").should be false
89
+ end
90
+ it "fails to validate a short authenticator" do
91
+ authenticator.verify(tag[0,tag.bytesize - 2], message).should be false
92
+ end
93
+ it "fails to validate a long authenticator" do
94
+ authenticator.verify(tag+"\0", message).should be false
95
+ end
96
+ end
97
+
98
+ context "hex" do
99
+ it "verifies an hexencoded authenticator" do
100
+ authenticator.verify(message, hex_tag, :hex).should be true
101
+ end
102
+ it "fails to validate an invalid authenticator" do
103
+ authenticator.verify(message+"\0", hex_tag , :hex).should be false
104
+ end
105
+ it "fails to validate a short authenticator" do
106
+ authenticator.verify( message, hex_tag[0,hex_tag.bytesize - 2], :hex).should be false
107
+ end
108
+ it "fails to validate a long authenticator" do
109
+ authenticator.verify(message, hex_tag+"00", :hex).should be false
110
+ end
111
+ end
112
+ end
113
+ end
114
+ end