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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 15ef68a1b4b1742cf2b8a582119a6772c5faa159
4
- data.tar.gz: 28a60711d07476e92d19c42981c58ced76e46d22
3
+ metadata.gz: 5f8462f580b5f1517e510c7cf5137b4dc5edec1f
4
+ data.tar.gz: e6ef35925227eeb5e49edb8868ab1f375002fa3a
5
5
  SHA512:
6
- metadata.gz: 9f0da08b8631268141302d8613d0bf161db9868046e1b94b8b069b8042179c5d23e3936bfeaa1e10e8207f683b698faf5d61fcdac5194378dc56e7046fead956
7
- data.tar.gz: 280fd06fbc3a3805d14ee843df4bd3b46865f0be809d6be2ada67094b140af92c1d6c9cce825ec994371696f855b0d04b8d405af1383a18439b7f5b4a7bcc016
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
- HEAD
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 1.8 / REE
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
- #### OS X
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
- [homebrew]: https://github.com/mxcl/homebrew/pull/17275
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, self.class::KEYBYTES, "#{self.class} 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(self.class::BYTES)
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 == self.class::BYTES
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
@@ -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 = Encoder[encoding].decode(public_key) if public_key
79
- @private_key = Encoder[encoding].decode(private_key) if private_key
80
- Util.check_length(@public_key, PublicKey::BYTES, "Public key")
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, Crypto::NaCl::NONCEBYTES, "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.crypto_box_afternm(ct, msg, msg.bytesize, nonce, beforenm) || raise(CryptoError, "Encryption failed")
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, Crypto::NaCl::NONCEBYTES, "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.crypto_box_open_afternm(message, ct, ct.bytesize, nonce, beforenm) || raise(CryptoError, "Decryption failed. Ciphertext failed verification.")
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::BEFORENMBYTES)
136
- NaCl.crypto_box_beforenm(k, @public_key, @private_key) || raise(CryptoError, "Failed to derive shared key")
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
@@ -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 = Crypto::NaCl::SECRETKEYBYTES
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::PUBLICKEYBYTES)
43
- sk = Util.zeros(NaCl::SECRETKEYBYTES)
44
- NaCl.crypto_box_keypair(pk, sk) || raise(CryptoError, "Failed to generate a key pair")
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 = Crypto::NaCl::PUBLICKEYBYTES
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::SECRETKEYBYTES)
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::SECRETKEYBYTES, "seed")
42
+ Util.check_length(seed, NaCl::ED25519_SEED_BYTES, "seed")
43
43
 
44
- pk = Util.zeros(NaCl::PUBLICKEYBYTES)
45
- sk = Util.zeros(NaCl::SECRETKEYBYTES * 2)
44
+ pk = Util.zeros(NaCl::ED25519_VERIFYKEY_BYTES)
45
+ sk = Util.zeros(NaCl::ED25519_SIGNINGKEY_BYTES)
46
46
 
47
- NaCl.crypto_sign_seed_keypair(pk, sk, seed) || raise(CryptoError, "Failed to generate a key pair")
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(NaCl::SIGNATUREBYTES, message)
60
+ buffer = Util.prepend_zeros(signature_bytes, message)
61
61
  buffer_len = Util.zeros(FFI::Type::LONG_LONG.size)
62
62
 
63
- NaCl.crypto_sign(buffer, buffer_len, message, message.bytesize, @signing_key)
63
+ NaCl.crypto_sign_ed25519(buffer, buffer_len, message, message.bytesize, @signing_key)
64
64
 
65
- signature = buffer[0, NaCl::SIGNATUREBYTES]
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