rbnacl 5.0.0 → 6.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.gitignore +1 -0
- data/.rubocop.yml +34 -12
- data/.travis.yml +16 -16
- data/CHANGES.md +37 -10
- data/Gemfile +4 -3
- data/Guardfile +2 -0
- data/LICENSE.txt +1 -1
- data/README.md +31 -21
- data/Rakefile +4 -3
- data/lib/rbnacl.rb +8 -3
- data/lib/rbnacl/aead/base.rb +3 -0
- data/lib/rbnacl/aead/chacha20poly1305_ietf.rb +2 -2
- data/lib/rbnacl/aead/chacha20poly1305_legacy.rb +2 -2
- data/lib/rbnacl/aead/xchacha20poly1305_ietf.rb +44 -0
- data/lib/rbnacl/boxes/curve25519xsalsa20poly1305.rb +6 -5
- data/lib/rbnacl/boxes/curve25519xsalsa20poly1305/private_key.rb +1 -1
- data/lib/rbnacl/group_elements/curve25519.rb +2 -1
- data/lib/rbnacl/hash/blake2b.rb +6 -4
- data/lib/rbnacl/hash/sha256.rb +1 -1
- data/lib/rbnacl/hash/sha512.rb +1 -1
- data/lib/rbnacl/hmac/sha256.rb +73 -8
- data/lib/rbnacl/hmac/sha512.rb +73 -8
- data/lib/rbnacl/hmac/sha512256.rb +71 -8
- data/lib/rbnacl/init.rb +1 -5
- data/lib/rbnacl/one_time_auths/poly1305.rb +2 -2
- data/lib/rbnacl/password_hash.rb +33 -2
- data/lib/rbnacl/password_hash/argon2.rb +37 -18
- data/lib/rbnacl/password_hash/scrypt.rb +1 -1
- data/lib/rbnacl/random.rb +1 -3
- data/lib/rbnacl/secret_boxes/xsalsa20poly1305.rb +2 -2
- data/lib/rbnacl/signatures/ed25519/signing_key.rb +2 -2
- data/lib/rbnacl/signatures/ed25519/verify_key.rb +1 -1
- data/lib/rbnacl/sodium.rb +16 -12
- data/lib/rbnacl/sodium/version.rb +3 -1
- data/lib/rbnacl/test_vectors.rb +104 -44
- data/lib/rbnacl/util.rb +92 -8
- data/lib/rbnacl/version.rb +1 -1
- data/rbnacl.gemspec +6 -7
- data/spec/rbnacl/aead/xchacha20poly1305_ietf_spec.rb +14 -0
- data/spec/rbnacl/authenticators/poly1305_spec.rb +21 -1
- data/spec/rbnacl/boxes/curve25519xsalsa20poly1305_spec.rb +18 -6
- data/spec/rbnacl/hmac/sha256_spec.rb +6 -1
- data/spec/rbnacl/hmac/sha512256_spec.rb +6 -1
- data/spec/rbnacl/hmac/sha512_spec.rb +6 -1
- data/spec/rbnacl/password_hash/argon2_spec.rb +56 -14
- data/spec/rbnacl/signatures/ed25519/signing_key_spec.rb +5 -4
- data/spec/rbnacl/util_spec.rb +63 -4
- data/spec/shared/aead.rb +33 -13
- data/spec/shared/authenticator.rb +0 -19
- data/spec/shared/box.rb +18 -6
- data/spec/shared/hmac.rb +46 -0
- data/spec/spec_helper.rb +3 -1
- metadata +22 -18
- data/.ruby-version +0 -1
data/lib/rbnacl/util.rb
CHANGED
@@ -6,8 +6,9 @@ module RbNaCl
|
|
6
6
|
module Util
|
7
7
|
extend Sodium
|
8
8
|
|
9
|
-
sodium_function :c_verify16, :crypto_verify_16, [
|
10
|
-
sodium_function :c_verify32, :crypto_verify_32, [
|
9
|
+
sodium_function :c_verify16, :crypto_verify_16, %i[pointer pointer]
|
10
|
+
sodium_function :c_verify32, :crypto_verify_32, %i[pointer pointer]
|
11
|
+
sodium_function :c_verify64, :crypto_verify_64, %i[pointer pointer]
|
11
12
|
|
12
13
|
module_function
|
13
14
|
|
@@ -81,6 +82,8 @@ module RbNaCl
|
|
81
82
|
# @param description [String] Description of the string (used in the error)
|
82
83
|
def check_length(string, length, description)
|
83
84
|
if string.nil?
|
85
|
+
# code below is runs only in test cases
|
86
|
+
# nil can't be converted to str with #to_str method
|
84
87
|
raise LengthError,
|
85
88
|
"#{description} was nil (Expected #{length.to_int})",
|
86
89
|
caller
|
@@ -106,19 +109,98 @@ module RbNaCl
|
|
106
109
|
# @param length [Integer] The only acceptable length of the string
|
107
110
|
# @param description [String] Description of the string (used in the error)
|
108
111
|
def check_string(string, length, description)
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
+
check_string_validation(string)
|
113
|
+
string = string.to_s
|
114
|
+
check_length(string, length, description)
|
115
|
+
|
116
|
+
string
|
117
|
+
end
|
118
|
+
|
119
|
+
# Check a passed in string, convertion if necessary
|
120
|
+
#
|
121
|
+
# This method will check the key, and raise error
|
122
|
+
# if argument is not a string, and if it's empty string.
|
123
|
+
#
|
124
|
+
# RFC 2104 HMAC
|
125
|
+
# The key for HMAC can be of any length (keys longer than B bytes are
|
126
|
+
# first hashed using H). However, less than L bytes is strongly
|
127
|
+
# discouraged as it would decrease the security strength of the
|
128
|
+
# function. Keys longer than L bytes are acceptable but the extra
|
129
|
+
# length would not significantly increase the function strength. (A
|
130
|
+
# longer key may be advisable if the randomness of the key is
|
131
|
+
# considered weak.)
|
132
|
+
#
|
133
|
+
# see https://tools.ietf.org/html/rfc2104#section-3
|
134
|
+
#
|
135
|
+
#
|
136
|
+
# @raise [ArgumentError] If we cannot convert to a string with #to_str
|
137
|
+
# @raise [RbNaCl::LengthError] If the string is empty
|
138
|
+
#
|
139
|
+
# @param string [#to_str] The input string
|
140
|
+
def check_hmac_key(string, _description)
|
141
|
+
check_string_validation(string)
|
112
142
|
|
113
143
|
string = string.to_str
|
114
|
-
|
115
|
-
|
144
|
+
|
145
|
+
if string.bytesize.zero?
|
146
|
+
raise LengthError,
|
147
|
+
"#{Description} was #{string.bytesize} bytes (Expected more than 0)",
|
148
|
+
caller
|
116
149
|
end
|
117
|
-
check_length(string, length, description)
|
118
150
|
|
119
151
|
string
|
120
152
|
end
|
121
153
|
|
154
|
+
# Check a passed string is it valid
|
155
|
+
#
|
156
|
+
# Raise an error if passed argument is invalid
|
157
|
+
#
|
158
|
+
# @raise [TypeError] If string cannot convert to a string with #to_str
|
159
|
+
# @raise [EncodingError] If string have wrong encoding
|
160
|
+
#
|
161
|
+
# @param string [#to_str] The input string
|
162
|
+
def check_string_validation(string)
|
163
|
+
raise TypeError, "can't convert #{string.class} into String with #to_str" unless string.respond_to? :to_str
|
164
|
+
|
165
|
+
string = string.to_str
|
166
|
+
|
167
|
+
raise EncodingError, "strings must use BINARY encoding (got #{string.encoding})" if string.encoding != Encoding::BINARY
|
168
|
+
end
|
169
|
+
|
170
|
+
# Compare two 64 byte strings in constant time
|
171
|
+
#
|
172
|
+
# This should help to avoid timing attacks for string comparisons in your
|
173
|
+
# application. Note that many of the functions (such as HmacSha512#verify)
|
174
|
+
# use this method under the hood already.
|
175
|
+
#
|
176
|
+
# @param [String] one String #1
|
177
|
+
# @param [String] two String #2
|
178
|
+
#
|
179
|
+
# @return [Boolean] Well, are they equal?
|
180
|
+
def verify64(one, two)
|
181
|
+
return false unless two.bytesize == 64 && one.bytesize == 64
|
182
|
+
|
183
|
+
c_verify64(one, two)
|
184
|
+
end
|
185
|
+
|
186
|
+
# Compare two 64 byte strings in constant time
|
187
|
+
#
|
188
|
+
# This should help to avoid timing attacks for string comparisons in your
|
189
|
+
# application. Note that many of the functions (such as HmacSha512#verify)
|
190
|
+
# use this method under the hood already.
|
191
|
+
#
|
192
|
+
# @param [String] one String #1
|
193
|
+
# @param [String] two String #2
|
194
|
+
#
|
195
|
+
# @raise [ArgumentError] If the strings are not equal in length
|
196
|
+
#
|
197
|
+
# @return [Boolean] Well, are they equal?
|
198
|
+
def verify64!(one, two)
|
199
|
+
check_length(one, 64, "First message")
|
200
|
+
check_length(two, 64, "Second message")
|
201
|
+
c_verify64(one, two)
|
202
|
+
end
|
203
|
+
|
122
204
|
# Compare two 32 byte strings in constant time
|
123
205
|
#
|
124
206
|
# This should help to avoid timing attacks for string comparisons in your
|
@@ -131,6 +213,7 @@ module RbNaCl
|
|
131
213
|
# @return [Boolean] Well, are they equal?
|
132
214
|
def verify32(one, two)
|
133
215
|
return false unless two.bytesize == 32 && one.bytesize == 32
|
216
|
+
|
134
217
|
c_verify32(one, two)
|
135
218
|
end
|
136
219
|
|
@@ -164,6 +247,7 @@ module RbNaCl
|
|
164
247
|
# @return [Boolean] Well, are they equal?
|
165
248
|
def verify16(one, two)
|
166
249
|
return false unless two.bytesize == 16 && one.bytesize == 16
|
250
|
+
|
167
251
|
c_verify16(one, two)
|
168
252
|
end
|
169
253
|
|
data/lib/rbnacl/version.rb
CHANGED
data/rbnacl.gemspec
CHANGED
@@ -1,5 +1,6 @@
|
|
1
|
-
#
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
lib = File.expand_path("lib", __dir__)
|
3
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
5
|
require "rbnacl/version"
|
5
6
|
|
@@ -8,21 +9,19 @@ Gem::Specification.new do |spec|
|
|
8
9
|
spec.version = RbNaCl::VERSION
|
9
10
|
spec.authors = ["Tony Arcieri", "Jonathan Stott"]
|
10
11
|
spec.email = ["bascule@gmail.com", "jonathan.stott@gmail.com"]
|
11
|
-
spec.homepage = "https://github.com/
|
12
|
+
spec.homepage = "https://github.com/crypto-rb/rbnacl"
|
12
13
|
spec.licenses = ["MIT"]
|
13
|
-
spec.summary = "Ruby binding to the
|
14
|
-
spec.description
|
14
|
+
spec.summary = "Ruby binding to the libsodium/NaCl cryptography library"
|
15
|
+
spec.description = <<-DESCRIPTION.strip.gsub(/\s+/, " ")
|
15
16
|
The Networking and Cryptography (NaCl) library provides a high-level toolkit for building
|
16
17
|
cryptographic systems and protocols
|
17
18
|
DESCRIPTION
|
18
|
-
|
19
19
|
spec.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
|
20
20
|
spec.executables = spec.files.grep(%r{^bin/}).map { |f| File.basename(f) }
|
21
21
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
22
22
|
spec.require_paths = ["lib"]
|
23
23
|
|
24
24
|
spec.required_ruby_version = ">= 2.2.6"
|
25
|
-
spec.platform = "jruby" if defined? JRUBY_VERSION
|
26
25
|
|
27
26
|
spec.add_runtime_dependency "ffi"
|
28
27
|
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# encoding: binary
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
RSpec.describe RbNaCl::AEAD::XChaCha20Poly1305IETF do
|
5
|
+
if RbNaCl::Sodium::Version.supported_version?("1.0.12")
|
6
|
+
include_examples "aead" do
|
7
|
+
let(:key) { vector :aead_xchacha20poly1305_ietf_key }
|
8
|
+
let(:message) { vector :aead_xchacha20poly1305_ietf_message }
|
9
|
+
let(:nonce) { vector :aead_xchacha20poly1305_ietf_nonce }
|
10
|
+
let(:ad) { vector :aead_xchacha20poly1305_ietf_ad }
|
11
|
+
let(:ciphertext) { vector :aead_xchacha20poly1305_ietf_ciphertext }
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -2,7 +2,27 @@
|
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
RSpec.describe RbNaCl::OneTimeAuth do
|
5
|
-
let(:
|
5
|
+
let(:key) { vector "auth_key_#{described_class.key_bytes}".to_sym }
|
6
|
+
let(:message) { vector :auth_message }
|
7
|
+
let(:tag) { vector :auth_onetime }
|
8
|
+
|
9
|
+
context ".new" do
|
10
|
+
it "raises ArgumentError on a key which is too long" do
|
11
|
+
expect { described_class.new("\0" * described_class.key_bytes.succ) }.to raise_error(ArgumentError)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context ".auth" do
|
16
|
+
it "raises ArgumentError on a key which is too long" do
|
17
|
+
expect { described_class.auth("\0" * described_class.key_bytes.succ, message) }.to raise_error(ArgumentError)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
context ".verify" do
|
22
|
+
it "raises ArgumentError on a key which is too long" do
|
23
|
+
expect { described_class.verify("\0" * described_class.key_bytes.succ, tag, message) }.to raise_error(ArgumentError)
|
24
|
+
end
|
25
|
+
end
|
6
26
|
|
7
27
|
include_examples "authenticator"
|
8
28
|
end
|
@@ -9,27 +9,39 @@ RSpec.describe RbNaCl::Box do
|
|
9
9
|
|
10
10
|
context "new" do
|
11
11
|
it "accepts strings" do
|
12
|
-
expect
|
12
|
+
expect do
|
13
|
+
RbNaCl::Box.new(alicepk, bobsk)
|
14
|
+
end.to_not raise_error
|
13
15
|
end
|
14
16
|
|
15
17
|
it "accepts KeyPairs" do
|
16
|
-
expect
|
18
|
+
expect do
|
19
|
+
RbNaCl::Box.new(alice_key, bob_key)
|
20
|
+
end.to_not raise_error
|
17
21
|
end
|
18
22
|
|
19
23
|
it "raises TypeError on a nil public key" do
|
20
|
-
expect
|
24
|
+
expect do
|
25
|
+
RbNaCl::Box.new(nil, bobsk)
|
26
|
+
end.to raise_error(TypeError)
|
21
27
|
end
|
22
28
|
|
23
29
|
it "raises RbNaCl::LengthError on an invalid public key" do
|
24
|
-
expect
|
30
|
+
expect do
|
31
|
+
RbNaCl::Box.new("hello", bobsk)
|
32
|
+
end.to raise_error(RbNaCl::LengthError, /Public key was 5 bytes \(Expected 32\)/)
|
25
33
|
end
|
26
34
|
|
27
35
|
it "raises TypeError on a nil secret key" do
|
28
|
-
expect
|
36
|
+
expect do
|
37
|
+
RbNaCl::Box.new(alicepk, nil)
|
38
|
+
end.to raise_error(TypeError)
|
29
39
|
end
|
30
40
|
|
31
41
|
it "raises RbNaCl::LengthError on an invalid secret key" do
|
32
|
-
expect
|
42
|
+
expect do
|
43
|
+
RbNaCl::Box.new(alicepk, "hello")
|
44
|
+
end.to raise_error(RbNaCl::LengthError, /Private key was 5 bytes \(Expected 32\)/)
|
33
45
|
end
|
34
46
|
end
|
35
47
|
|
@@ -2,7 +2,12 @@
|
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
RSpec.describe RbNaCl::HMAC::SHA256 do
|
5
|
-
let(:
|
5
|
+
let(:key) { vector :auth_hmac_key }
|
6
|
+
let(:message) { vector :auth_hmac_data }
|
7
|
+
let(:tag) { vector :auth_hmacsha256_tag }
|
8
|
+
let(:mult_tag) { vector :auth_hmacsha256_mult_tag }
|
9
|
+
let(:wrong_key) { "key".encode("utf-8") }
|
6
10
|
|
11
|
+
include_examples "HMAC"
|
7
12
|
include_examples "authenticator"
|
8
13
|
end
|
@@ -2,7 +2,12 @@
|
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
RSpec.describe RbNaCl::HMAC::SHA512256 do
|
5
|
-
let(:
|
5
|
+
let(:key) { vector :auth_hmac_key }
|
6
|
+
let(:message) { vector :auth_message }
|
7
|
+
let(:tag) { vector :auth_hmacsha512256_tag }
|
8
|
+
let(:mult_tag) { vector :auth_hmacsha512256_mult_tag }
|
9
|
+
let(:wrong_key) { "key".encode("utf-8") }
|
6
10
|
|
11
|
+
include_examples "HMAC"
|
7
12
|
include_examples "authenticator"
|
8
13
|
end
|
@@ -2,7 +2,12 @@
|
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
RSpec.describe RbNaCl::HMAC::SHA512 do
|
5
|
-
let(:
|
5
|
+
let(:key) { vector :auth_hmac_key }
|
6
|
+
let(:message) { vector :auth_hmac_data }
|
7
|
+
let(:tag) { vector :auth_hmacsha512_tag }
|
8
|
+
let(:mult_tag) { vector :auth_hmacsha512_mult_tag }
|
9
|
+
let(:wrong_key) { "key".encode("utf-8") }
|
6
10
|
|
11
|
+
include_examples "HMAC"
|
7
12
|
include_examples "authenticator"
|
8
13
|
end
|
@@ -3,26 +3,68 @@
|
|
3
3
|
|
4
4
|
if RbNaCl::Sodium::Version::ARGON2_SUPPORTED
|
5
5
|
RSpec.describe RbNaCl::PasswordHash::Argon2 do
|
6
|
-
let(:
|
7
|
-
let(:
|
8
|
-
let(:
|
9
|
-
let(:
|
10
|
-
let(:
|
11
|
-
let(:
|
6
|
+
let(:argon2i_password) { vector :argon2i_password }
|
7
|
+
let(:argon2i_salt) { vector :argon2i_salt }
|
8
|
+
let(:argon2i_opslimit) { RbNaCl::TEST_VECTORS[:argon2i_opslimit] }
|
9
|
+
let(:argon2i_memlimit) { RbNaCl::TEST_VECTORS[:argon2i_memlimit] }
|
10
|
+
let(:argon2i_digest) { vector :argon2i_digest }
|
11
|
+
let(:argon2i_outlen) { RbNaCl::TEST_VECTORS[:argon2i_outlen] }
|
12
|
+
|
13
|
+
let(:argon2id_password) { vector :argon2id_password }
|
14
|
+
let(:argon2id_salt) { vector :argon2id_salt }
|
15
|
+
let(:argon2id_opslimit) { RbNaCl::TEST_VECTORS[:argon2id_opslimit] }
|
16
|
+
let(:argon2id_memlimit) { RbNaCl::TEST_VECTORS[:argon2id_memlimit] }
|
17
|
+
let(:argon2id_digest) { vector :argon2id_digest }
|
18
|
+
let(:argon2id_outlen) { RbNaCl::TEST_VECTORS[:argon2id_outlen] }
|
12
19
|
|
13
20
|
let(:str_ref_password) { RbNaCl::TEST_VECTORS[:argon2_str_passwd] }
|
14
21
|
let(:str_ref_digest) { RbNaCl::TEST_VECTORS[:argon2_str_digest] }
|
15
22
|
|
16
|
-
it "calculates the correct digest for a reference password/salt" do
|
17
|
-
digest = RbNaCl::PasswordHash.
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
+
it "calculates the correct argon2i digest for a reference password/salt" do
|
24
|
+
digest = RbNaCl::PasswordHash.argon2i(
|
25
|
+
argon2i_password,
|
26
|
+
argon2i_salt,
|
27
|
+
argon2i_opslimit,
|
28
|
+
argon2i_memlimit,
|
29
|
+
argon2i_outlen
|
23
30
|
)
|
31
|
+
expect(digest).to eq argon2i_digest
|
32
|
+
end
|
33
|
+
|
34
|
+
if RbNaCl::Sodium::Version::ARGON2_SUPPORTED
|
35
|
+
it "calculates the correct argon2id digest for a reference password/salt" do
|
36
|
+
digest = RbNaCl::PasswordHash.argon2id(
|
37
|
+
argon2id_password,
|
38
|
+
argon2id_salt,
|
39
|
+
argon2id_opslimit,
|
40
|
+
argon2id_memlimit,
|
41
|
+
argon2id_outlen
|
42
|
+
)
|
43
|
+
expect(digest).to eq argon2id_digest
|
44
|
+
end
|
45
|
+
|
46
|
+
it "calculates the correct argon2 default digest" do
|
47
|
+
if RbNaCl::Sodium::Version.supported_version?("1.0.15")
|
48
|
+
digest = RbNaCl::PasswordHash.argon2(
|
49
|
+
argon2id_password,
|
50
|
+
argon2id_salt,
|
51
|
+
argon2id_opslimit,
|
52
|
+
argon2id_memlimit,
|
53
|
+
argon2id_outlen
|
54
|
+
)
|
55
|
+
expect(digest).to eq argon2id_digest
|
56
|
+
else
|
57
|
+
digest = RbNaCl::PasswordHash.argon2(
|
58
|
+
argon2i_password,
|
59
|
+
argon2i_salt,
|
60
|
+
argon2i_opslimit,
|
61
|
+
argon2i_memlimit,
|
62
|
+
argon2i_outlen
|
63
|
+
)
|
64
|
+
expect(digest).to eq argon2i_digest
|
65
|
+
end
|
66
|
+
end
|
24
67
|
|
25
|
-
expect(digest).to eq reference_digest
|
26
68
|
end
|
27
69
|
|
28
70
|
it "verifies password" do
|
@@ -2,9 +2,10 @@
|
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
RSpec.describe RbNaCl::SigningKey do
|
5
|
-
let(:signing_key)
|
6
|
-
let(:
|
7
|
-
let(:
|
5
|
+
let(:signing_key) { vector :sign_private }
|
6
|
+
let(:signing_keypair) { vector :sign_keypair }
|
7
|
+
let(:message) { vector :sign_message }
|
8
|
+
let(:signature) { vector :sign_signature }
|
8
9
|
|
9
10
|
subject { described_class.new(signing_key) }
|
10
11
|
|
@@ -22,7 +23,7 @@ RSpec.describe RbNaCl::SigningKey do
|
|
22
23
|
|
23
24
|
it "serializes the internal signing key to bytes" do
|
24
25
|
expect(subject.keypair_bytes.length).to eq 64
|
25
|
-
expect(subject.keypair_bytes).to eq
|
26
|
+
expect(subject.keypair_bytes).to eq signing_keypair
|
26
27
|
end
|
27
28
|
|
28
29
|
include_examples "key equality" do
|
data/spec/rbnacl/util_spec.rb
CHANGED
@@ -2,6 +2,57 @@
|
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
RSpec.describe RbNaCl::Util do
|
5
|
+
context ".verify64" do
|
6
|
+
let(:msg) { RbNaCl::Util.zeros(64) }
|
7
|
+
let(:identical_msg) { RbNaCl::Util.zeros(64) }
|
8
|
+
let(:other_msg) { RbNaCl::Util.zeros(63) + "\001" }
|
9
|
+
let(:short_msg) { RbNaCl::Util.zeros(63) }
|
10
|
+
let(:long_msg) { RbNaCl::Util.zeros(65) }
|
11
|
+
|
12
|
+
it "confirms identical messages are identical" do
|
13
|
+
expect(RbNaCl::Util.verify64(msg, identical_msg)).to be true
|
14
|
+
end
|
15
|
+
|
16
|
+
it "confirms non-identical messages are non-identical" do
|
17
|
+
expect(RbNaCl::Util.verify64(msg, other_msg)).to be false
|
18
|
+
expect(RbNaCl::Util.verify64(other_msg, msg)).to be false
|
19
|
+
expect(RbNaCl::Util.verify64(short_msg, msg)).to be false
|
20
|
+
expect(RbNaCl::Util.verify64(msg, short_msg)).to be false
|
21
|
+
expect(RbNaCl::Util.verify64(long_msg, msg)).to be false
|
22
|
+
expect(RbNaCl::Util.verify64(msg, long_msg)).to be false
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context ".verify64!" do
|
27
|
+
let(:msg) { RbNaCl::Util.zeros(64) }
|
28
|
+
let(:identical_msg) { RbNaCl::Util.zeros(64) }
|
29
|
+
let(:other_msg) { RbNaCl::Util.zeros(63) + "\001" }
|
30
|
+
let(:short_msg) { RbNaCl::Util.zeros(63) }
|
31
|
+
let(:long_msg) { RbNaCl::Util.zeros(65) }
|
32
|
+
|
33
|
+
it "confirms identical messages are identical" do
|
34
|
+
expect(RbNaCl::Util.verify64!(msg, identical_msg)).to be true
|
35
|
+
end
|
36
|
+
|
37
|
+
it "confirms non-identical messages are non-identical" do
|
38
|
+
expect(RbNaCl::Util.verify64!(msg, other_msg)).to be false
|
39
|
+
expect(RbNaCl::Util.verify64!(other_msg, msg)).to be false
|
40
|
+
end
|
41
|
+
|
42
|
+
it "raises descriptively on a short message in position 1" do
|
43
|
+
expect { RbNaCl::Util.verify64!(short_msg, msg) }.to raise_error(RbNaCl::LengthError)
|
44
|
+
end
|
45
|
+
it "raises descriptively on a short message in position 2" do
|
46
|
+
expect { RbNaCl::Util.verify64!(msg, short_msg) }.to raise_error(RbNaCl::LengthError)
|
47
|
+
end
|
48
|
+
it "raises descriptively on a long message in position 1" do
|
49
|
+
expect { RbNaCl::Util.verify64!(long_msg, msg) }.to raise_error(RbNaCl::LengthError)
|
50
|
+
end
|
51
|
+
it "raises descriptively on a long message in position 2" do
|
52
|
+
expect { RbNaCl::Util.verify64!(msg, long_msg) }.to raise_error(RbNaCl::LengthError)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
5
56
|
context ".verify32!" do
|
6
57
|
let(:msg) { RbNaCl::Util.zeros(32) }
|
7
58
|
let(:identical_msg) { RbNaCl::Util.zeros(32) }
|
@@ -106,16 +157,24 @@ RSpec.describe RbNaCl::Util do
|
|
106
157
|
|
107
158
|
context "check_length" do
|
108
159
|
it "accepts strings of the correct length" do
|
109
|
-
expect
|
160
|
+
expect do
|
161
|
+
RbNaCl::Util.check_length("A" * 4, 4, "Test String")
|
162
|
+
end.not_to raise_error
|
110
163
|
end
|
111
164
|
it "rejects strings which are too short" do
|
112
|
-
expect
|
165
|
+
expect do
|
166
|
+
RbNaCl::Util.check_length("A" * 3, 4, "Test String")
|
167
|
+
end.to raise_error(RbNaCl::LengthError, "Test String was 3 bytes (Expected 4)")
|
113
168
|
end
|
114
169
|
it "rejects strings which are too long" do
|
115
|
-
expect
|
170
|
+
expect do
|
171
|
+
RbNaCl::Util.check_length("A" * 5, 4, "Test String")
|
172
|
+
end.to raise_error(RbNaCl::LengthError, "Test String was 5 bytes (Expected 4)")
|
116
173
|
end
|
117
174
|
it "rejects nil strings" do
|
118
|
-
expect
|
175
|
+
expect do
|
176
|
+
RbNaCl::Util.check_length(nil, 4, "Test String")
|
177
|
+
end.to raise_error(RbNaCl::LengthError, "Test String was nil (Expected 4)")
|
119
178
|
end
|
120
179
|
end
|
121
180
|
|