rbnacl 1.1.0 → 2.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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data/.travis.yml +1 -5
- data/CHANGES.md +27 -0
- data/Gemfile +4 -1
- data/Guardfile +8 -0
- data/README.md +52 -3
- data/lib/rbnacl/auth.rb +22 -19
- data/lib/rbnacl/{keys → boxes/curve25519xsalsa20poly1305}/private_key.rb +26 -23
- data/lib/rbnacl/{keys → boxes/curve25519xsalsa20poly1305}/public_key.rb +13 -12
- data/lib/rbnacl/boxes/curve25519xsalsa20poly1305.rb +185 -0
- data/lib/rbnacl/group_elements/curve25519.rb +81 -0
- data/lib/rbnacl/hash/blake2b.rb +64 -0
- data/lib/rbnacl/hash/sha256.rb +15 -0
- data/lib/rbnacl/hash/sha512.rb +15 -0
- data/lib/rbnacl/hash.rb +30 -14
- data/lib/rbnacl/hmac/sha256.rb +19 -17
- data/lib/rbnacl/hmac/sha512256.rb +18 -19
- data/lib/rbnacl/init.rb +10 -0
- data/lib/rbnacl/{keys/key_comparator.rb → key_comparator.rb} +1 -1
- data/lib/rbnacl/{auth/one_time.rb → one_time_auths/poly1305.rb} +21 -19
- data/lib/rbnacl/rake_tasks.rb +7 -6
- data/lib/rbnacl/random.rb +12 -3
- data/lib/rbnacl/random_nonce_box.rb +9 -14
- data/lib/rbnacl/secret_boxes/xsalsa20poly1305.rb +125 -0
- data/lib/rbnacl/self_test.rb +67 -43
- data/lib/rbnacl/serializable.rb +4 -12
- data/lib/rbnacl/signatures/ed25519/signing_key.rb +104 -0
- data/lib/rbnacl/signatures/ed25519/verify_key.rb +78 -0
- data/lib/rbnacl/signatures/ed25519.rb +15 -0
- data/lib/rbnacl/sodium/version.rb +23 -0
- data/lib/rbnacl/sodium.rb +43 -0
- data/lib/rbnacl/test_vectors.rb +34 -1
- data/lib/rbnacl/util.rb +50 -7
- data/lib/rbnacl/version.rb +2 -2
- data/lib/rbnacl.rb +64 -29
- data/rbnacl.gemspec +6 -5
- data/spec/rbnacl/{auth/one_time_spec.rb → authenticators/poly1305_spec.rb} +2 -2
- data/spec/rbnacl/boxes/curve25519xsalsa20poly1305/private_key_spec.rb +65 -0
- data/spec/rbnacl/{keys → boxes/curve25519xsalsa20poly1305}/public_key_spec.rb +10 -13
- data/spec/rbnacl/boxes/curve25519xsalsa20poly1305_spec.rb +39 -0
- data/spec/rbnacl/{point_spec.rb → group_element_spec.rb} +6 -8
- data/spec/rbnacl/hash/blake2b_spec.rb +30 -0
- data/spec/rbnacl/hash_spec.rb +13 -33
- data/spec/rbnacl/hmac/sha256_spec.rb +2 -2
- data/spec/rbnacl/hmac/sha512256_spec.rb +2 -2
- data/spec/rbnacl/random_nonce_box_spec.rb +21 -26
- data/spec/rbnacl/random_spec.rb +3 -3
- data/spec/rbnacl/secret_box_spec.rb +6 -6
- data/spec/rbnacl/signatures/ed25519/signing_key_spec.rb +30 -0
- data/spec/rbnacl/signatures/ed25519/verify_key_spec.rb +39 -0
- data/spec/rbnacl/util_spec.rb +67 -53
- data/spec/shared/authenticator.rb +36 -55
- data/spec/shared/box.rb +10 -10
- data/spec/shared/key_equality.rb +3 -3
- data/spec/shared/serializable.rb +17 -0
- data/spec/spec_helper.rb +15 -16
- data/tasks/rspec.rake +1 -0
- data.tar.gz.sig +2 -3
- metadata +41 -42
- metadata.gz.sig +2 -2
- data/lib/rbnacl/box.rb +0 -171
- data/lib/rbnacl/encoder.rb +0 -44
- data/lib/rbnacl/encoders/base32.rb +0 -33
- data/lib/rbnacl/encoders/base64.rb +0 -30
- data/lib/rbnacl/encoders/hex.rb +0 -30
- data/lib/rbnacl/encoders/raw.rb +0 -12
- data/lib/rbnacl/keys/signing_key.rb +0 -95
- data/lib/rbnacl/keys/verify_key.rb +0 -96
- data/lib/rbnacl/nacl.rb +0 -146
- data/lib/rbnacl/point.rb +0 -70
- data/lib/rbnacl/secret_box.rb +0 -119
- data/spec/rbnacl/box_spec.rb +0 -42
- data/spec/rbnacl/encoder_spec.rb +0 -14
- data/spec/rbnacl/encoders/base32_spec.rb +0 -16
- data/spec/rbnacl/encoders/base64_spec.rb +0 -15
- data/spec/rbnacl/encoders/hex_spec.rb +0 -15
- data/spec/rbnacl/keys/private_key_spec.rb +0 -68
- data/spec/rbnacl/keys/signing_key_spec.rb +0 -39
- data/spec/rbnacl/keys/verify_key_spec.rb +0 -51
data/lib/rbnacl.rb
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# encoding: binary
|
|
2
|
-
|
|
2
|
+
require "rbnacl/version"
|
|
3
|
+
require "rbnacl/sodium"
|
|
4
|
+
require "rbnacl/sodium/version"
|
|
5
|
+
require "rbnacl/serializable"
|
|
6
|
+
require "rbnacl/key_comparator"
|
|
7
|
+
require "rbnacl/auth"
|
|
8
|
+
require "rbnacl/util"
|
|
9
|
+
require "rbnacl/random"
|
|
10
|
+
require "rbnacl/random_nonce_box"
|
|
11
|
+
require "rbnacl/test_vectors"
|
|
12
|
+
require "rbnacl/init"
|
|
13
|
+
|
|
14
|
+
module RbNaCl
|
|
3
15
|
# Oh no, something went wrong!
|
|
4
16
|
#
|
|
5
17
|
# This indicates a failure in the operation of a cryptographic primitive such
|
|
@@ -18,35 +30,58 @@ module Crypto
|
|
|
18
30
|
# This indicates that an attempt has been made to use something (probably a key)
|
|
19
31
|
# with an incorrect primitive
|
|
20
32
|
class IncorrectPrimitiveError < ArgumentError; end
|
|
21
|
-
end
|
|
22
33
|
|
|
23
|
-
#
|
|
24
|
-
|
|
34
|
+
# The signature was forged or otherwise corrupt
|
|
35
|
+
class BadSignatureError < CryptoError; end
|
|
25
36
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
require "rbnacl/
|
|
32
|
-
require "rbnacl/
|
|
33
|
-
require "rbnacl/
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
require "rbnacl/
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
require "rbnacl/
|
|
40
|
-
require "rbnacl/
|
|
41
|
-
require "rbnacl/
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
require "rbnacl/
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
require "rbnacl/
|
|
48
|
-
|
|
49
|
-
|
|
37
|
+
# The authenticator was forged or otherwise corrupt
|
|
38
|
+
class BadAuthenticatorError < CryptoError; end
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
# Public Key Encryption (Box): Curve25519XSalsa20Poly1305
|
|
42
|
+
require "rbnacl/boxes/curve25519xsalsa20poly1305"
|
|
43
|
+
require "rbnacl/boxes/curve25519xsalsa20poly1305/private_key"
|
|
44
|
+
require "rbnacl/boxes/curve25519xsalsa20poly1305/public_key"
|
|
45
|
+
|
|
46
|
+
# Secret Key Encryption (SecretBox): XSalsa20Poly1305
|
|
47
|
+
require "rbnacl/secret_boxes/xsalsa20poly1305"
|
|
48
|
+
|
|
49
|
+
# Digital Signatures: Ed25519
|
|
50
|
+
require "rbnacl/signatures/ed25519"
|
|
51
|
+
require "rbnacl/signatures/ed25519/signing_key"
|
|
52
|
+
require "rbnacl/signatures/ed25519/verify_key"
|
|
53
|
+
|
|
54
|
+
# Group Elements: Curve25519
|
|
55
|
+
require "rbnacl/group_elements/curve25519"
|
|
56
|
+
|
|
57
|
+
# One-time Authentication: Poly1305
|
|
58
|
+
require "rbnacl/one_time_auths/poly1305"
|
|
59
|
+
|
|
60
|
+
# Hash functions: SHA256/512 and Blake2b
|
|
61
|
+
require "rbnacl/hash"
|
|
62
|
+
require "rbnacl/hash/sha256"
|
|
63
|
+
require "rbnacl/hash/sha512"
|
|
64
|
+
require "rbnacl/hash/blake2b"
|
|
65
|
+
|
|
66
|
+
# HMAC: SHA256 and SHA512256
|
|
67
|
+
require "rbnacl/hmac/sha256"
|
|
68
|
+
require "rbnacl/hmac/sha512256"
|
|
69
|
+
|
|
70
|
+
#
|
|
71
|
+
# Bind aliases used by the public API
|
|
72
|
+
#
|
|
73
|
+
Box = Boxes::Curve25519XSalsa20Poly1305
|
|
74
|
+
PrivateKey = Boxes::Curve25519XSalsa20Poly1305::PrivateKey
|
|
75
|
+
PublicKey = Boxes::Curve25519XSalsa20Poly1305::PublicKey
|
|
76
|
+
SecretBox = SecretBoxes::XSalsa20Poly1305
|
|
77
|
+
SigningKey = Signatures::Ed25519::SigningKey
|
|
78
|
+
VerifyKey = Signatures::Ed25519::VerifyKey
|
|
79
|
+
GroupElement = GroupElements::Curve25519
|
|
80
|
+
OneTimeAuth = OneTimeAuths::Poly1305
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# Select platform-optimized versions of algorithms
|
|
84
|
+
Thread.exclusive { RbNaCl::Init.sodium_init }
|
|
50
85
|
|
|
51
86
|
# Perform self test on load
|
|
52
|
-
require "rbnacl/self_test"
|
|
87
|
+
require "rbnacl/self_test" unless $RBNACL_SELF_TEST == false
|
data/rbnacl.gemspec
CHANGED
|
@@ -5,12 +5,13 @@ require 'rbnacl/version'
|
|
|
5
5
|
|
|
6
6
|
Gem::Specification.new do |gem|
|
|
7
7
|
gem.name = "rbnacl"
|
|
8
|
-
gem.version =
|
|
8
|
+
gem.version = RbNaCl::VERSION
|
|
9
9
|
gem.authors = ["Tony Arcieri", "Jonathan Stott"]
|
|
10
10
|
gem.email = ["tony.arcieri@gmail.com", "jonathan.stott@gmail.com"]
|
|
11
11
|
gem.description = "Ruby binding to the Networking and Cryptography (NaCl) library"
|
|
12
12
|
gem.summary = "The Networking and Cryptography (NaCl) library provides a high-level toolkit for building cryptographic systems and protocols"
|
|
13
13
|
gem.homepage = "https://github.com/cryptosphere/rbnacl"
|
|
14
|
+
gem.licenses = ["MIT"]
|
|
14
15
|
|
|
15
16
|
gem.files = `git ls-files`.split($/)
|
|
16
17
|
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
|
@@ -21,11 +22,11 @@ Gem::Specification.new do |gem|
|
|
|
21
22
|
gem.platform = "jruby"
|
|
22
23
|
end
|
|
23
24
|
|
|
24
|
-
gem.add_runtime_dependency
|
|
25
|
+
gem.add_runtime_dependency "ffi"
|
|
25
26
|
|
|
26
27
|
gem.add_development_dependency "rake"
|
|
27
|
-
gem.add_development_dependency "rspec"
|
|
28
|
+
gem.add_development_dependency "rspec", ">= 2.14"
|
|
28
29
|
|
|
29
|
-
gem.signing_key = "
|
|
30
|
-
gem.cert_chain = ["
|
|
30
|
+
gem.signing_key = "../.sekretz/gem-private_key.pem"
|
|
31
|
+
gem.cert_chain = ["bascule.cert"]
|
|
31
32
|
end
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# encoding: binary
|
|
2
|
+
require 'spec_helper'
|
|
3
|
+
|
|
4
|
+
describe RbNaCl::PrivateKey do
|
|
5
|
+
let(:bobsk) { vector :bob_private }
|
|
6
|
+
let(:bobpk) { vector :bob_public }
|
|
7
|
+
|
|
8
|
+
subject { RbNaCl::PrivateKey.new(bobsk) }
|
|
9
|
+
|
|
10
|
+
context "generate" do
|
|
11
|
+
let(:secret_key) { RbNaCl::PrivateKey.generate }
|
|
12
|
+
|
|
13
|
+
it "returns a secret key" do
|
|
14
|
+
secret_key.should be_a RbNaCl::PrivateKey
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it "has the public key also set" do
|
|
18
|
+
secret_key.public_key.should be_a RbNaCl::PublicKey
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
context "new" do
|
|
23
|
+
it "accepts a valid key" do
|
|
24
|
+
expect { RbNaCl::PrivateKey.new(bobsk) }.not_to raise_error
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it "raises TypeError when given a nil key" do
|
|
28
|
+
expect { RbNaCl::PrivateKey.new(nil) }.to raise_error(TypeError)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it "raises ArgumentError when given a short key" do
|
|
32
|
+
expect { RbNaCl::PrivateKey.new("short") }.to raise_error(ArgumentError)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
context "public_key" do
|
|
37
|
+
it "returns a public key" do
|
|
38
|
+
subject.public_key.should be_a RbNaCl::PublicKey
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it "returns the correct public key" do
|
|
42
|
+
subject.public_key.to_s.should eql bobpk
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
context "#to_bytes" do
|
|
47
|
+
it "returns the bytes of the key" do
|
|
48
|
+
subject.to_s.should eq bobsk
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
context "#to_s" do
|
|
53
|
+
it "returns the raw bytes of the key" do
|
|
54
|
+
subject.to_bytes.should eq bobsk
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
include_examples "key equality" do
|
|
59
|
+
let(:key) { subject }
|
|
60
|
+
let(:key_bytes) { subject.to_bytes }
|
|
61
|
+
let(:other_key) { described_class.new(bobpk) }
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
include_examples "serializable"
|
|
65
|
+
end
|
|
@@ -1,24 +1,22 @@
|
|
|
1
1
|
# encoding: binary
|
|
2
2
|
require 'spec_helper'
|
|
3
3
|
|
|
4
|
-
describe
|
|
5
|
-
let(:alicepk) {
|
|
6
|
-
let(:alicepk_hex) { bytes2hex alicepk }
|
|
4
|
+
describe RbNaCl::PublicKey do
|
|
5
|
+
let(:alicepk) { vector :alice_public }
|
|
7
6
|
|
|
8
|
-
subject {
|
|
7
|
+
subject { RbNaCl::PublicKey.new(alicepk) }
|
|
9
8
|
|
|
10
9
|
context "new" do
|
|
11
10
|
it "accepts a valid key" do
|
|
12
|
-
expect {
|
|
13
|
-
end
|
|
14
|
-
it "accepts a valid key in hex" do
|
|
15
|
-
expect { Crypto::PublicKey.new(alicepk_hex, :hex) }.not_to raise_error
|
|
11
|
+
expect { RbNaCl::PublicKey.new(alicepk) }.not_to raise_error
|
|
16
12
|
end
|
|
13
|
+
|
|
17
14
|
it "rejects a nil key" do
|
|
18
|
-
expect {
|
|
15
|
+
expect { RbNaCl::PublicKey.new(nil) }.to raise_error(TypeError)
|
|
19
16
|
end
|
|
17
|
+
|
|
20
18
|
it "rejects a short key" do
|
|
21
|
-
expect {
|
|
19
|
+
expect { RbNaCl::PublicKey.new("short") }.to raise_error(ArgumentError)
|
|
22
20
|
end
|
|
23
21
|
end
|
|
24
22
|
|
|
@@ -32,9 +30,6 @@ describe Crypto::PublicKey do
|
|
|
32
30
|
it "returns the bytes of the key" do
|
|
33
31
|
subject.to_s.should eq alicepk
|
|
34
32
|
end
|
|
35
|
-
it "returns the bytes of the key hex encoded" do
|
|
36
|
-
subject.to_s(:hex).should eq alicepk_hex
|
|
37
|
-
end
|
|
38
33
|
end
|
|
39
34
|
|
|
40
35
|
include_examples "key equality" do
|
|
@@ -42,4 +37,6 @@ describe Crypto::PublicKey do
|
|
|
42
37
|
let(:key_bytes) { subject.to_bytes }
|
|
43
38
|
let(:other_key) { described_class.new(alicepk.succ) }
|
|
44
39
|
end
|
|
40
|
+
|
|
41
|
+
include_examples "serializable"
|
|
45
42
|
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# encoding: binary
|
|
2
|
+
require 'spec_helper'
|
|
3
|
+
|
|
4
|
+
describe RbNaCl::Box do
|
|
5
|
+
let(:alicepk) { vector :alice_public }
|
|
6
|
+
let(:bobsk) { vector :bob_private }
|
|
7
|
+
let(:alice_key) { RbNaCl::PublicKey.new(alicepk) }
|
|
8
|
+
let(:bob_key) { RbNaCl::PrivateKey.new(bobsk) }
|
|
9
|
+
|
|
10
|
+
context "new" do
|
|
11
|
+
it "accepts strings" do
|
|
12
|
+
expect { RbNaCl::Box.new(alicepk, bobsk) }.to_not raise_error(Exception)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it "accepts KeyPairs" do
|
|
16
|
+
expect { RbNaCl::Box.new(alice_key, bob_key) }.to_not raise_error(Exception)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it "raises TypeError on a nil public key" do
|
|
20
|
+
expect { RbNaCl::Box.new(nil, bobsk) }.to raise_error(TypeError)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it "raises RbNaCl::LengthError on an invalid public key" do
|
|
24
|
+
expect { RbNaCl::Box.new("hello", bobsk) }.to raise_error(RbNaCl::LengthError, /Public key was 5 bytes \(Expected 32\)/)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it "raises TypeError on a nil secret key" do
|
|
28
|
+
expect { RbNaCl::Box.new(alicepk, nil) }.to raise_error(TypeError)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it "raises RbNaCl::LengthError on an invalid secret key" do
|
|
32
|
+
expect { RbNaCl::Box.new(alicepk, "hello") }.to raise_error(RbNaCl::LengthError, /Private key was 5 bytes \(Expected 32\)/)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
include_examples 'box' do
|
|
37
|
+
let(:box) { RbNaCl::Box.new(alicepk, bobsk) }
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
# encoding: binary
|
|
2
2
|
require 'spec_helper'
|
|
3
3
|
|
|
4
|
-
describe
|
|
5
|
-
let(:alice_private) {
|
|
6
|
-
let(:alice_public) {
|
|
4
|
+
describe RbNaCl::GroupElement do
|
|
5
|
+
let(:alice_private) { vector :alice_private }
|
|
6
|
+
let(:alice_public) { vector :alice_public }
|
|
7
7
|
|
|
8
|
-
let(:bob_public) {
|
|
8
|
+
let(:bob_public) { vector :bob_public }
|
|
9
9
|
|
|
10
|
-
let(:alice_mult_bob) {
|
|
10
|
+
let(:alice_mult_bob) { vector :alice_mult_bob }
|
|
11
11
|
|
|
12
12
|
subject { described_class.new(bob_public) }
|
|
13
13
|
|
|
@@ -23,7 +23,5 @@ describe Crypto::Point do
|
|
|
23
23
|
subject.to_bytes.should eq bob_public
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
subject.to_s(:hex).should eq bytes2hex bob_public
|
|
28
|
-
end
|
|
26
|
+
include_examples "serializable"
|
|
29
27
|
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# encoding: binary
|
|
2
|
+
require 'spec_helper'
|
|
3
|
+
|
|
4
|
+
describe RbNaCl::Hash::Blake2b do
|
|
5
|
+
let(:reference_string) { vector :blake2b_message }
|
|
6
|
+
let(:reference_string_hash) { vector :blake2b_digest }
|
|
7
|
+
let(:empty_string_hash) { vector :blake2b_empty }
|
|
8
|
+
|
|
9
|
+
it "calculates the correct hash for a reference string" do
|
|
10
|
+
expect(RbNaCl::Hash.blake2b(reference_string)).to eq reference_string_hash
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it "calculates the correct hash for an empty string" do
|
|
14
|
+
expect(RbNaCl::Hash.blake2b("")).to eq empty_string_hash
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
context "keyed" do
|
|
18
|
+
let(:reference_string) { vector :blake2b_keyed_message }
|
|
19
|
+
let(:reference_key) { vector :blake2b_key }
|
|
20
|
+
let(:reference_string_hash) { vector :blake2b_keyed_digest }
|
|
21
|
+
|
|
22
|
+
it "calculates keyed hashes correctly" do
|
|
23
|
+
expect(RbNaCl::Hash.blake2b(reference_string, key: reference_key)).to eq reference_string_hash
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it "doesn't accept empty strings as a key" do
|
|
27
|
+
expect { RbNaCl::Hash.blake2b(reference_string, key: "") }.to raise_exception
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
data/spec/rbnacl/hash_spec.rb
CHANGED
|
@@ -1,60 +1,40 @@
|
|
|
1
1
|
# encoding: binary
|
|
2
2
|
require 'spec_helper'
|
|
3
3
|
|
|
4
|
-
describe
|
|
4
|
+
describe RbNaCl::Hash do
|
|
5
5
|
context "sha256" do
|
|
6
|
-
let(:reference_string) {
|
|
7
|
-
let(:reference_string_hash) {
|
|
8
|
-
let(:empty_string_hash)
|
|
9
|
-
let(:reference_string_hash_hex) { reference_string_hash.unpack('H*').first }
|
|
10
|
-
let(:empty_string_hash_hex) { empty_string_hash.unpack('H*').first }
|
|
6
|
+
let(:reference_string) { vector :sha256_message }
|
|
7
|
+
let(:reference_string_hash) { vector :sha256_digest }
|
|
8
|
+
let(:empty_string_hash) { vector :sha256_empty }
|
|
11
9
|
|
|
12
10
|
it "calculates the correct hash for a reference string" do
|
|
13
|
-
|
|
11
|
+
RbNaCl::Hash.sha256(reference_string).should eq reference_string_hash
|
|
14
12
|
end
|
|
15
13
|
|
|
16
14
|
it "calculates the correct hash for an empty string" do
|
|
17
|
-
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
it "calculates the correct hash for a reference string and returns it in hex" do
|
|
21
|
-
Crypto::Hash.sha256(reference_string, :hex).should eq reference_string_hash_hex
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
it "calculates the correct hash for an empty string and returns it in hex" do
|
|
25
|
-
Crypto::Hash.sha256("", :hex).should eq empty_string_hash_hex
|
|
15
|
+
RbNaCl::Hash.sha256("").should eq empty_string_hash
|
|
26
16
|
end
|
|
27
17
|
|
|
28
18
|
it "doesn't raise on a null byte" do
|
|
29
|
-
expect {
|
|
19
|
+
expect { RbNaCl::Hash.sha256("\0") }.to_not raise_error(/ArgumentError: string contains null byte/)
|
|
30
20
|
end
|
|
31
21
|
end
|
|
32
22
|
|
|
33
23
|
context "sha512" do
|
|
34
|
-
let(:reference_string)
|
|
35
|
-
let(:reference_string_hash) {
|
|
36
|
-
let(:empty_string_hash)
|
|
37
|
-
let(:reference_string_hash_hex) { reference_string_hash.unpack('H*').first }
|
|
38
|
-
let(:empty_string_hash_hex) { empty_string_hash.unpack('H*').first }
|
|
24
|
+
let(:reference_string) { vector :sha512_message }
|
|
25
|
+
let(:reference_string_hash) { vector :sha512_digest }
|
|
26
|
+
let(:empty_string_hash) { vector :sha512_empty }
|
|
39
27
|
|
|
40
28
|
it "calculates the correct hash for a reference string" do
|
|
41
|
-
|
|
29
|
+
RbNaCl::Hash.sha512(reference_string).should eq reference_string_hash
|
|
42
30
|
end
|
|
43
31
|
|
|
44
32
|
it "calculates the correct hash for an empty string" do
|
|
45
|
-
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
it "calculates the correct hash for a reference string and returns it in hex" do
|
|
49
|
-
Crypto::Hash.sha512(reference_string, :hex).should eq reference_string_hash_hex
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
it "calculates the correct hash for an empty string and returns it in hex" do
|
|
53
|
-
Crypto::Hash.sha512("", :hex).should eq empty_string_hash_hex
|
|
33
|
+
RbNaCl::Hash.sha512("").should eq empty_string_hash
|
|
54
34
|
end
|
|
55
35
|
|
|
56
36
|
it "doesn't raise on a null byte" do
|
|
57
|
-
expect {
|
|
37
|
+
expect { RbNaCl::Hash.sha512("\0") }.to_not raise_error(/ArgumentError: string contains null byte/)
|
|
58
38
|
end
|
|
59
39
|
end
|
|
60
40
|
end
|
|
@@ -1,40 +1,42 @@
|
|
|
1
1
|
# encoding: binary
|
|
2
2
|
require 'spec_helper'
|
|
3
3
|
|
|
4
|
-
describe
|
|
5
|
-
let
|
|
6
|
-
let(:secret_box) {
|
|
7
|
-
let
|
|
8
|
-
let
|
|
4
|
+
describe RbNaCl::RandomNonceBox do
|
|
5
|
+
let(:secret_key) { vector :secret_key }
|
|
6
|
+
let(:secret_box) { RbNaCl::SecretBox.new(secret_key) }
|
|
7
|
+
let(:alicepk) { vector :alice_public }
|
|
8
|
+
let(:bobsk) { vector :bob_private }
|
|
9
9
|
|
|
10
10
|
context "instantiation" do
|
|
11
11
|
it "can be instantiated from an already existing box" do
|
|
12
|
-
expect {
|
|
12
|
+
expect { RbNaCl::RandomNonceBox.new(secret_box) }.not_to raise_error
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
it "can be instantiated from a secret key" do
|
|
16
|
-
|
|
16
|
+
RbNaCl::RandomNonceBox.from_secret_key(secret_key).should be_a RbNaCl::RandomNonceBox
|
|
17
17
|
end
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
|
|
19
|
+
it "raises TypeError when given a nil secret key" do
|
|
20
|
+
expect { RbNaCl::RandomNonceBox.from_secret_key(nil) }.to raise_error(TypeError)
|
|
20
21
|
end
|
|
22
|
+
|
|
21
23
|
it "can be instantiated from a key-pair" do
|
|
22
|
-
|
|
24
|
+
RbNaCl::RandomNonceBox.from_keypair(alicepk, bobsk).should be_a RbNaCl::RandomNonceBox
|
|
23
25
|
end
|
|
24
|
-
|
|
25
|
-
|
|
26
|
+
|
|
27
|
+
it "raises TypeError when given nil secret keys in the pair" do
|
|
28
|
+
expect { RbNaCl::RandomNonceBox.from_keypair(nil, bobsk) }.to raise_error(TypeError)
|
|
29
|
+
expect { RbNaCl::RandomNonceBox.from_keypair(alicepk, nil) }.to raise_error(TypeError)
|
|
26
30
|
end
|
|
27
31
|
end
|
|
28
32
|
|
|
29
|
-
|
|
30
|
-
|
|
31
33
|
context "cryptography" do
|
|
32
|
-
let(:nonce) {
|
|
33
|
-
let(:message) {
|
|
34
|
-
let(:ciphertext) {
|
|
35
|
-
let(:random_box) {
|
|
34
|
+
let(:nonce) { vector :box_nonce }
|
|
35
|
+
let(:message) { vector :box_message }
|
|
36
|
+
let(:ciphertext) { vector :box_ciphertext }
|
|
37
|
+
let(:random_box) { RbNaCl::RandomNonceBox.from_keypair(alicepk, bobsk) }
|
|
36
38
|
let(:enciphered_message) { random_box.box(message) }
|
|
37
|
-
let(:enciphered_message_hex) { random_box.box(message
|
|
39
|
+
let(:enciphered_message_hex) { random_box.box(message) }
|
|
38
40
|
|
|
39
41
|
it "descrypts a message with a 'random' nonce" do
|
|
40
42
|
random_box.open(nonce+ciphertext).should eql message
|
|
@@ -43,12 +45,5 @@ describe Crypto::RandomNonceBox do
|
|
|
43
45
|
it "can successfully round-trip a message" do
|
|
44
46
|
random_box.open(enciphered_message).should eql message
|
|
45
47
|
end
|
|
46
|
-
|
|
47
|
-
it "can encode a ciphertext as hex" do
|
|
48
|
-
enciphered_message_hex.should match /\A[0-9a-f]+\z/
|
|
49
|
-
end
|
|
50
|
-
it "can roundtrip a message as hex" do
|
|
51
|
-
random_box.open(enciphered_message_hex, :hex).should eql message
|
|
52
|
-
end
|
|
53
48
|
end
|
|
54
49
|
end
|
data/spec/rbnacl/random_spec.rb
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# encoding: binary
|
|
2
|
-
describe
|
|
2
|
+
describe RbNaCl::Random do
|
|
3
3
|
it "produces random bytes" do
|
|
4
|
-
|
|
4
|
+
RbNaCl::Random.random_bytes(16).bytesize.should == 16
|
|
5
5
|
end
|
|
6
6
|
it "produces different random bytes" do
|
|
7
|
-
|
|
7
|
+
RbNaCl::Random.random_bytes(16).should_not == RbNaCl::Random.random_bytes(16)
|
|
8
8
|
end
|
|
9
9
|
end
|
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
# encoding: binary
|
|
2
2
|
require 'spec_helper'
|
|
3
3
|
|
|
4
|
-
describe
|
|
5
|
-
let (:key) {
|
|
4
|
+
describe RbNaCl::SecretBox do
|
|
5
|
+
let (:key) { vector :secret_key }
|
|
6
6
|
|
|
7
7
|
context "new" do
|
|
8
8
|
it "accepts strings" do
|
|
9
|
-
expect {
|
|
9
|
+
expect { RbNaCl::SecretBox.new(key) }.to_not raise_error(Exception)
|
|
10
10
|
end
|
|
11
11
|
|
|
12
12
|
it "raises on a nil key" do
|
|
13
|
-
expect {
|
|
13
|
+
expect { RbNaCl::SecretBox.new(nil) }.to raise_error(TypeError)
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
it "raises on a short key" do
|
|
17
|
-
expect {
|
|
17
|
+
expect { RbNaCl::SecretBox.new("hello") }.to raise_error(RbNaCl::LengthError, "Secret key was 5 bytes \(Expected #{RbNaCl::SecretBox::KEYBYTES}\)")
|
|
18
18
|
end
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
include_examples "box" do
|
|
22
|
-
let(:box) {
|
|
22
|
+
let(:box) { RbNaCl::SecretBox.new(key) }
|
|
23
23
|
end
|
|
24
24
|
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# encoding: binary
|
|
2
|
+
require 'spec_helper'
|
|
3
|
+
|
|
4
|
+
describe RbNaCl::SigningKey do
|
|
5
|
+
let(:signing_key) { vector :sign_private }
|
|
6
|
+
let(:message) { vector :sign_message }
|
|
7
|
+
let(:signature) { vector :sign_signature }
|
|
8
|
+
|
|
9
|
+
subject { described_class.new(signing_key) }
|
|
10
|
+
|
|
11
|
+
it "generates keys" do
|
|
12
|
+
described_class.generate.should be_a described_class
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it "signs messages as bytes" do
|
|
16
|
+
subject.sign(message).should eq signature
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it "serializes to bytes" do
|
|
20
|
+
subject.to_bytes.should eq signing_key
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
include_examples "key equality" do
|
|
24
|
+
let(:key_bytes) { signing_key }
|
|
25
|
+
let(:key) { described_class.new(key_bytes) }
|
|
26
|
+
let(:other_key) { described_class.new("B"*32) }
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
include_examples "serializable"
|
|
30
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# encoding: binary
|
|
2
|
+
describe RbNaCl::VerifyKey do
|
|
3
|
+
let(:signing_key) { vector :sign_private }
|
|
4
|
+
let(:verify_key) { vector :sign_public }
|
|
5
|
+
|
|
6
|
+
let(:message) { vector :sign_message }
|
|
7
|
+
let(:signature) { vector :sign_signature }
|
|
8
|
+
let(:bad_signature) { sig = signature.dup; sig[0] = (sig[0].ord + 1).chr; sig }
|
|
9
|
+
|
|
10
|
+
subject { RbNaCl::SigningKey.new(signing_key).verify_key }
|
|
11
|
+
|
|
12
|
+
it "verifies correct signatures" do
|
|
13
|
+
subject.verify(signature, message).should be_true
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it "raises when asked to verify a bad signature" do
|
|
17
|
+
expect { subject.verify(bad_signature, message) }.to raise_exception RbNaCl::BadSignatureError
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it "raises when asked to verify a short signature" do
|
|
21
|
+
expect { subject.verify(bad_signature[0,63], message) }.to raise_exception RbNaCl::LengthError
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it "serializes to bytes" do
|
|
25
|
+
subject.to_bytes.should eq verify_key
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it "initializes from bytes" do
|
|
29
|
+
described_class.new(verify_key).to_s.should eq verify_key
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
include_examples "key equality" do
|
|
33
|
+
let(:key_bytes) { verify_key }
|
|
34
|
+
let(:key) { described_class.new(verify_key) }
|
|
35
|
+
let(:other_key) { described_class.new("B"*32) }
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
include_examples "serializable"
|
|
39
|
+
end
|