rbnacl 1.1.0 → 2.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.
- checksums.yaml +4 -4
- data/.travis.yml +1 -5
- data/CHANGES.md +15 -0
- data/Gemfile +4 -1
- data/Guardfile +8 -0
- data/README.md +52 -3
- data/lib/rbnacl.rb +65 -29
- data/lib/rbnacl/auth.rb +14 -18
- data/lib/rbnacl/boxes/curve25519xsalsa20poly1305.rb +185 -0
- 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/group_elements/curve25519.rb +81 -0
- data/lib/rbnacl/hash.rb +30 -14
- data/lib/rbnacl/hash/blake2b.rb +57 -0
- data/lib/rbnacl/hash/sha256.rb +15 -0
- data/lib/rbnacl/hash/sha512.rb +15 -0
- 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 +8 -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 +59 -40
- data/lib/rbnacl/serializable.rb +4 -12
- data/lib/rbnacl/signatures/ed25519.rb +15 -0
- data/lib/rbnacl/signatures/ed25519/signing_key.rb +104 -0
- data/lib/rbnacl/signatures/ed25519/verify_key.rb +91 -0
- data/lib/rbnacl/sodium.rb +43 -0
- data/lib/rbnacl/test_vectors.rb +34 -1
- data/lib/rbnacl/util.rb +52 -7
- data/lib/rbnacl/version.rb +2 -2
- data/rbnacl.gemspec +3 -6
- 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 +26 -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 -54
- 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 +14 -16
- data/tasks/rspec.rake +1 -0
- metadata +42 -67
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -3
- 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
- metadata.gz.sig +0 -2
@@ -1,9 +1,9 @@
|
|
1
1
|
# encoding: binary
|
2
|
-
module
|
2
|
+
module RbNaCl
|
3
3
|
module HMAC
|
4
4
|
# Computes an authenticator as HMAC-SHA-512 truncated to 256-bits
|
5
5
|
#
|
6
|
-
# The authenticator can be used at a later time to verify the
|
6
|
+
# The authenticator can be used at a later time to verify the provenance of
|
7
7
|
# the message by recomputing the HMAC over the message and then comparing it to
|
8
8
|
# the provided authenticator. The class provides methods for generating
|
9
9
|
# signatures and also has a constant-time implementation for checking them.
|
@@ -13,30 +13,29 @@ module Crypto
|
|
13
13
|
#
|
14
14
|
# @see http://nacl.cr.yp.to/auth.html
|
15
15
|
class SHA512256 < Auth
|
16
|
-
|
17
|
-
KEYBYTES = NaCl::HMACSHA512256_KEYBYTES
|
16
|
+
extend Sodium
|
18
17
|
|
19
|
-
|
20
|
-
|
18
|
+
sodium_type :auth
|
19
|
+
sodium_primitive :hmacsha512256
|
20
|
+
sodium_constant :BYTES
|
21
|
+
sodium_constant :KEYBYTES
|
22
|
+
|
23
|
+
sodium_function :auth_hmacsha512256,
|
24
|
+
:crypto_auth_hmacsha512256,
|
25
|
+
[:pointer, :pointer, :ulong_long, :pointer]
|
21
26
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
def self.primitive
|
26
|
-
:hmac_sha512256
|
27
|
-
end
|
27
|
+
sodium_function :auth_hmacsha512256_verify,
|
28
|
+
:crypto_auth_hmacsha512256_verify,
|
29
|
+
[:pointer, :pointer, :ulong_long, :pointer]
|
28
30
|
|
29
31
|
private
|
30
|
-
def compute_authenticator(
|
31
|
-
|
32
|
+
def compute_authenticator(authenticator, message)
|
33
|
+
self.class.auth_hmacsha512256(authenticator, message, message.bytesize, key)
|
32
34
|
end
|
33
35
|
|
34
|
-
def verify_message(
|
35
|
-
|
36
|
+
def verify_message(authenticator, message)
|
37
|
+
self.class.auth_hmacsha512256_verify(authenticator, message, message.bytesize, key)
|
36
38
|
end
|
37
39
|
end
|
38
|
-
|
39
|
-
# TIMTOWTDI!
|
40
|
-
SHA512 = SHA512256
|
41
40
|
end
|
42
41
|
end
|
data/lib/rbnacl/init.rb
ADDED
@@ -1,9 +1,9 @@
|
|
1
1
|
# encoding: binary
|
2
|
-
module
|
3
|
-
|
2
|
+
module RbNaCl
|
3
|
+
module OneTimeAuths
|
4
4
|
# Computes an authenticator using poly1305
|
5
5
|
#
|
6
|
-
# The authenticator can be used at a later time to verify the
|
6
|
+
# The authenticator can be used at a later time to verify the provenance of
|
7
7
|
# the message by recomputing the tag over the message and then comparing it to
|
8
8
|
# the provided authenticator. The class provides methods for generating
|
9
9
|
# signatures and also has a constant-time implementation for checking them.
|
@@ -17,27 +17,29 @@ module Crypto
|
|
17
17
|
# can also create them.
|
18
18
|
#
|
19
19
|
# @see http://nacl.cr.yp.to/onetimeauth.html
|
20
|
-
class
|
21
|
-
|
22
|
-
KEYBYTES = NaCl::ONETIME_KEYBYTES
|
20
|
+
class Poly1305 < Auth
|
21
|
+
extend Sodium
|
23
22
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
23
|
+
sodium_type :onetimeauth
|
24
|
+
sodium_primitive :poly1305
|
25
|
+
sodium_constant :BYTES
|
26
|
+
sodium_constant :KEYBYTES
|
27
|
+
|
28
|
+
sodium_function :onetimeauth_poly1305,
|
29
|
+
:crypto_onetimeauth_poly1305,
|
30
|
+
[:pointer, :pointer, :ulong_long, :pointer]
|
31
|
+
|
32
|
+
sodium_function :onetimeauth_poly1305_verify,
|
33
|
+
:crypto_onetimeauth_poly1305_verify,
|
34
|
+
[:pointer, :pointer, :ulong_long, :pointer]
|
33
35
|
|
34
36
|
private
|
35
|
-
def compute_authenticator(
|
36
|
-
|
37
|
+
def compute_authenticator(authenticator, message)
|
38
|
+
self.class.onetimeauth_poly1305(authenticator, message, message.bytesize, key)
|
37
39
|
end
|
38
40
|
|
39
|
-
def verify_message(
|
40
|
-
|
41
|
+
def verify_message(authenticator, message)
|
42
|
+
self.class.onetimeauth_poly1305_verify(authenticator, message, message.bytesize, key)
|
41
43
|
end
|
42
44
|
|
43
45
|
end
|
data/lib/rbnacl/rake_tasks.rb
CHANGED
@@ -3,7 +3,8 @@ require 'rake'
|
|
3
3
|
require 'rake/clean'
|
4
4
|
require 'digest/sha2'
|
5
5
|
|
6
|
-
LIBSODIUM_VERSION = "0.
|
6
|
+
LIBSODIUM_VERSION = "0.4.5"
|
7
|
+
LIBSODIUM_DIGEST = "7ad5202df53eeac0eb29b064ae5d05b65d82b2fc1c082899c9c6a09b0ee1ac32"
|
7
8
|
|
8
9
|
def sh_hidden(command)
|
9
10
|
STDERR.puts("*** Executing: #{command}")
|
@@ -19,17 +20,17 @@ end
|
|
19
20
|
libsodium_tarball = "libsodium-#{LIBSODIUM_VERSION}.tar.gz"
|
20
21
|
|
21
22
|
file libsodium_tarball do
|
22
|
-
sh "curl -O
|
23
|
+
sh "curl -L -O https://github.com/jedisct1/libsodium/releases/download/#{LIBSODIUM_VERSION}/#{libsodium_tarball}"
|
23
24
|
|
24
25
|
digest = Digest::SHA256.hexdigest(File.read(libsodium_tarball))
|
25
|
-
if digest !=
|
26
|
+
if digest != LIBSODIUM_DIGEST
|
26
27
|
rm libsodium_tarball
|
27
|
-
raise "#{libsodium_tarball} failed checksum!"
|
28
|
+
raise "#{libsodium_tarball} failed checksum! Got #{digest}"
|
28
29
|
end
|
29
30
|
end
|
30
31
|
|
31
|
-
file "libsodium" =>
|
32
|
-
sh "tar
|
32
|
+
file "libsodium" => libsodium_tarball do
|
33
|
+
sh "tar -zxf #{libsodium_tarball}"
|
33
34
|
mv "libsodium-#{LIBSODIUM_VERSION}", "libsodium"
|
34
35
|
end
|
35
36
|
|
data/lib/rbnacl/random.rb
CHANGED
@@ -1,18 +1,23 @@
|
|
1
1
|
# encoding: binary
|
2
|
-
module
|
2
|
+
module RbNaCl
|
3
3
|
# Functions for random number generation
|
4
4
|
#
|
5
5
|
# This uses the underlying source of random number generation on the OS, so
|
6
6
|
# /dev/urandom on UNIX-like systems, and the MS crypto providor on windows.
|
7
7
|
module Random
|
8
|
+
extend Sodium
|
9
|
+
|
10
|
+
sodium_function :c_random_bytes,
|
11
|
+
:randombytes_buf,
|
12
|
+
[:pointer, :ulong_long]
|
8
13
|
# Returns a string of random bytes
|
9
14
|
#
|
10
15
|
# @param [Integer] n number of random bytes desired
|
11
16
|
#
|
12
17
|
# @return [String] random bytes.
|
13
18
|
def self.random_bytes(n=32)
|
14
|
-
buf =
|
15
|
-
|
19
|
+
buf = RbNaCl::Util.zeros(n)
|
20
|
+
c_random_bytes(buf, n)
|
16
21
|
buf
|
17
22
|
end
|
18
23
|
end
|
@@ -1,15 +1,15 @@
|
|
1
1
|
# encoding: binary
|
2
2
|
require 'forwardable'
|
3
|
-
module
|
3
|
+
module RbNaCl
|
4
4
|
# The simplest nonce strategy that could possibly work
|
5
5
|
#
|
6
6
|
# This class implements the simplest possible nonce generation strategy to
|
7
|
-
# wrap a
|
7
|
+
# wrap a RbNaCl::Box or RbNaCl::SecretBox. A 24-byte random nonce is used
|
8
8
|
# for the encryption and is prepended to the message. When it is time to
|
9
9
|
# open the box, the message is split into nonce and ciphertext, and then the
|
10
10
|
# box is decrypted.
|
11
11
|
#
|
12
|
-
# Thanks to the size of the nonce, the chance of a collision is
|
12
|
+
# Thanks to the size of the nonce, the chance of a collision is negligible. For
|
13
13
|
# example, after encrypting 2^64 messages, the odds of their having been
|
14
14
|
# repeated nonce is approximately 2^-64. As an additional convenience, the
|
15
15
|
# ciphertexts may be encoded or decoded by any of the encoders implemented in
|
@@ -31,10 +31,6 @@ module Crypto
|
|
31
31
|
extend Forwardable
|
32
32
|
def_delegators :@box, :nonce_bytes, :primitive
|
33
33
|
|
34
|
-
# the size of the nonce
|
35
|
-
# DO NOT USE THIS, use the #nonce_bytes method instead
|
36
|
-
NONCEBYTES = NaCl::NONCEBYTES
|
37
|
-
|
38
34
|
# Create a new RandomNonceBox
|
39
35
|
#
|
40
36
|
# @param box [SecretBox, Box] the SecretBox or Box to use.
|
@@ -75,14 +71,14 @@ module Crypto
|
|
75
71
|
# the nonce prepended. Optionally encodes the message using an encoder.
|
76
72
|
#
|
77
73
|
# @param message [String] The message to encrypt
|
78
|
-
# @param encoding [Symbol] Optional encoding for the returned ciphertext
|
79
74
|
#
|
80
75
|
# @return [String] The enciphered message
|
81
|
-
def box(message
|
76
|
+
def box(message)
|
82
77
|
nonce = generate_nonce
|
83
78
|
cipher_text = @box.box(nonce, message)
|
84
|
-
|
79
|
+
nonce + cipher_text
|
85
80
|
end
|
81
|
+
alias encrypt box
|
86
82
|
|
87
83
|
# Decrypts the ciphertext with a random nonce
|
88
84
|
#
|
@@ -90,16 +86,15 @@ module Crypto
|
|
90
86
|
# front and uses this to decrypt. Returns the message.
|
91
87
|
#
|
92
88
|
# @param enciphered_message [String] The message to decrypt.
|
93
|
-
# @param encoding [Symbol] Optional decoding for the returned ciphertext
|
94
89
|
#
|
95
90
|
# @raise [CryptoError] If the message has been tampered with.
|
96
91
|
#
|
97
92
|
# @return [String] The decoded message
|
98
|
-
def open(enciphered_message
|
99
|
-
|
100
|
-
nonce, ciphertext = *extract_nonce(decoded)
|
93
|
+
def open(enciphered_message)
|
94
|
+
nonce, ciphertext = extract_nonce(enciphered_message.to_s)
|
101
95
|
@box.open(nonce, ciphertext)
|
102
96
|
end
|
97
|
+
alias decrypt open
|
103
98
|
|
104
99
|
private
|
105
100
|
def generate_nonce
|
@@ -0,0 +1,125 @@
|
|
1
|
+
# encoding: binary
|
2
|
+
module RbNaCl
|
3
|
+
module SecretBoxes
|
4
|
+
# The SecretBox class boxes and unboxes messages
|
5
|
+
#
|
6
|
+
# This class uses the given secret key to encrypt and decrypt messages.
|
7
|
+
#
|
8
|
+
# It is VITALLY important that the nonce is a nonce, i.e. it is a number used
|
9
|
+
# only once for any given pair of keys. If you fail to do this, you
|
10
|
+
# compromise the privacy of the messages encrypted. Give your nonces a
|
11
|
+
# different prefix, or have one side use an odd counter and one an even counter.
|
12
|
+
# Just make sure they are different.
|
13
|
+
#
|
14
|
+
# The ciphertexts generated by this class include a 16-byte authenticator which
|
15
|
+
# is checked as part of the decryption. An invalid authenticator will cause
|
16
|
+
# the unbox function to raise. The authenticator is not a signature. Once
|
17
|
+
# you've looked in the box, you've demonstrated the ability to create
|
18
|
+
# arbitrary valid messages, so messages you send are repudiable. For
|
19
|
+
# non-repudiable messages, sign them before or after encryption.
|
20
|
+
class XSalsa20Poly1305
|
21
|
+
extend Sodium
|
22
|
+
|
23
|
+
sodium_type :secretbox
|
24
|
+
sodium_primitive :xsalsa20poly1305
|
25
|
+
sodium_constant :KEYBYTES
|
26
|
+
sodium_constant :NONCEBYTES
|
27
|
+
sodium_constant :ZEROBYTES
|
28
|
+
sodium_constant :BOXZEROBYTES
|
29
|
+
|
30
|
+
sodium_function :secretbox_xsalsa20poly1305,
|
31
|
+
:crypto_secretbox_xsalsa20poly1305,
|
32
|
+
[:pointer, :pointer, :ulong_long, :pointer, :pointer]
|
33
|
+
|
34
|
+
sodium_function :secretbox_xsalsa20poly1305_open,
|
35
|
+
:crypto_secretbox_xsalsa20poly1305_open,
|
36
|
+
[:pointer, :pointer, :ulong_long, :pointer, :pointer]
|
37
|
+
|
38
|
+
# Create a new SecretBox
|
39
|
+
#
|
40
|
+
# Sets up the Box with a secret key fro encrypting and decrypting messages.
|
41
|
+
#
|
42
|
+
# @param key [String] The key to encrypt and decrypt with
|
43
|
+
#
|
44
|
+
# @raise [RbNaCl::LengthError] on invalid keys
|
45
|
+
#
|
46
|
+
# @return [RbNaCl::SecretBox] The new Box, ready to use
|
47
|
+
def initialize(key)
|
48
|
+
@key = Util.check_string(key, KEYBYTES, "Secret key")
|
49
|
+
end
|
50
|
+
|
51
|
+
# Encrypts a message
|
52
|
+
#
|
53
|
+
# Encrypts the message with the given nonce to the key set up when
|
54
|
+
# initializing the class. Make sure the nonce is unique for any given
|
55
|
+
# key, or you might as well just send plain text.
|
56
|
+
#
|
57
|
+
# This function takes care of the padding required by the NaCL C API.
|
58
|
+
#
|
59
|
+
# @param nonce [String] A 24-byte string containing the nonce.
|
60
|
+
# @param message [String] The message to be encrypted.
|
61
|
+
#
|
62
|
+
# @raise [RbNaCl::LengthError] If the nonce is not valid
|
63
|
+
#
|
64
|
+
# @return [String] The ciphertext without the nonce prepended (BINARY encoded)
|
65
|
+
def box(nonce, message)
|
66
|
+
Util.check_length(nonce, nonce_bytes, "Nonce")
|
67
|
+
msg = Util.prepend_zeros(ZEROBYTES, message)
|
68
|
+
ct = Util.zeros(msg.bytesize)
|
69
|
+
|
70
|
+
self.class.secretbox_xsalsa20poly1305(ct, msg, msg.bytesize, nonce, @key) || raise(CryptoError, "Encryption failed")
|
71
|
+
Util.remove_zeros(BOXZEROBYTES, ct)
|
72
|
+
end
|
73
|
+
alias encrypt box
|
74
|
+
|
75
|
+
# Decrypts a ciphertext
|
76
|
+
#
|
77
|
+
# Decrypts the ciphertext with the given nonce using the key setup when
|
78
|
+
# initializing the class.
|
79
|
+
#
|
80
|
+
# This function takes care of the padding required by the NaCL C API.
|
81
|
+
#
|
82
|
+
# @param nonce [String] A 24-byte string containing the nonce.
|
83
|
+
# @param ciphertext [String] The message to be decrypted.
|
84
|
+
#
|
85
|
+
# @raise [RbNaCl::LengthError] If the nonce is not valid
|
86
|
+
# @raise [RbNaCl::CryptoError] If the ciphertext cannot be authenticated.
|
87
|
+
#
|
88
|
+
# @return [String] The decrypted message (BINARY encoded)
|
89
|
+
def open(nonce, ciphertext)
|
90
|
+
Util.check_length(nonce, nonce_bytes, "Nonce")
|
91
|
+
ct = Util.prepend_zeros(BOXZEROBYTES, ciphertext)
|
92
|
+
message = Util.zeros(ct.bytesize)
|
93
|
+
|
94
|
+
self.class.secretbox_xsalsa20poly1305_open(message, ct, ct.bytesize, nonce, @key) || raise(CryptoError, "Decryption failed. Ciphertext failed verification.")
|
95
|
+
Util.remove_zeros(ZEROBYTES, message)
|
96
|
+
end
|
97
|
+
alias decrypt open
|
98
|
+
|
99
|
+
# The crypto primitive for the SecretBox instance
|
100
|
+
#
|
101
|
+
# @return [Symbol] The primitive used
|
102
|
+
def primitive; self.class.primitive; end
|
103
|
+
|
104
|
+
# The nonce bytes for the SecretBox class
|
105
|
+
#
|
106
|
+
# @return [Integer] The number of bytes in a valid nonce
|
107
|
+
def self.nonce_bytes; NONCEBYTES; end
|
108
|
+
|
109
|
+
# The nonce bytes for the SecretBox instance
|
110
|
+
#
|
111
|
+
# @return [Integer] The number of bytes in a valid nonce
|
112
|
+
def nonce_bytes; NONCEBYTES; end
|
113
|
+
|
114
|
+
# The key bytes for the SecretBox class
|
115
|
+
#
|
116
|
+
# @return [Integer] The number of bytes in a valid key
|
117
|
+
def self.key_bytes; KEYBYTES; end
|
118
|
+
|
119
|
+
# The key bytes for the SecretBox instance
|
120
|
+
#
|
121
|
+
# @return [Integer] The number of bytes in a valid key
|
122
|
+
def key_bytes; KEYBYTES; end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
data/lib/rbnacl/self_test.rb
CHANGED
@@ -1,41 +1,52 @@
|
|
1
|
+
# encoding: binary
|
2
|
+
|
1
3
|
start = Time.now if $DEBUG
|
2
4
|
|
3
|
-
module
|
4
|
-
class SelfTestFailure <
|
5
|
+
module RbNaCl
|
6
|
+
class SelfTestFailure < RbNaCl::CryptoError; end
|
5
7
|
|
6
8
|
module SelfTest
|
7
9
|
module_function
|
8
10
|
|
11
|
+
def vector(name)
|
12
|
+
[TestVectors[name]].pack("H*")
|
13
|
+
end
|
14
|
+
|
9
15
|
def box_test
|
10
|
-
alicepk =
|
11
|
-
bobsk =
|
16
|
+
alicepk = RbNaCl::PublicKey.new(vector(:alice_public))
|
17
|
+
bobsk = RbNaCl::PrivateKey.new(vector(:bob_private))
|
12
18
|
|
13
|
-
box =
|
19
|
+
box = RbNaCl::Box.new(alicepk, bobsk)
|
14
20
|
box_common_test(box)
|
15
21
|
end
|
16
22
|
|
17
23
|
def secret_box_test
|
18
|
-
box = SecretBox.new(
|
24
|
+
box = SecretBox.new(vector(:secret_key))
|
19
25
|
box_common_test(box)
|
20
26
|
end
|
21
27
|
|
22
28
|
def box_common_test(box)
|
23
|
-
nonce =
|
24
|
-
message =
|
25
|
-
ciphertext =
|
29
|
+
nonce = vector :box_nonce
|
30
|
+
message = vector :box_message
|
31
|
+
ciphertext = vector :box_ciphertext
|
26
32
|
|
27
33
|
unless box.encrypt(nonce, message) == ciphertext
|
34
|
+
#:nocov:
|
28
35
|
raise SelfTestFailure, "failed to generate correct ciphertext"
|
36
|
+
#:nocov:
|
29
37
|
end
|
30
38
|
|
31
39
|
unless box.decrypt(nonce, ciphertext) == message
|
40
|
+
#:nocov:
|
32
41
|
raise SelfTestFailure, "failed to decrypt ciphertext correctly"
|
42
|
+
#:nocov:
|
33
43
|
end
|
34
44
|
|
35
45
|
begin
|
36
46
|
passed = false
|
37
47
|
corrupt_ct = ciphertext.dup
|
38
48
|
corrupt_ct[23] = ' '
|
49
|
+
corrupt_ct
|
39
50
|
box.decrypt(nonce, corrupt_ct)
|
40
51
|
rescue CryptoError
|
41
52
|
passed = true
|
@@ -45,74 +56,82 @@ module Crypto
|
|
45
56
|
end
|
46
57
|
|
47
58
|
def digital_signature_test
|
48
|
-
signing_key = SigningKey.new(
|
59
|
+
signing_key = SigningKey.new(vector(:sign_private))
|
49
60
|
verify_key = signing_key.verify_key
|
50
61
|
|
51
|
-
unless verify_key.to_s
|
62
|
+
unless verify_key.to_s == vector(:sign_public)
|
63
|
+
#:nocov:
|
52
64
|
raise SelfTestFailure, "failed to generate verify key correctly"
|
65
|
+
#:nocov:
|
53
66
|
end
|
54
67
|
|
55
|
-
message =
|
56
|
-
signature = signing_key.sign(message
|
68
|
+
message = vector :sign_message
|
69
|
+
signature = signing_key.sign(message)
|
57
70
|
|
58
|
-
unless signature ==
|
71
|
+
unless signature == vector(:sign_signature)
|
72
|
+
#:nocov:
|
59
73
|
raise SelfTestFailure, "failed to generate correct signature"
|
74
|
+
#:nocov:
|
60
75
|
end
|
61
76
|
|
62
|
-
unless verify_key.verify(
|
77
|
+
unless verify_key.verify(signature, message)
|
78
|
+
#:nocov:
|
63
79
|
raise SelfTestFailure, "failed to verify a valid signature"
|
80
|
+
#:nocov:
|
64
81
|
end
|
65
82
|
|
66
|
-
bad_signature = signature[0,
|
83
|
+
bad_signature = signature[0,63] + '0'
|
67
84
|
|
68
|
-
unless verify_key.verify(
|
85
|
+
unless verify_key.verify(bad_signature, message) == false
|
86
|
+
#:nocov:
|
69
87
|
raise SelfTestFailure, "failed to detect an invalid signature"
|
88
|
+
#:nocov:
|
70
89
|
end
|
71
90
|
end
|
72
91
|
|
73
92
|
def sha256_test
|
74
|
-
message =
|
75
|
-
digest =
|
93
|
+
message = vector :sha256_message
|
94
|
+
digest = vector :sha256_digest
|
76
95
|
|
77
|
-
unless
|
96
|
+
unless RbNaCl::Hash.sha256(message) == digest
|
97
|
+
#:nocov:
|
78
98
|
raise SelfTestFailure, "failed to generate a correct SHA256 digest"
|
99
|
+
#:nocov:
|
79
100
|
end
|
80
101
|
end
|
81
102
|
|
82
103
|
def hmac_test(klass, tag)
|
83
|
-
authenticator = klass.new(
|
104
|
+
authenticator = klass.new(vector(:auth_key))
|
84
105
|
|
85
|
-
message =
|
106
|
+
message = vector :auth_message
|
86
107
|
|
87
|
-
unless authenticator.auth(message
|
108
|
+
unless authenticator.auth(message) == vector(tag)
|
109
|
+
#:nocov:
|
88
110
|
raise SelfTestFailure, "#{klass} failed to generate correct authentication tag"
|
111
|
+
#:nocov:
|
89
112
|
end
|
90
113
|
|
91
|
-
unless authenticator.verify(
|
114
|
+
unless authenticator.verify(vector(tag), message)
|
115
|
+
#:nocov:
|
92
116
|
raise SelfTestFailure, "#{klass} failed to verify correct authentication tag"
|
117
|
+
#:nocov:
|
93
118
|
end
|
94
119
|
|
95
|
-
if authenticator.verify(message+' '
|
120
|
+
if authenticator.verify(vector(tag), message + ' ')
|
121
|
+
#:nocov:
|
96
122
|
raise SelfTestFailure, "#{klass} failed to detect invalid authentication tag"
|
123
|
+
#:nocov:
|
97
124
|
end
|
98
125
|
end
|
99
|
-
|
100
|
-
def hexdecode(string)
|
101
|
-
Encoder[:hex].decode(string)
|
102
|
-
end
|
103
|
-
|
104
|
-
def hexdecode_vector(name)
|
105
|
-
hexdecode TestVectors[name]
|
106
|
-
end
|
107
126
|
end
|
108
127
|
end
|
109
128
|
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
129
|
+
RbNaCl::SelfTest.box_test
|
130
|
+
RbNaCl::SelfTest.secret_box_test
|
131
|
+
RbNaCl::SelfTest.digital_signature_test
|
132
|
+
RbNaCl::SelfTest.sha256_test
|
133
|
+
RbNaCl::SelfTest.hmac_test RbNaCl::HMAC::SHA256, :auth_hmacsha256
|
134
|
+
RbNaCl::SelfTest.hmac_test RbNaCl::HMAC::SHA512256, :auth_hmacsha512256
|
135
|
+
RbNaCl::SelfTest.hmac_test RbNaCl::OneTimeAuth, :auth_onetime
|
117
136
|
|
118
137
|
puts "POST Completed in #{Time.now - start} s" if $DEBUG
|