rbnacl 1.1.0 → 2.0.0.pre
Sign up to get free protection for your applications and to get access to all the features.
- 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
@@ -1,6 +1,7 @@
|
|
1
1
|
# encoding: binary
|
2
|
-
|
3
|
-
|
2
|
+
|
3
|
+
module RbNaCl
|
4
|
+
# RbNaCl::Box private key. Keep it safe
|
4
5
|
#
|
5
6
|
# This class generates and stores NaCL private keys, as well as providing a
|
6
7
|
# reference to the public key associated with this private key, if that's
|
@@ -9,12 +10,22 @@ module Crypto
|
|
9
10
|
# Note that the documentation for NaCl refers to this as a secret key, but in
|
10
11
|
# this library its a private key, to avoid confusing the issue with the
|
11
12
|
# SecretBox, which does symmetric encryption.
|
12
|
-
class PrivateKey
|
13
|
+
class Boxes::Curve25519XSalsa20Poly1305::PrivateKey
|
14
|
+
|
13
15
|
include KeyComparator
|
14
16
|
include Serializable
|
17
|
+
|
18
|
+
extend Sodium
|
19
|
+
|
20
|
+
sodium_type :box
|
21
|
+
sodium_primitive :curve25519xsalsa20poly1305
|
22
|
+
|
23
|
+
sodium_function :box_curve25519xsalsa20poly1305_keypair,
|
24
|
+
:crypto_box_curve25519xsalsa20poly1305_keypair,
|
25
|
+
[:pointer, :pointer]
|
15
26
|
|
16
27
|
# The size of the key, in bytes
|
17
|
-
BYTES =
|
28
|
+
BYTES = Boxes::Curve25519XSalsa20Poly1305::PRIVATEKEYBYTES
|
18
29
|
|
19
30
|
# Initializes a new PrivateKey for key operations.
|
20
31
|
#
|
@@ -25,23 +36,23 @@ module Crypto
|
|
25
36
|
# @param private_key [String] The private key
|
26
37
|
# @param key_encoding [Symbol] The encoding of the key
|
27
38
|
#
|
28
|
-
# @raise [
|
39
|
+
# @raise [TypeError] If the key is nil
|
40
|
+
# @raise [RbNaCl::LengthError] If the key is not valid after decoding.
|
29
41
|
#
|
30
42
|
# @return A new PrivateKey
|
31
|
-
def initialize(private_key
|
32
|
-
@private_key =
|
33
|
-
Util.check_length(@private_key, BYTES, "Private key")
|
43
|
+
def initialize(private_key)
|
44
|
+
@private_key = Util.check_string(private_key, BYTES, "Private key")
|
34
45
|
end
|
35
46
|
|
36
47
|
# Generates a new keypair
|
37
48
|
#
|
38
|
-
# @raise [
|
49
|
+
# @raise [RbNaCl::CryptoError] if key generation fails, due to insufficient randomness.
|
39
50
|
#
|
40
|
-
# @return [
|
51
|
+
# @return [RbNaCl::PrivateKey] A new private key, with the associated public key also set.
|
41
52
|
def self.generate
|
42
|
-
pk = Util.zeros(
|
43
|
-
sk = Util.zeros(
|
44
|
-
|
53
|
+
pk = Util.zeros(Boxes::Curve25519XSalsa20Poly1305::PUBLICKEYBYTES)
|
54
|
+
sk = Util.zeros(Boxes::Curve25519XSalsa20Poly1305::PRIVATEKEYBYTES)
|
55
|
+
self.box_curve25519xsalsa20poly1305_keypair(pk, sk) || raise(CryptoError, "Failed to generate a key pair")
|
45
56
|
new(sk)
|
46
57
|
end
|
47
58
|
|
@@ -56,22 +67,14 @@ module Crypto
|
|
56
67
|
#
|
57
68
|
# @return [PublicKey] the key
|
58
69
|
def public_key
|
59
|
-
@public_key ||= PublicKey.new
|
60
|
-
end
|
61
|
-
|
62
|
-
# The crypto primitive the PrivateKey class is to be used for
|
63
|
-
#
|
64
|
-
# @return [Symbol] The primitive
|
65
|
-
def self.primitive
|
66
|
-
:curve25519_xsalsa20_poly1305
|
70
|
+
@public_key ||= PublicKey.new GroupElements::Curve25519.base.mult(to_bytes)
|
67
71
|
end
|
68
|
-
|
72
|
+
|
69
73
|
# The crypto primitive this PrivateKey is to be used for.
|
70
74
|
#
|
71
75
|
# @return [Symbol] The primitive
|
72
76
|
def primitive
|
73
77
|
self.class.primitive
|
74
78
|
end
|
75
|
-
|
76
79
|
end
|
77
80
|
end
|
@@ -1,31 +1,31 @@
|
|
1
1
|
# encoding: binary
|
2
|
-
|
3
|
-
|
2
|
+
|
3
|
+
module RbNaCl
|
4
|
+
# RbNaCl::Box public key. Send it (securely!) to your friends.
|
4
5
|
#
|
5
|
-
# This class stores the NaCL public key, and provides some
|
6
|
+
# This class stores the NaCL public key, and provides some convenience
|
6
7
|
# functions for working with it.
|
7
|
-
class PublicKey
|
8
|
+
class Boxes::Curve25519XSalsa20Poly1305::PublicKey
|
9
|
+
|
8
10
|
include KeyComparator
|
9
11
|
include Serializable
|
10
12
|
|
11
13
|
# The size of the key, in bytes
|
12
|
-
BYTES =
|
14
|
+
BYTES = Boxes::Curve25519XSalsa20Poly1305::PUBLICKEYBYTES
|
13
15
|
|
14
16
|
# Initializes a new PublicKey for key operations.
|
15
17
|
#
|
16
18
|
# Takes the (optionally encoded) public key bytes. This can be shared with
|
17
19
|
# many people and used to establish key pairs with their private key, for
|
18
|
-
# the exchanging of messages using a
|
20
|
+
# the exchanging of messages using a RbNaCl::Box
|
19
21
|
#
|
20
22
|
# @param public_key [String] The public key
|
21
|
-
# @param key_encoding [Symbol] The encoding of the key
|
22
23
|
#
|
23
|
-
# @raise [
|
24
|
+
# @raise [RbNaCl::LengthError] If the key is not valid after decoding.
|
24
25
|
#
|
25
26
|
# @return A new PublicKey
|
26
|
-
def initialize(public_key
|
27
|
-
@public_key =
|
28
|
-
Util.check_length(@public_key, BYTES, "Public key")
|
27
|
+
def initialize(public_key)
|
28
|
+
@public_key = Util.check_string(public_key, BYTES, "Public key")
|
29
29
|
end
|
30
30
|
|
31
31
|
# The raw bytes of the key
|
@@ -39,7 +39,7 @@ module Crypto
|
|
39
39
|
#
|
40
40
|
# @return [Symbol] The primitive
|
41
41
|
def self.primitive
|
42
|
-
:
|
42
|
+
:curve25519xsalsa20poly1305
|
43
43
|
end
|
44
44
|
|
45
45
|
# The crypto primitive this PublicKey is to be used for.
|
@@ -49,4 +49,5 @@ module Crypto
|
|
49
49
|
self.class.primitive
|
50
50
|
end
|
51
51
|
end
|
52
|
+
|
52
53
|
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
# encoding: binary
|
2
|
+
module RbNaCl
|
3
|
+
module GroupElements
|
4
|
+
# Points provide the interface to NaCl's Curve25519 high-speed elliptic
|
5
|
+
# curve cryptography, which can be used for implementing Diffie-Hellman
|
6
|
+
# and other forms of public key cryptography (e.g. RbNaCl::Box)
|
7
|
+
#
|
8
|
+
# Objects of the Point class represent points on Edwards curves. NaCl
|
9
|
+
# defines a base point (the "standard group element") which we can
|
10
|
+
# multiply by an arbitrary integer. This is how NaCl computes public
|
11
|
+
# keys from private keys.
|
12
|
+
class Curve25519
|
13
|
+
# NaCl's Curve25519 base point (a.k.a. standard group element), serialized as hex
|
14
|
+
STANDARD_GROUP_ELEMENT = ["0900000000000000000000000000000000000000000000000000000000000000"].pack("H*").freeze
|
15
|
+
|
16
|
+
# Order of the standard group
|
17
|
+
STANDARD_GROUP_ORDER = 2**252 + 27742317777372353535851937790883648493
|
18
|
+
|
19
|
+
include KeyComparator
|
20
|
+
include Serializable
|
21
|
+
|
22
|
+
extend Sodium
|
23
|
+
|
24
|
+
sodium_type :scalarmult
|
25
|
+
sodium_primitive :curve25519
|
26
|
+
|
27
|
+
sodium_function :scalarmult_curve25519,
|
28
|
+
:crypto_scalarmult_curve25519,
|
29
|
+
[:pointer, :pointer, :pointer]
|
30
|
+
|
31
|
+
# Number of bytes in a scalar on this curve
|
32
|
+
SCALARBYTES = 32
|
33
|
+
BYTES = 32
|
34
|
+
|
35
|
+
# Number of bytes in a scalar on this curve
|
36
|
+
|
37
|
+
# Creates a new Point from the given serialization
|
38
|
+
#
|
39
|
+
# @param [String] point location of a group element (32-bytes)
|
40
|
+
#
|
41
|
+
# @return [RbNaCl::Point] the Point at this location
|
42
|
+
def initialize(point)
|
43
|
+
@point = point.to_str
|
44
|
+
|
45
|
+
# FIXME: really should have a separate constant here for group element size
|
46
|
+
# Group elements and scalars are both 32-bits, but that's for convenience
|
47
|
+
Util.check_length(@point, SCALARBYTES, "group element")
|
48
|
+
end
|
49
|
+
|
50
|
+
# Multiply the given integer by this point
|
51
|
+
# This ordering is a bit confusing because traditionally the point
|
52
|
+
# would be the right-hand operand.
|
53
|
+
#
|
54
|
+
# @param [String] integer value to multiply with this Point (32-bytes)
|
55
|
+
#
|
56
|
+
# @return [RbNaCl::Point] result as a Point object
|
57
|
+
def mult(integer, encoding = :raw)
|
58
|
+
integer = integer.to_str
|
59
|
+
Util.check_length(integer, SCALARBYTES, "integer")
|
60
|
+
|
61
|
+
result = Util.zeros(SCALARBYTES)
|
62
|
+
self.class.scalarmult_curve25519(result, integer, @point)
|
63
|
+
|
64
|
+
self.class.new(result)
|
65
|
+
end
|
66
|
+
|
67
|
+
# Return the point serialized as bytes
|
68
|
+
#
|
69
|
+
# @return [String] 32-byte string representing this point
|
70
|
+
def to_bytes; @point; end
|
71
|
+
|
72
|
+
@base_point = new(STANDARD_GROUP_ELEMENT)
|
73
|
+
|
74
|
+
# NaCl's standard base point for all Curve25519 public keys
|
75
|
+
#
|
76
|
+
# @return [RbNaCl::Point] standard base point (a.k.a. standard group element)
|
77
|
+
def self.base; @base_point; end
|
78
|
+
def self.base_point; @base_point; end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
data/lib/rbnacl/hash.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# encoding: binary
|
2
|
-
module
|
2
|
+
module RbNaCl
|
3
3
|
# Cryptographic hash functions
|
4
4
|
#
|
5
5
|
# Cryptographic hash functions take a variable length message and compute a
|
@@ -11,38 +11,54 @@ module Crypto
|
|
11
11
|
# there is no secret involved in the hashing, so anyone can create the hash of
|
12
12
|
# a given message.
|
13
13
|
#
|
14
|
-
# RbNaCl provides the SHA-256
|
14
|
+
# RbNaCl provides the SHA-256,SHA-512 as well as the Blake2b hash functions.
|
15
15
|
module Hash
|
16
16
|
# Returns the SHA-256 hash of the given data
|
17
17
|
#
|
18
18
|
# There's no streaming done, just pass in the data and be done with it.
|
19
19
|
#
|
20
|
-
# @param [
|
21
|
-
# @param [#to_sym] encoding Encoding of the returned hash.
|
20
|
+
# @param [#to_str] data The data, as a collection of bytes
|
22
21
|
#
|
23
22
|
# @raise [CryptoError] If the hashing fails for some reason.
|
24
23
|
#
|
25
24
|
# @return [String] The SHA-256 hash as raw bytes (Or encoded as per the second argument)
|
26
|
-
def self.sha256(data
|
27
|
-
|
28
|
-
|
29
|
-
|
25
|
+
def self.sha256(data)
|
26
|
+
data = data.to_str
|
27
|
+
digest = Util.zeros(SHA256::BYTES)
|
28
|
+
SHA256.hash_sha256(digest, data, data.bytesize) || raise(CryptoError, "Hashing failed!")
|
29
|
+
digest
|
30
30
|
end
|
31
31
|
|
32
32
|
# Returns the SHA-512 hash of the given data
|
33
33
|
#
|
34
34
|
# There's no streaming done, just pass in the data and be done with it.
|
35
35
|
#
|
36
|
-
# @param [
|
37
|
-
# @param [#to_sym] encoding Encoding of the returned hash.
|
36
|
+
# @param [#to_str] data The data, as a collection of bytes
|
38
37
|
#
|
39
38
|
# @raise [CryptoError] If the hashing fails for some reason.
|
40
39
|
#
|
41
40
|
# @return [String] The SHA-512 hash as raw bytes (Or encoded as per the second argument)
|
42
|
-
def self.sha512(data
|
43
|
-
|
44
|
-
|
45
|
-
|
41
|
+
def self.sha512(data)
|
42
|
+
digest = Util.zeros(SHA512::BYTES)
|
43
|
+
SHA512.hash_sha512(digest, data, data.bytesize) || raise(CryptoError, "Hashing failed!")
|
44
|
+
digest
|
45
|
+
end
|
46
|
+
|
47
|
+
# Returns the Blake2b hash of the given data
|
48
|
+
#
|
49
|
+
# There's no streaming done, just pass in the data and be done with it.
|
50
|
+
# This method returns a 64-byte hash by default.
|
51
|
+
#
|
52
|
+
# @param [String] data The data, as a collection of bytes
|
53
|
+
# @option options [Fixnum] digest_size Size in bytes (1-64, default 64)
|
54
|
+
# @option options [String] key 64-byte (or less) key for keyed mode
|
55
|
+
#
|
56
|
+
# @raise [CryptoError] If the hashing fails for some reason.
|
57
|
+
#
|
58
|
+
# @return [String] The blake2b hash as raw bytes (Or encoded as per the second argument)
|
59
|
+
def self.blake2b(data, options = {})
|
60
|
+
key = options[:key]
|
61
|
+
Blake2b.new(options).digest(data)
|
46
62
|
end
|
47
63
|
end
|
48
64
|
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# encoding: binary
|
2
|
+
module RbNaCl
|
3
|
+
module Hash
|
4
|
+
# The Blake2b hash function
|
5
|
+
#
|
6
|
+
# Blake2b is based on Blake, a SHA3 finalist which was snubbed in favor of
|
7
|
+
# Keccak, a much slower hash function but one sufficiently different from
|
8
|
+
# SHA2 to let the SHA3 judges panel sleep easy. Back in the real world,
|
9
|
+
# it'd be great if we can calculate hashes quickly if possible.
|
10
|
+
#
|
11
|
+
# Blake2b provides for up to 64-bit digests and also supports a keyed mode
|
12
|
+
# similar to HMAC
|
13
|
+
class Blake2b
|
14
|
+
extend Sodium
|
15
|
+
|
16
|
+
sodium_type :generichash
|
17
|
+
sodium_primitive :blake2b
|
18
|
+
sodium_constant :BYTES_MIN
|
19
|
+
sodium_constant :BYTES_MAX
|
20
|
+
sodium_constant :KEYBYTES_MIN
|
21
|
+
sodium_constant :KEYBYTES_MAX
|
22
|
+
|
23
|
+
sodium_function :generichash_blake2b,
|
24
|
+
:crypto_generichash_blake2b,
|
25
|
+
[:pointer, :ulong_long, :pointer, :ulong_long, :pointer, :ulong_long]
|
26
|
+
|
27
|
+
# Create a new Blake2b hash object
|
28
|
+
#
|
29
|
+
# @param [Hash] opts Blake2b configuration
|
30
|
+
# @option opts [String] :key for Blake2b keyed mode
|
31
|
+
# @option opts [Integer] :digest_size size of output digest in bytes
|
32
|
+
#
|
33
|
+
# @raise [RbNaCl::LengthError] Invalid length specified for one or more options
|
34
|
+
#
|
35
|
+
# @return [RbNaCl::Hash::Blake2b] A Blake2b hasher object
|
36
|
+
def initialize(opts = {})
|
37
|
+
@key = opts.fetch(:key, nil)
|
38
|
+
@key_size = @key ? @key.bytesize : 0
|
39
|
+
raise LengthError, "Invalid key size" if (@key_size != 0) && (@key_size < KEYBYTES_MIN || @key_size > KEYBYTES_MAX)
|
40
|
+
|
41
|
+
@digest_size = opts.fetch(:digest_size, BYTES_MAX)
|
42
|
+
raise LengthError, "Invalid digest size" if @digest_size < BYTES_MIN || @digest_size > BYTES_MAX
|
43
|
+
end
|
44
|
+
|
45
|
+
# Calculate a Blake2b digest
|
46
|
+
#
|
47
|
+
# @param [String] message Message to be hashed
|
48
|
+
#
|
49
|
+
# @return [String] Blake2b digest of the string as raw bytes
|
50
|
+
def digest(message)
|
51
|
+
digest = Util.zeros(@digest_size)
|
52
|
+
self.class.generichash_blake2b(digest, @digest_size, message, message.bytesize, @key, @key_size) || raise(CryptoError, "Hashing failed!")
|
53
|
+
digest
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# encoding: binary
|
2
|
+
module RbNaCl
|
3
|
+
module Hash
|
4
|
+
# Provides a binding for the SHA256 function in libsodium
|
5
|
+
module SHA256
|
6
|
+
extend Sodium
|
7
|
+
sodium_type :hash
|
8
|
+
sodium_primitive :sha256
|
9
|
+
sodium_constant :BYTES
|
10
|
+
sodium_function :hash_sha256,
|
11
|
+
:crypto_hash_sha256,
|
12
|
+
[:pointer, :pointer, :ulong_long]
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# encoding: binary
|
2
|
+
module RbNaCl
|
3
|
+
module Hash
|
4
|
+
# Provides the binding for the SHA512 hash function
|
5
|
+
module SHA512
|
6
|
+
extend Sodium
|
7
|
+
sodium_type :hash
|
8
|
+
sodium_primitive :sha512
|
9
|
+
sodium_constant :BYTES
|
10
|
+
sodium_function :hash_sha512,
|
11
|
+
:crypto_hash_sha512,
|
12
|
+
[:pointer, :pointer, :ulong_long]
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/lib/rbnacl/hmac/sha256.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
# encoding: binary
|
2
|
-
module
|
2
|
+
module RbNaCl
|
3
3
|
module HMAC
|
4
4
|
# Computes an authenticator as HMAC-SHA-256
|
5
5
|
#
|
6
|
-
# The authenticator can be used at a later time to verify the
|
6
|
+
# The authenticator can be used at a later time to verify the provenance of
|
7
7
|
# the message by recomputing the HMAC over the message and then comparing it to
|
8
8
|
# the provided authenticator. The class provides methods for generating
|
9
9
|
# signatures and also has a constant-time implementation for checking them.
|
@@ -13,26 +13,28 @@ module Crypto
|
|
13
13
|
#
|
14
14
|
# @see http://nacl.cr.yp.to/auth.html
|
15
15
|
class SHA256 < Auth
|
16
|
-
|
17
|
-
KEYBYTES = NaCl::HMACSHA256_KEYBYTES
|
16
|
+
extend Sodium
|
18
17
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
#
|
24
|
-
# @return [Symbol] The primitive used
|
25
|
-
def self.primitive
|
26
|
-
:hmac_sha256
|
27
|
-
end
|
18
|
+
sodium_type :auth
|
19
|
+
sodium_primitive :hmacsha256
|
20
|
+
sodium_constant :BYTES
|
21
|
+
sodium_constant :KEYBYTES
|
28
22
|
|
23
|
+
sodium_function :auth_hmacsha256,
|
24
|
+
:crypto_auth_hmacsha256,
|
25
|
+
[:pointer, :pointer, :ulong_long, :pointer]
|
26
|
+
|
27
|
+
sodium_function :auth_hmacsha256_verify,
|
28
|
+
:crypto_auth_hmacsha256_verify,
|
29
|
+
[:pointer, :pointer, :ulong_long, :pointer]
|
30
|
+
|
29
31
|
private
|
30
|
-
def compute_authenticator(
|
31
|
-
|
32
|
+
def compute_authenticator(authenticator, message)
|
33
|
+
self.class.auth_hmacsha256(authenticator, message, message.bytesize, key)
|
32
34
|
end
|
33
35
|
|
34
|
-
def verify_message(
|
35
|
-
|
36
|
+
def verify_message(authenticator, message)
|
37
|
+
self.class.auth_hmacsha256_verify(authenticator, message, message.bytesize, key)
|
36
38
|
end
|
37
39
|
end
|
38
40
|
end
|