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.
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