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.
- checksums.yaml +4 -4
- data/.travis.yml +1 -5
- data/CHANGES.md +15 -0
- data/Gemfile +4 -1
- data/Guardfile +8 -0
- data/README.md +52 -3
- data/lib/rbnacl.rb +65 -29
- data/lib/rbnacl/auth.rb +14 -18
- data/lib/rbnacl/boxes/curve25519xsalsa20poly1305.rb +185 -0
- data/lib/rbnacl/{keys → boxes/curve25519xsalsa20poly1305}/private_key.rb +26 -23
- data/lib/rbnacl/{keys → boxes/curve25519xsalsa20poly1305}/public_key.rb +13 -12
- data/lib/rbnacl/group_elements/curve25519.rb +81 -0
- data/lib/rbnacl/hash.rb +30 -14
- data/lib/rbnacl/hash/blake2b.rb +57 -0
- data/lib/rbnacl/hash/sha256.rb +15 -0
- data/lib/rbnacl/hash/sha512.rb +15 -0
- data/lib/rbnacl/hmac/sha256.rb +19 -17
- data/lib/rbnacl/hmac/sha512256.rb +18 -19
- data/lib/rbnacl/init.rb +10 -0
- data/lib/rbnacl/{keys/key_comparator.rb → key_comparator.rb} +1 -1
- data/lib/rbnacl/{auth/one_time.rb → one_time_auths/poly1305.rb} +21 -19
- data/lib/rbnacl/rake_tasks.rb +7 -6
- data/lib/rbnacl/random.rb +8 -3
- data/lib/rbnacl/random_nonce_box.rb +9 -14
- data/lib/rbnacl/secret_boxes/xsalsa20poly1305.rb +125 -0
- data/lib/rbnacl/self_test.rb +59 -40
- data/lib/rbnacl/serializable.rb +4 -12
- data/lib/rbnacl/signatures/ed25519.rb +15 -0
- data/lib/rbnacl/signatures/ed25519/signing_key.rb +104 -0
- data/lib/rbnacl/signatures/ed25519/verify_key.rb +91 -0
- data/lib/rbnacl/sodium.rb +43 -0
- data/lib/rbnacl/test_vectors.rb +34 -1
- data/lib/rbnacl/util.rb +52 -7
- data/lib/rbnacl/version.rb +2 -2
- data/rbnacl.gemspec +3 -6
- data/spec/rbnacl/{auth/one_time_spec.rb → authenticators/poly1305_spec.rb} +2 -2
- data/spec/rbnacl/boxes/curve25519xsalsa20poly1305/private_key_spec.rb +65 -0
- data/spec/rbnacl/{keys → boxes/curve25519xsalsa20poly1305}/public_key_spec.rb +10 -13
- data/spec/rbnacl/boxes/curve25519xsalsa20poly1305_spec.rb +39 -0
- data/spec/rbnacl/{point_spec.rb → group_element_spec.rb} +6 -8
- data/spec/rbnacl/hash/blake2b_spec.rb +26 -0
- data/spec/rbnacl/hash_spec.rb +13 -33
- data/spec/rbnacl/hmac/sha256_spec.rb +2 -2
- data/spec/rbnacl/hmac/sha512256_spec.rb +2 -2
- data/spec/rbnacl/random_nonce_box_spec.rb +21 -26
- data/spec/rbnacl/random_spec.rb +3 -3
- data/spec/rbnacl/secret_box_spec.rb +6 -6
- data/spec/rbnacl/signatures/ed25519/signing_key_spec.rb +30 -0
- data/spec/rbnacl/signatures/ed25519/verify_key_spec.rb +39 -0
- data/spec/rbnacl/util_spec.rb +67 -53
- data/spec/shared/authenticator.rb +36 -54
- data/spec/shared/box.rb +10 -10
- data/spec/shared/key_equality.rb +3 -3
- data/spec/shared/serializable.rb +17 -0
- data/spec/spec_helper.rb +14 -16
- data/tasks/rspec.rake +1 -0
- metadata +42 -67
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -3
- data/lib/rbnacl/box.rb +0 -171
- data/lib/rbnacl/encoder.rb +0 -44
- data/lib/rbnacl/encoders/base32.rb +0 -33
- data/lib/rbnacl/encoders/base64.rb +0 -30
- data/lib/rbnacl/encoders/hex.rb +0 -30
- data/lib/rbnacl/encoders/raw.rb +0 -12
- data/lib/rbnacl/keys/signing_key.rb +0 -95
- data/lib/rbnacl/keys/verify_key.rb +0 -96
- data/lib/rbnacl/nacl.rb +0 -146
- data/lib/rbnacl/point.rb +0 -70
- data/lib/rbnacl/secret_box.rb +0 -119
- data/spec/rbnacl/box_spec.rb +0 -42
- data/spec/rbnacl/encoder_spec.rb +0 -14
- data/spec/rbnacl/encoders/base32_spec.rb +0 -16
- data/spec/rbnacl/encoders/base64_spec.rb +0 -15
- data/spec/rbnacl/encoders/hex_spec.rb +0 -15
- data/spec/rbnacl/keys/private_key_spec.rb +0 -68
- data/spec/rbnacl/keys/signing_key_spec.rb +0 -39
- data/spec/rbnacl/keys/verify_key_spec.rb +0 -51
- metadata.gz.sig +0 -2
data/lib/rbnacl/serializable.rb
CHANGED
@@ -1,23 +1,15 @@
|
|
1
1
|
# encoding: binary
|
2
|
-
module
|
2
|
+
module RbNaCl
|
3
3
|
# Serialization features shared across all "key-like" classes
|
4
4
|
module Serializable
|
5
|
-
|
6
|
-
|
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}:#{
|
12
|
+
"#<#{self.class}:#{Util.bin2hex(to_bytes)[0,8]}>"
|
21
13
|
end
|
22
14
|
end
|
23
15
|
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,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,91 @@
|
|
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
|
+
# @param signature [String] Alleged signature to be checked
|
37
|
+
# @param message [String] Message to be authenticated
|
38
|
+
#
|
39
|
+
# @return [Boolean] was the signature authentic?
|
40
|
+
def verify(signature, message)
|
41
|
+
signature = signature.to_str
|
42
|
+
Util.check_length(signature, signature_bytes, "signature")
|
43
|
+
|
44
|
+
sig_and_msg = signature + message
|
45
|
+
buffer = Util.zeros(sig_and_msg.bytesize)
|
46
|
+
buffer_len = Util.zeros(FFI::Type::LONG_LONG.size)
|
47
|
+
|
48
|
+
self.class.sign_ed25519_open(buffer, buffer_len, sig_and_msg, sig_and_msg.bytesize, @key)
|
49
|
+
end
|
50
|
+
|
51
|
+
# Verify a signature for a given message or raise exception
|
52
|
+
#
|
53
|
+
# "Dangerous" (but really safer) verify that raises an exception if a
|
54
|
+
# signature check fails. This is probably less likely to go unnoticed than
|
55
|
+
# an improperly checked verify, as you are forced to deal with the
|
56
|
+
# exception explicitly (and failing signature checks are certainly an
|
57
|
+
# exceptional condition!)
|
58
|
+
#
|
59
|
+
# The arguments are otherwise the same as the verify method.
|
60
|
+
#
|
61
|
+
# @param message [String] Message to be authenticated
|
62
|
+
# @param signature [String] Alleged signature to be checked
|
63
|
+
#
|
64
|
+
# @return [true] Will raise BadSignatureError if signature check fails
|
65
|
+
def verify!(message, signature)
|
66
|
+
verify(message, signature) or raise BadSignatureError, "signature was forged/corrupt"
|
67
|
+
end
|
68
|
+
|
69
|
+
# Return the raw key in byte format
|
70
|
+
#
|
71
|
+
# @return [String] raw key as bytes
|
72
|
+
def to_bytes; @key; end
|
73
|
+
|
74
|
+
# The crypto primitive this VerifyKey class uses for signatures
|
75
|
+
#
|
76
|
+
# @return [Symbol] The primitive
|
77
|
+
def primitive; self.class.primitive; end
|
78
|
+
|
79
|
+
# The size of signatures verified by the VerifyKey class
|
80
|
+
#
|
81
|
+
# @return [Integer] The number of bytes in a signature
|
82
|
+
def self.signature_bytes; Ed25519::SIGNATUREBYTES; end
|
83
|
+
|
84
|
+
# The size of signatures verified by the VerifyKey instance
|
85
|
+
#
|
86
|
+
# @return [Integer] The number of bytes in a signature
|
87
|
+
def signature_bytes; Ed25519::SIGNATUREBYTES; end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
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
|
data/lib/rbnacl/test_vectors.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# encoding: binary
|
2
|
-
module
|
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,13 @@
|
|
1
1
|
# encoding: binary
|
2
|
-
module
|
2
|
+
module RbNaCl
|
3
3
|
# Various utility functions
|
4
4
|
module Util
|
5
|
+
extend Sodium
|
6
|
+
|
7
|
+
attach_function :sodium_version_string, [], :string
|
8
|
+
|
9
|
+
sodium_function :c_verify16, :crypto_verify_16, [:pointer, :pointer]
|
10
|
+
sodium_function :c_verify32, :crypto_verify_32, [:pointer, :pointer]
|
5
11
|
module_function
|
6
12
|
# Returns a string of n zeros
|
7
13
|
#
|
@@ -46,7 +52,7 @@ module Crypto
|
|
46
52
|
# In several places through the codebase we have to be VERY strict with
|
47
53
|
# what length of string we accept. This method supports that.
|
48
54
|
#
|
49
|
-
# @raise [
|
55
|
+
# @raise [RbNaCl::LengthError] If the string is not the right length
|
50
56
|
#
|
51
57
|
# @param string [String] The string to compare
|
52
58
|
# @param length [Integer] The desired length
|
@@ -57,7 +63,7 @@ module Crypto
|
|
57
63
|
"#{description} was nil (Expected #{length.to_int})",
|
58
64
|
caller
|
59
65
|
end
|
60
|
-
|
66
|
+
|
61
67
|
if string.bytesize != length.to_int
|
62
68
|
raise LengthError,
|
63
69
|
"#{description} was #{string.bytesize} bytes (Expected #{length.to_int})",
|
@@ -66,6 +72,27 @@ module Crypto
|
|
66
72
|
true
|
67
73
|
end
|
68
74
|
|
75
|
+
# Check a passed in string, converting the argument if necessary
|
76
|
+
#
|
77
|
+
# In several places through the codebase we have to be VERY strict with
|
78
|
+
# the strings we accept. This method supports that.
|
79
|
+
#
|
80
|
+
# @raise [ArgumentError] If we cannot convert to a string with #to_str
|
81
|
+
# @raise [RbNaCl::LengthError] If the string is not the right length
|
82
|
+
#
|
83
|
+
# @param string [#to_str] The input string
|
84
|
+
# @param length [Integer] The only acceptable length of the string
|
85
|
+
# @param description [String] Description of the string (used in the error)
|
86
|
+
def check_string(string, length, description)
|
87
|
+
unless string.respond_to? :to_str
|
88
|
+
raise TypeError, "can't convert #{string.class} into String with #to_str"
|
89
|
+
end
|
90
|
+
|
91
|
+
string = string.to_str
|
92
|
+
check_length(string, length, description)
|
93
|
+
|
94
|
+
string
|
95
|
+
end
|
69
96
|
|
70
97
|
# Compare two 32 byte strings in constant time
|
71
98
|
#
|
@@ -79,7 +106,7 @@ module Crypto
|
|
79
106
|
# @return [Boolean] Well, are they equal?
|
80
107
|
def verify32(one, two)
|
81
108
|
return false unless two.bytesize == 32 && one.bytesize == 32
|
82
|
-
|
109
|
+
c_verify32(one, two)
|
83
110
|
end
|
84
111
|
|
85
112
|
# Compare two 32 byte strings in constant time
|
@@ -97,7 +124,7 @@ module Crypto
|
|
97
124
|
def verify32!(one, two)
|
98
125
|
check_length(one, 32, "First message")
|
99
126
|
check_length(two, 32, "Second message")
|
100
|
-
|
127
|
+
c_verify32(one, two)
|
101
128
|
end
|
102
129
|
|
103
130
|
# Compare two 16 byte strings in constant time
|
@@ -112,7 +139,7 @@ module Crypto
|
|
112
139
|
# @return [Boolean] Well, are they equal?
|
113
140
|
def verify16(one, two)
|
114
141
|
return false unless two.bytesize == 16 && one.bytesize == 16
|
115
|
-
|
142
|
+
c_verify16(one, two)
|
116
143
|
end
|
117
144
|
|
118
145
|
# Compare two 16 byte strings in constant time
|
@@ -130,7 +157,25 @@ module Crypto
|
|
130
157
|
def verify16!(one, two)
|
131
158
|
check_length(one, 16, "First message")
|
132
159
|
check_length(two, 16, "Second message")
|
133
|
-
|
160
|
+
c_verify16(one, two)
|
161
|
+
end
|
162
|
+
|
163
|
+
# Hex encodes a message
|
164
|
+
#
|
165
|
+
# @param [String] bytes The bytes to encode
|
166
|
+
#
|
167
|
+
# @return [String] Tasty, tasty hexadecimal
|
168
|
+
def bin2hex(bytes)
|
169
|
+
bytes.to_s.unpack("H*").first
|
170
|
+
end
|
171
|
+
|
172
|
+
# Hex decodes a message
|
173
|
+
#
|
174
|
+
# @param [String] hex hex to decode.
|
175
|
+
#
|
176
|
+
# @return [String] crisp and clean bytes
|
177
|
+
def hex2bin(hex)
|
178
|
+
[hex.to_s].pack("H*")
|
134
179
|
end
|
135
180
|
end
|
136
181
|
end
|
data/lib/rbnacl/version.rb
CHANGED