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.
- checksums.yaml +4 -4
- data/.travis.yml +1 -5
- data/CHANGES.md +15 -0
- data/Gemfile +4 -1
- data/Guardfile +8 -0
- data/README.md +52 -3
- data/lib/rbnacl.rb +65 -29
- data/lib/rbnacl/auth.rb +14 -18
- data/lib/rbnacl/boxes/curve25519xsalsa20poly1305.rb +185 -0
- data/lib/rbnacl/{keys → boxes/curve25519xsalsa20poly1305}/private_key.rb +26 -23
- data/lib/rbnacl/{keys → boxes/curve25519xsalsa20poly1305}/public_key.rb +13 -12
- data/lib/rbnacl/group_elements/curve25519.rb +81 -0
- data/lib/rbnacl/hash.rb +30 -14
- data/lib/rbnacl/hash/blake2b.rb +57 -0
- data/lib/rbnacl/hash/sha256.rb +15 -0
- data/lib/rbnacl/hash/sha512.rb +15 -0
- data/lib/rbnacl/hmac/sha256.rb +19 -17
- data/lib/rbnacl/hmac/sha512256.rb +18 -19
- data/lib/rbnacl/init.rb +10 -0
- data/lib/rbnacl/{keys/key_comparator.rb → key_comparator.rb} +1 -1
- data/lib/rbnacl/{auth/one_time.rb → one_time_auths/poly1305.rb} +21 -19
- data/lib/rbnacl/rake_tasks.rb +7 -6
- data/lib/rbnacl/random.rb +8 -3
- data/lib/rbnacl/random_nonce_box.rb +9 -14
- data/lib/rbnacl/secret_boxes/xsalsa20poly1305.rb +125 -0
- data/lib/rbnacl/self_test.rb +59 -40
- data/lib/rbnacl/serializable.rb +4 -12
- data/lib/rbnacl/signatures/ed25519.rb +15 -0
- data/lib/rbnacl/signatures/ed25519/signing_key.rb +104 -0
- data/lib/rbnacl/signatures/ed25519/verify_key.rb +91 -0
- data/lib/rbnacl/sodium.rb +43 -0
- data/lib/rbnacl/test_vectors.rb +34 -1
- data/lib/rbnacl/util.rb +52 -7
- data/lib/rbnacl/version.rb +2 -2
- data/rbnacl.gemspec +3 -6
- data/spec/rbnacl/{auth/one_time_spec.rb → authenticators/poly1305_spec.rb} +2 -2
- data/spec/rbnacl/boxes/curve25519xsalsa20poly1305/private_key_spec.rb +65 -0
- data/spec/rbnacl/{keys → boxes/curve25519xsalsa20poly1305}/public_key_spec.rb +10 -13
- data/spec/rbnacl/boxes/curve25519xsalsa20poly1305_spec.rb +39 -0
- data/spec/rbnacl/{point_spec.rb → group_element_spec.rb} +6 -8
- data/spec/rbnacl/hash/blake2b_spec.rb +26 -0
- data/spec/rbnacl/hash_spec.rb +13 -33
- data/spec/rbnacl/hmac/sha256_spec.rb +2 -2
- data/spec/rbnacl/hmac/sha512256_spec.rb +2 -2
- data/spec/rbnacl/random_nonce_box_spec.rb +21 -26
- data/spec/rbnacl/random_spec.rb +3 -3
- data/spec/rbnacl/secret_box_spec.rb +6 -6
- data/spec/rbnacl/signatures/ed25519/signing_key_spec.rb +30 -0
- data/spec/rbnacl/signatures/ed25519/verify_key_spec.rb +39 -0
- data/spec/rbnacl/util_spec.rb +67 -53
- data/spec/shared/authenticator.rb +36 -54
- data/spec/shared/box.rb +10 -10
- data/spec/shared/key_equality.rb +3 -3
- data/spec/shared/serializable.rb +17 -0
- data/spec/spec_helper.rb +14 -16
- data/tasks/rspec.rake +1 -0
- metadata +42 -67
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -3
- data/lib/rbnacl/box.rb +0 -171
- data/lib/rbnacl/encoder.rb +0 -44
- data/lib/rbnacl/encoders/base32.rb +0 -33
- data/lib/rbnacl/encoders/base64.rb +0 -30
- data/lib/rbnacl/encoders/hex.rb +0 -30
- data/lib/rbnacl/encoders/raw.rb +0 -12
- data/lib/rbnacl/keys/signing_key.rb +0 -95
- data/lib/rbnacl/keys/verify_key.rb +0 -96
- data/lib/rbnacl/nacl.rb +0 -146
- data/lib/rbnacl/point.rb +0 -70
- data/lib/rbnacl/secret_box.rb +0 -119
- data/spec/rbnacl/box_spec.rb +0 -42
- data/spec/rbnacl/encoder_spec.rb +0 -14
- data/spec/rbnacl/encoders/base32_spec.rb +0 -16
- data/spec/rbnacl/encoders/base64_spec.rb +0 -15
- data/spec/rbnacl/encoders/hex_spec.rb +0 -15
- data/spec/rbnacl/keys/private_key_spec.rb +0 -68
- data/spec/rbnacl/keys/signing_key_spec.rb +0 -39
- data/spec/rbnacl/keys/verify_key_spec.rb +0 -51
- metadata.gz.sig +0 -2
data/spec/shared/key_equality.rb
CHANGED
@@ -8,7 +8,7 @@ shared_examples "key equality" do
|
|
8
8
|
(key == key_bytes).should be true
|
9
9
|
end
|
10
10
|
it "keys are not equal to zero" do
|
11
|
-
(key ==
|
11
|
+
(key == RbNaCl::Util.zeros(32)).should be false
|
12
12
|
end
|
13
13
|
it "keys are not equal to another key" do
|
14
14
|
(key == other_key).should be false
|
@@ -17,10 +17,10 @@ shared_examples "key equality" do
|
|
17
17
|
|
18
18
|
context "lexicographic sorting" do
|
19
19
|
it "can be compared lexicographically to a key smaller than it" do
|
20
|
-
(key >
|
20
|
+
(key > RbNaCl::Util.zeros(32)).should be true
|
21
21
|
end
|
22
22
|
it "can be compared lexicographically to a key larger than it" do
|
23
|
-
(described_class.new(
|
23
|
+
(described_class.new(RbNaCl::Util.zeros(32)) < key).should be true
|
24
24
|
end
|
25
25
|
end
|
26
26
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# encoding: binary
|
2
|
+
|
3
|
+
shared_examples "serializable" do
|
4
|
+
context "serialization" do
|
5
|
+
it "supports #to_s" do
|
6
|
+
expect(subject.to_s).to be_a String
|
7
|
+
end
|
8
|
+
|
9
|
+
it "supports #to_str" do
|
10
|
+
expect(subject.to_str).to be_a String
|
11
|
+
end
|
12
|
+
|
13
|
+
it "supports #inspect" do
|
14
|
+
expect(subject.inspect).to be_a String
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,26 +1,24 @@
|
|
1
1
|
# encoding: binary
|
2
|
-
require '
|
2
|
+
require 'coveralls'
|
3
|
+
Coveralls.wear!
|
4
|
+
|
5
|
+
# Run the specs prior to running the self-test
|
6
|
+
$RBNACL_SELF_TEST = false
|
7
|
+
|
3
8
|
require 'bundler/setup'
|
4
9
|
require 'rbnacl'
|
5
10
|
require 'shared/box'
|
6
11
|
require 'shared/authenticator'
|
7
12
|
require 'shared/key_equality'
|
8
|
-
require '
|
9
|
-
|
10
|
-
Coveralls.wear!
|
11
|
-
|
12
|
-
def hex2bytes(hex)
|
13
|
-
Crypto::Encoder[:hex].decode(hex)
|
14
|
-
end
|
15
|
-
|
16
|
-
def bytes2hex(bytes)
|
17
|
-
Crypto::Encoder[:hex].encode(bytes)
|
18
|
-
end
|
13
|
+
require 'shared/serializable'
|
19
14
|
|
20
|
-
def
|
21
|
-
|
15
|
+
def vector(name)
|
16
|
+
[RbNaCl::TestVectors[name]].pack("H*")
|
22
17
|
end
|
23
18
|
|
24
|
-
|
25
|
-
|
19
|
+
RSpec.configure do |config|
|
20
|
+
config.after :all do
|
21
|
+
# Run the self-test after all the specs have passed
|
22
|
+
require 'rbnacl/self_test'
|
23
|
+
end
|
26
24
|
end
|
data/tasks/rspec.rake
CHANGED
metadata
CHANGED
@@ -1,37 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rbnacl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0.pre
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tony Arcieri
|
8
8
|
- Jonathan Stott
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
|
-
cert_chain:
|
12
|
-
-
|
13
|
-
-----BEGIN CERTIFICATE-----
|
14
|
-
MIIDbDCCAlSgAwIBAgIBATANBgkqhkiG9w0BAQUFADA+MRAwDgYDVQQDDAdiYXNj
|
15
|
-
dWxlMRUwEwYKCZImiZPyLGQBGRYFZ21haWwxEzARBgoJkiaJk/IsZAEZFgNjb20w
|
16
|
-
HhcNMTMwMzA4MDYwNzA1WhcNMTQwMzA4MDYwNzA1WjA+MRAwDgYDVQQDDAdiYXNj
|
17
|
-
dWxlMRUwEwYKCZImiZPyLGQBGRYFZ21haWwxEzARBgoJkiaJk/IsZAEZFgNjb20w
|
18
|
-
ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC8S9Y1eahE5w/b0P1jVbO4
|
19
|
-
nZbGwJGnGUTPPujZZfCXdkJu1pa8MvsU+pzgm051/yy9bWUp5eMTIjP9Qg+v92gK
|
20
|
-
bfjiUoVwAqISW7zD98gbXwdOgcbCjPFfdP7XmAlxbmq0/T+kYXVngfYo737SukWz
|
21
|
-
/3LLzfmtzBAZipJhTL3EAvlD2O2n2m/JARtxUwHjohd5199BBrSgbjKBXrbZ159F
|
22
|
-
rJzDZef9SLCeXbVL218C4Z4Yf3QvOAvlkBQbYZmD0jnivAvXaoylZnCgIpGUnEiA
|
23
|
-
C3raBW2/zMeKZC7dxygqezxwKiA/u4rxeCK3XDwYlRkF35UtAyIbIJYGODJL4MR9
|
24
|
-
AgMBAAGjdTBzMAkGA1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQWBBRP3DGA
|
25
|
-
NBCsdSMAHGzKpylnYy90ejAcBgNVHREEFTATgRFiYXNjdWxlQGdtYWlsLmNvbTAc
|
26
|
-
BgNVHRIEFTATgRFiYXNjdWxlQGdtYWlsLmNvbTANBgkqhkiG9w0BAQUFAAOCAQEA
|
27
|
-
NhP3rks+x49coXHS0vPPxXb7V0HDnuYP5R+pN1+T2Z7D4qwJKjEF4EC8mQYtwcNe
|
28
|
-
Qquz1t9Uxtr7i3QqjnwhNKlIVig1nikNF+FnApjYs4mwAtMHn77WOwx8wkn7ykej
|
29
|
-
7sF7dRE+BLgpJ88/ycnA6zsEiSQVcIMDVpiYUqUBx+MDNnq5jw5dI0Kct8vBirNA
|
30
|
-
QiZB6YQD1raVKUTpRubo4i0SnGpbMSxMy+YreqwNQiWG9iWCbp0JJWaOPSYTeQHe
|
31
|
-
3L/NVZQttSvxjd+WF6mA9yeCjpomboQMP36GRIZ30SoOVPMGvZ/+QpW52QU7mJW5
|
32
|
-
GzWyf92p0uscgUZVTYixjg==
|
33
|
-
-----END CERTIFICATE-----
|
34
|
-
date: 2013-04-19 00:00:00.000000000 Z
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-10-24 00:00:00.000000000 Z
|
35
13
|
dependencies:
|
36
14
|
- !ruby/object:Gem::Dependency
|
37
15
|
name: ffi
|
@@ -67,14 +45,14 @@ dependencies:
|
|
67
45
|
requirements:
|
68
46
|
- - '>='
|
69
47
|
- !ruby/object:Gem::Version
|
70
|
-
version: '
|
48
|
+
version: '2.14'
|
71
49
|
type: :development
|
72
50
|
prerelease: false
|
73
51
|
version_requirements: !ruby/object:Gem::Requirement
|
74
52
|
requirements:
|
75
53
|
- - '>='
|
76
54
|
- !ruby/object:Gem::Version
|
77
|
-
version: '
|
55
|
+
version: '2.14'
|
78
56
|
description: Ruby binding to the Networking and Cryptography (NaCl) library
|
79
57
|
email:
|
80
58
|
- tony.arcieri@gmail.com
|
@@ -90,6 +68,7 @@ files:
|
|
90
68
|
- .yardopts
|
91
69
|
- CHANGES.md
|
92
70
|
- Gemfile
|
71
|
+
- Guardfile
|
93
72
|
- LICENSE.txt
|
94
73
|
- README.md
|
95
74
|
- Rakefile
|
@@ -100,55 +79,53 @@ files:
|
|
100
79
|
- images/logo.png
|
101
80
|
- lib/rbnacl.rb
|
102
81
|
- lib/rbnacl/auth.rb
|
103
|
-
- lib/rbnacl/
|
104
|
-
- lib/rbnacl/
|
105
|
-
- lib/rbnacl/
|
106
|
-
- lib/rbnacl/
|
107
|
-
- lib/rbnacl/encoders/base64.rb
|
108
|
-
- lib/rbnacl/encoders/hex.rb
|
109
|
-
- lib/rbnacl/encoders/raw.rb
|
82
|
+
- lib/rbnacl/boxes/curve25519xsalsa20poly1305.rb
|
83
|
+
- lib/rbnacl/boxes/curve25519xsalsa20poly1305/private_key.rb
|
84
|
+
- lib/rbnacl/boxes/curve25519xsalsa20poly1305/public_key.rb
|
85
|
+
- lib/rbnacl/group_elements/curve25519.rb
|
110
86
|
- lib/rbnacl/hash.rb
|
87
|
+
- lib/rbnacl/hash/blake2b.rb
|
88
|
+
- lib/rbnacl/hash/sha256.rb
|
89
|
+
- lib/rbnacl/hash/sha512.rb
|
111
90
|
- lib/rbnacl/hmac/sha256.rb
|
112
91
|
- lib/rbnacl/hmac/sha512256.rb
|
113
|
-
- lib/rbnacl/
|
114
|
-
- lib/rbnacl/
|
115
|
-
- lib/rbnacl/
|
116
|
-
- lib/rbnacl/keys/signing_key.rb
|
117
|
-
- lib/rbnacl/keys/verify_key.rb
|
118
|
-
- lib/rbnacl/nacl.rb
|
119
|
-
- lib/rbnacl/point.rb
|
92
|
+
- lib/rbnacl/init.rb
|
93
|
+
- lib/rbnacl/key_comparator.rb
|
94
|
+
- lib/rbnacl/one_time_auths/poly1305.rb
|
120
95
|
- lib/rbnacl/rake_tasks.rb
|
121
96
|
- lib/rbnacl/random.rb
|
122
97
|
- lib/rbnacl/random_nonce_box.rb
|
123
|
-
- lib/rbnacl/
|
98
|
+
- lib/rbnacl/secret_boxes/xsalsa20poly1305.rb
|
124
99
|
- lib/rbnacl/self_test.rb
|
125
100
|
- lib/rbnacl/serializable.rb
|
101
|
+
- lib/rbnacl/signatures/ed25519.rb
|
102
|
+
- lib/rbnacl/signatures/ed25519/signing_key.rb
|
103
|
+
- lib/rbnacl/signatures/ed25519/verify_key.rb
|
104
|
+
- lib/rbnacl/sodium.rb
|
126
105
|
- lib/rbnacl/test_vectors.rb
|
127
106
|
- lib/rbnacl/util.rb
|
128
107
|
- lib/rbnacl/version.rb
|
129
108
|
- rbnacl.gemspec
|
130
109
|
- rbnacl.gpg
|
131
|
-
- spec/rbnacl/
|
132
|
-
- spec/rbnacl/
|
133
|
-
- spec/rbnacl/
|
134
|
-
- spec/rbnacl/
|
135
|
-
- spec/rbnacl/
|
136
|
-
- spec/rbnacl/
|
110
|
+
- spec/rbnacl/authenticators/poly1305_spec.rb
|
111
|
+
- spec/rbnacl/boxes/curve25519xsalsa20poly1305/private_key_spec.rb
|
112
|
+
- spec/rbnacl/boxes/curve25519xsalsa20poly1305/public_key_spec.rb
|
113
|
+
- spec/rbnacl/boxes/curve25519xsalsa20poly1305_spec.rb
|
114
|
+
- spec/rbnacl/group_element_spec.rb
|
115
|
+
- spec/rbnacl/hash/blake2b_spec.rb
|
137
116
|
- spec/rbnacl/hash_spec.rb
|
138
117
|
- spec/rbnacl/hmac/sha256_spec.rb
|
139
118
|
- spec/rbnacl/hmac/sha512256_spec.rb
|
140
|
-
- spec/rbnacl/keys/private_key_spec.rb
|
141
|
-
- spec/rbnacl/keys/public_key_spec.rb
|
142
|
-
- spec/rbnacl/keys/signing_key_spec.rb
|
143
|
-
- spec/rbnacl/keys/verify_key_spec.rb
|
144
|
-
- spec/rbnacl/point_spec.rb
|
145
119
|
- spec/rbnacl/random_nonce_box_spec.rb
|
146
120
|
- spec/rbnacl/random_spec.rb
|
147
121
|
- spec/rbnacl/secret_box_spec.rb
|
122
|
+
- spec/rbnacl/signatures/ed25519/signing_key_spec.rb
|
123
|
+
- spec/rbnacl/signatures/ed25519/verify_key_spec.rb
|
148
124
|
- spec/rbnacl/util_spec.rb
|
149
125
|
- spec/shared/authenticator.rb
|
150
126
|
- spec/shared/box.rb
|
151
127
|
- spec/shared/key_equality.rb
|
128
|
+
- spec/shared/serializable.rb
|
152
129
|
- spec/spec_helper.rb
|
153
130
|
- tasks/ci.rake
|
154
131
|
- tasks/rspec.rake
|
@@ -166,36 +143,34 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
166
143
|
version: '0'
|
167
144
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
168
145
|
requirements:
|
169
|
-
- - '
|
146
|
+
- - '>'
|
170
147
|
- !ruby/object:Gem::Version
|
171
|
-
version:
|
148
|
+
version: 1.3.1
|
172
149
|
requirements: []
|
173
150
|
rubyforge_project:
|
174
|
-
rubygems_version: 2.0.
|
151
|
+
rubygems_version: 2.0.6
|
175
152
|
signing_key:
|
176
153
|
specification_version: 4
|
177
154
|
summary: The Networking and Cryptography (NaCl) library provides a high-level toolkit
|
178
155
|
for building cryptographic systems and protocols
|
179
156
|
test_files:
|
180
|
-
- spec/rbnacl/
|
181
|
-
- spec/rbnacl/
|
182
|
-
- spec/rbnacl/
|
183
|
-
- spec/rbnacl/
|
184
|
-
- spec/rbnacl/
|
185
|
-
- spec/rbnacl/
|
157
|
+
- spec/rbnacl/authenticators/poly1305_spec.rb
|
158
|
+
- spec/rbnacl/boxes/curve25519xsalsa20poly1305/private_key_spec.rb
|
159
|
+
- spec/rbnacl/boxes/curve25519xsalsa20poly1305/public_key_spec.rb
|
160
|
+
- spec/rbnacl/boxes/curve25519xsalsa20poly1305_spec.rb
|
161
|
+
- spec/rbnacl/group_element_spec.rb
|
162
|
+
- spec/rbnacl/hash/blake2b_spec.rb
|
186
163
|
- spec/rbnacl/hash_spec.rb
|
187
164
|
- spec/rbnacl/hmac/sha256_spec.rb
|
188
165
|
- spec/rbnacl/hmac/sha512256_spec.rb
|
189
|
-
- spec/rbnacl/keys/private_key_spec.rb
|
190
|
-
- spec/rbnacl/keys/public_key_spec.rb
|
191
|
-
- spec/rbnacl/keys/signing_key_spec.rb
|
192
|
-
- spec/rbnacl/keys/verify_key_spec.rb
|
193
|
-
- spec/rbnacl/point_spec.rb
|
194
166
|
- spec/rbnacl/random_nonce_box_spec.rb
|
195
167
|
- spec/rbnacl/random_spec.rb
|
196
168
|
- spec/rbnacl/secret_box_spec.rb
|
169
|
+
- spec/rbnacl/signatures/ed25519/signing_key_spec.rb
|
170
|
+
- spec/rbnacl/signatures/ed25519/verify_key_spec.rb
|
197
171
|
- spec/rbnacl/util_spec.rb
|
198
172
|
- spec/shared/authenticator.rb
|
199
173
|
- spec/shared/box.rb
|
200
174
|
- spec/shared/key_equality.rb
|
175
|
+
- spec/shared/serializable.rb
|
201
176
|
- spec/spec_helper.rb
|
checksums.yaml.gz.sig
DELETED
Binary file
|
data.tar.gz.sig
DELETED
data/lib/rbnacl/box.rb
DELETED
@@ -1,171 +0,0 @@
|
|
1
|
-
# encoding: binary
|
2
|
-
module Crypto
|
3
|
-
# The Box class boxes and unboxes messages between a pair of keys
|
4
|
-
#
|
5
|
-
# This class uses the given public and secret keys to derive a shared key,
|
6
|
-
# which is used with the nonce given to encrypt the given messages and
|
7
|
-
# decrypt the given ciphertexts. The same shared key will generated from
|
8
|
-
# both pairing of keys, so given two keypairs belonging to alice (pkalice,
|
9
|
-
# skalice) and bob(pkbob, skbob), the key derived from (pkalice, skbob) with
|
10
|
-
# equal that from (pkbob, skalice). This is how the system works:
|
11
|
-
#
|
12
|
-
# @example
|
13
|
-
# # On bob's system
|
14
|
-
# bobkey = Crypto::PrivateKey.generate
|
15
|
-
# #=> #<Crypto::PrivateKey ...>
|
16
|
-
#
|
17
|
-
# # send bobkey.public_key to alice
|
18
|
-
# # recieve alice's public key, alicepk
|
19
|
-
# # NB: This is actually the hard part of the system. How to do it securely
|
20
|
-
# # is left as an exercise to for the reader.
|
21
|
-
# alice_pubkey = "..."
|
22
|
-
#
|
23
|
-
# # make a box
|
24
|
-
# alicebob_box = Crypto::Box.new(alice_pubkey, bobkey)
|
25
|
-
# #=> #<Crypto::Box ...>
|
26
|
-
#
|
27
|
-
# # encrypt a message to alice
|
28
|
-
# cipher_text = alicebob_box.box("A bad example of a nonce", "Hello, Alice!")
|
29
|
-
# #=> "..." # a string of bytes, 29 bytes long
|
30
|
-
#
|
31
|
-
# # send ["A bad example of a nonce", cipher_text] to alice
|
32
|
-
# # note that nonces don't have to be secret
|
33
|
-
# # receive [nonce, cipher_text_to_bob] from alice
|
34
|
-
#
|
35
|
-
# # decrypt the reply
|
36
|
-
# # Alice has been a little more sensible than bob, and has a random nonce
|
37
|
-
# # that is too fiddly to type here. But there are other choices than just
|
38
|
-
# # random
|
39
|
-
# plain_text = alicebob_box.open(nonce, cipher_text_to_bob)
|
40
|
-
# #=> "Hey there, Bob!"
|
41
|
-
#
|
42
|
-
# # we have a new message!
|
43
|
-
# # But Eve has tampered with this message, by flipping some bytes around!
|
44
|
-
# # [nonce2, cipher_text_to_bob_honest_love_eve]
|
45
|
-
# alicebob_box.open(nonce2, cipher_text_to_bob_honest_love_eve)
|
46
|
-
#
|
47
|
-
# # BOOM!
|
48
|
-
# # Bob gets a Crypto::CryptoError to deal with!
|
49
|
-
#
|
50
|
-
# It is VITALLY important that the nonce is a nonce, i.e. it is a number used
|
51
|
-
# only once for any given pair of keys. If you fail to do this, you
|
52
|
-
# compromise the privacy of the the messages encrypted. Also, bear in mind
|
53
|
-
# the property mentioned just above. Give your nonces a different prefix, or
|
54
|
-
# have one side use an odd counter and one an even counter. Just make sure
|
55
|
-
# they are different.
|
56
|
-
#
|
57
|
-
# The ciphertexts generated by this class include a 16-byte authenticator which
|
58
|
-
# is checked as part of the decryption. An invalid authenticator will cause
|
59
|
-
# the unbox function to raise. The authenticator is not a signature. Once
|
60
|
-
# you've looked in the box, you've demonstrated the ability to create
|
61
|
-
# arbitrary valid messages, so messages you send are repudiatable. For
|
62
|
-
# non-repudiatable messages, sign them before or after encryption.
|
63
|
-
class Box
|
64
|
-
|
65
|
-
# Number of bytes in a Box nonce
|
66
|
-
NONCEBYTES = NaCl::CURVE25519_XSALSA20_POLY1305_BOX_NONCEBYTES
|
67
|
-
|
68
|
-
# Create a new Box
|
69
|
-
#
|
70
|
-
# Sets up the Box for deriving the shared key and encrypting and
|
71
|
-
# decrypting messages.
|
72
|
-
#
|
73
|
-
# @param public_key [String,Crypto::PublicKey] The public key to encrypt to
|
74
|
-
# @param private_key [String,Crypto::PrivateKey] The private key to encrypt with
|
75
|
-
# @param encoding [Symbol] Parse keys from the given encoding
|
76
|
-
#
|
77
|
-
# @raise [Crypto::LengthError] on invalid keys
|
78
|
-
#
|
79
|
-
# @return [Crypto::Box] The new Box, ready to use
|
80
|
-
def initialize(public_key, private_key, encoding = :raw)
|
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
|
84
|
-
end
|
85
|
-
|
86
|
-
# Encrypts a message
|
87
|
-
#
|
88
|
-
# Encrypts the message with the given nonce to the keypair set up when
|
89
|
-
# initializing the class. Make sure the nonce is unique for any given
|
90
|
-
# keypair, or you might as well just send plain text.
|
91
|
-
#
|
92
|
-
# This function takes care of the padding required by the NaCL C API.
|
93
|
-
#
|
94
|
-
# @param nonce [String] A 24-byte string containing the nonce.
|
95
|
-
# @param message [String] The message to be encrypted.
|
96
|
-
#
|
97
|
-
# @raise [Crypto::LengthError] If the nonce is not valid
|
98
|
-
#
|
99
|
-
# @return [String] The ciphertext without the nonce prepended (BINARY encoded)
|
100
|
-
def box(nonce, message)
|
101
|
-
Util.check_length(nonce, nonce_bytes, "Nonce")
|
102
|
-
msg = Util.prepend_zeros(NaCl::ZEROBYTES, message)
|
103
|
-
ct = Util.zeros(msg.bytesize)
|
104
|
-
|
105
|
-
NaCl.crypto_box_curve25519_xsalsa20_poly1305_afternm(ct, msg, msg.bytesize, nonce, beforenm) || raise(CryptoError, "Encryption failed")
|
106
|
-
Util.remove_zeros(NaCl::BOXZEROBYTES, ct)
|
107
|
-
end
|
108
|
-
alias encrypt box
|
109
|
-
|
110
|
-
# Decrypts a ciphertext
|
111
|
-
#
|
112
|
-
# Decrypts the ciphertext with the given nonce using the keypair setup when
|
113
|
-
# initializing the class.
|
114
|
-
#
|
115
|
-
# This function takes care of the padding required by the NaCL C API.
|
116
|
-
#
|
117
|
-
# @param nonce [String] A 24-byte string containing the nonce.
|
118
|
-
# @param ciphertext [String] The message to be decrypted.
|
119
|
-
#
|
120
|
-
# @raise [Crypto::LengthError] If the nonce is not valid
|
121
|
-
# @raise [Crypto::CryptoError] If the ciphertext cannot be authenticated.
|
122
|
-
#
|
123
|
-
# @return [String] The decrypted message (BINARY encoded)
|
124
|
-
def open(nonce, ciphertext)
|
125
|
-
Util.check_length(nonce, nonce_bytes, "Nonce")
|
126
|
-
ct = Util.prepend_zeros(NaCl::BOXZEROBYTES, ciphertext)
|
127
|
-
message = Util.zeros(ct.bytesize)
|
128
|
-
|
129
|
-
NaCl.crypto_box_curve25519_xsalsa20_poly1305_open_afternm(message, ct, ct.bytesize, nonce, beforenm) || raise(CryptoError, "Decryption failed. Ciphertext failed verification.")
|
130
|
-
Util.remove_zeros(NaCl::ZEROBYTES, message)
|
131
|
-
end
|
132
|
-
alias decrypt open
|
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
|
-
|
162
|
-
private
|
163
|
-
def beforenm
|
164
|
-
@k ||= begin
|
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")
|
167
|
-
k
|
168
|
-
end
|
169
|
-
end
|
170
|
-
end
|
171
|
-
end
|