rbnacl 1.1.0 → 2.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 (80) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/.travis.yml +1 -5
  4. data/CHANGES.md +27 -0
  5. data/Gemfile +4 -1
  6. data/Guardfile +8 -0
  7. data/README.md +52 -3
  8. data/lib/rbnacl/auth.rb +22 -19
  9. data/lib/rbnacl/{keys → boxes/curve25519xsalsa20poly1305}/private_key.rb +26 -23
  10. data/lib/rbnacl/{keys → boxes/curve25519xsalsa20poly1305}/public_key.rb +13 -12
  11. data/lib/rbnacl/boxes/curve25519xsalsa20poly1305.rb +185 -0
  12. data/lib/rbnacl/group_elements/curve25519.rb +81 -0
  13. data/lib/rbnacl/hash/blake2b.rb +64 -0
  14. data/lib/rbnacl/hash/sha256.rb +15 -0
  15. data/lib/rbnacl/hash/sha512.rb +15 -0
  16. data/lib/rbnacl/hash.rb +30 -14
  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 +12 -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 +67 -43
  27. data/lib/rbnacl/serializable.rb +4 -12
  28. data/lib/rbnacl/signatures/ed25519/signing_key.rb +104 -0
  29. data/lib/rbnacl/signatures/ed25519/verify_key.rb +78 -0
  30. data/lib/rbnacl/signatures/ed25519.rb +15 -0
  31. data/lib/rbnacl/sodium/version.rb +23 -0
  32. data/lib/rbnacl/sodium.rb +43 -0
  33. data/lib/rbnacl/test_vectors.rb +34 -1
  34. data/lib/rbnacl/util.rb +50 -7
  35. data/lib/rbnacl/version.rb +2 -2
  36. data/lib/rbnacl.rb +64 -29
  37. data/rbnacl.gemspec +6 -5
  38. data/spec/rbnacl/{auth/one_time_spec.rb → authenticators/poly1305_spec.rb} +2 -2
  39. data/spec/rbnacl/boxes/curve25519xsalsa20poly1305/private_key_spec.rb +65 -0
  40. data/spec/rbnacl/{keys → boxes/curve25519xsalsa20poly1305}/public_key_spec.rb +10 -13
  41. data/spec/rbnacl/boxes/curve25519xsalsa20poly1305_spec.rb +39 -0
  42. data/spec/rbnacl/{point_spec.rb → group_element_spec.rb} +6 -8
  43. data/spec/rbnacl/hash/blake2b_spec.rb +30 -0
  44. data/spec/rbnacl/hash_spec.rb +13 -33
  45. data/spec/rbnacl/hmac/sha256_spec.rb +2 -2
  46. data/spec/rbnacl/hmac/sha512256_spec.rb +2 -2
  47. data/spec/rbnacl/random_nonce_box_spec.rb +21 -26
  48. data/spec/rbnacl/random_spec.rb +3 -3
  49. data/spec/rbnacl/secret_box_spec.rb +6 -6
  50. data/spec/rbnacl/signatures/ed25519/signing_key_spec.rb +30 -0
  51. data/spec/rbnacl/signatures/ed25519/verify_key_spec.rb +39 -0
  52. data/spec/rbnacl/util_spec.rb +67 -53
  53. data/spec/shared/authenticator.rb +36 -55
  54. data/spec/shared/box.rb +10 -10
  55. data/spec/shared/key_equality.rb +3 -3
  56. data/spec/shared/serializable.rb +17 -0
  57. data/spec/spec_helper.rb +15 -16
  58. data/tasks/rspec.rake +1 -0
  59. data.tar.gz.sig +2 -3
  60. metadata +41 -42
  61. metadata.gz.sig +2 -2
  62. data/lib/rbnacl/box.rb +0 -171
  63. data/lib/rbnacl/encoder.rb +0 -44
  64. data/lib/rbnacl/encoders/base32.rb +0 -33
  65. data/lib/rbnacl/encoders/base64.rb +0 -30
  66. data/lib/rbnacl/encoders/hex.rb +0 -30
  67. data/lib/rbnacl/encoders/raw.rb +0 -12
  68. data/lib/rbnacl/keys/signing_key.rb +0 -95
  69. data/lib/rbnacl/keys/verify_key.rb +0 -96
  70. data/lib/rbnacl/nacl.rb +0 -146
  71. data/lib/rbnacl/point.rb +0 -70
  72. data/lib/rbnacl/secret_box.rb +0 -119
  73. data/spec/rbnacl/box_spec.rb +0 -42
  74. data/spec/rbnacl/encoder_spec.rb +0 -14
  75. data/spec/rbnacl/encoders/base32_spec.rb +0 -16
  76. data/spec/rbnacl/encoders/base64_spec.rb +0 -15
  77. data/spec/rbnacl/encoders/hex_spec.rb +0 -15
  78. data/spec/rbnacl/keys/private_key_spec.rb +0 -68
  79. data/spec/rbnacl/keys/signing_key_spec.rb +0 -39
  80. data/spec/rbnacl/keys/verify_key_spec.rb +0 -51
@@ -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,87 @@ 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'
67
-
68
- unless verify_key.verify(message, bad_signature, :hex) == false
69
- raise SelfTestFailure, "failed to detect an invalid signature"
83
+ begin
84
+ passed = false
85
+ bad_signature = signature[0,63] + '0'
86
+ verify_key.verify(bad_signature, message)
87
+ rescue CryptoError
88
+ passed = true
89
+ ensure
90
+ passed or raise SelfTestFailure, "failed to detect corrupt ciphertext"
70
91
  end
71
92
  end
72
93
 
73
94
  def sha256_test
74
- message = hexdecode_vector :sha256_message
75
- digest = hexdecode_vector :sha256_digest
95
+ message = vector :sha256_message
96
+ digest = vector :sha256_digest
76
97
 
77
- unless Crypto::Hash.sha256(message) == digest
98
+ unless RbNaCl::Hash.sha256(message) == digest
99
+ #:nocov:
78
100
  raise SelfTestFailure, "failed to generate a correct SHA256 digest"
101
+ #:nocov:
79
102
  end
80
103
  end
81
104
 
82
105
  def hmac_test(klass, tag)
83
- authenticator = klass.new(TestVectors[:auth_key], :hex)
106
+ authenticator = klass.new(vector(:auth_key))
84
107
 
85
- message = hexdecode_vector :auth_message
108
+ message = vector :auth_message
86
109
 
87
- unless authenticator.auth(message, :hex) == TestVectors[tag]
110
+ unless authenticator.auth(message) == vector(tag)
111
+ #:nocov:
88
112
  raise SelfTestFailure, "#{klass} failed to generate correct authentication tag"
113
+ #:nocov:
89
114
  end
90
115
 
91
- unless authenticator.verify(message, TestVectors[tag], :hex)
116
+ unless authenticator.verify(vector(tag), message)
117
+ #:nocov:
92
118
  raise SelfTestFailure, "#{klass} failed to verify correct authentication tag"
119
+ #:nocov:
93
120
  end
94
121
 
95
- if authenticator.verify(message+' ', TestVectors[tag], :hex)
96
- raise SelfTestFailure, "#{klass} failed to detect invalid authentication tag"
122
+ begin
123
+ passed = false
124
+ authenticator.verify(vector(tag), message + ' ')
125
+ rescue CryptoError
126
+ passed = true
127
+ ensure
128
+ passed or raise SelfTestFailure, "failed to detect corrupt ciphertext"
97
129
  end
98
130
  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
131
  end
108
132
  end
109
133
 
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
134
+ RbNaCl::SelfTest.box_test
135
+ RbNaCl::SelfTest.secret_box_test
136
+ RbNaCl::SelfTest.digital_signature_test
137
+ RbNaCl::SelfTest.sha256_test
138
+ RbNaCl::SelfTest.hmac_test RbNaCl::HMAC::SHA256, :auth_hmacsha256
139
+ RbNaCl::SelfTest.hmac_test RbNaCl::HMAC::SHA512256, :auth_hmacsha512256
140
+ RbNaCl::SelfTest.hmac_test RbNaCl::OneTimeAuth, :auth_onetime
117
141
 
118
142
  puts "POST Completed in #{Time.now - start} s" if $DEBUG
@@ -1,23 +1,15 @@
1
1
  # encoding: binary
2
- module Crypto
2
+ module RbNaCl
3
3
  # Serialization features shared across all "key-like" classes
4
4
  module Serializable
5
- # Return a string representation of this key, possibly encoded into a
6
- # given serialization format.
7
- #
8
- # @param encoding [String] string encoding format in which to encode the key
9
- #
10
- # @return [String] key encoded in the specified format
11
- def to_s(encoding = :raw)
12
- Encoder[encoding].encode(to_bytes)
13
- end
14
- alias_method :to_str, :to_s
5
+ def to_s; to_bytes; end
6
+ def to_str; to_bytes; end
15
7
 
16
8
  # Inspect this key
17
9
  #
18
10
  # @return [String] a string representing this key
19
11
  def inspect
20
- "#<#{self.class}:#{to_s(:hex)[0,8]}>"
12
+ "#<#{self.class}:#{Util.bin2hex(to_bytes)[0,8]}>"
21
13
  end
22
14
  end
23
15
  end
@@ -0,0 +1,104 @@
1
+ # encoding: binary
2
+ module RbNaCl
3
+ module Signatures
4
+ module Ed25519
5
+ # Private key for producing digital signatures using the Ed25519 algorithm.
6
+ # Ed25519 provides a 128-bit security level, that is to say, all known attacks
7
+ # take at least 2^128 operations, providing the same security level as
8
+ # AES-128, NIST P-256, and RSA-3072.
9
+ #
10
+ # Signing keys are produced from a 32-byte (256-bit) random seed value.
11
+ # This value can be passed into the SigningKey constructor as a String
12
+ # whose bytesize is 32.
13
+ #
14
+ # The public VerifyKey can be computed from the private 32-byte seed value
15
+ # as well, eliminating the need to store a "keypair".
16
+ #
17
+ # SigningKey produces 64-byte (512-bit) signatures. The signatures are
18
+ # deterministic: signing the same message will always produce the same
19
+ # signature. This prevents "entropy failure" seen in other signature
20
+ # algorithms like DSA and ECDSA, where poor random number generators can
21
+ # leak enough information to recover the private key.
22
+ class SigningKey
23
+ include KeyComparator
24
+ include Serializable
25
+
26
+ extend Sodium
27
+
28
+ sodium_type :sign
29
+ sodium_primitive :ed25519
30
+
31
+ sodium_function :sign_ed25519,
32
+ :crypto_sign_ed25519,
33
+ [:pointer, :pointer, :pointer, :ulong_long, :pointer]
34
+
35
+ sodium_function :sign_ed25519_seed_keypair,
36
+ :crypto_sign_ed25519_seed_keypair,
37
+ [:pointer, :pointer, :pointer]
38
+
39
+ attr_reader :verify_key
40
+
41
+ # Generate a random SigningKey
42
+ #
43
+ # @return [RbNaCl::SigningKey] Freshly-generated random SigningKey
44
+ def self.generate
45
+ new RbNaCl::Random.random_bytes(Ed25519::SEEDBYTES)
46
+ end
47
+
48
+ # Create a SigningKey from a seed value
49
+ #
50
+ # @param seed [String] Random 32-byte value (i.e. private key)
51
+ #
52
+ # @return [RbNaCl::SigningKey] Key which can sign messages
53
+ def initialize(seed)
54
+ seed = seed.to_s
55
+
56
+ Util.check_length(seed, Ed25519::SEEDBYTES, "seed")
57
+
58
+ pk = Util.zeros(Ed25519::VERIFYKEYBYTES)
59
+ sk = Util.zeros(Ed25519::SIGNINGKEYBYTES)
60
+
61
+ self.class.sign_ed25519_seed_keypair(pk, sk, seed) || raise(CryptoError, "Failed to generate a key pair")
62
+
63
+ @seed, @signing_key = seed, sk
64
+ @verify_key = VerifyKey.new(pk)
65
+ end
66
+
67
+ # Sign a message using this key
68
+ #
69
+ # @param message [String] Message to be signed by this key
70
+ #
71
+ # @return [String] Signature as bytes
72
+ def sign(message)
73
+ buffer = Util.prepend_zeros(signature_bytes, message)
74
+ buffer_len = Util.zeros(FFI::Type::LONG_LONG.size)
75
+
76
+ self.class.sign_ed25519(buffer, buffer_len, message, message.bytesize, @signing_key)
77
+
78
+ buffer[0, signature_bytes]
79
+ end
80
+
81
+ # Return the raw seed value of this key
82
+ #
83
+ # @return [String] seed used to create this key
84
+ def to_bytes; @seed; end
85
+
86
+ # The crypto primitive this SigningKey class uses for signatures
87
+ #
88
+ # @return [Symbol] The primitive
89
+ def primitive; self.class.primitive; end
90
+
91
+ # The size of signatures generated by the SigningKey class
92
+ #
93
+ # @return [Integer] The number of bytes in a signature
94
+ def self.signature_bytes; Ed25519::SIGNATUREBYTES; end
95
+
96
+ # The size of signatures generated by the SigningKey instance
97
+ #
98
+ # @return [Integer] The number of bytes in a signature
99
+ def signature_bytes; Ed25519::SIGNATUREBYTES; end
100
+
101
+ end
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,78 @@
1
+ # encoding: binary
2
+ module RbNaCl
3
+ module Signatures
4
+ module Ed25519
5
+ # The public key counterpart to an Ed25519 SigningKey for producing digital
6
+ # signatures. Like the name says, VerifyKeys can be used to verify that a
7
+ # given digital signature is authentic.
8
+ #
9
+ # For more information on the Ed25519 digital signature system, please see
10
+ # the SigningKey documentation.
11
+ class VerifyKey
12
+ include KeyComparator
13
+ include Serializable
14
+
15
+ extend Sodium
16
+
17
+ sodium_type :sign
18
+ sodium_primitive :ed25519
19
+
20
+ sodium_function :sign_ed25519_open,
21
+ :crypto_sign_ed25519_open,
22
+ [:pointer, :pointer, :pointer, :ulong_long, :pointer]
23
+
24
+ # Create a new VerifyKey object from a public key.
25
+ #
26
+ # @param key [String] Ed25519 public key
27
+ #
28
+ # @return [RbNaCl::VerifyKey] Key which can verify messages
29
+ def initialize(key)
30
+ @key = key.to_str
31
+ Util.check_length(@key, Ed25519::VERIFYKEYBYTES, "key")
32
+ end
33
+
34
+ # Verify a signature for a given message
35
+ #
36
+ # Raises if the signature is invalid.
37
+ #
38
+ # @param signature [String] Alleged signature to be checked
39
+ # @param message [String] Message to be authenticated
40
+ #
41
+ # @raise [BadSignatureError] if the signature check fails
42
+ # @raise [LengthError] if the signature is of the wrong length
43
+ #
44
+ # @return [Boolean] was the signature authentic?
45
+ def verify(signature, message)
46
+ signature = signature.to_str
47
+ Util.check_length(signature, signature_bytes, "signature")
48
+
49
+ sig_and_msg = signature + message
50
+ buffer = Util.zeros(sig_and_msg.bytesize)
51
+ buffer_len = Util.zeros(FFI::Type::LONG_LONG.size)
52
+
53
+ self.class.sign_ed25519_open(buffer, buffer_len, sig_and_msg, sig_and_msg.bytesize, @key) || raise(BadSignatureError, "signature was forged/corrupt")
54
+ end
55
+
56
+ # Return the raw key in byte format
57
+ #
58
+ # @return [String] raw key as bytes
59
+ def to_bytes; @key; end
60
+
61
+ # The crypto primitive this VerifyKey class uses for signatures
62
+ #
63
+ # @return [Symbol] The primitive
64
+ def primitive; self.class.primitive; end
65
+
66
+ # The size of signatures verified by the VerifyKey class
67
+ #
68
+ # @return [Integer] The number of bytes in a signature
69
+ def self.signature_bytes; Ed25519::SIGNATUREBYTES; end
70
+
71
+ # The size of signatures verified by the VerifyKey instance
72
+ #
73
+ # @return [Integer] The number of bytes in a signature
74
+ def signature_bytes; Ed25519::SIGNATUREBYTES; end
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,15 @@
1
+ # encoding: binary
2
+ module RbNaCl
3
+ module Signatures
4
+ module Ed25519
5
+ extend Sodium
6
+
7
+ sodium_type :sign
8
+ sodium_primitive :ed25519
9
+ sodium_constant :SEEDBYTES
10
+ sodium_constant :PUBLICKEYBYTES, :VERIFYKEYBYTES
11
+ sodium_constant :SECRETKEYBYTES, :SIGNINGKEYBYTES
12
+ sodium_constant :BYTES, :SIGNATUREBYTES
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,23 @@
1
+ require 'rbnacl/sodium'
2
+
3
+ module RbNaCl
4
+ module Sodium
5
+ module Version
6
+ MINIMUM_LIBSODIUM_VERSION = "0.4.3"
7
+
8
+ extend Sodium
9
+ attach_function :sodium_version_string, [], :string
10
+
11
+ STRING = sodium_version_string
12
+ MAJOR, MINOR, PATCH = STRING.split(".").map(&:to_i)
13
+
14
+ installed_version = [MAJOR, MINOR, PATCH]
15
+ minimum_version = MINIMUM_LIBSODIUM_VERSION.split(".").map(&:to_i)
16
+
17
+ case installed_version <=> minimum_version
18
+ when -1
19
+ raise "Sorry, you need to install libsodium #{MINIMUM_LIBSODIUM_VERSION}+. You have #{Version::STRING} installed"
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,43 @@
1
+ # encoding: binary
2
+ require 'ffi'
3
+
4
+ module RbNaCl
5
+ # Provides helpers for defining the libsodium bindings
6
+ module Sodium
7
+ def self.extended(klass)
8
+ klass.extend FFI::Library
9
+ klass.ffi_lib 'sodium'
10
+ end
11
+
12
+
13
+ def sodium_type(type = nil)
14
+ return @type if type.nil?
15
+ @type = type
16
+ end
17
+
18
+ def sodium_primitive(primitive = nil)
19
+ return @primitive if primitive.nil?
20
+ @primitive = primitive
21
+ end
22
+
23
+ def primitive
24
+ sodium_primitive
25
+ end
26
+
27
+ def sodium_constant(constant, name=constant)
28
+ fn = "crypto_#{sodium_type}_#{sodium_primitive}_#{constant.to_s.downcase}"
29
+ attach_function fn, [], :ulong_long
30
+ self.const_set(name, self.public_send(fn))
31
+ end
32
+
33
+ def sodium_function(name, function, arguments)
34
+ self.module_eval <<-eos, __FILE__, __LINE__ + 1
35
+ attach_function #{function.inspect}, #{arguments.inspect}, :int
36
+ def self.#{name}(*args)
37
+ ret = #{function}(*args)
38
+ ret == 0
39
+ end
40
+ eos
41
+ end
42
+ end
43
+ end
@@ -1,5 +1,5 @@
1
1
  # encoding: binary
2
- module Crypto
2
+ module RbNaCl
3
3
  # Reference library of test vectors used to verify the software is correct
4
4
  TestVectors = {
5
5
  #
@@ -50,8 +50,41 @@ module Crypto
50
50
  :sha256_message => "6162636462636465636465666465666765666768666768696768696a68696a6b" +
51
51
  "696a6b6c6a6b6c6d6b6c6d6e6c6d6e6f6d6e6f706e6f7071",
52
52
  :sha256_digest => "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1",
53
+ :sha256_empty => "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
53
54
 
54
55
  #
56
+ # SHA512 test vectors
57
+ # self-created (FIXME: find standard test vectors)
58
+ :sha512_message => "54686520717569636b2062726f776e20666f78206a756d7073206f7665722074" +
59
+ "6865206c617a7920646f672e",
60
+ :sha512_digest => "91ea1245f20d46ae9a037a989f54f1f790f0a47607eeb8a14d12890cea77a1bb" +
61
+ "c6c7ed9cf205e67b7f2b8fd4c7dfd3a7a8617e45f3c463d481c7e586c39ac1ed",
62
+ :sha512_empty => "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce" +
63
+ "47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e",
64
+
65
+ # Blake2b test vectors
66
+ # self-created? (TODO: double check, fix)
67
+ :blake2b_message => "54686520717569636b2062726f776e20666f78206a756d7073206f7665722074" +
68
+ "6865206c617a7920646f67",
69
+ :blake2b_digest => "a8add4bdddfd93e4877d2746e62817b116364a1fa7bc148d95090bc7333b3673" +
70
+ "f82401cf7aa2e4cb1ecd90296e3f14cb5413f8ed77be73045b13914cdcd6a918",
71
+ :blake2b_empty => "786a02f742015903c6c6fd852552d272912f4740e15847618a86e217f71f5419" +
72
+ "d25e1031afee585313896444934eb04b903a685b1448b755d56f701afe9be2ce",
73
+
74
+ # from the Blake2 paper(?) (TODO: double check)
75
+ :blake2b_keyed_message => "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" +
76
+ "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f" +
77
+ "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f" +
78
+ "606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f" +
79
+ "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f" +
80
+ "a0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebf" +
81
+ "c0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedf" +
82
+ "e0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfe",
83
+ :blake2b_key => "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" +
84
+ "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
85
+ :blake2b_keyed_digest => "142709d62e28fcccd0af97fad0f8465b971e82201dc51070faa0372aa43e9248" +
86
+ "4be1c1e73ba10906d5d1853db6a4106e0a7bf9800d373d6dee2d46d62ef2a461",
87
+
55
88
  # Auth test vectors
56
89
  # Taken from NaCl distribution
57
90
  #
data/lib/rbnacl/util.rb CHANGED
@@ -1,7 +1,11 @@
1
1
  # encoding: binary
2
- module Crypto
2
+ module RbNaCl
3
3
  # Various utility functions
4
4
  module Util
5
+ extend Sodium
6
+
7
+ sodium_function :c_verify16, :crypto_verify_16, [:pointer, :pointer]
8
+ sodium_function :c_verify32, :crypto_verify_32, [:pointer, :pointer]
5
9
  module_function
6
10
  # Returns a string of n zeros
7
11
  #
@@ -46,7 +50,7 @@ module Crypto
46
50
  # In several places through the codebase we have to be VERY strict with
47
51
  # what length of string we accept. This method supports that.
48
52
  #
49
- # @raise [Crypto::LengthError] If the string is not the right length
53
+ # @raise [RbNaCl::LengthError] If the string is not the right length
50
54
  #
51
55
  # @param string [String] The string to compare
52
56
  # @param length [Integer] The desired length
@@ -57,7 +61,7 @@ module Crypto
57
61
  "#{description} was nil (Expected #{length.to_int})",
58
62
  caller
59
63
  end
60
-
64
+
61
65
  if string.bytesize != length.to_int
62
66
  raise LengthError,
63
67
  "#{description} was #{string.bytesize} bytes (Expected #{length.to_int})",
@@ -66,6 +70,27 @@ module Crypto
66
70
  true
67
71
  end
68
72
 
73
+ # Check a passed in string, converting the argument if necessary
74
+ #
75
+ # In several places through the codebase we have to be VERY strict with
76
+ # the strings we accept. This method supports that.
77
+ #
78
+ # @raise [ArgumentError] If we cannot convert to a string with #to_str
79
+ # @raise [RbNaCl::LengthError] If the string is not the right length
80
+ #
81
+ # @param string [#to_str] The input string
82
+ # @param length [Integer] The only acceptable length of the string
83
+ # @param description [String] Description of the string (used in the error)
84
+ def check_string(string, length, description)
85
+ unless string.respond_to? :to_str
86
+ raise TypeError, "can't convert #{string.class} into String with #to_str"
87
+ end
88
+
89
+ string = string.to_str
90
+ check_length(string, length, description)
91
+
92
+ string
93
+ end
69
94
 
70
95
  # Compare two 32 byte strings in constant time
71
96
  #
@@ -79,7 +104,7 @@ module Crypto
79
104
  # @return [Boolean] Well, are they equal?
80
105
  def verify32(one, two)
81
106
  return false unless two.bytesize == 32 && one.bytesize == 32
82
- NaCl.crypto_verify_32(one, two)
107
+ c_verify32(one, two)
83
108
  end
84
109
 
85
110
  # Compare two 32 byte strings in constant time
@@ -97,7 +122,7 @@ module Crypto
97
122
  def verify32!(one, two)
98
123
  check_length(one, 32, "First message")
99
124
  check_length(two, 32, "Second message")
100
- NaCl.crypto_verify_32(one, two)
125
+ c_verify32(one, two)
101
126
  end
102
127
 
103
128
  # Compare two 16 byte strings in constant time
@@ -112,7 +137,7 @@ module Crypto
112
137
  # @return [Boolean] Well, are they equal?
113
138
  def verify16(one, two)
114
139
  return false unless two.bytesize == 16 && one.bytesize == 16
115
- NaCl.crypto_verify_16(one, two)
140
+ c_verify16(one, two)
116
141
  end
117
142
 
118
143
  # Compare two 16 byte strings in constant time
@@ -130,7 +155,25 @@ module Crypto
130
155
  def verify16!(one, two)
131
156
  check_length(one, 16, "First message")
132
157
  check_length(two, 16, "Second message")
133
- NaCl.crypto_verify_16(one, two)
158
+ c_verify16(one, two)
159
+ end
160
+
161
+ # Hex encodes a message
162
+ #
163
+ # @param [String] bytes The bytes to encode
164
+ #
165
+ # @return [String] Tasty, tasty hexadecimal
166
+ def bin2hex(bytes)
167
+ bytes.to_s.unpack("H*").first
168
+ end
169
+
170
+ # Hex decodes a message
171
+ #
172
+ # @param [String] hex hex to decode.
173
+ #
174
+ # @return [String] crisp and clean bytes
175
+ def hex2bin(hex)
176
+ [hex.to_s].pack("H*")
134
177
  end
135
178
  end
136
179
  end
@@ -1,5 +1,5 @@
1
1
  # encoding: binary
2
- module Crypto
2
+ module RbNaCl
3
3
  # The library's version
4
- VERSION = "1.1.0"
4
+ VERSION = "2.0.0"
5
5
  end