sodium 0.0.0 → 0.5.0
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/.gitignore +4 -0
- data/.travis.yml +27 -0
- data/Gemfile +9 -0
- data/README.md +111 -0
- data/Rakefile +3 -0
- data/VERSION +1 -0
- data/config/nacl_ffi.yml +90 -0
- data/lib/sodium.rb +24 -0
- data/lib/sodium/auth.rb +52 -0
- data/lib/sodium/box.rb +127 -0
- data/lib/sodium/buffer.rb +141 -0
- data/lib/sodium/delegate.rb +58 -0
- data/lib/sodium/ffi.rb +9 -0
- data/lib/sodium/ffi/crypto.rb +106 -0
- data/lib/sodium/ffi/lib_c.rb +9 -0
- data/lib/sodium/ffi/random.rb +11 -0
- data/lib/sodium/hash.rb +23 -0
- data/lib/sodium/one_time_auth.rb +52 -0
- data/lib/sodium/random.rb +16 -0
- data/lib/sodium/secret_box.rb +65 -0
- data/lib/sodium/sign.rb +75 -0
- data/lib/sodium/version.rb +5 -0
- data/sodium.gemspec +9 -3
- data/sodium.pub.gpg +37 -0
- data/tasks/libsodium.rake +70 -0
- data/tasks/test.rake +6 -0
- data/tasks/version.rake +3 -0
- data/test/sodium/auth/hmacsha256_test.rb +54 -0
- data/test/sodium/auth/hmacsha512256_test.rb +53 -0
- data/test/sodium/auth_test.rb +49 -0
- data/test/sodium/box/curve25519xsalsa20poly1305_test.rb +79 -0
- data/test/sodium/box_test.rb +109 -0
- data/test/sodium/buffer_test.rb +120 -0
- data/test/sodium/delegate_test.rb +44 -0
- data/test/sodium/hash/sha256_test.rb +31 -0
- data/test/sodium/hash/sha512_test.rb +35 -0
- data/test/sodium/hash_test.rb +35 -0
- data/test/sodium/one_time_auth/poly1305_test.rb +54 -0
- data/test/sodium/one_time_auth_test.rb +49 -0
- data/test/sodium/random_test.rb +25 -0
- data/test/sodium/secret_box/xsalsa20poly1305_test.rb +50 -0
- data/test/sodium/secret_box_test.rb +56 -0
- data/test/sodium/sign/ed25519_test.rb +52 -0
- data/test/sodium/sign_test.rb +58 -0
- data/test/test_helper.rb +44 -0
- metadata +117 -8
- checksums.yaml +0 -7
@@ -0,0 +1,109 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
describe Sodium::Box do
|
4
|
+
include SodiumTestHelpers
|
5
|
+
|
6
|
+
subject { self.klass.new(*self.keypair) }
|
7
|
+
let(:klass) { Sodium::Box }
|
8
|
+
let(:keypair) { self.klass.keypair }
|
9
|
+
|
10
|
+
it 'must default to the Curve22519XSalsa20Poly1305 implementation' do
|
11
|
+
self.klass.implementation.
|
12
|
+
must_equal Sodium::Box::Curve25519XSalsa20Poly1305
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'must allow access to alternate implementations' do
|
16
|
+
self.klass.implementation(:xyz).
|
17
|
+
must_equal nil
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'must instantiate the default implementation' do
|
21
|
+
self.subject.
|
22
|
+
must_be_kind_of Sodium::Box::Curve25519XSalsa20Poly1305
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'must mint keypairs from the default implementation' do
|
26
|
+
sodium_mock_default(self.klass) do |klass, mock|
|
27
|
+
mock.expect :nacl_keypair, true, [ '', '' ]
|
28
|
+
mock.expect :[], 0, [:PUBLICKEYBYTES]
|
29
|
+
mock.expect :[], 0, [:SECRETKEYBYTES]
|
30
|
+
|
31
|
+
sk, pk = klass.keypair
|
32
|
+
|
33
|
+
sk.to_str.must_equal ''
|
34
|
+
pk.to_str.must_equal ''
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'must raise when instantiating with an invalid keypair' do
|
39
|
+
secret_key, public_key = self.keypair
|
40
|
+
|
41
|
+
lambda { self.klass.new(secret_key.to_str[0..-2], public_key) }.
|
42
|
+
must_raise Sodium::LengthError
|
43
|
+
|
44
|
+
lambda { self.klass.new(secret_key, public_key.to_str[0..-2]) }.
|
45
|
+
must_raise Sodium::LengthError
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'must raise when receiving an invalid nonce' do
|
49
|
+
lambda { self.subject.box('message', self.subject.nonce.to_str[0..-2]) }.
|
50
|
+
must_raise Sodium::LengthError
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'must raise when receiving an invalid shared key' do
|
54
|
+
lambda { self.klass.afternm('key', 'message', self.subject.nonce) }.
|
55
|
+
must_raise Sodium::LengthError
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'must raise when failing to generate keypairs' do
|
59
|
+
sodium_stub_failure(self.klass, :nacl_keypair) do
|
60
|
+
lambda { self.keypair }.
|
61
|
+
must_raise Sodium::CryptoError
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'must raise when failing to close a box' do
|
66
|
+
sodium_stub_failure(self.klass, :nacl) do
|
67
|
+
lambda { self.subject.box('message', self.subject.nonce) }.
|
68
|
+
must_raise Sodium::CryptoError
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'must raise when failing to open a box' do
|
73
|
+
sodium_stub_failure(self.klass, :nacl_open) do
|
74
|
+
lambda { self.subject.open('ciphertext', self.subject.nonce) }.
|
75
|
+
must_raise Sodium::CryptoError
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'must raise when failing to generate a shared key' do
|
80
|
+
sodium_stub_failure(self.klass, :nacl_beforenm) do
|
81
|
+
lambda { self.subject.beforenm }.
|
82
|
+
must_raise Sodium::CryptoError
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'must raise when failing to close a box with a shared key' do
|
87
|
+
sodium_stub_failure(self.klass, :nacl_afternm) do
|
88
|
+
lambda do
|
89
|
+
key = self.subject.beforenm
|
90
|
+
nonce = self.subject.nonce
|
91
|
+
message = 'message'
|
92
|
+
|
93
|
+
self.klass.afternm(key, message, nonce)
|
94
|
+
end.must_raise Sodium::CryptoError
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'must raise when failing to open a box with a shared key' do
|
99
|
+
sodium_stub_failure(self.klass, :nacl_open_afternm) do
|
100
|
+
lambda do
|
101
|
+
key = self.subject.beforenm
|
102
|
+
nonce = self.subject.nonce
|
103
|
+
ciphertext = 'ciphertext'
|
104
|
+
|
105
|
+
self.klass.open_afternm(key, ciphertext, nonce)
|
106
|
+
end.must_raise Sodium::CryptoError
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
describe Sodium::Buffer do
|
4
|
+
subject { Sodium::Buffer }
|
5
|
+
|
6
|
+
it '::key must securely generate random keys of specified length' do
|
7
|
+
Sodium::Random.stub(:bytes, lambda {|l| ' ' * l }) do
|
8
|
+
subject.key( 7).to_str.must_equal(' ' * 7)
|
9
|
+
subject.key( 8).to_str.must_equal(' ' * 8)
|
10
|
+
subject.key(16).to_str.must_equal(' ' * 16)
|
11
|
+
subject.key(32).to_str.must_equal(' ' * 32)
|
12
|
+
subject.key(64).to_str.must_equal(' ' * 64)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
it '::nonce must securely generate random nonces of specified length' do
|
17
|
+
Sodium::Random.stub(:bytes, lambda {|l| ' ' * l }) do
|
18
|
+
subject.nonce( 7).to_str.must_equal(' ' * 7)
|
19
|
+
subject.nonce( 8).to_str.must_equal(' ' * 8)
|
20
|
+
subject.nonce(16).to_str.must_equal(' ' * 16)
|
21
|
+
subject.nonce(32).to_str.must_equal(' ' * 32)
|
22
|
+
subject.nonce(64).to_str.must_equal(' ' * 64)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
it '::empty must generate an empty buffer of specified length' do
|
27
|
+
subject.empty(32).to_str.must_equal("\0" * 32)
|
28
|
+
subject.empty(40).to_str.must_equal("\0" * 40)
|
29
|
+
end
|
30
|
+
|
31
|
+
it '::empty must yield to a block when given' do
|
32
|
+
mock = MiniTest::Mock.new
|
33
|
+
mock.expect :flag, nil
|
34
|
+
|
35
|
+
subject.empty(5) {|buffer| mock.flag }
|
36
|
+
|
37
|
+
mock.verify
|
38
|
+
end
|
39
|
+
|
40
|
+
it '::new must create a buffer containing the specified string' do
|
41
|
+
subject.new('xyz' ).to_str.must_equal('xyz')
|
42
|
+
subject.new('xyz' * 50).to_str.must_equal('xyz' * 50)
|
43
|
+
end
|
44
|
+
|
45
|
+
it '::new must do optional length checking' do
|
46
|
+
lambda { subject.new('xyz', 4).to_str }.
|
47
|
+
must_raise Sodium::LengthError
|
48
|
+
end
|
49
|
+
|
50
|
+
it '#initialize must freeze its bytes' do
|
51
|
+
subject.new('s').to_str.must_be :frozen?
|
52
|
+
end
|
53
|
+
|
54
|
+
it '#initialize must wipe the memory from the original string' do
|
55
|
+
'test'.tap do |s|
|
56
|
+
subject.new(s)
|
57
|
+
end.must_equal("\0" * 4)
|
58
|
+
end
|
59
|
+
|
60
|
+
it '#initialize must wipe the buffer during finalization'
|
61
|
+
it '#initialize must prevent the string from being paged to disk'
|
62
|
+
|
63
|
+
it '#pad bytes onto the front' do
|
64
|
+
subject.new('s').pad(3).to_str.must_equal "\0\0\0s"
|
65
|
+
end
|
66
|
+
|
67
|
+
it '#unpad bytes from the front' do
|
68
|
+
subject.new("\0\0\0s").unpad(3).to_str.must_equal 's'
|
69
|
+
end
|
70
|
+
|
71
|
+
it '#byteslice must accept an indivdual byte offset to return' do
|
72
|
+
subject.new('xyz').tap do |buffer|
|
73
|
+
buffer.byteslice(-4).to_str.must_equal ''
|
74
|
+
buffer.byteslice(-3).to_str.must_equal 'x'
|
75
|
+
buffer.byteslice(-2).to_str.must_equal 'y'
|
76
|
+
buffer.byteslice(-1).to_str.must_equal 'z'
|
77
|
+
buffer.byteslice( 0).to_str.must_equal 'x'
|
78
|
+
buffer.byteslice( 1).to_str.must_equal 'y'
|
79
|
+
buffer.byteslice( 2).to_str.must_equal 'z'
|
80
|
+
buffer.byteslice( 3).to_str.must_equal ''
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
it '#byteslice must accept ranges of bytes to return' do
|
85
|
+
subject.new('xyz').tap do |buffer|
|
86
|
+
buffer.byteslice( 0.. 0).to_str.must_equal 'x'
|
87
|
+
buffer.byteslice( 0.. 1).to_str.must_equal 'xy'
|
88
|
+
buffer.byteslice( 0.. 2).to_str.must_equal 'xyz'
|
89
|
+
buffer.byteslice( 0.. 3).to_str.must_equal 'xyz'
|
90
|
+
buffer.byteslice( 1..-1).to_str.must_equal 'yz'
|
91
|
+
buffer.byteslice( 2..-2).to_str.must_equal ''
|
92
|
+
buffer.byteslice(-3..-1).to_str.must_equal 'xyz'
|
93
|
+
buffer.byteslice(-4.. 1).to_str.must_equal ''
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
it '#byteslice must accept an offset and number of bytes to return' do
|
98
|
+
subject.new('xyz').tap do |buffer|
|
99
|
+
buffer.byteslice( 0, 0).to_str.must_equal ''
|
100
|
+
buffer.byteslice( 0, 1).to_str.must_equal 'x'
|
101
|
+
buffer.byteslice( 0, 3).to_str.must_equal 'xyz'
|
102
|
+
buffer.byteslice( 2, 4).to_str.must_equal 'z'
|
103
|
+
buffer.byteslice( 2, 1).to_str.must_equal 'z'
|
104
|
+
buffer.byteslice(-2, 1).to_str.must_equal 'y'
|
105
|
+
buffer.byteslice( 0, -1).to_str.must_equal ''
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
it '#bytesize must return its length' do
|
110
|
+
subject.new('testing').bytesize.must_equal 7
|
111
|
+
end
|
112
|
+
|
113
|
+
it '#inspect must not reveal its instance variables' do
|
114
|
+
subject.new('blah').inspect.wont_include 'blah'
|
115
|
+
end
|
116
|
+
|
117
|
+
it '#to_str must return its internal bytes' do
|
118
|
+
subject.new('xyz').to_str.must_equal('xyz')
|
119
|
+
end
|
120
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class DelegateTest
|
4
|
+
include Sodium::Delegate
|
5
|
+
|
6
|
+
def self.[](key)
|
7
|
+
self.const_get(key)
|
8
|
+
end
|
9
|
+
|
10
|
+
class Subclass1 < self; PRIMITIVE = :subclass1; end
|
11
|
+
class Subclass2 < self; PRIMITIVE = :subclass2; end
|
12
|
+
|
13
|
+
DEFAULT = :subclass1
|
14
|
+
end
|
15
|
+
|
16
|
+
describe Sodium::Delegate do
|
17
|
+
subject { self.klass.new }
|
18
|
+
let(:klass) { DelegateTest }
|
19
|
+
let(:subclass) { DelegateTest::Subclass1 }
|
20
|
+
|
21
|
+
it '::implementation must be the default' do
|
22
|
+
self.klass.implementation.must_equal self.subclass
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'must allow access to constants through indexing' do
|
26
|
+
self.klass.implementation[:PRIMITIVE].must_equal :subclass1
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'must allow access to arbitrary implementations' do
|
30
|
+
self.klass.implementation(:subclass2).must_equal DelegateTest::Subclass2
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'must instantiate the default implementation' do
|
34
|
+
self.klass.new.class.must_equal self.subclass
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'must allow instance access to the instantiated primitive' do
|
38
|
+
self.subject.primitive.must_equal self.subclass::PRIMITIVE
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'must allow class access to the instantiated primitive' do
|
42
|
+
self.subject.class.primitive.must_equal self.subclass::PRIMITIVE
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
describe Sodium::Hash::SHA256 do
|
4
|
+
include SodiumTestHelpers
|
5
|
+
|
6
|
+
let (:klass) { Sodium::Hash::SHA256 }
|
7
|
+
let (:primitive) { :sha256 }
|
8
|
+
|
9
|
+
let :constants do
|
10
|
+
{ :BYTES => 32 }
|
11
|
+
end
|
12
|
+
|
13
|
+
let_64(:hash) { 'q1MKE+RZFJgrefm34/uplM/R8/si9xzqGvvwK0YMbR0=' }
|
14
|
+
let_64(:plaintext) { 'bWVzc2FnZQ==' }
|
15
|
+
|
16
|
+
it '::primitive must be correct' do
|
17
|
+
self.klass.primitive.must_equal self.primitive
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'must have correct values for its constants' do
|
21
|
+
self.constants.each_pair do |name, value|
|
22
|
+
self.klass[name].must_equal value
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'must generate hashes' do
|
27
|
+
self.klass.hash(
|
28
|
+
self.plaintext
|
29
|
+
).to_str.must_equal self.hash
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
describe Sodium::Hash::SHA512 do
|
4
|
+
include SodiumTestHelpers
|
5
|
+
|
6
|
+
let (:klass) { Sodium::Hash::SHA512 }
|
7
|
+
let (:primitive) { :sha512 }
|
8
|
+
|
9
|
+
let :constants do
|
10
|
+
{ :BYTES => 64 }
|
11
|
+
end
|
12
|
+
|
13
|
+
let_64(:hash) do
|
14
|
+
%{ +Nr1ejNHzE1rnVdbMf5gd+LLSH9gqWIzwIy0edvzFTjMkV7G1IvbqpbdwaFt
|
15
|
+
tPT5bzcnbPyzUQuCRiQXcNWVLA== }
|
16
|
+
end
|
17
|
+
|
18
|
+
let_64(:plaintext) { 'bWVzc2FnZQ==' }
|
19
|
+
|
20
|
+
it '::primitive must be correct' do
|
21
|
+
self.klass.primitive.must_equal self.primitive
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'must have correct values for its constants' do
|
25
|
+
self.constants.each_pair do |name, value|
|
26
|
+
self.klass[name].must_equal value
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'must generate hashes' do
|
31
|
+
self.klass.hash(
|
32
|
+
self.plaintext
|
33
|
+
).to_str.must_equal self.hash
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
describe Sodium::Hash do
|
4
|
+
include SodiumTestHelpers
|
5
|
+
|
6
|
+
let(:klass) { Sodium::Hash }
|
7
|
+
|
8
|
+
let_64(:plaintext) { 'bWVzc2FnZQ==' }
|
9
|
+
|
10
|
+
it 'must default to the SHA512 implementation' do
|
11
|
+
self.klass.implementation.
|
12
|
+
must_equal Sodium::Hash::SHA512
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'must allow access to alternate implementations' do
|
16
|
+
self.klass.implementation(:sha256).
|
17
|
+
must_equal Sodium::Hash::SHA256
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'must hash from the default implementation' do
|
21
|
+
sodium_mock_default(self.klass) do |klass, mock|
|
22
|
+
mock.expect :[], 0, [ :BYTES ]
|
23
|
+
mock.expect :nacl, '', [ String, self.plaintext, self.plaintext.bytesize ]
|
24
|
+
|
25
|
+
klass.hash(self.plaintext).to_str.must_equal ''
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'must raise when failing to generate a hash' do
|
30
|
+
sodium_stub_failure(self.klass, :nacl) do
|
31
|
+
lambda { self.klass.hash(self.plaintext) }.
|
32
|
+
must_raise Sodium::CryptoError
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
describe Sodium::OneTimeAuth::Poly1305 do
|
4
|
+
include SodiumTestHelpers
|
5
|
+
|
6
|
+
subject { self.klass.new(self.key) }
|
7
|
+
|
8
|
+
let(:klass) { Sodium::OneTimeAuth::Poly1305 }
|
9
|
+
let(:primitive) { :poly1305 }
|
10
|
+
|
11
|
+
let :constants do
|
12
|
+
{ :BYTES => 16,
|
13
|
+
:KEYBYTES => 32, }
|
14
|
+
end
|
15
|
+
|
16
|
+
let_64(:key) { 'tZUeTVtSHOfgOei4DUwCt10xqrIYhALpO08NIDMWFB0=' }
|
17
|
+
let_64(:authenticator) { 'n+6StqC6SLRuLT8YZoQoFw==' }
|
18
|
+
let_64(:plaintext) { 'bWVzc2FnZQ==' }
|
19
|
+
|
20
|
+
it '::primitive must be correct' do
|
21
|
+
self.klass.primitive.must_equal self.primitive
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'must have correct values for its constants' do
|
25
|
+
self.constants.each_pair do |name, value|
|
26
|
+
self.klass[name].must_equal value
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'must mint keys' do
|
31
|
+
self.klass.key.bytesize.
|
32
|
+
must_equal self.klass::KEYBYTES
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'must generate authenticators' do
|
36
|
+
self.subject.one_time_auth(
|
37
|
+
self.plaintext
|
38
|
+
).to_str.must_equal self.authenticator
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'must verify authenticators' do
|
42
|
+
self.subject.verify(
|
43
|
+
self.plaintext,
|
44
|
+
self.authenticator
|
45
|
+
).must_equal true
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'must not verify forged authenticators' do
|
49
|
+
self.subject.verify(
|
50
|
+
self.plaintext,
|
51
|
+
self.authenticator.succ
|
52
|
+
).must_equal false
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
describe Sodium::OneTimeAuth do
|
4
|
+
include SodiumTestHelpers
|
5
|
+
|
6
|
+
subject { self.klass.new(self.key) }
|
7
|
+
let(:klass) { Sodium::OneTimeAuth }
|
8
|
+
let(:key) { self.klass.key }
|
9
|
+
|
10
|
+
it 'must default to the Poly1305 implementation' do
|
11
|
+
self.klass.implementation.
|
12
|
+
must_equal Sodium::OneTimeAuth::Poly1305
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'must allow access to alternate implementations' do
|
16
|
+
self.klass.implementation(:foo).
|
17
|
+
must_equal nil
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'must instantiate the default implementation' do
|
21
|
+
self.subject.
|
22
|
+
must_be_kind_of Sodium::OneTimeAuth::Poly1305
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'must mint keys from the default implementation' do
|
26
|
+
sodium_mock_default(self.klass) do |klass, mock|
|
27
|
+
mock.expect :[], 0, [:KEYBYTES]
|
28
|
+
|
29
|
+
klass.key.to_str.must_equal ''
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'must raise when instantiating with an invalid key' do
|
34
|
+
lambda { self.klass.new(self.key.to_str[0..-2]) }.
|
35
|
+
must_raise Sodium::LengthError
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'must raise when verifying an invalid authenticator' do
|
39
|
+
lambda { self.subject.verify('message', 'blaah') }.
|
40
|
+
must_raise Sodium::LengthError
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'must raise when failing to generate an authenticator' do
|
44
|
+
sodium_stub_failure(self.klass, :nacl) do
|
45
|
+
lambda { self.subject.one_time_auth('message') }.
|
46
|
+
must_raise Sodium::CryptoError
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|