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.
- data/.coveralls.yml +1 -0
- data/.gitignore +19 -0
- data/.rspec +4 -0
- data/.travis.yml +21 -0
- data/.yardopts +1 -0
- data/CHANGES.md +4 -0
- data/Gemfile +9 -0
- data/LICENSE.txt +23 -0
- data/README.md +179 -0
- data/Rakefile +5 -0
- data/images/dragons.png +0 -0
- data/images/ed25519.png +0 -0
- data/images/logo.png +0 -0
- data/lib/rbnacl.rb +46 -0
- data/lib/rbnacl/auth.rb +78 -0
- data/lib/rbnacl/auth/one_time.rb +38 -0
- data/lib/rbnacl/box.rb +141 -0
- data/lib/rbnacl/encoder.rb +44 -0
- data/lib/rbnacl/encoders/base32.rb +33 -0
- data/lib/rbnacl/encoders/base64.rb +30 -0
- data/lib/rbnacl/encoders/hex.rb +30 -0
- data/lib/rbnacl/encoders/raw.rb +12 -0
- data/lib/rbnacl/hash.rb +48 -0
- data/lib/rbnacl/hmac/sha256.rb +32 -0
- data/lib/rbnacl/hmac/sha512256.rb +35 -0
- data/lib/rbnacl/keys/key_comparator.rb +59 -0
- data/lib/rbnacl/keys/private_key.rb +62 -0
- data/lib/rbnacl/keys/public_key.rb +38 -0
- data/lib/rbnacl/keys/signing_key.rb +74 -0
- data/lib/rbnacl/keys/verify_key.rb +76 -0
- data/lib/rbnacl/nacl.rb +132 -0
- data/lib/rbnacl/point.rb +67 -0
- data/lib/rbnacl/rake_tasks.rb +56 -0
- data/lib/rbnacl/random.rb +19 -0
- data/lib/rbnacl/random_nonce_box.rb +109 -0
- data/lib/rbnacl/secret_box.rb +86 -0
- data/lib/rbnacl/self_test.rb +118 -0
- data/lib/rbnacl/serializable.rb +23 -0
- data/lib/rbnacl/test_vectors.rb +69 -0
- data/lib/rbnacl/util.rb +137 -0
- data/lib/rbnacl/version.rb +5 -0
- data/rbnacl.gemspec +28 -0
- data/rbnacl.gpg +30 -0
- data/spec/rbnacl/auth/one_time_spec.rb +8 -0
- data/spec/rbnacl/box_spec.rb +42 -0
- data/spec/rbnacl/encoder_spec.rb +14 -0
- data/spec/rbnacl/encoders/base32_spec.rb +16 -0
- data/spec/rbnacl/encoders/base64_spec.rb +15 -0
- data/spec/rbnacl/encoders/hex_spec.rb +15 -0
- data/spec/rbnacl/hash_spec.rb +52 -0
- data/spec/rbnacl/hmac/sha256_spec.rb +8 -0
- data/spec/rbnacl/hmac/sha512256_spec.rb +8 -0
- data/spec/rbnacl/keys/private_key_spec.rb +68 -0
- data/spec/rbnacl/keys/public_key_spec.rb +45 -0
- data/spec/rbnacl/keys/signing_key_spec.rb +40 -0
- data/spec/rbnacl/keys/verify_key_spec.rb +51 -0
- data/spec/rbnacl/point_spec.rb +29 -0
- data/spec/rbnacl/random_nonce_box_spec.rb +78 -0
- data/spec/rbnacl/random_spec.rb +9 -0
- data/spec/rbnacl/secret_box_spec.rb +24 -0
- data/spec/rbnacl/util_spec.rb +119 -0
- data/spec/shared/authenticator.rb +114 -0
- data/spec/shared/box.rb +51 -0
- data/spec/shared/key_equality.rb +26 -0
- data/spec/spec_helper.rb +14 -0
- data/tasks/ci.rake +11 -0
- data/tasks/rspec.rake +7 -0
- 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
|