rbnacl 5.0.0 → 6.0.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.
- 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
|
|