rbnacl 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/CHANGES.md +3 -4
- data/README.md +41 -14
- data/bascule.cert +21 -0
- data/lib/rbnacl.rb +6 -0
- data/lib/rbnacl/auth.rb +30 -3
- data/lib/rbnacl/auth/one_time.rb +7 -0
- data/lib/rbnacl/box.rb +40 -10
- data/lib/rbnacl/hmac/sha256.rb +7 -0
- data/lib/rbnacl/hmac/sha512256.rb +7 -0
- data/lib/rbnacl/keys/private_key.rb +19 -4
- data/lib/rbnacl/keys/public_key.rb +15 -1
- data/lib/rbnacl/keys/signing_key.rb +30 -9
- data/lib/rbnacl/keys/verify_key.rb +23 -3
- data/lib/rbnacl/nacl.rb +33 -19
- data/lib/rbnacl/point.rb +7 -4
- data/lib/rbnacl/random_nonce_box.rb +7 -2
- data/lib/rbnacl/secret_box.rb +38 -5
- data/lib/rbnacl/version.rb +1 -1
- data/rbnacl.gemspec +2 -2
- data/spec/rbnacl/auth/one_time_spec.rb +1 -1
- data/spec/rbnacl/box_spec.rb +6 -6
- data/spec/rbnacl/hash_spec.rb +10 -2
- data/spec/rbnacl/hmac/sha256_spec.rb +1 -1
- data/spec/rbnacl/hmac/sha512256_spec.rb +1 -1
- data/spec/rbnacl/keys/private_key_spec.rb +12 -12
- data/spec/rbnacl/keys/public_key_spec.rb +10 -10
- data/spec/rbnacl/keys/signing_key_spec.rb +11 -12
- data/spec/rbnacl/keys/verify_key_spec.rb +6 -6
- data/spec/rbnacl/point_spec.rb +10 -10
- data/spec/rbnacl/random_nonce_box_spec.rb +6 -30
- data/spec/rbnacl/secret_box_spec.rb +3 -3
- data/spec/shared/authenticator.rb +5 -5
- data/spec/shared/box.rb +3 -3
- data/spec/spec_helper.rb +12 -0
- metadata +5 -2
- metadata.gz.sig +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5f8462f580b5f1517e510c7cf5137b4dc5edec1f
|
4
|
+
data.tar.gz: e6ef35925227eeb5e49edb8868ab1f375002fa3a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3f66ffdf3087fd9f5b77f85c0e87f68825ed7c9c4cfe07c45d37cab48f299971cd4e07e0a443dde9fa7d7bf245df0834eda82cc4a9f1c4afc52c10cc0602b184
|
7
|
+
data.tar.gz: a25f2a0fbed4b8b09a9c8bbb4e2d4029e0327684483b1aabf7f2ac8d7023cab716b51a78a38c5531c786f9a143ad6b8c5176a6aafa27ca6347a34f4379aaf06c
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
data/CHANGES.md
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
Unreleased!
|
1
|
+
1.0.0 (2013-03-08)
|
2
|
+
------------------
|
3
|
+
* Initial release
|
data/README.md
CHANGED
@@ -13,7 +13,8 @@ This is a crypto library.
|
|
13
13
|
On a completely unrelated topic, RbNaCl is also the empirical formula for
|
14
14
|
Rubidium Sodium Chloride.
|
15
15
|
|
16
|
-
Need help with RbNaCl? Join the [RbNaCl Google Group][group]
|
16
|
+
Need help with RbNaCl? Join the [RbNaCl Google Group][group].
|
17
|
+
We're also on IRC at #cryptosphere on irc.freenode.net
|
17
18
|
|
18
19
|
[nacl]: http://nacl.cr.yp.to/
|
19
20
|
[djb]: http://cr.yp.to/djb.html
|
@@ -51,8 +52,9 @@ For more information on NaCl's goals, see Dan Bernstein's presentation
|
|
51
52
|
You can use RbNaCl anywhere you can get libsodium installed (see below).
|
52
53
|
RbNaCl is continuously integration tested on the following Ruby VMs:
|
53
54
|
|
54
|
-
* MRI
|
55
|
+
* MRI 2.0
|
55
56
|
* MRI 1.9 (YARV)
|
57
|
+
* MRI 1.8 / REE
|
56
58
|
* JRuby 1.7 (in both 1.8/1.9 mode)
|
57
59
|
* Rubinius HEAD (in both 1.8/1.9 mode)
|
58
60
|
|
@@ -74,19 +76,9 @@ for information regarding installation:
|
|
74
76
|
|
75
77
|
https://github.com/jedisct1/libsodium
|
76
78
|
|
77
|
-
|
78
|
-
|
79
|
-
Unfortunately libsodium is not in homebrew proper yet (I would strongly
|
80
|
-
encourage you to [ask for libsodium's inclusion in homebrew][homebrew]),
|
81
|
-
however you can use homebrew's "tap" feature for the time being to
|
82
|
-
install libsodium:
|
83
|
-
|
84
|
-
```
|
85
|
-
brew tap qmx/homebrew-libsodium
|
86
|
-
brew install libsodium
|
87
|
-
```
|
79
|
+
For OS X users, libsodium is available via homebrew and can be installed with:
|
88
80
|
|
89
|
-
|
81
|
+
brew install libsodium
|
90
82
|
|
91
83
|
### RbNaCl gem
|
92
84
|
|
@@ -102,6 +94,12 @@ Or install it yourself as:
|
|
102
94
|
|
103
95
|
$ gem install rbnacl
|
104
96
|
|
97
|
+
Inside of your Ruby program do:
|
98
|
+
|
99
|
+
require 'rbnacl'
|
100
|
+
|
101
|
+
...to pull it in as a dependency.
|
102
|
+
|
105
103
|
## Documentation
|
106
104
|
|
107
105
|
RbNaCl's documentation can be found [in the Wiki][wiki]. The following features
|
@@ -121,12 +119,15 @@ are supported:
|
|
121
119
|
Additional power-user features are available. Please see the Wiki for further
|
122
120
|
information.
|
123
121
|
|
122
|
+
[RDoc documentation][rdoc] is also available.
|
123
|
+
|
124
124
|
[wiki]: https://github.com/cryptosphere/rbnacl/wiki
|
125
125
|
[secretkey]: https://github.com/cryptosphere/rbnacl/wiki/Secret-Key-Encryption
|
126
126
|
[publickey]: https://github.com/cryptosphere/rbnacl/wiki/Public-Key-Encryption
|
127
127
|
[signatures]: https://github.com/cryptosphere/rbnacl/wiki/Digital-Signatures
|
128
128
|
[macs]: https://github.com/cryptosphere/rbnacl/wiki/Authenticators
|
129
129
|
[hashes]: https://github.com/cryptosphere/rbnacl/wiki/Hash-Functions
|
130
|
+
[rdoc]: http://rubydoc.info/github/cryptosphere/rbnacl/master/frames
|
130
131
|
|
131
132
|
## Security Notes
|
132
133
|
|
@@ -138,6 +139,32 @@ by professional cryptographers.
|
|
138
139
|
|
139
140
|
That said, it's probably still a million times better than OpenSSL...
|
140
141
|
|
142
|
+
## Using Signed Gems
|
143
|
+
|
144
|
+
The RbNaCl gem is signed by Tony Arcieri's certificate, which identifies
|
145
|
+
as `bascule@gmail.com`. You can obtain the official certificate with:
|
146
|
+
|
147
|
+
```
|
148
|
+
curl https://raw.github.com/cryptosphere/rbnacl/master/bascule.cert > /tmp/bascule.cert
|
149
|
+
gem cert -a /tmp/bascule.cert
|
150
|
+
```
|
151
|
+
|
152
|
+
You can verify the authenticity of bascule.cert by its SHA256 hash:
|
153
|
+
|
154
|
+
```
|
155
|
+
$ shasum -a 256 bascule.cert
|
156
|
+
6e8b7e53d347ca6c6d214efef2b923aadecdd7650565f0eb1d8d0419723ae20c bascule.cert
|
157
|
+
```
|
158
|
+
|
159
|
+
If you get a different number than `6e8b7e53...`, this is not the cert you are
|
160
|
+
looking for!
|
161
|
+
|
162
|
+
If you'd like to install the gem in high security mode, run:
|
163
|
+
|
164
|
+
```
|
165
|
+
gem install rbnacl-1.0.0.gem -P HighSecurity
|
166
|
+
```
|
167
|
+
|
141
168
|
## Reporting Security Problems
|
142
169
|
|
143
170
|
If you have discovered a bug in RbNaCl of a sensitive nature, i.e.
|
data/bascule.cert
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
-----BEGIN CERTIFICATE-----
|
2
|
+
MIIDbDCCAlSgAwIBAgIBATANBgkqhkiG9w0BAQUFADA+MRAwDgYDVQQDDAdiYXNj
|
3
|
+
dWxlMRUwEwYKCZImiZPyLGQBGRYFZ21haWwxEzARBgoJkiaJk/IsZAEZFgNjb20w
|
4
|
+
HhcNMTMwMzA4MDYwNzA1WhcNMTQwMzA4MDYwNzA1WjA+MRAwDgYDVQQDDAdiYXNj
|
5
|
+
dWxlMRUwEwYKCZImiZPyLGQBGRYFZ21haWwxEzARBgoJkiaJk/IsZAEZFgNjb20w
|
6
|
+
ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC8S9Y1eahE5w/b0P1jVbO4
|
7
|
+
nZbGwJGnGUTPPujZZfCXdkJu1pa8MvsU+pzgm051/yy9bWUp5eMTIjP9Qg+v92gK
|
8
|
+
bfjiUoVwAqISW7zD98gbXwdOgcbCjPFfdP7XmAlxbmq0/T+kYXVngfYo737SukWz
|
9
|
+
/3LLzfmtzBAZipJhTL3EAvlD2O2n2m/JARtxUwHjohd5199BBrSgbjKBXrbZ159F
|
10
|
+
rJzDZef9SLCeXbVL218C4Z4Yf3QvOAvlkBQbYZmD0jnivAvXaoylZnCgIpGUnEiA
|
11
|
+
C3raBW2/zMeKZC7dxygqezxwKiA/u4rxeCK3XDwYlRkF35UtAyIbIJYGODJL4MR9
|
12
|
+
AgMBAAGjdTBzMAkGA1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQWBBRP3DGA
|
13
|
+
NBCsdSMAHGzKpylnYy90ejAcBgNVHREEFTATgRFiYXNjdWxlQGdtYWlsLmNvbTAc
|
14
|
+
BgNVHRIEFTATgRFiYXNjdWxlQGdtYWlsLmNvbTANBgkqhkiG9w0BAQUFAAOCAQEA
|
15
|
+
NhP3rks+x49coXHS0vPPxXb7V0HDnuYP5R+pN1+T2Z7D4qwJKjEF4EC8mQYtwcNe
|
16
|
+
Qquz1t9Uxtr7i3QqjnwhNKlIVig1nikNF+FnApjYs4mwAtMHn77WOwx8wkn7ykej
|
17
|
+
7sF7dRE+BLgpJ88/ycnA6zsEiSQVcIMDVpiYUqUBx+MDNnq5jw5dI0Kct8vBirNA
|
18
|
+
QiZB6YQD1raVKUTpRubo4i0SnGpbMSxMy+YreqwNQiWG9iWCbp0JJWaOPSYTeQHe
|
19
|
+
3L/NVZQttSvxjd+WF6mA9yeCjpomboQMP36GRIZ30SoOVPMGvZ/+QpW52QU7mJW5
|
20
|
+
GzWyf92p0uscgUZVTYixjg==
|
21
|
+
-----END CERTIFICATE-----
|
data/lib/rbnacl.rb
CHANGED
@@ -12,6 +12,12 @@ module Crypto
|
|
12
12
|
# This indicates some argument with an expected length was not that length.
|
13
13
|
# Since this is probably a cryptographic key, you should check that!
|
14
14
|
class LengthError < ArgumentError; end
|
15
|
+
|
16
|
+
# An incorrect primitive has been passed to a method
|
17
|
+
#
|
18
|
+
# This indicates that an attempt has been made to use something (probably a key)
|
19
|
+
# with an incorrect primitive
|
20
|
+
class IncorrectPrimitiveError < ArgumentError; end
|
15
21
|
end
|
16
22
|
|
17
23
|
# TIMTOWTDI!
|
data/lib/rbnacl/auth.rb
CHANGED
@@ -21,7 +21,7 @@ module Crypto
|
|
21
21
|
# @param [#to_sym] encoding decode key from this format (default raw)
|
22
22
|
def initialize(key, encoding = :raw)
|
23
23
|
@key = Encoder[encoding].decode(key)
|
24
|
-
Util.check_length(@key,
|
24
|
+
Util.check_length(@key, key_bytes, "#{self.class} key")
|
25
25
|
end
|
26
26
|
|
27
27
|
# Compute authenticator for message
|
@@ -52,7 +52,7 @@ module Crypto
|
|
52
52
|
#
|
53
53
|
# @return [String] The authenticator in the requested encoding (default raw)
|
54
54
|
def auth(message, authenticator_encoding = :raw)
|
55
|
-
authenticator = Util.zeros(
|
55
|
+
authenticator = Util.zeros(tag_bytes)
|
56
56
|
message = message.to_str
|
57
57
|
compute_authenticator(message, authenticator)
|
58
58
|
Encoder[authenticator_encoding].encode(authenticator)
|
@@ -67,10 +67,37 @@ module Crypto
|
|
67
67
|
# @return [Boolean] Was it valid?
|
68
68
|
def verify(message, authenticator, authenticator_encoding = :raw)
|
69
69
|
auth = Encoder[authenticator_encoding].decode(authenticator)
|
70
|
-
return false unless auth.bytesize ==
|
70
|
+
return false unless auth.bytesize == tag_bytes
|
71
71
|
verify_message(message, auth)
|
72
72
|
end
|
73
73
|
|
74
|
+
# The crypto primitive for this authenticator instance
|
75
|
+
#
|
76
|
+
# @return [Symbol] The primitive used
|
77
|
+
def primitive
|
78
|
+
self.class.primitive
|
79
|
+
end
|
80
|
+
|
81
|
+
# The number of key bytes for this Auth class
|
82
|
+
#
|
83
|
+
# @return [Integer] number of key bytes
|
84
|
+
def self.key_bytes; self::KEYBYTES; end
|
85
|
+
|
86
|
+
# The number of key bytes for this Auth instance
|
87
|
+
#
|
88
|
+
# @return [Integer] number of key bytes
|
89
|
+
def key_bytes; self.class.key_bytes; end
|
90
|
+
|
91
|
+
# The number bytes in the tag or authenticator from this Auth class
|
92
|
+
#
|
93
|
+
# @return [Integer] number of tag bytes
|
94
|
+
def self.tag_bytes; self::BYTES; end
|
95
|
+
|
96
|
+
# The number of bytes in the tag or authenticator for this Auth instance
|
97
|
+
#
|
98
|
+
# @return [Integer] number of tag bytes
|
99
|
+
def tag_bytes; self.class.tag_bytes; end
|
100
|
+
|
74
101
|
private
|
75
102
|
def compute_authenticator(message, authenticator); raise NotImplementedError; end
|
76
103
|
def verify_message(message, authenticator); raise NotImplementedError; end
|
data/lib/rbnacl/auth/one_time.rb
CHANGED
@@ -23,6 +23,13 @@ module Crypto
|
|
23
23
|
|
24
24
|
# Number of bytes in a valid authenticator
|
25
25
|
BYTES = NaCl::ONETIME_BYTES
|
26
|
+
|
27
|
+
# The crypto primitive for the Auth::OneTime class
|
28
|
+
#
|
29
|
+
# @return [Symbol] The primitive used
|
30
|
+
def self.primitive
|
31
|
+
:poly_1305
|
32
|
+
end
|
26
33
|
|
27
34
|
private
|
28
35
|
def compute_authenticator(message, authenticator)
|
data/lib/rbnacl/box.rb
CHANGED
@@ -62,6 +62,9 @@ module Crypto
|
|
62
62
|
# non-repudiatable messages, sign them before or after encryption.
|
63
63
|
class Box
|
64
64
|
|
65
|
+
# Number of bytes in a Box nonce
|
66
|
+
NONCEBYTES = NaCl::CURVE25519_XSALSA20_POLY1305_BOX_NONCEBYTES
|
67
|
+
|
65
68
|
# Create a new Box
|
66
69
|
#
|
67
70
|
# Sets up the Box for deriving the shared key and encrypting and
|
@@ -75,10 +78,9 @@ module Crypto
|
|
75
78
|
#
|
76
79
|
# @return [Crypto::Box] The new Box, ready to use
|
77
80
|
def initialize(public_key, private_key, encoding = :raw)
|
78
|
-
@public_key
|
79
|
-
@private_key
|
80
|
-
|
81
|
-
Util.check_length(@private_key, PrivateKey::BYTES, "Private key")
|
81
|
+
@public_key = PublicKey === public_key ? public_key : PublicKey.new(public_key, encoding)
|
82
|
+
@private_key = PrivateKey === private_key ? private_key : PrivateKey.new(private_key, encoding)
|
83
|
+
raise IncorrectPrimitiveError unless @public_key.primitive == primitive && @private_key.primitive == primitive
|
82
84
|
end
|
83
85
|
|
84
86
|
# Encrypts a message
|
@@ -96,11 +98,11 @@ module Crypto
|
|
96
98
|
#
|
97
99
|
# @return [String] The ciphertext without the nonce prepended (BINARY encoded)
|
98
100
|
def box(nonce, message)
|
99
|
-
Util.check_length(nonce,
|
101
|
+
Util.check_length(nonce, nonce_bytes, "Nonce")
|
100
102
|
msg = Util.prepend_zeros(NaCl::ZEROBYTES, message)
|
101
103
|
ct = Util.zeros(msg.bytesize)
|
102
104
|
|
103
|
-
NaCl.
|
105
|
+
NaCl.crypto_box_curve25519_xsalsa20_poly1305_afternm(ct, msg, msg.bytesize, nonce, beforenm) || raise(CryptoError, "Encryption failed")
|
104
106
|
Util.remove_zeros(NaCl::BOXZEROBYTES, ct)
|
105
107
|
end
|
106
108
|
alias encrypt box
|
@@ -120,20 +122,48 @@ module Crypto
|
|
120
122
|
#
|
121
123
|
# @return [String] The decrypted message (BINARY encoded)
|
122
124
|
def open(nonce, ciphertext)
|
123
|
-
Util.check_length(nonce,
|
125
|
+
Util.check_length(nonce, nonce_bytes, "Nonce")
|
124
126
|
ct = Util.prepend_zeros(NaCl::BOXZEROBYTES, ciphertext)
|
125
127
|
message = Util.zeros(ct.bytesize)
|
126
128
|
|
127
|
-
NaCl.
|
129
|
+
NaCl.crypto_box_curve25519_xsalsa20_poly1305_open_afternm(message, ct, ct.bytesize, nonce, beforenm) || raise(CryptoError, "Decryption failed. Ciphertext failed verification.")
|
128
130
|
Util.remove_zeros(NaCl::ZEROBYTES, message)
|
129
131
|
end
|
130
132
|
alias decrypt open
|
131
133
|
|
134
|
+
# The crypto primitive for the box class
|
135
|
+
#
|
136
|
+
# @return [Symbol] The primitive used
|
137
|
+
def self.primitive
|
138
|
+
:curve25519_xsalsa20_poly1305
|
139
|
+
end
|
140
|
+
|
141
|
+
# The crypto primitive for the box class
|
142
|
+
#
|
143
|
+
# @return [Symbol] The primitive used
|
144
|
+
def primitive
|
145
|
+
self.class.primitive
|
146
|
+
end
|
147
|
+
|
148
|
+
# The nonce bytes for the box class
|
149
|
+
#
|
150
|
+
# @return [Integer] The number of bytes in a valid nonce
|
151
|
+
def self.nonce_bytes
|
152
|
+
NONCEBYTES
|
153
|
+
end
|
154
|
+
|
155
|
+
# The nonce bytes for the box instance
|
156
|
+
#
|
157
|
+
# @return [Integer] The number of bytes in a valid nonce
|
158
|
+
def nonce_bytes
|
159
|
+
NONCEBYTES
|
160
|
+
end
|
161
|
+
|
132
162
|
private
|
133
163
|
def beforenm
|
134
164
|
@k ||= begin
|
135
|
-
k = Util.zeros(NaCl::
|
136
|
-
NaCl.
|
165
|
+
k = Util.zeros(NaCl::CURVE25519_XSALSA20_POLY1305_BOX_BEFORENMBYTES)
|
166
|
+
NaCl.crypto_box_curve25519_xsalsa20_poly1305_beforenm(k, @public_key.to_s, @private_key.to_s) || raise(CryptoError, "Failed to derive shared key")
|
137
167
|
k
|
138
168
|
end
|
139
169
|
end
|
data/lib/rbnacl/hmac/sha256.rb
CHANGED
@@ -19,6 +19,13 @@ module Crypto
|
|
19
19
|
# Number of bytes in a valid authenticator
|
20
20
|
BYTES = NaCl::HMACSHA256_BYTES
|
21
21
|
|
22
|
+
# The crypto primitive for the HMAC::SHA256 class
|
23
|
+
#
|
24
|
+
# @return [Symbol] The primitive used
|
25
|
+
def self.primitive
|
26
|
+
:hmac_sha256
|
27
|
+
end
|
28
|
+
|
22
29
|
private
|
23
30
|
def compute_authenticator(message, authenticator)
|
24
31
|
NaCl.crypto_auth_hmacsha256(authenticator, message, message.bytesize, key)
|
@@ -18,6 +18,13 @@ module Crypto
|
|
18
18
|
|
19
19
|
# Number of bytes in a valid authenticator
|
20
20
|
BYTES = NaCl::HMACSHA512256_BYTES
|
21
|
+
|
22
|
+
# The crypto primitive for the HMAC::SHA512256 class
|
23
|
+
#
|
24
|
+
# @return [Symbol] The primitive used
|
25
|
+
def self.primitive
|
26
|
+
:hmac_sha512256
|
27
|
+
end
|
21
28
|
|
22
29
|
private
|
23
30
|
def compute_authenticator(message, authenticator)
|
@@ -14,7 +14,7 @@ module Crypto
|
|
14
14
|
include Serializable
|
15
15
|
|
16
16
|
# The size of the key, in bytes
|
17
|
-
BYTES =
|
17
|
+
BYTES = NaCl::CURVE25519_XSALSA20_POLY1305_SECRETKEY_BYTES
|
18
18
|
|
19
19
|
# Initializes a new PrivateKey for key operations.
|
20
20
|
#
|
@@ -39,9 +39,9 @@ module Crypto
|
|
39
39
|
#
|
40
40
|
# @return [Crypto::PrivateKey] A new private key, with the associated public key also set.
|
41
41
|
def self.generate
|
42
|
-
pk = Util.zeros(NaCl::
|
43
|
-
sk = Util.zeros(NaCl::
|
44
|
-
NaCl.
|
42
|
+
pk = Util.zeros(NaCl::CURVE25519_XSALSA20_POLY1305_PUBLICKEY_BYTES)
|
43
|
+
sk = Util.zeros(NaCl::CURVE25519_XSALSA20_POLY1305_SECRETKEY_BYTES)
|
44
|
+
NaCl.crypto_box_curve25519xsalsa20poly1305_keypair(pk, sk) || raise(CryptoError, "Failed to generate a key pair")
|
45
45
|
new(sk)
|
46
46
|
end
|
47
47
|
|
@@ -58,5 +58,20 @@ module Crypto
|
|
58
58
|
def public_key
|
59
59
|
@public_key ||= PublicKey.new(Point.base.mult(to_bytes))
|
60
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
|
67
|
+
end
|
68
|
+
|
69
|
+
# The crypto primitive this PrivateKey is to be used for.
|
70
|
+
#
|
71
|
+
# @return [Symbol] The primitive
|
72
|
+
def primitive
|
73
|
+
self.class.primitive
|
74
|
+
end
|
75
|
+
|
61
76
|
end
|
62
77
|
end
|
@@ -9,7 +9,7 @@ module Crypto
|
|
9
9
|
include Serializable
|
10
10
|
|
11
11
|
# The size of the key, in bytes
|
12
|
-
BYTES =
|
12
|
+
BYTES = NaCl::CURVE25519_XSALSA20_POLY1305_PUBLICKEY_BYTES
|
13
13
|
|
14
14
|
# Initializes a new PublicKey for key operations.
|
15
15
|
#
|
@@ -34,5 +34,19 @@ module Crypto
|
|
34
34
|
def to_bytes
|
35
35
|
@public_key
|
36
36
|
end
|
37
|
+
|
38
|
+
# The crypto primitive the PublicKey class is to be used for
|
39
|
+
#
|
40
|
+
# @return [Symbol] The primitive
|
41
|
+
def self.primitive
|
42
|
+
:curve25519_xsalsa20_poly1305
|
43
|
+
end
|
44
|
+
|
45
|
+
# The crypto primitive this PublicKey is to be used for.
|
46
|
+
#
|
47
|
+
# @return [Symbol] The primitive
|
48
|
+
def primitive
|
49
|
+
self.class.primitive
|
50
|
+
end
|
37
51
|
end
|
38
52
|
end
|
@@ -27,7 +27,7 @@ module Crypto
|
|
27
27
|
#
|
28
28
|
# @return [Crypto::SigningKey] Freshly-generated random SigningKey
|
29
29
|
def self.generate
|
30
|
-
new Crypto::Random.random_bytes(NaCl::
|
30
|
+
new Crypto::Random.random_bytes(NaCl::ED25519_SEED_BYTES)
|
31
31
|
end
|
32
32
|
|
33
33
|
# Create a SigningKey from a seed value
|
@@ -39,12 +39,12 @@ module Crypto
|
|
39
39
|
def initialize(seed, encoding = :raw)
|
40
40
|
seed = Encoder[encoding].decode(seed)
|
41
41
|
|
42
|
-
Util.check_length(seed, NaCl::
|
42
|
+
Util.check_length(seed, NaCl::ED25519_SEED_BYTES, "seed")
|
43
43
|
|
44
|
-
pk = Util.zeros(NaCl::
|
45
|
-
sk = Util.zeros(NaCl::
|
44
|
+
pk = Util.zeros(NaCl::ED25519_VERIFYKEY_BYTES)
|
45
|
+
sk = Util.zeros(NaCl::ED25519_SIGNINGKEY_BYTES)
|
46
46
|
|
47
|
-
NaCl.
|
47
|
+
NaCl.crypto_sign_ed25519_seed_keypair(pk, sk, seed) || raise(CryptoError, "Failed to generate a key pair")
|
48
48
|
|
49
49
|
@seed, @signing_key = seed, sk
|
50
50
|
@verify_key = VerifyKey.new(pk)
|
@@ -55,14 +55,14 @@ module Crypto
|
|
55
55
|
# @param message [String] Message to be signed by this key
|
56
56
|
# @param encoding [Symbol] Encode signature in the given format
|
57
57
|
#
|
58
|
-
# @return [String] Signature as bytes
|
58
|
+
# @return [String] Signature as bytes
|
59
59
|
def sign(message, encoding = :raw)
|
60
|
-
buffer = Util.prepend_zeros(
|
60
|
+
buffer = Util.prepend_zeros(signature_bytes, message)
|
61
61
|
buffer_len = Util.zeros(FFI::Type::LONG_LONG.size)
|
62
62
|
|
63
|
-
NaCl.
|
63
|
+
NaCl.crypto_sign_ed25519(buffer, buffer_len, message, message.bytesize, @signing_key)
|
64
64
|
|
65
|
-
signature = buffer[0,
|
65
|
+
signature = buffer[0, signature_bytes]
|
66
66
|
Encoder[encoding].encode(signature)
|
67
67
|
end
|
68
68
|
|
@@ -70,5 +70,26 @@ module Crypto
|
|
70
70
|
#
|
71
71
|
# @return [String] seed used to create this key
|
72
72
|
def to_bytes; @seed; end
|
73
|
+
|
74
|
+
# The crypto primitive the SigningKey class uses for signatures
|
75
|
+
#
|
76
|
+
# @return [Symbol] The primitive
|
77
|
+
def self.primitive; :ed25519; end
|
78
|
+
|
79
|
+
# The crypto primitive this SigningKey class uses for signatures
|
80
|
+
#
|
81
|
+
# @return [Symbol] The primitive
|
82
|
+
def primitive; self.class.primitive; end
|
83
|
+
|
84
|
+
# The size of signatures generated by the SigningKey class
|
85
|
+
#
|
86
|
+
# @return [Integer] The number of bytes in a signature
|
87
|
+
def self.signature_bytes; NaCl::ED25519_SIGNATUREBYTES; end
|
88
|
+
|
89
|
+
# The size of signatures generated by the SigningKey instance
|
90
|
+
#
|
91
|
+
# @return [Integer] The number of bytes in a signature
|
92
|
+
def signature_bytes; NaCl::ED25519_SIGNATUREBYTES; end
|
93
|
+
|
73
94
|
end
|
74
95
|
end
|