rbnacl 1.0.0 → 1.1.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.
- 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
|