rbnacl 1.1.0 → 2.0.0.pre

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.
Files changed (79) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -5
  3. data/CHANGES.md +15 -0
  4. data/Gemfile +4 -1
  5. data/Guardfile +8 -0
  6. data/README.md +52 -3
  7. data/lib/rbnacl.rb +65 -29
  8. data/lib/rbnacl/auth.rb +14 -18
  9. data/lib/rbnacl/boxes/curve25519xsalsa20poly1305.rb +185 -0
  10. data/lib/rbnacl/{keys → boxes/curve25519xsalsa20poly1305}/private_key.rb +26 -23
  11. data/lib/rbnacl/{keys → boxes/curve25519xsalsa20poly1305}/public_key.rb +13 -12
  12. data/lib/rbnacl/group_elements/curve25519.rb +81 -0
  13. data/lib/rbnacl/hash.rb +30 -14
  14. data/lib/rbnacl/hash/blake2b.rb +57 -0
  15. data/lib/rbnacl/hash/sha256.rb +15 -0
  16. data/lib/rbnacl/hash/sha512.rb +15 -0
  17. data/lib/rbnacl/hmac/sha256.rb +19 -17
  18. data/lib/rbnacl/hmac/sha512256.rb +18 -19
  19. data/lib/rbnacl/init.rb +10 -0
  20. data/lib/rbnacl/{keys/key_comparator.rb → key_comparator.rb} +1 -1
  21. data/lib/rbnacl/{auth/one_time.rb → one_time_auths/poly1305.rb} +21 -19
  22. data/lib/rbnacl/rake_tasks.rb +7 -6
  23. data/lib/rbnacl/random.rb +8 -3
  24. data/lib/rbnacl/random_nonce_box.rb +9 -14
  25. data/lib/rbnacl/secret_boxes/xsalsa20poly1305.rb +125 -0
  26. data/lib/rbnacl/self_test.rb +59 -40
  27. data/lib/rbnacl/serializable.rb +4 -12
  28. data/lib/rbnacl/signatures/ed25519.rb +15 -0
  29. data/lib/rbnacl/signatures/ed25519/signing_key.rb +104 -0
  30. data/lib/rbnacl/signatures/ed25519/verify_key.rb +91 -0
  31. data/lib/rbnacl/sodium.rb +43 -0
  32. data/lib/rbnacl/test_vectors.rb +34 -1
  33. data/lib/rbnacl/util.rb +52 -7
  34. data/lib/rbnacl/version.rb +2 -2
  35. data/rbnacl.gemspec +3 -6
  36. data/spec/rbnacl/{auth/one_time_spec.rb → authenticators/poly1305_spec.rb} +2 -2
  37. data/spec/rbnacl/boxes/curve25519xsalsa20poly1305/private_key_spec.rb +65 -0
  38. data/spec/rbnacl/{keys → boxes/curve25519xsalsa20poly1305}/public_key_spec.rb +10 -13
  39. data/spec/rbnacl/boxes/curve25519xsalsa20poly1305_spec.rb +39 -0
  40. data/spec/rbnacl/{point_spec.rb → group_element_spec.rb} +6 -8
  41. data/spec/rbnacl/hash/blake2b_spec.rb +26 -0
  42. data/spec/rbnacl/hash_spec.rb +13 -33
  43. data/spec/rbnacl/hmac/sha256_spec.rb +2 -2
  44. data/spec/rbnacl/hmac/sha512256_spec.rb +2 -2
  45. data/spec/rbnacl/random_nonce_box_spec.rb +21 -26
  46. data/spec/rbnacl/random_spec.rb +3 -3
  47. data/spec/rbnacl/secret_box_spec.rb +6 -6
  48. data/spec/rbnacl/signatures/ed25519/signing_key_spec.rb +30 -0
  49. data/spec/rbnacl/signatures/ed25519/verify_key_spec.rb +39 -0
  50. data/spec/rbnacl/util_spec.rb +67 -53
  51. data/spec/shared/authenticator.rb +36 -54
  52. data/spec/shared/box.rb +10 -10
  53. data/spec/shared/key_equality.rb +3 -3
  54. data/spec/shared/serializable.rb +17 -0
  55. data/spec/spec_helper.rb +14 -16
  56. data/tasks/rspec.rake +1 -0
  57. metadata +42 -67
  58. checksums.yaml.gz.sig +0 -0
  59. data.tar.gz.sig +0 -3
  60. data/lib/rbnacl/box.rb +0 -171
  61. data/lib/rbnacl/encoder.rb +0 -44
  62. data/lib/rbnacl/encoders/base32.rb +0 -33
  63. data/lib/rbnacl/encoders/base64.rb +0 -30
  64. data/lib/rbnacl/encoders/hex.rb +0 -30
  65. data/lib/rbnacl/encoders/raw.rb +0 -12
  66. data/lib/rbnacl/keys/signing_key.rb +0 -95
  67. data/lib/rbnacl/keys/verify_key.rb +0 -96
  68. data/lib/rbnacl/nacl.rb +0 -146
  69. data/lib/rbnacl/point.rb +0 -70
  70. data/lib/rbnacl/secret_box.rb +0 -119
  71. data/spec/rbnacl/box_spec.rb +0 -42
  72. data/spec/rbnacl/encoder_spec.rb +0 -14
  73. data/spec/rbnacl/encoders/base32_spec.rb +0 -16
  74. data/spec/rbnacl/encoders/base64_spec.rb +0 -15
  75. data/spec/rbnacl/encoders/hex_spec.rb +0 -15
  76. data/spec/rbnacl/keys/private_key_spec.rb +0 -68
  77. data/spec/rbnacl/keys/signing_key_spec.rb +0 -39
  78. data/spec/rbnacl/keys/verify_key_spec.rb +0 -51
  79. metadata.gz.sig +0 -2
@@ -1,23 +1,15 @@
1
1
  # encoding: binary
2
- module Crypto
2
+ module RbNaCl
3
3
  # Serialization features shared across all "key-like" classes
4
4
  module Serializable
5
- # Return a string representation of this key, possibly encoded into a
6
- # given serialization format.
7
- #
8
- # @param encoding [String] string encoding format in which to encode the key
9
- #
10
- # @return [String] key encoded in the specified format
11
- def to_s(encoding = :raw)
12
- Encoder[encoding].encode(to_bytes)
13
- end
14
- alias_method :to_str, :to_s
5
+ def to_s; to_bytes; end
6
+ def to_str; to_bytes; end
15
7
 
16
8
  # Inspect this key
17
9
  #
18
10
  # @return [String] a string representing this key
19
11
  def inspect
20
- "#<#{self.class}:#{to_s(:hex)[0,8]}>"
12
+ "#<#{self.class}:#{Util.bin2hex(to_bytes)[0,8]}>"
21
13
  end
22
14
  end
23
15
  end
@@ -0,0 +1,15 @@
1
+ # encoding: binary
2
+ module RbNaCl
3
+ module Signatures
4
+ module Ed25519
5
+ extend Sodium
6
+
7
+ sodium_type :sign
8
+ sodium_primitive :ed25519
9
+ sodium_constant :SEEDBYTES
10
+ sodium_constant :PUBLICKEYBYTES, :VERIFYKEYBYTES
11
+ sodium_constant :SECRETKEYBYTES, :SIGNINGKEYBYTES
12
+ sodium_constant :BYTES, :SIGNATUREBYTES
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,104 @@
1
+ # encoding: binary
2
+ module RbNaCl
3
+ module Signatures
4
+ module Ed25519
5
+ # Private key for producing digital signatures using the Ed25519 algorithm.
6
+ # Ed25519 provides a 128-bit security level, that is to say, all known attacks
7
+ # take at least 2^128 operations, providing the same security level as
8
+ # AES-128, NIST P-256, and RSA-3072.
9
+ #
10
+ # Signing keys are produced from a 32-byte (256-bit) random seed value.
11
+ # This value can be passed into the SigningKey constructor as a String
12
+ # whose bytesize is 32.
13
+ #
14
+ # The public VerifyKey can be computed from the private 32-byte seed value
15
+ # as well, eliminating the need to store a "keypair".
16
+ #
17
+ # SigningKey produces 64-byte (512-bit) signatures. The signatures are
18
+ # deterministic: signing the same message will always produce the same
19
+ # signature. This prevents "entropy failure" seen in other signature
20
+ # algorithms like DSA and ECDSA, where poor random number generators can
21
+ # leak enough information to recover the private key.
22
+ class SigningKey
23
+ include KeyComparator
24
+ include Serializable
25
+
26
+ extend Sodium
27
+
28
+ sodium_type :sign
29
+ sodium_primitive :ed25519
30
+
31
+ sodium_function :sign_ed25519,
32
+ :crypto_sign_ed25519,
33
+ [:pointer, :pointer, :pointer, :ulong_long, :pointer]
34
+
35
+ sodium_function :sign_ed25519_seed_keypair,
36
+ :crypto_sign_ed25519_seed_keypair,
37
+ [:pointer, :pointer, :pointer]
38
+
39
+ attr_reader :verify_key
40
+
41
+ # Generate a random SigningKey
42
+ #
43
+ # @return [RbNaCl::SigningKey] Freshly-generated random SigningKey
44
+ def self.generate
45
+ new RbNaCl::Random.random_bytes(Ed25519::SEEDBYTES)
46
+ end
47
+
48
+ # Create a SigningKey from a seed value
49
+ #
50
+ # @param seed [String] Random 32-byte value (i.e. private key)
51
+ #
52
+ # @return [RbNaCl::SigningKey] Key which can sign messages
53
+ def initialize(seed)
54
+ seed = seed.to_s
55
+
56
+ Util.check_length(seed, Ed25519::SEEDBYTES, "seed")
57
+
58
+ pk = Util.zeros(Ed25519::VERIFYKEYBYTES)
59
+ sk = Util.zeros(Ed25519::SIGNINGKEYBYTES)
60
+
61
+ self.class.sign_ed25519_seed_keypair(pk, sk, seed) || raise(CryptoError, "Failed to generate a key pair")
62
+
63
+ @seed, @signing_key = seed, sk
64
+ @verify_key = VerifyKey.new(pk)
65
+ end
66
+
67
+ # Sign a message using this key
68
+ #
69
+ # @param message [String] Message to be signed by this key
70
+ #
71
+ # @return [String] Signature as bytes
72
+ def sign(message)
73
+ buffer = Util.prepend_zeros(signature_bytes, message)
74
+ buffer_len = Util.zeros(FFI::Type::LONG_LONG.size)
75
+
76
+ self.class.sign_ed25519(buffer, buffer_len, message, message.bytesize, @signing_key)
77
+
78
+ buffer[0, signature_bytes]
79
+ end
80
+
81
+ # Return the raw seed value of this key
82
+ #
83
+ # @return [String] seed used to create this key
84
+ def to_bytes; @seed; end
85
+
86
+ # The crypto primitive this SigningKey class uses for signatures
87
+ #
88
+ # @return [Symbol] The primitive
89
+ def primitive; self.class.primitive; end
90
+
91
+ # The size of signatures generated by the SigningKey class
92
+ #
93
+ # @return [Integer] The number of bytes in a signature
94
+ def self.signature_bytes; Ed25519::SIGNATUREBYTES; end
95
+
96
+ # The size of signatures generated by the SigningKey instance
97
+ #
98
+ # @return [Integer] The number of bytes in a signature
99
+ def signature_bytes; Ed25519::SIGNATUREBYTES; end
100
+
101
+ end
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,91 @@
1
+ # encoding: binary
2
+ module RbNaCl
3
+ module Signatures
4
+ module Ed25519
5
+ # The public key counterpart to an Ed25519 SigningKey for producing digital
6
+ # signatures. Like the name says, VerifyKeys can be used to verify that a
7
+ # given digital signature is authentic.
8
+ #
9
+ # For more information on the Ed25519 digital signature system, please see
10
+ # the SigningKey documentation.
11
+ class VerifyKey
12
+ include KeyComparator
13
+ include Serializable
14
+
15
+ extend Sodium
16
+
17
+ sodium_type :sign
18
+ sodium_primitive :ed25519
19
+
20
+ sodium_function :sign_ed25519_open,
21
+ :crypto_sign_ed25519_open,
22
+ [:pointer, :pointer, :pointer, :ulong_long, :pointer]
23
+
24
+ # Create a new VerifyKey object from a public key.
25
+ #
26
+ # @param key [String] Ed25519 public key
27
+ #
28
+ # @return [RbNaCl::VerifyKey] Key which can verify messages
29
+ def initialize(key)
30
+ @key = key.to_str
31
+ Util.check_length(@key, Ed25519::VERIFYKEYBYTES, "key")
32
+ end
33
+
34
+ # Verify a signature for a given message
35
+ #
36
+ # @param signature [String] Alleged signature to be checked
37
+ # @param message [String] Message to be authenticated
38
+ #
39
+ # @return [Boolean] was the signature authentic?
40
+ def verify(signature, message)
41
+ signature = signature.to_str
42
+ Util.check_length(signature, signature_bytes, "signature")
43
+
44
+ sig_and_msg = signature + message
45
+ buffer = Util.zeros(sig_and_msg.bytesize)
46
+ buffer_len = Util.zeros(FFI::Type::LONG_LONG.size)
47
+
48
+ self.class.sign_ed25519_open(buffer, buffer_len, sig_and_msg, sig_and_msg.bytesize, @key)
49
+ end
50
+
51
+ # Verify a signature for a given message or raise exception
52
+ #
53
+ # "Dangerous" (but really safer) verify that raises an exception if a
54
+ # signature check fails. This is probably less likely to go unnoticed than
55
+ # an improperly checked verify, as you are forced to deal with the
56
+ # exception explicitly (and failing signature checks are certainly an
57
+ # exceptional condition!)
58
+ #
59
+ # The arguments are otherwise the same as the verify method.
60
+ #
61
+ # @param message [String] Message to be authenticated
62
+ # @param signature [String] Alleged signature to be checked
63
+ #
64
+ # @return [true] Will raise BadSignatureError if signature check fails
65
+ def verify!(message, signature)
66
+ verify(message, signature) or raise BadSignatureError, "signature was forged/corrupt"
67
+ end
68
+
69
+ # Return the raw key in byte format
70
+ #
71
+ # @return [String] raw key as bytes
72
+ def to_bytes; @key; end
73
+
74
+ # The crypto primitive this VerifyKey class uses for signatures
75
+ #
76
+ # @return [Symbol] The primitive
77
+ def primitive; self.class.primitive; end
78
+
79
+ # The size of signatures verified by the VerifyKey class
80
+ #
81
+ # @return [Integer] The number of bytes in a signature
82
+ def self.signature_bytes; Ed25519::SIGNATUREBYTES; end
83
+
84
+ # The size of signatures verified by the VerifyKey instance
85
+ #
86
+ # @return [Integer] The number of bytes in a signature
87
+ def signature_bytes; Ed25519::SIGNATUREBYTES; end
88
+ end
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,43 @@
1
+ # encoding: binary
2
+ require 'ffi'
3
+
4
+ module RbNaCl
5
+ # Provides helpers for defining the libsodium bindings
6
+ module Sodium
7
+ def self.extended(klass)
8
+ klass.extend FFI::Library
9
+ klass.ffi_lib 'sodium'
10
+ end
11
+
12
+
13
+ def sodium_type(type = nil)
14
+ return @type if type.nil?
15
+ @type = type
16
+ end
17
+
18
+ def sodium_primitive(primitive = nil)
19
+ return @primitive if primitive.nil?
20
+ @primitive = primitive
21
+ end
22
+
23
+ def primitive
24
+ sodium_primitive
25
+ end
26
+
27
+ def sodium_constant(constant, name=constant)
28
+ fn = "crypto_#{sodium_type}_#{sodium_primitive}_#{constant.to_s.downcase}"
29
+ attach_function fn, [], :ulong_long
30
+ self.const_set(name, self.public_send(fn))
31
+ end
32
+
33
+ def sodium_function(name, function, arguments)
34
+ self.module_eval <<-eos, __FILE__, __LINE__ + 1
35
+ attach_function #{function.inspect}, #{arguments.inspect}, :int
36
+ def self.#{name}(*args)
37
+ ret = #{function}(*args)
38
+ ret == 0
39
+ end
40
+ eos
41
+ end
42
+ end
43
+ end
@@ -1,5 +1,5 @@
1
1
  # encoding: binary
2
- module Crypto
2
+ module RbNaCl
3
3
  # Reference library of test vectors used to verify the software is correct
4
4
  TestVectors = {
5
5
  #
@@ -50,8 +50,41 @@ module Crypto
50
50
  :sha256_message => "6162636462636465636465666465666765666768666768696768696a68696a6b" +
51
51
  "696a6b6c6a6b6c6d6b6c6d6e6c6d6e6f6d6e6f706e6f7071",
52
52
  :sha256_digest => "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1",
53
+ :sha256_empty => "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
53
54
 
54
55
  #
56
+ # SHA512 test vectors
57
+ # self-created (FIXME: find standard test vectors)
58
+ :sha512_message => "54686520717569636b2062726f776e20666f78206a756d7073206f7665722074" +
59
+ "6865206c617a7920646f672e",
60
+ :sha512_digest => "91ea1245f20d46ae9a037a989f54f1f790f0a47607eeb8a14d12890cea77a1bb" +
61
+ "c6c7ed9cf205e67b7f2b8fd4c7dfd3a7a8617e45f3c463d481c7e586c39ac1ed",
62
+ :sha512_empty => "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce" +
63
+ "47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e",
64
+
65
+ # Blake2b test vectors
66
+ # self-created? (TODO: double check, fix)
67
+ :blake2b_message => "54686520717569636b2062726f776e20666f78206a756d7073206f7665722074" +
68
+ "6865206c617a7920646f67",
69
+ :blake2b_digest => "a8add4bdddfd93e4877d2746e62817b116364a1fa7bc148d95090bc7333b3673" +
70
+ "f82401cf7aa2e4cb1ecd90296e3f14cb5413f8ed77be73045b13914cdcd6a918",
71
+ :blake2b_empty => "786a02f742015903c6c6fd852552d272912f4740e15847618a86e217f71f5419" +
72
+ "d25e1031afee585313896444934eb04b903a685b1448b755d56f701afe9be2ce",
73
+
74
+ # from the Blake2 paper(?) (TODO: double check)
75
+ :blake2b_keyed_message => "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" +
76
+ "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f" +
77
+ "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f" +
78
+ "606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f" +
79
+ "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f" +
80
+ "a0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebf" +
81
+ "c0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedf" +
82
+ "e0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfe",
83
+ :blake2b_key => "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" +
84
+ "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
85
+ :blake2b_keyed_digest => "142709d62e28fcccd0af97fad0f8465b971e82201dc51070faa0372aa43e9248" +
86
+ "4be1c1e73ba10906d5d1853db6a4106e0a7bf9800d373d6dee2d46d62ef2a461",
87
+
55
88
  # Auth test vectors
56
89
  # Taken from NaCl distribution
57
90
  #
@@ -1,7 +1,13 @@
1
1
  # encoding: binary
2
- module Crypto
2
+ module RbNaCl
3
3
  # Various utility functions
4
4
  module Util
5
+ extend Sodium
6
+
7
+ attach_function :sodium_version_string, [], :string
8
+
9
+ sodium_function :c_verify16, :crypto_verify_16, [:pointer, :pointer]
10
+ sodium_function :c_verify32, :crypto_verify_32, [:pointer, :pointer]
5
11
  module_function
6
12
  # Returns a string of n zeros
7
13
  #
@@ -46,7 +52,7 @@ module Crypto
46
52
  # In several places through the codebase we have to be VERY strict with
47
53
  # what length of string we accept. This method supports that.
48
54
  #
49
- # @raise [Crypto::LengthError] If the string is not the right length
55
+ # @raise [RbNaCl::LengthError] If the string is not the right length
50
56
  #
51
57
  # @param string [String] The string to compare
52
58
  # @param length [Integer] The desired length
@@ -57,7 +63,7 @@ module Crypto
57
63
  "#{description} was nil (Expected #{length.to_int})",
58
64
  caller
59
65
  end
60
-
66
+
61
67
  if string.bytesize != length.to_int
62
68
  raise LengthError,
63
69
  "#{description} was #{string.bytesize} bytes (Expected #{length.to_int})",
@@ -66,6 +72,27 @@ module Crypto
66
72
  true
67
73
  end
68
74
 
75
+ # Check a passed in string, converting the argument if necessary
76
+ #
77
+ # In several places through the codebase we have to be VERY strict with
78
+ # the strings we accept. This method supports that.
79
+ #
80
+ # @raise [ArgumentError] If we cannot convert to a string with #to_str
81
+ # @raise [RbNaCl::LengthError] If the string is not the right length
82
+ #
83
+ # @param string [#to_str] The input string
84
+ # @param length [Integer] The only acceptable length of the string
85
+ # @param description [String] Description of the string (used in the error)
86
+ def check_string(string, length, description)
87
+ unless string.respond_to? :to_str
88
+ raise TypeError, "can't convert #{string.class} into String with #to_str"
89
+ end
90
+
91
+ string = string.to_str
92
+ check_length(string, length, description)
93
+
94
+ string
95
+ end
69
96
 
70
97
  # Compare two 32 byte strings in constant time
71
98
  #
@@ -79,7 +106,7 @@ module Crypto
79
106
  # @return [Boolean] Well, are they equal?
80
107
  def verify32(one, two)
81
108
  return false unless two.bytesize == 32 && one.bytesize == 32
82
- NaCl.crypto_verify_32(one, two)
109
+ c_verify32(one, two)
83
110
  end
84
111
 
85
112
  # Compare two 32 byte strings in constant time
@@ -97,7 +124,7 @@ module Crypto
97
124
  def verify32!(one, two)
98
125
  check_length(one, 32, "First message")
99
126
  check_length(two, 32, "Second message")
100
- NaCl.crypto_verify_32(one, two)
127
+ c_verify32(one, two)
101
128
  end
102
129
 
103
130
  # Compare two 16 byte strings in constant time
@@ -112,7 +139,7 @@ module Crypto
112
139
  # @return [Boolean] Well, are they equal?
113
140
  def verify16(one, two)
114
141
  return false unless two.bytesize == 16 && one.bytesize == 16
115
- NaCl.crypto_verify_16(one, two)
142
+ c_verify16(one, two)
116
143
  end
117
144
 
118
145
  # Compare two 16 byte strings in constant time
@@ -130,7 +157,25 @@ module Crypto
130
157
  def verify16!(one, two)
131
158
  check_length(one, 16, "First message")
132
159
  check_length(two, 16, "Second message")
133
- NaCl.crypto_verify_16(one, two)
160
+ c_verify16(one, two)
161
+ end
162
+
163
+ # Hex encodes a message
164
+ #
165
+ # @param [String] bytes The bytes to encode
166
+ #
167
+ # @return [String] Tasty, tasty hexadecimal
168
+ def bin2hex(bytes)
169
+ bytes.to_s.unpack("H*").first
170
+ end
171
+
172
+ # Hex decodes a message
173
+ #
174
+ # @param [String] hex hex to decode.
175
+ #
176
+ # @return [String] crisp and clean bytes
177
+ def hex2bin(hex)
178
+ [hex.to_s].pack("H*")
134
179
  end
135
180
  end
136
181
  end
@@ -1,5 +1,5 @@
1
1
  # encoding: binary
2
- module Crypto
2
+ module RbNaCl
3
3
  # The library's version
4
- VERSION = "1.1.0"
4
+ VERSION = "2.0.0.pre"
5
5
  end