rbnacl 5.0.0 → 6.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +1 -0
  3. data/.rubocop.yml +34 -12
  4. data/.travis.yml +16 -16
  5. data/CHANGES.md +37 -10
  6. data/Gemfile +4 -3
  7. data/Guardfile +2 -0
  8. data/LICENSE.txt +1 -1
  9. data/README.md +31 -21
  10. data/Rakefile +4 -3
  11. data/lib/rbnacl.rb +8 -3
  12. data/lib/rbnacl/aead/base.rb +3 -0
  13. data/lib/rbnacl/aead/chacha20poly1305_ietf.rb +2 -2
  14. data/lib/rbnacl/aead/chacha20poly1305_legacy.rb +2 -2
  15. data/lib/rbnacl/aead/xchacha20poly1305_ietf.rb +44 -0
  16. data/lib/rbnacl/boxes/curve25519xsalsa20poly1305.rb +6 -5
  17. data/lib/rbnacl/boxes/curve25519xsalsa20poly1305/private_key.rb +1 -1
  18. data/lib/rbnacl/group_elements/curve25519.rb +2 -1
  19. data/lib/rbnacl/hash/blake2b.rb +6 -4
  20. data/lib/rbnacl/hash/sha256.rb +1 -1
  21. data/lib/rbnacl/hash/sha512.rb +1 -1
  22. data/lib/rbnacl/hmac/sha256.rb +73 -8
  23. data/lib/rbnacl/hmac/sha512.rb +73 -8
  24. data/lib/rbnacl/hmac/sha512256.rb +71 -8
  25. data/lib/rbnacl/init.rb +1 -5
  26. data/lib/rbnacl/one_time_auths/poly1305.rb +2 -2
  27. data/lib/rbnacl/password_hash.rb +33 -2
  28. data/lib/rbnacl/password_hash/argon2.rb +37 -18
  29. data/lib/rbnacl/password_hash/scrypt.rb +1 -1
  30. data/lib/rbnacl/random.rb +1 -3
  31. data/lib/rbnacl/secret_boxes/xsalsa20poly1305.rb +2 -2
  32. data/lib/rbnacl/signatures/ed25519/signing_key.rb +2 -2
  33. data/lib/rbnacl/signatures/ed25519/verify_key.rb +1 -1
  34. data/lib/rbnacl/sodium.rb +16 -12
  35. data/lib/rbnacl/sodium/version.rb +3 -1
  36. data/lib/rbnacl/test_vectors.rb +104 -44
  37. data/lib/rbnacl/util.rb +92 -8
  38. data/lib/rbnacl/version.rb +1 -1
  39. data/rbnacl.gemspec +6 -7
  40. data/spec/rbnacl/aead/xchacha20poly1305_ietf_spec.rb +14 -0
  41. data/spec/rbnacl/authenticators/poly1305_spec.rb +21 -1
  42. data/spec/rbnacl/boxes/curve25519xsalsa20poly1305_spec.rb +18 -6
  43. data/spec/rbnacl/hmac/sha256_spec.rb +6 -1
  44. data/spec/rbnacl/hmac/sha512256_spec.rb +6 -1
  45. data/spec/rbnacl/hmac/sha512_spec.rb +6 -1
  46. data/spec/rbnacl/password_hash/argon2_spec.rb +56 -14
  47. data/spec/rbnacl/signatures/ed25519/signing_key_spec.rb +5 -4
  48. data/spec/rbnacl/util_spec.rb +63 -4
  49. data/spec/shared/aead.rb +33 -13
  50. data/spec/shared/authenticator.rb +0 -19
  51. data/spec/shared/box.rb +18 -6
  52. data/spec/shared/hmac.rb +46 -0
  53. data/spec/spec_helper.rb +3 -1
  54. metadata +22 -18
  55. data/.ruby-version +0 -1
@@ -5,11 +5,7 @@ module RbNaCl
5
5
  # Defines the libsodium init function
6
6
  module Init
7
7
  extend FFI::Library
8
- if defined?(RBNACL_LIBSODIUM_GEM_LIB_PATH)
9
- ffi_lib RBNACL_LIBSODIUM_GEM_LIB_PATH
10
- else
11
- ffi_lib "sodium"
12
- end
8
+ ffi_lib "sodium"
13
9
 
14
10
  attach_function :sodium_init, [], :int
15
11
  end
@@ -29,11 +29,11 @@ module RbNaCl
29
29
 
30
30
  sodium_function :onetimeauth_poly1305,
31
31
  :crypto_onetimeauth_poly1305,
32
- [:pointer, :pointer, :ulong_long, :pointer]
32
+ %i[pointer pointer ulong_long pointer]
33
33
 
34
34
  sodium_function :onetimeauth_poly1305_verify,
35
35
  :crypto_onetimeauth_poly1305_verify,
36
- [:pointer, :pointer, :ulong_long, :pointer]
36
+ %i[pointer pointer ulong_long pointer]
37
37
 
38
38
  private
39
39
 
@@ -36,7 +36,8 @@ module RbNaCl
36
36
  SCrypt.new(opslimit, memlimit, digest_size).digest(password, salt)
37
37
  end
38
38
 
39
- # argon2: state of the art in the design of memory-hard hashing functions.
39
+ # argon2: state of the art in the design of memory-hard hashing functions
40
+ # (default digest algorithm).
40
41
  #
41
42
  # @param [String] password to be hashed
42
43
  # @param [String] salt to make the digest unique
@@ -46,11 +47,41 @@ module RbNaCl
46
47
  #
47
48
  # @raise [CryptoError] If calculating the digest fails for some reason.
48
49
  #
49
- # @return [String] The argon2i digest as raw bytes
50
+ # @return [String] The argon2 digest as raw bytes
50
51
  def self.argon2(password, salt, opslimit, memlimit, digest_size = 64)
51
52
  argon2_supported? && Argon2.new(opslimit, memlimit, digest_size).digest(password, salt)
52
53
  end
53
54
 
55
+ # argon2i: argon2, using argon2i digest algorithm.
56
+ #
57
+ # @param [String] password to be hashed
58
+ # @param [String] salt to make the digest unique
59
+ # @param [Integer] opslimit the CPU cost (3..10)
60
+ # @param [Integer] memlimit the memory cost, in bytes
61
+ # @param [Integer] digest_size of the output
62
+ #
63
+ # @raise [CryptoError] If calculating the digest fails for some reason.
64
+ #
65
+ # @return [String] The argon2i digest as raw bytes
66
+ def self.argon2i(password, salt, opslimit, memlimit, digest_size = 64)
67
+ argon2_supported? && Argon2.new(opslimit, memlimit, digest_size).digest(password, salt, :argon2i)
68
+ end
69
+
70
+ # argon2id: argon2, using argon2id digest algorithm.
71
+ #
72
+ # @param [String] password to be hashed
73
+ # @param [String] salt to make the digest unique
74
+ # @param [Integer] opslimit the CPU cost (3..10)
75
+ # @param [Integer] memlimit the memory cost, in bytes
76
+ # @param [Integer] digest_size of the output
77
+ #
78
+ # @raise [CryptoError] If calculating the digest fails for some reason.
79
+ #
80
+ # @return [String] The argon2id digest as raw bytes
81
+ def self.argon2id(password, salt, opslimit, memlimit, digest_size = 64)
82
+ argon2_supported? && Argon2.new(opslimit, memlimit, digest_size).digest(password, salt, :argon2id)
83
+ end
84
+
54
85
  # argon2_str: crypt-style password digest
55
86
  #
56
87
  # @param [String] password to be hashed
@@ -13,46 +13,45 @@ module RbNaCl
13
13
  extend Sodium
14
14
 
15
15
  sodium_type :pwhash
16
- sodium_primitive :argon2i
17
16
 
17
+ sodium_constant :ALG_DEFAULT
18
18
  sodium_constant :ALG_ARGON2I13
19
- sodium_constant :SALTBYTES
20
- sodium_constant :STRBYTES
19
+ sodium_constant :ALG_ARGON2ID13 if Sodium::Version::ARGON2ID_SUPPORTED
20
+
21
+ sodium_constant :SALTBYTES # 16
22
+ sodium_constant :STRBYTES # 128
21
23
  sodium_constant :OPSLIMIT_INTERACTIVE # 4
22
24
  sodium_constant :MEMLIMIT_INTERACTIVE # 2 ** 25 (32mb)
23
25
  sodium_constant :OPSLIMIT_MODERATE # 6
24
26
  sodium_constant :MEMLIMIT_MODERATE # 2 ** 27 (128mb)
25
27
  sodium_constant :OPSLIMIT_SENSITIVE # 8
26
28
  sodium_constant :MEMLIMIT_SENSITIVE # 2 ** 29 (512mb)
29
+ sodium_constant :MEMLIMIT_MIN # 8192
30
+ sodium_constant :MEMLIMIT_MAX # 4_294_967_296
31
+ sodium_constant :OPSLIMIT_MIN # 3
32
+ sodium_constant :OPSLIMIT_MAX # 10
27
33
 
28
34
  ARGON2_MIN_OUTLEN = 16
29
35
  ARGON2_MAX_OUTLEN = 0xFFFFFFFF
30
36
 
31
- MEMLIMIT_MIN = 8192
32
- MEMLIMIT_MAX = 4_294_967_296
33
- OPSLIMIT_MIN = 3
34
- OPSLIMIT_MAX = 10
35
-
36
37
  sodium_function_with_return_code(
37
38
  :pwhash,
38
- :crypto_pwhash_argon2i,
39
- [:pointer, :ulong_long, :pointer, :ulong_long, :pointer, :ulong_long, :size_t, :int]
39
+ :crypto_pwhash,
40
+ %i[pointer ulong_long pointer ulong_long pointer ulong_long size_t int]
40
41
  )
41
42
 
42
43
  sodium_function(
43
44
  :pwhash_str,
44
- :crypto_pwhash_argon2i_str,
45
- [:pointer, :pointer, :ulong_long, :ulong_long, :size_t]
45
+ :crypto_pwhash_str,
46
+ %i[pointer pointer ulong_long ulong_long size_t]
46
47
  )
47
48
 
48
49
  sodium_function(
49
50
  :pwhash_str_verify,
50
- :crypto_pwhash_argon2i_str_verify,
51
- [:pointer, :pointer, :ulong_long]
51
+ :crypto_pwhash_str_verify,
52
+ %i[pointer pointer ulong_long]
52
53
  )
53
54
 
54
- ALG_DEFAULT = ALG_ARGON2I13
55
-
56
55
  ARGON_ERROR_CODES = {
57
56
  -1 => "ARGON2_OUTPUT_PTR_NULL", -2 => "ARGON2_OUTPUT_TOO_SHORT",
58
57
  -3 => "ARGON2_OUTPUT_TOO_LONG", -4 => "ARGON2_PWD_TOO_SHORT",
@@ -103,19 +102,35 @@ module RbNaCl
103
102
  #
104
103
  # @param [String] password to be hashed
105
104
  # @param [String] salt to make the digest unique
105
+ # @param [Symbol] digest algorithm to use (may be :argon2i or :argon2id)
106
+ # if nil, the default is determined by libsodium
107
+ # (argon2i for libsodium < 1.0.15, and argon2id for
108
+ # libsodium >= 1.0.15).
106
109
  #
107
110
  # @return [String] scrypt digest of the string as raw bytes
108
- def digest(password, salt)
111
+ def digest(password, salt, algo = nil)
109
112
  raise ArgumentError, "digest_size is required" unless @digest_size
113
+
110
114
  digest = Util.zeros(@digest_size)
111
115
  salt = Util.check_string(salt, SALTBYTES, "salt")
112
116
 
117
+ if algo.nil?
118
+ algorithm = ALG_DEFAULT
119
+ elsif algo == :argon2i
120
+ algorithm = ALG_ARGON2I13
121
+ elsif algo == :argon2id && Sodium::Version::ARGON2ID_SUPPORTED
122
+ algorithm = ALG_ARGON2ID13
123
+ else
124
+ raise ArgumentError, "digest algorithm is not supported"
125
+ end
126
+
113
127
  status = self.class.pwhash(
114
128
  digest, @digest_size,
115
129
  password, password.bytesize, salt,
116
- @opslimit, @memlimit, ALG_DEFAULT
130
+ @opslimit, @memlimit, algorithm
117
131
  )
118
132
  raise CryptoError, ARGON_ERROR_CODES[status] if status.nonzero?
133
+
119
134
  digest
120
135
  end
121
136
 
@@ -127,6 +142,7 @@ module RbNaCl
127
142
  # @return [String] argon2 digest string
128
143
  def digest_str(password)
129
144
  raise ArgumentError, "password must be a String" unless password.is_a?(String)
145
+
130
146
  result = Util.zeros(STRBYTES)
131
147
 
132
148
  ok = self.class.pwhash_str(
@@ -135,6 +151,7 @@ module RbNaCl
135
151
  @opslimit, @memlimit
136
152
  )
137
153
  raise CryptoError, "unknown error in Argon2#digest_str" unless ok
154
+
138
155
  result.delete("\x00")
139
156
  end
140
157
 
@@ -147,6 +164,7 @@ module RbNaCl
147
164
  def self.digest_str_verify(password, digest_string)
148
165
  raise ArgumentError, "password must be a String" unless password.is_a?(String)
149
166
  raise ArgumentError, "digest_string must be a String" unless digest_string.is_a?(String)
167
+
150
168
  pwhash_str_verify(
151
169
  digest_string,
152
170
  password, password.bytesize
@@ -198,6 +216,7 @@ module RbNaCl
198
216
  digest_size = digest_size.to_i
199
217
  raise LengthError, "digest size too short" if digest_size < ARGON2_MIN_OUTLEN
200
218
  raise LengthError, "digest size too long" if digest_size > ARGON2_MAX_OUTLEN
219
+
201
220
  digest_size
202
221
  end
203
222
  end
@@ -26,7 +26,7 @@ module RbNaCl
26
26
 
27
27
  sodium_function :scrypt,
28
28
  :crypto_pwhash_scryptsalsa208sha256,
29
- [:pointer, :ulong_long, :pointer, :ulong_long, :pointer, :ulong_long, :size_t]
29
+ %i[pointer ulong_long pointer ulong_long pointer ulong_long size_t]
30
30
 
31
31
  # Create a new SCrypt password hash object
32
32
  #
@@ -1,8 +1,6 @@
1
1
  # encoding: binary
2
2
  # frozen_string_literal: true
3
3
 
4
- require "thread"
5
-
6
4
  module RbNaCl
7
5
  # Functions for random number generation
8
6
  #
@@ -15,7 +13,7 @@ module RbNaCl
15
13
 
16
14
  sodium_function :c_random_bytes,
17
15
  :randombytes_buf,
18
- [:pointer, :ulong_long]
16
+ %i[pointer size_t]
19
17
 
20
18
  # Returns a string of random bytes
21
19
  #
@@ -31,11 +31,11 @@ module RbNaCl
31
31
 
32
32
  sodium_function :secretbox_xsalsa20poly1305,
33
33
  :crypto_secretbox_xsalsa20poly1305,
34
- [:pointer, :pointer, :ulong_long, :pointer, :pointer]
34
+ %i[pointer pointer ulong_long pointer pointer]
35
35
 
36
36
  sodium_function :secretbox_xsalsa20poly1305_open,
37
37
  :crypto_secretbox_xsalsa20poly1305_open,
38
- [:pointer, :pointer, :ulong_long, :pointer, :pointer]
38
+ %i[pointer pointer ulong_long pointer pointer]
39
39
 
40
40
  # Create a new SecretBox
41
41
  #
@@ -32,11 +32,11 @@ module RbNaCl
32
32
 
33
33
  sodium_function :sign_ed25519,
34
34
  :crypto_sign_ed25519,
35
- [:pointer, :pointer, :pointer, :ulong_long, :pointer]
35
+ %i[pointer pointer pointer ulong_long pointer]
36
36
 
37
37
  sodium_function :sign_ed25519_seed_keypair,
38
38
  :crypto_sign_ed25519_seed_keypair,
39
- [:pointer, :pointer, :pointer]
39
+ %i[pointer pointer pointer]
40
40
 
41
41
  attr_reader :verify_key
42
42
 
@@ -21,7 +21,7 @@ module RbNaCl
21
21
 
22
22
  sodium_function :sign_ed25519_open,
23
23
  :crypto_sign_ed25519_open,
24
- [:pointer, :pointer, :pointer, :ulong_long, :pointer]
24
+ %i[pointer pointer pointer ulong_long pointer]
25
25
 
26
26
  # Create a new VerifyKey object from a public key.
27
27
  #
@@ -8,21 +8,21 @@ module RbNaCl
8
8
  module Sodium
9
9
  def self.extended(klass)
10
10
  klass.extend FFI::Library
11
- if defined?(RBNACL_LIBSODIUM_GEM_LIB_PATH)
12
- klass.ffi_lib RBNACL_LIBSODIUM_GEM_LIB_PATH
13
- else
14
- klass.ffi_lib "sodium"
15
- end
11
+ klass.ffi_lib "sodium"
16
12
  end
17
13
 
18
14
  def sodium_type(type = nil)
19
15
  return @type if type.nil?
16
+
20
17
  @type = type
21
18
  end
22
19
 
23
20
  def sodium_primitive(primitive = nil)
24
- return @primitive if primitive.nil?
25
- @primitive = primitive
21
+ if primitive.nil?
22
+ @primitive if defined?(@primitive)
23
+ else
24
+ @primitive = primitive
25
+ end
26
26
  end
27
27
 
28
28
  def primitive
@@ -30,28 +30,32 @@ module RbNaCl
30
30
  end
31
31
 
32
32
  def sodium_constant(constant, name = constant)
33
- fn = "crypto_#{sodium_type}_#{sodium_primitive}_#{constant.to_s.downcase}"
33
+ fn = if sodium_primitive
34
+ "crypto_#{sodium_type}_#{sodium_primitive}_#{constant.to_s.downcase}"
35
+ else
36
+ "crypto_#{sodium_type}_#{constant.to_s.downcase}"
37
+ end
34
38
  attach_function fn, [], :size_t
35
39
  const_set(name, public_send(fn))
36
40
  end
37
41
 
38
42
  def sodium_function(name, function, arguments)
39
- module_eval <<-eos, __FILE__, __LINE__ + 1
43
+ module_eval <<-RUBY, __FILE__, __LINE__ + 1
40
44
  attach_function #{function.inspect}, #{arguments.inspect}, :int
41
45
  def self.#{name}(*args)
42
46
  ret = #{function}(*args)
43
47
  ret == 0
44
48
  end
45
- eos
49
+ RUBY
46
50
  end
47
51
 
48
52
  def sodium_function_with_return_code(name, function, arguments)
49
- module_eval <<-eos, __FILE__, __LINE__ + 1
53
+ module_eval <<-RUBY, __FILE__, __LINE__ + 1
50
54
  attach_function #{function.inspect}, #{arguments.inspect}, :int
51
55
  def self.#{name}(*args)
52
56
  #{function}(*args)
53
57
  end
54
- eos
58
+ RUBY
55
59
  end
56
60
  end
57
61
  end
@@ -9,6 +9,7 @@ module RbNaCl
9
9
  module Version
10
10
  MINIMUM_LIBSODIUM_VERSION = [0, 4, 3].freeze
11
11
  MINIMUM_LIBSODIUM_VERSION_FOR_ARGON2 = [1, 0, 9].freeze
12
+ MINIMUM_LIBSODIUM_VERSION_FOR_ARGON2ID = [1, 0, 13].freeze
12
13
 
13
14
  extend Sodium
14
15
  attach_function :sodium_version_string, [], :string
@@ -23,7 +24,8 @@ module RbNaCl
23
24
  raise "Sorry, you need to install libsodium #{MINIMUM_LIBSODIUM_VERSION}+. You have #{Version::STRING} installed"
24
25
  end
25
26
 
26
- ARGON2_SUPPORTED = (INSTALLED_VERSION <=> MINIMUM_LIBSODIUM_VERSION_FOR_ARGON2) == -1 ? false : true
27
+ ARGON2_SUPPORTED = (INSTALLED_VERSION <=> MINIMUM_LIBSODIUM_VERSION_FOR_ARGON2) != -1
28
+ ARGON2ID_SUPPORTED = (INSTALLED_VERSION <=> MINIMUM_LIBSODIUM_VERSION_FOR_ARGON2ID) != -1
27
29
 
28
30
  # Determine if a given feature is supported based on Sodium version
29
31
  def self.supported_version?(version)
@@ -2,6 +2,7 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  # NaCl/libsodium for Ruby
5
+ # rubocop:disable Metrics/ModuleLength
5
6
  module RbNaCl
6
7
  # Reference library of test vectors used to verify the software is correct
7
8
  TEST_VECTORS = {
@@ -9,10 +10,10 @@ module RbNaCl
9
10
  # Curve25519 test vectors
10
11
  # Taken from the NaCl distribution
11
12
  #
12
- alice_private: "77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a",
13
- alice_public: "8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a",
14
- bob_private: "5dab087e624a8a4b79e17f8b83800ee66f3bb1292618b6fd1c2f8b27ff88e0eb",
15
- bob_public: "de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f",
13
+ alice_private: "77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a",
14
+ alice_public: "8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a",
15
+ bob_private: "5dab087e624a8a4b79e17f8b83800ee66f3bb1292618b6fd1c2f8b27ff88e0eb",
16
+ bob_public: "de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f",
16
17
  alice_mult_bob: "4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742",
17
18
 
18
19
  #
@@ -37,9 +38,11 @@ module RbNaCl
37
38
  # Ed25519 test vectors
38
39
  # Taken from the Python test vectors: http://ed25519.cr.yp.to/python/sign.input
39
40
  #
40
- sign_private: "b18e1d0045995ec3d010c387ccfeb984d783af8fbb0f40fa7db126d889f6dadd",
41
- sign_public: "77f48b59caeda77751ed138b0ec667ff50f8768c25d48309a8f386a2bad187fb",
42
- sign_message: "916c7d1d268fc0e77c1bef238432573c39be577bbea0998936add2b50a653171" \
41
+ sign_private: "b18e1d0045995ec3d010c387ccfeb984d783af8fbb0f40fa7db126d889f6dadd",
42
+ sign_public: "77f48b59caeda77751ed138b0ec667ff50f8768c25d48309a8f386a2bad187fb",
43
+ sign_keypair: "b18e1d0045995ec3d010c387ccfeb984d783af8fbb0f40fa7db126d889f6dadd" \
44
+ "77f48b59caeda77751ed138b0ec667ff50f8768c25d48309a8f386a2bad187fb",
45
+ sign_message: "916c7d1d268fc0e77c1bef238432573c39be577bbea0998936add2b50a653171" \
43
46
  "ce18a542b0b7f96c1691a3be6031522894a8634183eda38798a0c5d5d79fbd01" \
44
47
  "dd04a8646d71873b77b221998a81922d8105f892316369d5224c9983372d2313" \
45
48
  "c6b1f4556ea26ba49d46e8b561e0fc76633ac9766e68e21fba7edca93c4c7460" \
@@ -52,26 +55,26 @@ module RbNaCl
52
55
  # Taken from the NSRL test vectors: http://www.nsrl.nist.gov/testdata/
53
56
  sha256_message: "6162636462636465636465666465666765666768666768696768696a68696a6b" \
54
57
  "696a6b6c6a6b6c6d6b6c6d6e6c6d6e6f6d6e6f706e6f7071",
55
- sha256_digest: "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1",
56
- sha256_empty: "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
58
+ sha256_digest: "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1",
59
+ sha256_empty: "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
57
60
 
58
61
  #
59
62
  # SHA512 test vectors
60
63
  # self-created (FIXME: find standard test vectors)
61
64
  sha512_message: "54686520717569636b2062726f776e20666f78206a756d7073206f7665722074" \
62
65
  "6865206c617a7920646f672e",
63
- sha512_digest: "91ea1245f20d46ae9a037a989f54f1f790f0a47607eeb8a14d12890cea77a1bb" \
66
+ sha512_digest: "91ea1245f20d46ae9a037a989f54f1f790f0a47607eeb8a14d12890cea77a1bb" \
64
67
  "c6c7ed9cf205e67b7f2b8fd4c7dfd3a7a8617e45f3c463d481c7e586c39ac1ed",
65
- sha512_empty: "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce" \
68
+ sha512_empty: "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce" \
66
69
  "47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e",
67
70
 
68
71
  # Blake2b test vectors
69
72
  # self-created? (TODO: double check, fix)
70
73
  blake2b_message: "54686520717569636b2062726f776e20666f78206a756d7073206f7665722074" \
71
74
  "6865206c617a7920646f67",
72
- blake2b_digest: "a8add4bdddfd93e4877d2746e62817b116364a1fa7bc148d95090bc7333b3673" \
75
+ blake2b_digest: "a8add4bdddfd93e4877d2746e62817b116364a1fa7bc148d95090bc7333b3673" \
73
76
  "f82401cf7aa2e4cb1ecd90296e3f14cb5413f8ed77be73045b13914cdcd6a918",
74
- blake2b_empty: "786a02f742015903c6c6fd852552d272912f4740e15847618a86e217f71f5419" \
77
+ blake2b_empty: "786a02f742015903c6c6fd852552d272912f4740e15847618a86e217f71f5419" \
75
78
  "d25e1031afee585313896444934eb04b903a685b1448b755d56f701afe9be2ce",
76
79
 
77
80
  # from the Blake2 paper(?) (TODO: double check)
@@ -83,23 +86,23 @@ module RbNaCl
83
86
  "a0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebf" \
84
87
  "c0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedf" \
85
88
  "e0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfe",
86
- blake2b_key: "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" \
89
+ blake2b_key: "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" \
87
90
  "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
88
- blake2b_keyed_digest: "142709d62e28fcccd0af97fad0f8465b971e82201dc51070faa0372aa43e9248" \
91
+ blake2b_keyed_digest: "142709d62e28fcccd0af97fad0f8465b971e82201dc51070faa0372aa43e9248" \
89
92
  "4be1c1e73ba10906d5d1853db6a4106e0a7bf9800d373d6dee2d46d62ef2a461",
90
93
 
91
94
  # Generated using the blake2 reference code
92
- blake2b_personal: "000102030405060708090a0b0c0d0e0f",
95
+ blake2b_personal: "000102030405060708090a0b0c0d0e0f",
93
96
 
94
- blake2b_personal_digest: "7c86d3f929c9ac7f08c7940095da7c1cad2cf29db2e7a25fb05d99163e587cbd" \
97
+ blake2b_personal_digest: "7c86d3f929c9ac7f08c7940095da7c1cad2cf29db2e7a25fb05d99163e587cbd" \
95
98
  "f3564e8ce727b734a0559ee76f6ff5aeebd4e1e8872f1829174c9b1a9dab80e3",
96
99
 
97
- blake2b_salt: "000102030405060708090a0b0c0d0e0f",
100
+ blake2b_salt: "000102030405060708090a0b0c0d0e0f",
98
101
 
99
- blake2b_salt_digest: "16e2e2cfb97e6061bccf2fcc1e605e117dee806c959ef2ad01249d4d12ce98cb" \
102
+ blake2b_salt_digest: "16e2e2cfb97e6061bccf2fcc1e605e117dee806c959ef2ad01249d4d12ce98cb" \
100
103
  "c993f400003ba57449f60a7b071ffdaff9c0acb16891a01a9b397ffe89db96bb",
101
104
 
102
- blake2b_personal_short: "0001020304050607",
105
+ blake2b_personal_short: "0001020304050607",
103
106
 
104
107
  blake2b_personal_short_digest: "41b984967f852308710a6042d25f5faf4a84900b2001039075dab13aecfab7c8" \
105
108
  "40def9506326563fbb355b3da629181d97d2556e4624711d68f8f655b7cbb435",
@@ -114,28 +117,43 @@ module RbNaCl
114
117
  scrypt_password: "4a857e2ee8aa9b6056f2424e84d24a72473378906ee04a46cb05311502d5250b" \
115
118
  "82ad86b83c8f20a23dbb74f6da60b0b6ecffd67134d45946ac8ebfb3064294bc" \
116
119
  "097d43ced68642bfb8bbbdd0f50b30118f5e",
117
- scrypt_salt: "39d82eef32010b8b79cc5ba88ed539fbaba741100f2edbeca7cc171ffeabf258",
120
+ scrypt_salt: "39d82eef32010b8b79cc5ba88ed539fbaba741100f2edbeca7cc171ffeabf258",
118
121
  scrypt_opslimit: 758_010,
119
122
  scrypt_memlimit: 5_432_947,
120
- scrypt_digest: "bcc5c2fd785e4781d1201ed43d84925537e2a540d3de55f5812f29e9dd0a4a00" \
123
+ scrypt_digest: "bcc5c2fd785e4781d1201ed43d84925537e2a540d3de55f5812f29e9dd0a4a00" \
121
124
  "451a5c8ddbb4862c03d45c75bf91b7fb49265feb667ad5c899fdbf2ca19eac67",
122
125
 
123
126
  # argon2 vectors
124
- # from libsodium/test/default/pwhash.c
125
- argon2_password: "a347ae92bce9f80f6f595a4480fc9c2fe7e7d7148d371e9487d75f5c23008ffae0" \
127
+ # from libsodium/test/default/pwhash_argon2i.c
128
+ argon2i_password: "a347ae92bce9f80f6f595a4480fc9c2fe7e7d7148d371e9487d75f5c23008ffae0" \
126
129
  "65577a928febd9b1973a5a95073acdbeb6a030cfc0d79caa2dc5cd011cef02c08d" \
127
130
  "a232d76d52dfbca38ca8dcbd665b17d1665f7cf5fe59772ec909733b24de97d6f5" \
128
131
  "8d220b20c60d7c07ec1fd93c52c31020300c6c1facd77937a597c7a6",
129
- argon2_salt: "5541fbc995d5c197ba290346d2c559de",
130
- argon2_outlen: 155,
131
- argon2_opslimit: 5,
132
- argon2_memlimit: 7_256_678,
133
- argon2_digest: "23b803c84eaa25f4b44634cc1e5e37792c53fcd9b1eb20f865329c68e09cbfa9f19" \
132
+ argon2i_salt: "5541fbc995d5c197ba290346d2c559de",
133
+ argon2i_outlen: 155,
134
+ argon2i_opslimit: 5,
135
+ argon2i_memlimit: 7_256_678,
136
+ argon2i_digest: "23b803c84eaa25f4b44634cc1e5e37792c53fcd9b1eb20f865329c68e09cbfa9f19" \
134
137
  "68757901b383fce221afe27713f97914a041395bbe1fb70e079e5bed2c7145b1f61" \
135
138
  "54046f5958e9b1b29055454e264d1f2231c316f26be2e3738e83a80315e9a0951ce" \
136
139
  "4b137b52e7d5ee7b37f7d936dcee51362bcf792595e3c896ad5042734fc90c92cae" \
137
140
  "572ce63ff659a2f7974a3bd730d04d525d253ccc38",
138
141
 
142
+ # from libsodium/test/default/pwhash_argon2id.c
143
+ argon2id_password: "a347ae92bce9f80f6f595a4480fc9c2fe7e7d7148d371e9487d75f5c23008ffae0" \
144
+ "65577a928febd9b1973a5a95073acdbeb6a030cfc0d79caa2dc5cd011cef02c08d" \
145
+ "a232d76d52dfbca38ca8dcbd665b17d1665f7cf5fe59772ec909733b24de97d6f5" \
146
+ "8d220b20c60d7c07ec1fd93c52c31020300c6c1facd77937a597c7a6",
147
+ argon2id_salt: "5541fbc995d5c197ba290346d2c559de",
148
+ argon2id_outlen: 155,
149
+ argon2id_opslimit: 5,
150
+ argon2id_memlimit: 7_256_678,
151
+ argon2id_digest: "18acec5d6507739f203d1f5d9f1d862f7c2cdac4f19d2bdff64487e60d969e3ced6" \
152
+ "15337b9eec6ac4461c6ca07f0939741e57c24d0005c7ea171a0ee1e7348249d135b" \
153
+ "38f222e4dad7b9a033ed83f5ca27277393e316582033c74affe2566a2bea47f91f0" \
154
+ "fd9fe49ece7e1f79f3ad6e9b23e0277c8ecc4b313225748dd2a80f5679534a0700e" \
155
+ "246a79a49b3f74eb89ec6205fe1eeb941c73b1fcf1",
156
+
139
157
  # argon2_str vectors
140
158
  # from libsodium/test/default/pwhash.c
141
159
  argon2_str_digest: "$argon2i$v=19$m=4096,t=3,p=2$b2RpZHVlamRpc29kaXNrdw" \
@@ -145,8 +163,8 @@ module RbNaCl
145
163
  # Auth test vectors
146
164
  # Taken from NaCl distribution
147
165
  #
148
- auth_key_32: "eea6a7251c1e72916d11c2cb214d3c252539121d8e234e652d651fa4c8cff880",
149
- auth_key_64: "eaaa4c73ef13e7e9a53011304c5be141da9c3713b5ca822037ed57aded31b70a" \
166
+ auth_key_32: "eea6a7251c1e72916d11c2cb214d3c252539121d8e234e652d651fa4c8cff880",
167
+ auth_key_64: "eaaa4c73ef13e7e9a53011304c5be141da9c3713b5ca822037ed57aded31b70a" \
150
168
  "50a0dd80843d580fe5b57e470bb534333e907a624cf02873c6b9eaba70e0fc7e",
151
169
  auth_message: "8e993b9f48681273c29650ba32fc76ce48332ea7164d96a4476fb8c531a1186a" \
152
170
  "c0dfc17c98dce87b4da7f011ec48c97271d2c20f9b928fe2270d6fb863d51738" \
@@ -155,32 +173,74 @@ module RbNaCl
155
173
  "e355a5",
156
174
  auth_onetime: "f3ffc7703f9400e52a7dfb4b3d3305d9",
157
175
  # self-created (FIXME: find standard test vectors)
158
- auth_hmacsha256: "7f7b9b707e8790ca8620ff94df5e6533ddc8e994060ce310c9d7de04d44aabc3",
176
+ auth_hmacsha256: "7f7b9b707e8790ca8620ff94df5e6533ddc8e994060ce310c9d7de04d44aabc3",
159
177
  auth_hmacsha512256: "b2a31b8d4e01afcab2ee545b5caf4e3d212a99d7b3a116a97cec8e83c32e107d",
160
- auth_hmacsha512: "b2a31b8d4e01afcab2ee545b5caf4e3d212a99d7b3a116a97cec8e83c32e107d" \
178
+ auth_hmacsha512: "b2a31b8d4e01afcab2ee545b5caf4e3d212a99d7b3a116a97cec8e83c32e107d" \
161
179
  "270e3921f69016c267a63ab4b226449a0dee0dc7dcb897a9bce9d27d788f8e8d",
162
180
 
181
+ # HMAC-SHA Identifiers and Test Vectors
182
+ # ref: https://tools.ietf.org/html/rfc4231#section-4.8
183
+ #
184
+ auth_hmac_key: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" \
185
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" \
186
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" \
187
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" \
188
+ "aaaaaa",
189
+ auth_hmac_data: "5468697320697320612074657374207573696e672061206c6172676572207468" \
190
+ "616e20626c6f636b2d73697a65206b657920616e642061206c61726765722074" \
191
+ "68616e20626c6f636b2d73697a6520646174612e20546865206b6579206e6565" \
192
+ "647320746f20626520686173686564206265666f7265206265696e6720757365" \
193
+ "642062792074686520484d414320616c676f726974686d2e",
194
+ auth_hmacsha256_tag: "9b09ffa71b942fcb27635fbcd5b0e944bfdc63644f0713938a7f51535c3a35e2",
195
+ auth_hmacsha512_tag: "e37b6a775dc87dbaa4dfa9f96e5e3ffddebd71f8867289865df5a32d20cdc944" \
196
+ "b6022cac3c4982b10d5eeb55c3e4de15134676fb6de0446065c97440fa8c6a58",
197
+ auth_hmacsha512256_tag: "bfaae3b4292b56d6170154cc089af73f79e089ecf27d4720eed6fd0a7ffcccf1",
198
+
199
+ auth_hmacsha256_mult_tag: "367a7a7e8292759844dcf820c90daa5fea5a4b769e537038cd0dc28290fbf2cb",
200
+ auth_hmacsha512_mult_tag: "1006b7bef1e24725ed55049c8b787b7b174f4afbe197124a389205c499956a90" \
201
+ "fea5c44b616a9e1a286d024c2880c67ae0e1ec7524530f15ae1086b144192d93",
202
+ auth_hmacsha512256_mult_tag: "bf280508996bba2bd590a2c1662d8c47fcceb8111bfcc4bdff5f2c28b0301449",
163
203
  # AEAD ChaCha20-Poly1305 original implementation test vectors
164
204
  # Taken from https://tools.ietf.org/html/draft-agl-tls-chacha20poly1305-04
165
- aead_chacha20poly1305_orig_key: "4290bcb154173531f314af57f3be3b5006da371ece272afa1b5dbdd1100a1007",
166
- aead_chacha20poly1305_orig_message: "86d09974840bded2a5ca",
167
- aead_chacha20poly1305_orig_nonce: "cd7cf67be39c794a",
168
- aead_chacha20poly1305_orig_ad: "87e229d4500845a079c0",
169
- aead_chacha20poly1305_orig_ciphertext: "e3e446f7ede9a19b62a4677dabf4e3d24b876bb284753896e1d6",
205
+ aead_chacha20poly1305_orig_key: "4290bcb154173531f314af57f3be3b5006da371ece272afa1b5dbdd1100a1007",
206
+ aead_chacha20poly1305_orig_message: "86d09974840bded2a5ca",
207
+ aead_chacha20poly1305_orig_nonce: "cd7cf67be39c794a",
208
+ aead_chacha20poly1305_orig_ad: "87e229d4500845a079c0",
209
+ aead_chacha20poly1305_orig_ciphertext: "e3e446f7ede9a19b62a4677dabf4e3d24b876bb284753896e1d6",
170
210
 
171
211
  # AEAD ChaCha20-Poly1305 IETF test vectors
172
212
  # Taken from https://tools.ietf.org/html/rfc7539
173
- aead_chacha20poly1305_ietf_key: "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f",
174
- aead_chacha20poly1305_ietf_message: "4c616469657320616e642047656e746c656d656e206f662074686520636c6173" \
213
+ aead_chacha20poly1305_ietf_key: "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f",
214
+ aead_chacha20poly1305_ietf_message: "4c616469657320616e642047656e746c656d656e206f662074686520636c6173" \
175
215
  "73206f66202739393a204966204920636f756c64206f6666657220796f75206f" \
176
216
  "6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73" \
177
217
  "637265656e20776f756c642062652069742e",
178
- aead_chacha20poly1305_ietf_nonce: "070000004041424344454647",
179
- aead_chacha20poly1305_ietf_ad: "50515253c0c1c2c3c4c5c6c7",
180
- aead_chacha20poly1305_ietf_ciphertext: "d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d6" \
218
+ aead_chacha20poly1305_ietf_nonce: "070000004041424344454647",
219
+ aead_chacha20poly1305_ietf_ad: "50515253c0c1c2c3c4c5c6c7",
220
+ aead_chacha20poly1305_ietf_ciphertext: "d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d6" \
181
221
  "3dbea45e8ca9671282fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b36" \
182
222
  "92ddbd7f2d778b8c9803aee328091b58fab324e4fad675945585808b4831d7bc" \
183
223
  "3ff4def08e4b7a9de576d26586cec64b61161ae10b594f09e26a7e902ecbd060" \
184
- "0691"
224
+ "0691",
225
+
226
+ # Jank AEAD XChaCha20-Poly1305 test vectors
227
+ # Unfortunately, I couldn't find any public variants of these, so I used:
228
+ # https://github.com/jedisct1/libsodium/blob/1.0.16/test/default/aead_xchacha20poly1305.c
229
+ # Doubly unfortunately, that doesn't even have a ciphertext vector. I
230
+ # generated one using crypto_aead_xchacha20poly1305_ietf_encrypt on
231
+ # libsodium 1.0.16
232
+ aead_xchacha20poly1305_ietf_key: "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f",
233
+ aead_xchacha20poly1305_ietf_message: "4c616469657320616e642047656e746c656d656e206f662074686520636c6173" \
234
+ "73206f66202739393a204966204920636f756c64206f6666657220796f75206f" \
235
+ "6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73" \
236
+ "637265656e20776f756c642062652069742e",
237
+ aead_xchacha20poly1305_ietf_nonce: "07000000404142434445464748494a4b0000000000000000",
238
+ aead_xchacha20poly1305_ietf_ad: "50515253c0c1c2c3c4c5c6c7",
239
+ aead_xchacha20poly1305_ietf_ciphertext: "453c0693a7407f04ff4c56aedb17a3c0a1afff01174930fc22287c33dbcf0ac8" \
240
+ "b89ad929530a1bb3ab5e69f24c7f6070c8f840c9abb4f69fbfc8a7ff5126faee" \
241
+ "bbb55805ee9c1cf2ce5a57263287aec5780f04ec324c3514122cfc3231fc1a8b" \
242
+ "718a62863730a2702bb76366116bed09e0fd5c6d84b6b0c1abaf249d5dd0f7f5" \
243
+ "a7ea"
185
244
  }.freeze
186
245
  end
246
+ # rubocop:enable Metrics/ModuleLength