rbnacl 1.1.0 → 2.0.0.pre

Sign up to get free protection for your applications and to get access to all the features.
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