rbnacl 3.3.0 → 3.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ee6ee0f334ee9f46c4ec0bc6fd5c82666780740c
4
- data.tar.gz: 26c902ffe1a46d82e0ee822dff3b03ef7a00aae7
3
+ metadata.gz: bcf4ccd28c18cf4c35fbdaf0b6a477e76611dde0
4
+ data.tar.gz: 9e6e95385b32259c3de1a5be583e20f910ba3f9d
5
5
  SHA512:
6
- metadata.gz: 59b17731059eb1eed48984fb657af152eead63527e91840c17cee5114cd9ac579edd0427a1a2dcc3b846714beeecd66739926c9089663d75901d59468e969eef
7
- data.tar.gz: 04ce82d844ae5fdf10c634275db80e56aba13391f9f1364d306b1119ba646b4eff875377b6c94ed05dc9682f935ee8a9db3fc0e5177b8bcb7923ed4fe88eb293
6
+ metadata.gz: 06843ef90fb734f7b2003adf225f78701682766c45fc5f786e4ee2e09347f7b3827df96fa14e39a3347eb097db168327f58e8867f483cbfd07fcc6dbb0870849
7
+ data.tar.gz: 5afb3ed48547db7e6883478654fe4c06065aa2fec84e43ce78d6f950d3cc439130039aad2eb34240bfe1026ed4939efa10878dc31ec5a0faadc67af6f6adfa5c
@@ -9,7 +9,7 @@ LineLength:
9
9
  Style/StringLiterals:
10
10
  EnforcedStyle: double_quotes
11
11
 
12
- Style/SingleSpaceBeforeFirstArg:
12
+ Style/SpaceBeforeFirstArg:
13
13
  Enabled: false
14
14
 
15
15
  Style/GlobalVars:
@@ -20,8 +20,13 @@ Style/GlobalVars:
20
20
  #
21
21
 
22
22
  Metrics/MethodLength:
23
- CountComments: false
24
- Max: 25
23
+ Max: 22
25
24
 
26
25
  Metrics/AbcSize:
27
26
  Max: 20
27
+
28
+ AllCops:
29
+ Include:
30
+ - '**/Rakefile'
31
+ Exclude:
32
+ - 'spec/**/*'
@@ -1,13 +1,20 @@
1
+ language: ruby
2
+ sudo: false
1
3
  script: bundle exec rake ci
4
+ branches:
5
+ only:
6
+ - master
7
+
8
+ bundler_args: --without development
2
9
 
3
10
  rvm:
4
11
  - 2.0.0
5
- - 2.1.8
6
- - 2.2.4
7
- - 2.3.0
12
+ - 2.1.10
13
+ - 2.2.5
14
+ - 2.3.1
8
15
  - ruby-head
9
16
  - jruby
10
- - jruby-9.0.4.0
17
+ - jruby-9.0.5.0
11
18
  - jruby-head
12
19
  - rbx-2
13
20
 
data/CHANGES.md CHANGED
@@ -1,3 +1,13 @@
1
+ 3.4.0 (2015-05-07)
2
+ ------------------
3
+ * [#135](https://github.com/cryptosphere/rbnacl/pull/135)
4
+ Expose RbNaCl::Signatures::Ed25519#keypair_bytes.
5
+ (@grempe)
6
+
7
+ * [#137](https://github.com/cryptosphere/rbnacl/pull/137)
8
+ Expose HMAC-SHA512 (with 64-byte keys)
9
+ (@mwpastore)
10
+
1
11
  3.3.0 (2015-12-29)
2
12
  ------------------
3
13
  * [#105](https://github.com/cryptosphere/rbnacl/pull/105)
data/Gemfile CHANGED
@@ -1,6 +1,5 @@
1
1
  source "https://rubygems.org"
2
2
 
3
- # Specify your gem's dependencies in rbnacl.gemspec
4
3
  gemspec
5
4
 
6
5
  group :development do
@@ -8,6 +7,12 @@ group :development do
8
7
  end
9
8
 
10
9
  group :test do
10
+ gem "rspec"
11
+ gem "rubocop", "0.39.0"
11
12
  gem "coveralls", require: false
12
13
  gem "rbnacl-libsodium", ENV["LIBSODIUM_VERSION"]
13
14
  end
15
+
16
+ group :development, :test do
17
+ gem "rake"
18
+ end
data/README.md CHANGED
@@ -4,6 +4,7 @@
4
4
  [![Build Status](https://travis-ci.org/cryptosphere/rbnacl.svg?branch=master)](https://travis-ci.org/cryptosphere/rbnacl)
5
5
  [![Code Climate](https://codeclimate.com/github/cryptosphere/rbnacl.svg)](https://codeclimate.com/github/cryptosphere/rbnacl)
6
6
  [![Coverage Status](https://coveralls.io/repos/cryptosphere/rbnacl/badge.svg?branch=master)](https://coveralls.io/r/cryptosphere/rbnacl)
7
+ [![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/cryptosphere/rbnacl/blob/master/LICENSE.txt)
7
8
 
8
9
  A Ruby binding to the state-of-the-art [Networking and Cryptography][nacl]
9
10
  library by [Daniel J. Bernstein][djb]. This is **NOT** Google Native Client.
@@ -71,6 +72,8 @@ To use RbNaCl, you will need to install libsodium:
71
72
 
72
73
  https://github.com/jedisct1/libsodium
73
74
 
75
+ At least version `1.0.0` is recommended.
76
+
74
77
  For OS X users, libsodium is available via homebrew and can be installed with:
75
78
 
76
79
  brew install libsodium
@@ -195,5 +198,5 @@ Sure, here you go:
195
198
 
196
199
  ## License
197
200
 
198
- Copyright (c) 2012-2015 Jonathan Stott, Tony Arcieri.
199
- Distributed under the MIT License. See LICENSE.txt for further details.
201
+ Copyright (c) 2012-2016 Jonathan Stott, Tony Arcieri. Distributed under the MIT License.
202
+ See LICENSE.txt for further details.
@@ -67,9 +67,10 @@ module RbNaCl
67
67
  require "rbnacl/password_hash"
68
68
  require "rbnacl/password_hash/scrypt"
69
69
 
70
- # HMAC: SHA256 and SHA512256
70
+ # HMAC: SHA256/512 and SHA512256
71
71
  require "rbnacl/hmac/sha256"
72
72
  require "rbnacl/hmac/sha512256"
73
+ require "rbnacl/hmac/sha512"
73
74
 
74
75
  #
75
76
  # Bind aliases used by the public API
@@ -70,7 +70,7 @@ module RbNaCl
70
70
  def verify(authenticator, message)
71
71
  auth = authenticator.to_s
72
72
  Util.check_length(auth, tag_bytes, "Provided authenticator")
73
- verify_message(auth, message) || fail(BadAuthenticatorError, "Invalid authenticator provided, message is corrupt")
73
+ verify_message(auth, message) || raise(BadAuthenticatorError, "Invalid authenticator provided, message is corrupt")
74
74
  end
75
75
 
76
76
  # The crypto primitive for this authenticator instance
@@ -111,11 +111,11 @@ module RbNaCl
111
111
  private
112
112
 
113
113
  def compute_authenticator(_authenticator, _message)
114
- fail NotImplementedError
114
+ raise NotImplementedError
115
115
  end
116
116
 
117
117
  def verify_message(_authenticator, _message)
118
- fail NotImplementedError
118
+ raise NotImplementedError
119
119
  end
120
120
  end
121
121
  end
@@ -99,7 +99,7 @@ module RbNaCl
99
99
  def initialize(public_key, private_key)
100
100
  @public_key = public_key.is_a?(PublicKey) ? public_key : PublicKey.new(public_key)
101
101
  @private_key = private_key.is_a?(PrivateKey) ? private_key : PrivateKey.new(private_key)
102
- fail IncorrectPrimitiveError unless @public_key.primitive == primitive && @private_key.primitive == primitive
102
+ raise IncorrectPrimitiveError unless @public_key.primitive == primitive && @private_key.primitive == primitive
103
103
  end
104
104
 
105
105
  # Encrypts a message
@@ -121,10 +121,10 @@ module RbNaCl
121
121
  msg = Util.prepend_zeros(ZEROBYTES, message)
122
122
  ct = Util.zeros(msg.bytesize)
123
123
 
124
- self.class.box_curve25519xsalsa20poly1305_afternm(ct, msg, msg.bytesize, nonce, beforenm) || fail(CryptoError, "Encryption failed")
124
+ self.class.box_curve25519xsalsa20poly1305_afternm(ct, msg, msg.bytesize, nonce, beforenm) || raise(CryptoError, "Encryption failed")
125
125
  Util.remove_zeros(BOXZEROBYTES, ct)
126
126
  end
127
- alias_method :encrypt, :box
127
+ alias encrypt box
128
128
 
129
129
  # Decrypts a ciphertext
130
130
  #
@@ -146,11 +146,11 @@ module RbNaCl
146
146
  message = Util.zeros(ct.bytesize)
147
147
 
148
148
  success = self.class.box_curve25519xsalsa20poly1305_open_afternm(message, ct, ct.bytesize, nonce, beforenm)
149
- fail CryptoError, "Decryption failed. Ciphertext failed verification." unless success
149
+ raise CryptoError, "Decryption failed. Ciphertext failed verification." unless success
150
150
 
151
151
  Util.remove_zeros(ZEROBYTES, message)
152
152
  end
153
- alias_method :decrypt, :open
153
+ alias decrypt open
154
154
 
155
155
  # The crypto primitive for the box class
156
156
  #
@@ -179,7 +179,7 @@ module RbNaCl
179
179
  @_key ||= begin
180
180
  key = Util.zeros(BEFORENMBYTES)
181
181
  success = self.class.box_curve25519xsalsa20poly1305_beforenm(key, @public_key.to_s, @private_key.to_s)
182
- fail CryptoError, "Failed to derive shared key" unless success
182
+ raise CryptoError, "Failed to derive shared key" unless success
183
183
  key
184
184
  end
185
185
  end
@@ -52,7 +52,7 @@ module RbNaCl
52
52
  def self.generate
53
53
  pk = Util.zeros(Boxes::Curve25519XSalsa20Poly1305::PUBLICKEYBYTES)
54
54
  sk = Util.zeros(Boxes::Curve25519XSalsa20Poly1305::PRIVATEKEYBYTES)
55
- box_curve25519xsalsa20poly1305_keypair(pk, sk) || fail(CryptoError, "Failed to generate a key pair")
55
+ box_curve25519xsalsa20poly1305_keypair(pk, sk) || raise(CryptoError, "Failed to generate a key pair")
56
56
  new(sk)
57
57
  end
58
58
 
@@ -25,7 +25,7 @@ module RbNaCl
25
25
  def self.sha256(data)
26
26
  data = data.to_str
27
27
  digest = Util.zeros(SHA256::BYTES)
28
- SHA256.hash_sha256(digest, data, data.bytesize) || fail(CryptoError, "Hashing failed!")
28
+ SHA256.hash_sha256(digest, data, data.bytesize) || raise(CryptoError, "Hashing failed!")
29
29
  digest
30
30
  end
31
31
 
@@ -40,7 +40,7 @@ module RbNaCl
40
40
  # @return [String] The SHA-512 hash digest as raw bytes
41
41
  def self.sha512(data)
42
42
  digest = Util.zeros(SHA512::BYTES)
43
- SHA512.hash_sha512(digest, data, data.bytesize) || fail(CryptoError, "Hashing failed!")
43
+ SHA512.hash_sha512(digest, data, data.bytesize) || raise(CryptoError, "Hashing failed!")
44
44
  digest
45
45
  end
46
46
 
@@ -47,15 +47,15 @@ module RbNaCl
47
47
 
48
48
  if @key
49
49
  @key_size = @key.bytesize
50
- fail LengthError, "key too short" if @key_size < KEYBYTES_MIN
51
- fail LengthError, "key too long" if @key_size > KEYBYTES_MAX
50
+ raise LengthError, "key too short" if @key_size < KEYBYTES_MIN
51
+ raise LengthError, "key too long" if @key_size > KEYBYTES_MAX
52
52
  else
53
53
  @key_size = 0
54
54
  end
55
55
 
56
56
  @digest_size = opts.fetch(:digest_size, BYTES_MAX)
57
- fail LengthError, "digest size too short" if @digest_size < BYTES_MIN
58
- fail LengthError, "digest size too long" if @digest_size > BYTES_MAX
57
+ raise LengthError, "digest size too short" if @digest_size < BYTES_MIN
58
+ raise LengthError, "digest size too long" if @digest_size > BYTES_MAX
59
59
 
60
60
  @personal = opts.fetch(:personal, EMPTY_PERSONAL)
61
61
  @personal = Util.zero_pad(PERSONALBYTES, @personal)
@@ -72,7 +72,7 @@ module RbNaCl
72
72
  def digest(message)
73
73
  digest = Util.zeros(@digest_size)
74
74
  self.class.generichash_blake2b(digest, @digest_size, message, message.bytesize, @key, @key_size, @salt, @personal) ||
75
- fail(CryptoError, "Hashing failed!")
75
+ raise(CryptoError, "Hashing failed!")
76
76
  digest
77
77
  end
78
78
  end
@@ -0,0 +1,42 @@
1
+ # encoding: binary
2
+ module RbNaCl
3
+ module HMAC
4
+ # Computes an authenticator as HMAC-SHA-512
5
+ #
6
+ # The authenticator can be used at a later time to verify the provenance of
7
+ # the message by recomputing the HMAC over the message and then comparing it to
8
+ # the provided authenticator. The class provides methods for generating
9
+ # signatures and also has a constant-time implementation for checking them.
10
+ #
11
+ # This is a secret key authenticator, i.e. anyone who can verify signatures
12
+ # can also create them.
13
+ #
14
+ # @see http://nacl.cr.yp.to/auth.html
15
+ class SHA512 < Auth
16
+ extend Sodium
17
+
18
+ sodium_type :auth
19
+ sodium_primitive :hmacsha512
20
+ sodium_constant :BYTES
21
+ sodium_constant :KEYBYTES
22
+
23
+ sodium_function :auth_hmacsha512,
24
+ :crypto_auth_hmacsha512,
25
+ [:pointer, :pointer, :ulong_long, :pointer]
26
+
27
+ sodium_function :auth_hmacsha512_verify,
28
+ :crypto_auth_hmacsha512_verify,
29
+ [:pointer, :pointer, :ulong_long, :pointer]
30
+
31
+ private
32
+
33
+ def compute_authenticator(authenticator, message)
34
+ self.class.auth_hmacsha512(authenticator, message, message.bytesize, key)
35
+ end
36
+
37
+ def verify_message(authenticator, message)
38
+ self.class.auth_hmacsha512_verify(authenticator, message, message.bytesize, key)
39
+ end
40
+ end
41
+ end
42
+ end
@@ -22,14 +22,7 @@ module RbNaCl
22
22
  else
23
23
  return nil
24
24
  end
25
-
26
- if Util.verify32(to_bytes, other)
27
- return 0
28
- elsif to_bytes > other
29
- return 1
30
- else
31
- return -1
32
- end
25
+ compare32(other)
33
26
  end
34
27
 
35
28
  # equality operator
@@ -55,5 +48,17 @@ module RbNaCl
55
48
  end
56
49
  Util.verify32(to_bytes, other)
57
50
  end
51
+
52
+ private
53
+
54
+ def compare32(other)
55
+ if Util.verify32(to_bytes, other)
56
+ 0
57
+ elsif to_bytes > other
58
+ 1
59
+ else
60
+ -1
61
+ end
62
+ end
58
63
  end
59
64
  end
@@ -17,52 +17,45 @@ module RbNaCl
17
17
  # on GPUs or FPGAs) with additional computation.
18
18
  class SCrypt
19
19
  extend Sodium
20
+ sodium_type :pwhash
21
+ sodium_primitive :scryptsalsa208sha256
22
+
23
+ sodium_constant :SALTBYTES
24
+
25
+ sodium_function :scrypt,
26
+ :crypto_pwhash_scryptsalsa208sha256,
27
+ [:pointer, :ulong_long, :pointer, :ulong_long, :pointer, :ulong_long, :size_t]
28
+
29
+ # Create a new SCrypt password hash object
30
+ #
31
+ # @param [Integer] opslimit the CPU cost (e.g. 2**20)
32
+ # @param [Integer] memlimit the memory cost (e.g. 2**24)
33
+ #
34
+ # @return [RbNaCl::PasswordHash::SCrypt] An SCrypt password hasher object
35
+ def initialize(opslimit, memlimit, digest_size = 64)
36
+ # TODO: sanity check these parameters
37
+ @opslimit = opslimit
38
+ @memlimit = memlimit
39
+
40
+ # TODO: check digest size validity
41
+ # raise LengthError, "digest size too short" if @digest_size < BYTES_MIN
42
+ # raise LengthError, "digest size too long" if @digest_size > BYTES_MAX
43
+
44
+ @digest_size = digest_size
45
+ end
20
46
 
21
- begin
22
- sodium_type :pwhash
23
- sodium_primitive :scryptsalsa208sha256
24
-
25
- sodium_constant :SALTBYTES
26
-
27
- sodium_function :scrypt,
28
- :crypto_pwhash_scryptsalsa208sha256,
29
- [:pointer, :ulong_long, :pointer, :ulong_long, :pointer, :ulong_long, :size_t]
30
-
31
- # Create a new SCrypt password hash object
32
- #
33
- # @param [Integer] opslimit the CPU cost (e.g. 2**20)
34
- # @param [Integer] memlimit the memory cost (e.g. 2**24)
35
- #
36
- # @return [RbNaCl::PasswordHash::SCrypt] An SCrypt password hasher object
37
- def initialize(opslimit, memlimit, digest_size = 64)
38
- # TODO: sanity check these parameters
39
- @opslimit = opslimit
40
- @memlimit = memlimit
41
-
42
- # TODO: check digest size validity
43
- # raise LengthError, "digest size too short" if @digest_size < BYTES_MIN
44
- # raise LengthError, "digest size too long" if @digest_size > BYTES_MAX
45
-
46
- @digest_size = digest_size
47
- end
48
-
49
- # Calculate an scrypt digest for a given password and salt
50
- #
51
- # @param [String] password to be hashed
52
- # @param [String] salt to make the digest unique
53
- #
54
- # @return [String] scrypt digest of the string as raw bytes
55
- def digest(password, salt)
56
- digest = Util.zeros(@digest_size)
57
- salt = Util.check_string(salt, SALTBYTES, "salt")
58
-
59
- self.class.scrypt(digest, @digest_size, password, password.bytesize, salt, @opslimit, @memlimit) || fail(CryptoError, "scrypt failed!")
60
- digest
61
- end
62
- rescue FFI::NotFoundError
63
- def initialize(_opslimit, _memlimit, _digest_size = 64)
64
- raise NotImplementedError, "scrypt not implemented in this version of libsodium"
65
- end
47
+ # Calculate an scrypt digest for a given password and salt
48
+ #
49
+ # @param [String] password to be hashed
50
+ # @param [String] salt to make the digest unique
51
+ #
52
+ # @return [String] scrypt digest of the string as raw bytes
53
+ def digest(password, salt)
54
+ digest = Util.zeros(@digest_size)
55
+ salt = Util.check_string(salt, SALTBYTES, "salt")
56
+
57
+ self.class.scrypt(digest, @digest_size, password, password.bytesize, salt, @opslimit, @memlimit) || raise(CryptoError, "scrypt failed!")
58
+ digest
66
59
  end
67
60
  end
68
61
  end
@@ -68,11 +68,11 @@ module RbNaCl
68
68
  ct = Util.zeros(msg.bytesize)
69
69
 
70
70
  success = self.class.secretbox_xsalsa20poly1305(ct, msg, msg.bytesize, nonce, @key)
71
- fail CryptoError, "Encryption failed" unless success
71
+ raise CryptoError, "Encryption failed" unless success
72
72
 
73
73
  Util.remove_zeros(BOXZEROBYTES, ct)
74
74
  end
75
- alias_method :encrypt, :box
75
+ alias encrypt box
76
76
 
77
77
  # Decrypts a ciphertext
78
78
  #
@@ -94,11 +94,11 @@ module RbNaCl
94
94
  message = Util.zeros(ct.bytesize)
95
95
 
96
96
  success = self.class.secretbox_xsalsa20poly1305_open(message, ct, ct.bytesize, nonce, @key)
97
- fail CryptoError, "Decryption failed. Ciphertext failed verification." unless success
97
+ raise CryptoError, "Decryption failed. Ciphertext failed verification." unless success
98
98
 
99
99
  Util.remove_zeros(ZEROBYTES, message)
100
100
  end
101
- alias_method :decrypt, :open
101
+ alias decrypt open
102
102
 
103
103
  # The crypto primitive for the SecretBox instance
104
104
  #
@@ -32,8 +32,8 @@ module RbNaCl
32
32
  message = vector :box_message
33
33
  ciphertext = vector :box_ciphertext
34
34
 
35
- fail SelfTestFailure, "failed to generate correct ciphertext" unless box.encrypt(nonce, message) == ciphertext
36
- fail SelfTestFailure, "failed to decrypt ciphertext correctly" unless box.decrypt(nonce, ciphertext) == message
35
+ raise SelfTestFailure, "failed to generate correct ciphertext" unless box.encrypt(nonce, message) == ciphertext
36
+ raise SelfTestFailure, "failed to decrypt ciphertext correctly" unless box.decrypt(nonce, ciphertext) == message
37
37
 
38
38
  begin
39
39
  passed = false
@@ -43,7 +43,7 @@ module RbNaCl
43
43
  rescue CryptoError
44
44
  passed = true
45
45
  ensure
46
- passed || fail(SelfTestFailure, "failed to detect corrupt ciphertext")
46
+ passed || raise(SelfTestFailure, "failed to detect corrupt ciphertext")
47
47
  end
48
48
  end
49
49
 
@@ -53,7 +53,7 @@ module RbNaCl
53
53
 
54
54
  unless verify_key.to_s == vector(:sign_public)
55
55
  #:nocov:
56
- fail SelfTestFailure, "failed to generate verify key correctly"
56
+ raise SelfTestFailure, "failed to generate verify key correctly"
57
57
  #:nocov:
58
58
  end
59
59
 
@@ -62,13 +62,13 @@ module RbNaCl
62
62
 
63
63
  unless signature == vector(:sign_signature)
64
64
  #:nocov:
65
- fail SelfTestFailure, "failed to generate correct signature"
65
+ raise SelfTestFailure, "failed to generate correct signature"
66
66
  #:nocov:
67
67
  end
68
68
 
69
69
  unless verify_key.verify(signature, message)
70
70
  #:nocov:
71
- fail SelfTestFailure, "failed to verify a valid signature"
71
+ raise SelfTestFailure, "failed to verify a valid signature"
72
72
  #:nocov:
73
73
  end
74
74
 
@@ -79,7 +79,7 @@ module RbNaCl
79
79
  rescue CryptoError
80
80
  passed = true
81
81
  ensure
82
- passed || fail(SelfTestFailure, "failed to detect corrupt ciphertext")
82
+ passed || raise(SelfTestFailure, "failed to detect corrupt ciphertext")
83
83
  end
84
84
  end
85
85
 
@@ -87,16 +87,16 @@ module RbNaCl
87
87
  message = vector :sha256_message
88
88
  digest = vector :sha256_digest
89
89
 
90
- fail SelfTestFailure, "failed to generate a correct SHA256 digest" unless RbNaCl::Hash.sha256(message) == digest
90
+ raise SelfTestFailure, "failed to generate a correct SHA256 digest" unless RbNaCl::Hash.sha256(message) == digest
91
91
  end
92
92
 
93
93
  def hmac_test(klass, tag)
94
- authenticator = klass.new(vector(:auth_key))
94
+ authenticator = klass.new(vector("auth_key_#{klass.key_bytes}".to_sym))
95
95
 
96
96
  message = vector :auth_message
97
97
 
98
- fail SelfTestFailure, "#{klass} failed to generate correct authentication tag" unless authenticator.auth(message) == vector(tag)
99
- fail SelfTestFailure, "#{klass} failed to verify correct authentication tag" unless authenticator.verify(vector(tag), message)
98
+ raise SelfTestFailure, "#{klass} failed to generate correct authentication tag" unless authenticator.auth(message) == vector(tag)
99
+ raise SelfTestFailure, "#{klass} failed to verify correct authentication tag" unless authenticator.verify(vector(tag), message)
100
100
 
101
101
  begin
102
102
  passed = false
@@ -104,7 +104,7 @@ module RbNaCl
104
104
  rescue CryptoError
105
105
  passed = true
106
106
  ensure
107
- passed || fail(SelfTestFailure, "failed to detect corrupt ciphertext")
107
+ passed || raise(SelfTestFailure, "failed to detect corrupt ciphertext")
108
108
  end
109
109
  end
110
110
  end
@@ -58,7 +58,7 @@ module RbNaCl
58
58
  pk = Util.zeros(Ed25519::VERIFYKEYBYTES)
59
59
  sk = Util.zeros(Ed25519::SIGNINGKEYBYTES)
60
60
 
61
- self.class.sign_ed25519_seed_keypair(pk, sk, seed) || fail(CryptoError, "Failed to generate a key pair")
61
+ self.class.sign_ed25519_seed_keypair(pk, sk, seed) || raise(CryptoError, "Failed to generate a key pair")
62
62
 
63
63
  @seed = seed
64
64
  @signing_key = sk
@@ -86,6 +86,14 @@ module RbNaCl
86
86
  @seed
87
87
  end
88
88
 
89
+ # Return the raw 64 byte value of this key
90
+ #
91
+ # @return [String] The signature key bytes. Left half is 32-byte
92
+ # curve25519 private scalar, right half is 32-byte group element
93
+ def keypair_bytes
94
+ @signing_key
95
+ end
96
+
89
97
  # The crypto primitive this SigningKey class uses for signatures
90
98
  #
91
99
  # @return [Symbol] The primitive
@@ -51,7 +51,7 @@ module RbNaCl
51
51
  buffer_len = Util.zeros(FFI::Type::LONG_LONG.size)
52
52
 
53
53
  success = self.class.sign_ed25519_open(buffer, buffer_len, sig_and_msg, sig_and_msg.bytesize, @key)
54
- fail(BadSignatureError, "signature was forged/corrupt") unless success
54
+ raise(BadSignatureError, "signature was forged/corrupt") unless success
55
55
 
56
56
  true
57
57
  end
@@ -80,7 +80,7 @@ module RbNaCl
80
80
  cipher_text = @box.box(nonce, message)
81
81
  nonce + cipher_text
82
82
  end
83
- alias_method :encrypt, :box
83
+ alias encrypt box
84
84
 
85
85
  # Decrypts the ciphertext with a random nonce
86
86
  #
@@ -96,7 +96,7 @@ module RbNaCl
96
96
  nonce, ciphertext = extract_nonce(enciphered_message.to_s)
97
97
  @box.open(nonce, ciphertext)
98
98
  end
99
- alias_method :decrypt, :open
99
+ alias decrypt open
100
100
 
101
101
  private
102
102
 
@@ -4,7 +4,7 @@ module RbNaCl
4
4
  module Sodium
5
5
  # libsodium version API
6
6
  module Version
7
- MINIMUM_LIBSODIUM_VERSION = "0.4.3"
7
+ MINIMUM_LIBSODIUM_VERSION = "0.4.3".freeze
8
8
 
9
9
  extend Sodium
10
10
  attach_function :sodium_version_string, [], :string
@@ -17,7 +17,7 @@ module RbNaCl
17
17
 
18
18
  case installed_version <=> minimum_version
19
19
  when -1
20
- fail "Sorry, you need to install libsodium #{MINIMUM_LIBSODIUM_VERSION}+. You have #{Version::STRING} installed"
20
+ raise "Sorry, you need to install libsodium #{MINIMUM_LIBSODIUM_VERSION}+. You have #{Version::STRING} installed"
21
21
  end
22
22
  end
23
23
  end
@@ -122,7 +122,9 @@ module RbNaCl
122
122
  # Auth test vectors
123
123
  # Taken from NaCl distribution
124
124
  #
125
- auth_key: "eea6a7251c1e72916d11c2cb214d3c252539121d8e234e652d651fa4c8cff880",
125
+ auth_key_32: "eea6a7251c1e72916d11c2cb214d3c252539121d8e234e652d651fa4c8cff880",
126
+ auth_key_64: "eaaa4c73ef13e7e9a53011304c5be141da9c3713b5ca822037ed57aded31b70a" \
127
+ "50a0dd80843d580fe5b57e470bb534333e907a624cf02873c6b9eaba70e0fc7e",
126
128
  auth_message: "8e993b9f48681273c29650ba32fc76ce48332ea7164d96a4476fb8c531a1186a" \
127
129
  "c0dfc17c98dce87b4da7f011ec48c97271d2c20f9b928fe2270d6fb863d51738" \
128
130
  "b48eeee314a7cc8ab932164548e526ae90224368517acfeabd6bb3732bc0e9da" \
@@ -131,6 +133,8 @@ module RbNaCl
131
133
  auth_onetime: "f3ffc7703f9400e52a7dfb4b3d3305d9",
132
134
  # self-created (FIXME: find standard test vectors)
133
135
  auth_hmacsha256: "7f7b9b707e8790ca8620ff94df5e6533ddc8e994060ce310c9d7de04d44aabc3",
134
- auth_hmacsha512256: "b2a31b8d4e01afcab2ee545b5caf4e3d212a99d7b3a116a97cec8e83c32e107d"
135
- }
136
+ auth_hmacsha512256: "b2a31b8d4e01afcab2ee545b5caf4e3d212a99d7b3a116a97cec8e83c32e107d",
137
+ auth_hmacsha512: "b2a31b8d4e01afcab2ee545b5caf4e3d212a99d7b3a116a97cec8e83c32e107d" \
138
+ "270e3921f69016c267a63ab4b226449a0dee0dc7dcb897a9bce9d27d788f8e8d"
139
+ }.freeze
136
140
  end
@@ -60,7 +60,7 @@ module RbNaCl
60
60
  if len == n
61
61
  message
62
62
  elsif len > n
63
- fail LengthError, "String too long for zero-padding to #{n} bytes"
63
+ raise LengthError, "String too long for zero-padding to #{n} bytes"
64
64
  else
65
65
  message + zeros(n - len)
66
66
  end
@@ -78,15 +78,15 @@ module RbNaCl
78
78
  # @param description [String] Description of the string (used in the error)
79
79
  def check_length(string, length, description)
80
80
  if string.nil?
81
- fail LengthError,
82
- "#{description} was nil (Expected #{length.to_int})",
83
- caller
81
+ raise LengthError,
82
+ "#{description} was nil (Expected #{length.to_int})",
83
+ caller
84
84
  end
85
85
 
86
86
  if string.bytesize != length.to_int
87
- fail LengthError,
88
- "#{description} was #{string.bytesize} bytes (Expected #{length.to_int})",
89
- caller
87
+ raise LengthError,
88
+ "#{description} was #{string.bytesize} bytes (Expected #{length.to_int})",
89
+ caller
90
90
  end
91
91
  true
92
92
  end
@@ -104,12 +104,12 @@ module RbNaCl
104
104
  # @param description [String] Description of the string (used in the error)
105
105
  def check_string(string, length, description)
106
106
  unless string.respond_to? :to_str
107
- fail TypeError, "can't convert #{string.class} into String with #to_str"
107
+ raise TypeError, "can't convert #{string.class} into String with #to_str"
108
108
  end
109
109
 
110
110
  string = string.to_str
111
111
  unless string.encoding == Encoding::BINARY
112
- fail EncodingError, "strings must use BINARY encoding (got #{string.encoding})"
112
+ raise EncodingError, "strings must use BINARY encoding (got #{string.encoding})"
113
113
  end
114
114
  check_length(string, length, description)
115
115
 
@@ -3,5 +3,5 @@
3
3
  # NaCl/libsodium for Ruby
4
4
  module RbNaCl
5
5
  # The library's version
6
- VERSION = "3.3.0"
6
+ VERSION = "3.4.0".freeze
7
7
  end
@@ -0,0 +1,8 @@
1
+ # encoding: binary
2
+ require "spec_helper"
3
+
4
+ RSpec.describe RbNaCl::HMAC::SHA512 do
5
+ let(:tag) { vector :auth_hmacsha512 }
6
+
7
+ include_examples "authenticator"
8
+ end
@@ -20,6 +20,11 @@ RSpec.describe RbNaCl::SigningKey do
20
20
  expect(subject.to_bytes).to eq signing_key
21
21
  end
22
22
 
23
+ it "serializes the internal signing key to bytes" do
24
+ expect(subject.keypair_bytes.length).to eq 64
25
+ expect(subject.keypair_bytes).to eq "\xB1\x8E\x1D\x00E\x99^\xC3\xD0\x10\xC3\x87\xCC\xFE\xB9\x84\xD7\x83\xAF\x8F\xBB\x0F@\xFA}\xB1&\xD8\x89\xF6\xDA\xDDw\xF4\x8BY\xCA\xED\xA7wQ\xED\x13\x8B\x0E\xC6g\xFFP\xF8v\x8C%\xD4\x83\t\xA8\xF3\x86\xA2\xBA\xD1\x87\xFB"
26
+ end
27
+
23
28
  include_examples "key equality" do
24
29
  let(:key_bytes) { signing_key }
25
30
  let(:key) { described_class.new(key_bytes) }
@@ -1,6 +1,6 @@
1
1
  # encoding: binary
2
2
  RSpec.shared_examples "authenticator" do
3
- let(:key) { vector :auth_key }
3
+ let(:key) { vector "auth_key_#{described_class.key_bytes}".to_sym }
4
4
  let(:message) { vector :auth_message }
5
5
 
6
6
  context ".new" do
@@ -17,11 +17,11 @@ RSpec.shared_examples "authenticator" do
17
17
  end
18
18
 
19
19
  it "raises ArgumentError on a key which is too long" do
20
- expect { described_class.new("\0" * 33) }.to raise_error(ArgumentError)
20
+ expect { described_class.new("\0" * described_class.key_bytes.succ) }.to raise_error(ArgumentError)
21
21
  end
22
22
 
23
23
  it "raises ArgumentError on a key which is too short" do
24
- expect { described_class.new("\0" * 31) }.to raise_error(ArgumentError)
24
+ expect { described_class.new("\0" * described_class.key_bytes.pred) }.to raise_error(ArgumentError)
25
25
  end
26
26
  end
27
27
 
@@ -35,7 +35,7 @@ RSpec.shared_examples "authenticator" do
35
35
  end
36
36
 
37
37
  it "raises ArgumentError on a key which is too long" do
38
- expect { described_class.auth("\0" * 33, message) }.to raise_error(ArgumentError)
38
+ expect { described_class.auth("\0" * described_class.key_bytes.succ, message) }.to raise_error(ArgumentError)
39
39
  end
40
40
  end
41
41
 
@@ -49,7 +49,7 @@ RSpec.shared_examples "authenticator" do
49
49
  end
50
50
 
51
51
  it "raises ArgumentError on a key which is too long" do
52
- expect { described_class.verify("\0" * 33, tag, message) }.to raise_error(ArgumentError)
52
+ expect { described_class.verify("\0" * described_class.key_bytes.succ, tag, message) }.to raise_error(ArgumentError)
53
53
  end
54
54
 
55
55
  it "fails to validate an invalid authenticator" do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rbnacl
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.3.0
4
+ version: 3.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tony Arcieri
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain:
12
12
  - bascule.cert
13
- date: 2015-12-30 00:00:00.000000000 Z
13
+ date: 2016-05-07 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: ffi
@@ -105,6 +105,7 @@ files:
105
105
  - lib/rbnacl/hash/sha256.rb
106
106
  - lib/rbnacl/hash/sha512.rb
107
107
  - lib/rbnacl/hmac/sha256.rb
108
+ - lib/rbnacl/hmac/sha512.rb
108
109
  - lib/rbnacl/hmac/sha512256.rb
109
110
  - lib/rbnacl/init.rb
110
111
  - lib/rbnacl/key_comparator.rb
@@ -134,6 +135,7 @@ files:
134
135
  - spec/rbnacl/hash_spec.rb
135
136
  - spec/rbnacl/hmac/sha256_spec.rb
136
137
  - spec/rbnacl/hmac/sha512256_spec.rb
138
+ - spec/rbnacl/hmac/sha512_spec.rb
137
139
  - spec/rbnacl/password_hash/scrypt_spec.rb
138
140
  - spec/rbnacl/random_spec.rb
139
141
  - spec/rbnacl/secret_box_spec.rb
@@ -183,6 +185,7 @@ test_files:
183
185
  - spec/rbnacl/hash_spec.rb
184
186
  - spec/rbnacl/hmac/sha256_spec.rb
185
187
  - spec/rbnacl/hmac/sha512256_spec.rb
188
+ - spec/rbnacl/hmac/sha512_spec.rb
186
189
  - spec/rbnacl/password_hash/scrypt_spec.rb
187
190
  - spec/rbnacl/random_spec.rb
188
191
  - spec/rbnacl/secret_box_spec.rb
@@ -195,4 +198,3 @@ test_files:
195
198
  - spec/shared/key_equality.rb
196
199
  - spec/shared/serializable.rb
197
200
  - spec/spec_helper.rb
198
- has_rdoc: