rbnacl 1.1.0 → 2.0.0.pre
Sign up to get free protection for your applications and to get access to all the features.
- 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
|