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.
Files changed (79) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -5
  3. data/CHANGES.md +15 -0
  4. data/Gemfile +4 -1
  5. data/Guardfile +8 -0
  6. data/README.md +52 -3
  7. data/lib/rbnacl.rb +65 -29
  8. data/lib/rbnacl/auth.rb +14 -18
  9. data/lib/rbnacl/boxes/curve25519xsalsa20poly1305.rb +185 -0
  10. data/lib/rbnacl/{keys → boxes/curve25519xsalsa20poly1305}/private_key.rb +26 -23
  11. data/lib/rbnacl/{keys → boxes/curve25519xsalsa20poly1305}/public_key.rb +13 -12
  12. data/lib/rbnacl/group_elements/curve25519.rb +81 -0
  13. data/lib/rbnacl/hash.rb +30 -14
  14. data/lib/rbnacl/hash/blake2b.rb +57 -0
  15. data/lib/rbnacl/hash/sha256.rb +15 -0
  16. data/lib/rbnacl/hash/sha512.rb +15 -0
  17. data/lib/rbnacl/hmac/sha256.rb +19 -17
  18. data/lib/rbnacl/hmac/sha512256.rb +18 -19
  19. data/lib/rbnacl/init.rb +10 -0
  20. data/lib/rbnacl/{keys/key_comparator.rb → key_comparator.rb} +1 -1
  21. data/lib/rbnacl/{auth/one_time.rb → one_time_auths/poly1305.rb} +21 -19
  22. data/lib/rbnacl/rake_tasks.rb +7 -6
  23. data/lib/rbnacl/random.rb +8 -3
  24. data/lib/rbnacl/random_nonce_box.rb +9 -14
  25. data/lib/rbnacl/secret_boxes/xsalsa20poly1305.rb +125 -0
  26. data/lib/rbnacl/self_test.rb +59 -40
  27. data/lib/rbnacl/serializable.rb +4 -12
  28. data/lib/rbnacl/signatures/ed25519.rb +15 -0
  29. data/lib/rbnacl/signatures/ed25519/signing_key.rb +104 -0
  30. data/lib/rbnacl/signatures/ed25519/verify_key.rb +91 -0
  31. data/lib/rbnacl/sodium.rb +43 -0
  32. data/lib/rbnacl/test_vectors.rb +34 -1
  33. data/lib/rbnacl/util.rb +52 -7
  34. data/lib/rbnacl/version.rb +2 -2
  35. data/rbnacl.gemspec +3 -6
  36. data/spec/rbnacl/{auth/one_time_spec.rb → authenticators/poly1305_spec.rb} +2 -2
  37. data/spec/rbnacl/boxes/curve25519xsalsa20poly1305/private_key_spec.rb +65 -0
  38. data/spec/rbnacl/{keys → boxes/curve25519xsalsa20poly1305}/public_key_spec.rb +10 -13
  39. data/spec/rbnacl/boxes/curve25519xsalsa20poly1305_spec.rb +39 -0
  40. data/spec/rbnacl/{point_spec.rb → group_element_spec.rb} +6 -8
  41. data/spec/rbnacl/hash/blake2b_spec.rb +26 -0
  42. data/spec/rbnacl/hash_spec.rb +13 -33
  43. data/spec/rbnacl/hmac/sha256_spec.rb +2 -2
  44. data/spec/rbnacl/hmac/sha512256_spec.rb +2 -2
  45. data/spec/rbnacl/random_nonce_box_spec.rb +21 -26
  46. data/spec/rbnacl/random_spec.rb +3 -3
  47. data/spec/rbnacl/secret_box_spec.rb +6 -6
  48. data/spec/rbnacl/signatures/ed25519/signing_key_spec.rb +30 -0
  49. data/spec/rbnacl/signatures/ed25519/verify_key_spec.rb +39 -0
  50. data/spec/rbnacl/util_spec.rb +67 -53
  51. data/spec/shared/authenticator.rb +36 -54
  52. data/spec/shared/box.rb +10 -10
  53. data/spec/shared/key_equality.rb +3 -3
  54. data/spec/shared/serializable.rb +17 -0
  55. data/spec/spec_helper.rb +14 -16
  56. data/tasks/rspec.rake +1 -0
  57. metadata +42 -67
  58. checksums.yaml.gz.sig +0 -0
  59. data.tar.gz.sig +0 -3
  60. data/lib/rbnacl/box.rb +0 -171
  61. data/lib/rbnacl/encoder.rb +0 -44
  62. data/lib/rbnacl/encoders/base32.rb +0 -33
  63. data/lib/rbnacl/encoders/base64.rb +0 -30
  64. data/lib/rbnacl/encoders/hex.rb +0 -30
  65. data/lib/rbnacl/encoders/raw.rb +0 -12
  66. data/lib/rbnacl/keys/signing_key.rb +0 -95
  67. data/lib/rbnacl/keys/verify_key.rb +0 -96
  68. data/lib/rbnacl/nacl.rb +0 -146
  69. data/lib/rbnacl/point.rb +0 -70
  70. data/lib/rbnacl/secret_box.rb +0 -119
  71. data/spec/rbnacl/box_spec.rb +0 -42
  72. data/spec/rbnacl/encoder_spec.rb +0 -14
  73. data/spec/rbnacl/encoders/base32_spec.rb +0 -16
  74. data/spec/rbnacl/encoders/base64_spec.rb +0 -15
  75. data/spec/rbnacl/encoders/hex_spec.rb +0 -15
  76. data/spec/rbnacl/keys/private_key_spec.rb +0 -68
  77. data/spec/rbnacl/keys/signing_key_spec.rb +0 -39
  78. data/spec/rbnacl/keys/verify_key_spec.rb +0 -51
  79. metadata.gz.sig +0 -2
@@ -1,9 +1,9 @@
1
1
  # encoding: binary
2
- module Crypto
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 provenence of
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
- # Number of bytes in a valid key
17
- KEYBYTES = NaCl::HMACSHA512256_KEYBYTES
16
+ extend Sodium
18
17
 
19
- # Number of bytes in a valid authenticator
20
- BYTES = NaCl::HMACSHA512256_BYTES
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
- # The crypto primitive for the HMAC::SHA512256 class
23
- #
24
- # @return [Symbol] The primitive used
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(message, authenticator)
31
- NaCl.crypto_auth_hmacsha512256(authenticator, message, message.bytesize, key)
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(message, authenticator)
35
- NaCl.crypto_auth_hmacsha512256_verify(authenticator, message, message.bytesize, key)
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
@@ -0,0 +1,10 @@
1
+ # encoding: binary
2
+ module RbNaCl
3
+ # Defines the libsodium init function
4
+ module Init
5
+ extend FFI::Library
6
+ ffi_lib 'sodium'
7
+
8
+ attach_function :sodium_init, [], :int
9
+ end
10
+ end
@@ -1,5 +1,5 @@
1
1
  # encoding: binary
2
- module Crypto
2
+ module RbNaCl
3
3
  # Implements comparisons of keys
4
4
  #
5
5
  # This permits both timing invariant equality tests, as well as
@@ -1,9 +1,9 @@
1
1
  # encoding: binary
2
- module Crypto
3
- class Auth
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 provenence of
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 OneTime < self
21
- # Number of bytes in a valid key
22
- KEYBYTES = NaCl::ONETIME_KEYBYTES
20
+ class Poly1305 < Auth
21
+ extend Sodium
23
22
 
24
- # Number of bytes in a valid authenticator
25
- BYTES = NaCl::ONETIME_BYTES
26
-
27
- # The crypto primitive for the Auth::OneTime class
28
- #
29
- # @return [Symbol] The primitive used
30
- def self.primitive
31
- :poly_1305
32
- end
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(message, authenticator)
36
- NaCl.crypto_auth_onetime(authenticator, message, message.bytesize, key)
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(message, authenticator)
40
- NaCl.crypto_auth_onetime_verify(authenticator, message, message.bytesize, key)
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
@@ -3,7 +3,8 @@ require 'rake'
3
3
  require 'rake/clean'
4
4
  require 'digest/sha2'
5
5
 
6
- LIBSODIUM_VERSION = "0.2"
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 http://download.dnscrypt.org/libsodium/releases/libsodium-#{LIBSODIUM_VERSION}.tar.gz"
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 != "e99a6b69adc080a5acf6b8a49fdc74b61d6f3579b590e85c93446a8325dde100"
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" => "libsodium-#{LIBSODIUM_VERSION}.tar.gz" do
32
- sh "tar xzf libsodium-#{LIBSODIUM_VERSION}.tar.gz"
32
+ file "libsodium" => libsodium_tarball do
33
+ sh "tar -zxf #{libsodium_tarball}"
33
34
  mv "libsodium-#{LIBSODIUM_VERSION}", "libsodium"
34
35
  end
35
36
 
@@ -1,18 +1,23 @@
1
1
  # encoding: binary
2
- module Crypto
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 = Crypto::Util.zeros(n)
15
- NaCl.random_bytes(buf, n)
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 Crypto
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 Crypto::Box or Crypto::SecretBox. A 24-byte random nonce is used
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 neglible. For
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, encoding = :raw)
76
+ def box(message)
82
77
  nonce = generate_nonce
83
78
  cipher_text = @box.box(nonce, message)
84
- Encoder[encoding].encode(nonce + cipher_text)
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, encoding = :raw)
99
- decoded = Encoder[encoding].decode(enciphered_message)
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
@@ -1,41 +1,52 @@
1
+ # encoding: binary
2
+
1
3
  start = Time.now if $DEBUG
2
4
 
3
- module Crypto
4
- class SelfTestFailure < Crypto::CryptoError; end
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 = Crypto::PublicKey.new(TestVectors[:alice_public], :hex)
11
- bobsk = Crypto::PrivateKey.new(TestVectors[:bob_private], :hex)
16
+ alicepk = RbNaCl::PublicKey.new(vector(:alice_public))
17
+ bobsk = RbNaCl::PrivateKey.new(vector(:bob_private))
12
18
 
13
- box = Crypto::Box.new(alicepk, bobsk)
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(TestVectors[:secret_key], :hex)
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 = hexdecode_vector :box_nonce
24
- message = hexdecode_vector :box_message
25
- ciphertext = hexdecode_vector :box_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(TestVectors[:sign_private], :hex)
59
+ signing_key = SigningKey.new(vector(:sign_private))
49
60
  verify_key = signing_key.verify_key
50
61
 
51
- unless verify_key.to_s(:hex) == TestVectors[:sign_public]
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 = hexdecode_vector :sign_message
56
- signature = signing_key.sign(message, :hex)
68
+ message = vector :sign_message
69
+ signature = signing_key.sign(message)
57
70
 
58
- unless signature == TestVectors[:sign_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(message, signature, :hex)
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,127] + '0'
83
+ bad_signature = signature[0,63] + '0'
67
84
 
68
- unless verify_key.verify(message, bad_signature, :hex) == false
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 = hexdecode_vector :sha256_message
75
- digest = hexdecode_vector :sha256_digest
93
+ message = vector :sha256_message
94
+ digest = vector :sha256_digest
76
95
 
77
- unless Crypto::Hash.sha256(message) == digest
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(TestVectors[:auth_key], :hex)
104
+ authenticator = klass.new(vector(:auth_key))
84
105
 
85
- message = hexdecode_vector :auth_message
106
+ message = vector :auth_message
86
107
 
87
- unless authenticator.auth(message, :hex) == TestVectors[tag]
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(message, TestVectors[tag], :hex)
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+' ', TestVectors[tag], :hex)
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
- Crypto::SelfTest.box_test
111
- Crypto::SelfTest.secret_box_test
112
- Crypto::SelfTest.digital_signature_test
113
- Crypto::SelfTest.sha256_test
114
- Crypto::SelfTest.hmac_test Crypto::HMAC::SHA256, :auth_hmacsha256
115
- Crypto::SelfTest.hmac_test Crypto::HMAC::SHA512256, :auth_hmacsha512256
116
- Crypto::SelfTest.hmac_test Crypto::Auth::OneTime, :auth_onetime
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