rbnacl 1.0.0.pre

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 (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