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.
- 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
|