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,70 +0,0 @@
1
- # encoding: binary
2
- module Crypto
3
- # NaCl's base point (a.k.a. standard group element), serialized as hex
4
- STANDARD_GROUP_ELEMENT = "0900000000000000000000000000000000000000000000000000000000000000".freeze
5
-
6
- # Order of the standard group
7
- STANDARD_GROUP_ORDER = 2**252 + 27742317777372353535851937790883648493
8
-
9
- # Points provide the interface to NaCl's Curve25519 high-speed elliptic
10
- # curve cryptography, which can be used for implementing Diffie-Hellman
11
- # and other forms of public key cryptography (e.g. Crypto::Box)
12
- #
13
- # Objects of the Point class represent points on Edwards curves. NaCl
14
- # defines a base point (the "standard group element") which we can
15
- # multiply by an arbitrary integer. This is how NaCl computes public
16
- # keys from private keys.
17
- class Point
18
- include KeyComparator
19
- include Serializable
20
-
21
- # Number of bytes in a scalar on this curve
22
- SCALARBYTES = NaCl::ED25519_SCALARBYTES
23
-
24
- # Creates a new Point from the given serialization
25
- #
26
- # @param value [String] 32-byte value representing a group element
27
- # @param encoding [Symbol] The encoding format of the group element
28
- #
29
- # @return [Crypto::Point] New Crypto::Point object
30
- def initialize(value, encoding = :raw)
31
- @point = Encoder[encoding].decode(value)
32
-
33
- # FIXME: really should have a separate constant here for group element size
34
- # Group elements and scalars are both 32-bits, but that's for convenience
35
- Util.check_length(@point, SCALARBYTES, "group element")
36
- end
37
-
38
- # Multiply the given integer by this point
39
- # This ordering is a bit confusing because traditionally the point
40
- # would be the right-hand operand.
41
- #
42
- # @param integer [String] 32-byte integer value
43
- # @param encoding [Symbol] The encoding format of the integer
44
- #
45
- # @return [Crypto::Point] Result as a Point object
46
- def mult(integer, encoding = :raw)
47
- integer = Encoder[encoding].decode(integer)
48
- Util.check_length(integer, SCALARBYTES, "integer")
49
-
50
- result = Util.zeros(SCALARBYTES)
51
- NaCl.crypto_scalarmult_curve25519(result, integer, @point)
52
-
53
- self.class.new(result)
54
- end
55
-
56
- # Return the point serialized as bytes
57
- #
58
- # @return [String] 32-byte string representing this point
59
- def to_bytes; @point; end
60
-
61
- @base_point = Point.new(STANDARD_GROUP_ELEMENT, :hex)
62
-
63
- # NaCl's standard base point for all Curve25519 public keys
64
- #
65
- # @return [Crypto::Point] standard base point (a.k.a. standard group element)
66
- def self.base; @base_point; end
67
- def self.base_point; @base_point; end
68
- end
69
- end
70
-
@@ -1,119 +0,0 @@
1
- # encoding: binary
2
- module Crypto
3
- # The SecretBox class boxes and unboxes messages
4
- #
5
- # This class uses the given secret key to encrypt and decrypt messages.
6
- #
7
- # It is VITALLY important that the nonce is a nonce, i.e. it is a number used
8
- # only once for any given pair of keys. If you fail to do this, you
9
- # compromise the privacy of the messages encrypted. Give your nonces a
10
- # different prefix, or have one side use an odd counter and one an even counter.
11
- # Just make sure they are different.
12
- #
13
- # The ciphertexts generated by this class include a 16-byte authenticator which
14
- # is checked as part of the decryption. An invalid authenticator will cause
15
- # the unbox function to raise. The authenticator is not a signature. Once
16
- # you've looked in the box, you've demonstrated the ability to create
17
- # arbitrary valid messages, so messages you send are repudiatable. For
18
- # non-repudiatable messages, sign them before or after encryption.
19
- class SecretBox
20
- # Number of bytes for a secret key
21
- KEYBYTES = NaCl::XSALSA20_POLY1305_SECRETBOX_KEYBYTES
22
-
23
- # Number of bytes for a nonce
24
- NONCEBYTES = NaCl::XSALSA20_POLY1305_SECRETBOX_NONCEBYTES
25
-
26
- # Create a new SecretBox
27
- #
28
- # Sets up the Box with a secret key fro encrypting and decrypting messages.
29
- #
30
- # @param key [String] The key to encrypt and decrypt with
31
- # @param encoding [Symbol] Parse key from the given encoding
32
- #
33
- # @raise [Crypto::LengthError] on invalid keys
34
- #
35
- # @return [Crypto::SecretBox] The new Box, ready to use
36
- def initialize(key, encoding = :raw)
37
- @key = Encoder[encoding].decode(key) if key
38
- Util.check_length(@key, KEYBYTES, "Secret key")
39
- end
40
-
41
- # Encrypts a message
42
- #
43
- # Encrypts the message with the given nonce to the key set up when
44
- # initializing the class. Make sure the nonce is unique for any given
45
- # key, or you might as well just send plain text.
46
- #
47
- # This function takes care of the padding required by the NaCL C API.
48
- #
49
- # @param nonce [String] A 24-byte string containing the nonce.
50
- # @param message [String] The message to be encrypted.
51
- #
52
- # @raise [Crypto::LengthError] If the nonce is not valid
53
- #
54
- # @return [String] The ciphertext without the nonce prepended (BINARY encoded)
55
- def box(nonce, message)
56
- Util.check_length(nonce, nonce_bytes, "Nonce")
57
- msg = Util.prepend_zeros(NaCl::ZEROBYTES, message)
58
- ct = Util.zeros(msg.bytesize)
59
-
60
- NaCl.crypto_secretbox_xsalsa20poly1305(ct, msg, msg.bytesize, nonce, @key) || raise(CryptoError, "Encryption failed")
61
- Util.remove_zeros(NaCl::BOXZEROBYTES, ct)
62
- end
63
- alias encrypt box
64
-
65
- # Decrypts a ciphertext
66
- #
67
- # Decrypts the ciphertext with the given nonce using the key setup when
68
- # initializing the class.
69
- #
70
- # This function takes care of the padding required by the NaCL C API.
71
- #
72
- # @param nonce [String] A 24-byte string containing the nonce.
73
- # @param ciphertext [String] The message to be decrypted.
74
- #
75
- # @raise [Crypto::LengthError] If the nonce is not valid
76
- # @raise [Crypto::CryptoError] If the ciphertext cannot be authenticated.
77
- #
78
- # @return [String] The decrypted message (BINARY encoded)
79
- def open(nonce, ciphertext)
80
- Util.check_length(nonce, nonce_bytes, "Nonce")
81
- ct = Util.prepend_zeros(NaCl::BOXZEROBYTES, ciphertext)
82
- message = Util.zeros(ct.bytesize)
83
-
84
- NaCl.crypto_secretbox_xsalsa20poly1305_open(message, ct, ct.bytesize, nonce, @key) || raise(CryptoError, "Decryption failed. Ciphertext failed verification.")
85
- Util.remove_zeros(NaCl::ZEROBYTES, message)
86
- end
87
- alias decrypt open
88
-
89
- # The crypto primitive for the SecretBox class
90
- #
91
- # @return [Symbol] The primitive used
92
- def self.primitive; :xsalsa20_poly1305; end
93
-
94
- # The crypto primitive for the SecretBox instance
95
- #
96
- # @return [Symbol] The primitive used
97
- def primitive; self.class.primitive; end
98
-
99
- # The nonce bytes for the SecretBox class
100
- #
101
- # @return [Integer] The number of bytes in a valid nonce
102
- def self.nonce_bytes; NONCEBYTES; end
103
-
104
- # The nonce bytes for the SecretBox instance
105
- #
106
- # @return [Integer] The number of bytes in a valid nonce
107
- def nonce_bytes; NONCEBYTES; end
108
-
109
- # The key bytes for the SecretBox class
110
- #
111
- # @return [Integer] The number of bytes in a valid key
112
- def self.key_bytes; KEYBYTES; end
113
-
114
- # The key bytes for the SecretBox instance
115
- #
116
- # @return [Integer] The number of bytes in a valid key
117
- def key_bytes; KEYBYTES; end
118
- end
119
- end
@@ -1,42 +0,0 @@
1
- # encoding: binary
2
- require 'spec_helper'
3
-
4
- describe Crypto::Box do
5
- let(:alicepk_hex) { hex_vector :alice_public }
6
- let(:bobsk_hex) { hex_vector :bob_private }
7
-
8
- let(:alicepk) { hex2bytes(alicepk_hex) }
9
- let(:bobsk) { hex2bytes(bobsk_hex) }
10
- let(:alice_key) { Crypto::PublicKey.new(alicepk) }
11
- let(:bob_key) { Crypto::PrivateKey.new(bobsk) }
12
-
13
- context "new" do
14
- it "accepts strings" do
15
- expect { Crypto::Box.new(alicepk_hex, bobsk_hex, :hex) }.to_not raise_error(Exception)
16
- end
17
-
18
- it "accepts KeyPairs" do
19
- expect { Crypto::Box.new(alice_key, bob_key) }.to_not raise_error(Exception)
20
- end
21
-
22
- it "raises on a nil public key" do
23
- expect { Crypto::Box.new(nil, bobsk) }.to raise_error(Crypto::LengthError, /Public key was 0 bytes \(Expected 32\)/)
24
- end
25
-
26
- it "raises on an invalid public key" do
27
- expect { Crypto::Box.new("hello", bobsk) }.to raise_error(Crypto::LengthError, /Public key was 5 bytes \(Expected 32\)/)
28
- end
29
-
30
- it "raises on a nil secret key" do
31
- expect { Crypto::Box.new(alicepk, nil) }.to raise_error(Crypto::LengthError, /Private key was 0 bytes \(Expected 32\)/)
32
- end
33
-
34
- it "raises on an invalid secret key" do
35
- expect { Crypto::Box.new(alicepk, "hello") }.to raise_error(Crypto::LengthError, /Private key was 5 bytes \(Expected 32\)/)
36
- end
37
- end
38
-
39
- include_examples 'box' do
40
- let(:box) { Crypto::Box.new(alicepk, bobsk) }
41
- end
42
- end
@@ -1,14 +0,0 @@
1
- # encoding: binary
2
- require 'spec_helper'
3
-
4
- describe Crypto::Encoder do
5
- it "registers encoders" do
6
- expect { Crypto::Encoder[:foobar] }.to raise_exception(ArgumentError)
7
-
8
- class FoobarEncoder < described_class
9
- register :foobar
10
- end
11
-
12
- Crypto::Encoder[:foobar].should be_a FoobarEncoder
13
- end
14
- end
@@ -1,16 +0,0 @@
1
- # encoding: binary
2
- require 'spec_helper'
3
- require 'rbnacl/encoders/base32'
4
-
5
- describe Crypto::Encoders::Base32 do
6
- let(:source) { "abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789" }
7
- let(:base32) { "mfrggzdfmztwq2lknnwg23tpobyxe43uov3ho6dzpiydcmrtgq2tmnzyhfqwey3emvtgo2djnjvwy3lon5yhc4ttor2xm53ypf5damjsgm2dknrxha4wcytdmrswmz3infvgw3dnnzxxa4lson2hk5txpb4xumbrgiztinjwg44ds===" }
8
-
9
- it "encodes to base32" do
10
- subject.encode(source).should eq base32
11
- end
12
-
13
- it "decodes from base32" do
14
- subject.decode(base32).should eq source
15
- end
16
- end
@@ -1,15 +0,0 @@
1
- # encoding: binary
2
- require 'spec_helper'
3
-
4
- describe Crypto::Encoders::Base64 do
5
- let(:source) { "abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789" }
6
- let(:base64) { "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5" }
7
-
8
- it "encodes to base64" do
9
- subject.encode(source).should eq base64
10
- end
11
-
12
- it "decodes from base64" do
13
- subject.decode(base64).should eq source
14
- end
15
- end
@@ -1,15 +0,0 @@
1
- # encoding: binary
2
- require 'spec_helper'
3
-
4
- describe Crypto::Encoders::Hex do
5
- let (:bytes) { [0xDE,0xAD,0xBE,0xEF].pack('c*') }
6
- let (:hex) { "deadbeef" }
7
-
8
- it "encodes to hex" do
9
- subject.encode(bytes).should eq hex
10
- end
11
-
12
- it "decodes from hex" do
13
- subject.decode(hex).should eq bytes
14
- end
15
- end
@@ -1,68 +0,0 @@
1
- # encoding: binary
2
- require 'spec_helper'
3
-
4
- describe Crypto::PrivateKey do
5
- let(:bobsk) { test_vector :bob_private }
6
- let(:bobsk_hex) { bytes2hex bobsk }
7
- let(:bobpk) { test_vector :bob_public }
8
- let(:bobpk_hex) { bytes2hex bobpk }
9
-
10
- subject { Crypto::PrivateKey.new(bobsk) }
11
-
12
- context "generate" do
13
- let(:secret_key) { Crypto::PrivateKey.generate }
14
-
15
- it "returns a secret key" do
16
- secret_key.should be_a Crypto::PrivateKey
17
- end
18
-
19
- it "has the public key also set" do
20
- secret_key.public_key.should be_a Crypto::PublicKey
21
- end
22
- end
23
-
24
- context "new" do
25
- it "accepts a valid key" do
26
- expect { Crypto::PrivateKey.new(bobsk) }.not_to raise_error
27
- end
28
- it "accepts a hex encoded key" do
29
- expect { Crypto::PrivateKey.new(bobsk_hex, :hex) }.not_to raise_error
30
- end
31
- it "rejects a nil key" do
32
- expect { Crypto::PrivateKey.new(nil) }.to raise_error(ArgumentError)
33
- end
34
- it "rejects a short key" do
35
- expect { Crypto::PrivateKey.new("short") }.to raise_error(ArgumentError)
36
- end
37
- end
38
-
39
- context "public_key" do
40
- it "returns a public key" do
41
- subject.public_key.should be_a Crypto::PublicKey
42
- end
43
- it "returns the correct public key" do
44
- subject.public_key.to_s(:hex).should eql bobpk_hex
45
- end
46
- end
47
-
48
- context "#to_bytes" do
49
- it "returns the bytes of the key" do
50
- subject.to_s(:hex).should eq bobsk_hex
51
- end
52
- end
53
-
54
- context "#to_s" do
55
- it "returns the bytes of the key hex encoded" do
56
- subject.to_s(:hex).should eq bobsk_hex
57
- end
58
- it "returns the raw bytes of the key" do
59
- subject.to_bytes.should eq bobsk
60
- end
61
- end
62
-
63
- include_examples "key equality" do
64
- let(:key) { subject }
65
- let(:key_bytes) { subject.to_bytes }
66
- let(:other_key) { described_class.new(bobpk) }
67
- end
68
- end
@@ -1,39 +0,0 @@
1
- # encoding: binary
2
- require 'spec_helper'
3
-
4
- describe Crypto::SigningKey do
5
- let(:signing_key_hex) { hex_vector :sign_private }
6
- let(:signing_key) { hex2bytes signing_key_hex }
7
-
8
- let(:message) { test_vector :sign_message }
9
- let(:signature) { test_vector :sign_signature }
10
-
11
- # NOTE: this implicitly covers testing initialization from bytes
12
- subject { described_class.new(signing_key_hex, :hex) }
13
-
14
- it "generates keys" do
15
- described_class.generate.should be_a described_class
16
- end
17
-
18
- it "signs messages as bytes" do
19
- subject.sign(message).should eq signature
20
- end
21
-
22
- it "signs messages as hex" do
23
- subject.sign(message, :hex).should eq bytes2hex signature
24
- end
25
-
26
- it "serializes to hex" do
27
- subject.to_s(:hex).should eq signing_key_hex
28
- end
29
-
30
- it "serializes to bytes" do
31
- subject.to_bytes.should eq signing_key
32
- end
33
-
34
- include_examples "key equality" do
35
- let(:key_bytes) { signing_key }
36
- let(:key) { described_class.new(key_bytes) }
37
- let(:other_key) { described_class.new("B"*32) }
38
- end
39
- end
@@ -1,51 +0,0 @@
1
- # encoding: binary
2
- describe Crypto::VerifyKey do
3
- let(:signing_key) { hex_vector :sign_private }
4
- let(:verify_key) { hex_vector :sign_public }
5
- let(:verify_key_raw) { hex2bytes verify_key }
6
-
7
- let(:message) { test_vector :sign_message }
8
- let(:signature) { hex_vector :sign_signature }
9
- let(:signature_raw) { hex2bytes signature }
10
- let(:bad_signature) { sig = signature.dup; sig[0] = (sig[0].ord + 1).chr; sig }
11
-
12
- subject { Crypto::SigningKey.new(signing_key, :hex).verify_key }
13
-
14
- it "verifies correct signatures" do
15
- subject.verify(message, signature_raw).should be_true
16
- end
17
-
18
- it "verifies correct hex signatures" do
19
- subject.verify(message, signature, :hex).should be_true
20
- end
21
-
22
- it "detects bad signatures" do
23
- subject.verify(message, bad_signature, :hex).should be_false
24
- end
25
-
26
- it "raises when asked to verify with a bang" do
27
- expect { subject.verify!(message, bad_signature, :hex) }.to raise_exception Crypto::BadSignatureError
28
- end
29
-
30
- it "serializes to bytes" do
31
- subject.to_bytes.should eq verify_key_raw
32
- end
33
-
34
- it "serializes to hex" do
35
- subject.to_s(:hex).should eq verify_key
36
- end
37
-
38
- it "initializes from bytes" do
39
- described_class.new(verify_key_raw).to_s(:hex).should eq verify_key
40
- end
41
-
42
- it "initializes from hex" do
43
- described_class.new(verify_key, :hex).to_s(:hex).should eq verify_key
44
- end
45
-
46
- include_examples "key equality" do
47
- let(:key_bytes) { verify_key_raw }
48
- let(:key) { described_class.new(key_bytes) }
49
- let(:other_key) { described_class.new("B"*32) }
50
- end
51
- end