rbnacl 5.0.0 → 6.0.0

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