sodium 0.0.0 → 0.5.0
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.
- data/.gitignore +4 -0
- data/.travis.yml +27 -0
- data/Gemfile +9 -0
- data/README.md +111 -0
- data/Rakefile +3 -0
- data/VERSION +1 -0
- data/config/nacl_ffi.yml +90 -0
- data/lib/sodium.rb +24 -0
- data/lib/sodium/auth.rb +52 -0
- data/lib/sodium/box.rb +127 -0
- data/lib/sodium/buffer.rb +141 -0
- data/lib/sodium/delegate.rb +58 -0
- data/lib/sodium/ffi.rb +9 -0
- data/lib/sodium/ffi/crypto.rb +106 -0
- data/lib/sodium/ffi/lib_c.rb +9 -0
- data/lib/sodium/ffi/random.rb +11 -0
- data/lib/sodium/hash.rb +23 -0
- data/lib/sodium/one_time_auth.rb +52 -0
- data/lib/sodium/random.rb +16 -0
- data/lib/sodium/secret_box.rb +65 -0
- data/lib/sodium/sign.rb +75 -0
- data/lib/sodium/version.rb +5 -0
- data/sodium.gemspec +9 -3
- data/sodium.pub.gpg +37 -0
- data/tasks/libsodium.rake +70 -0
- data/tasks/test.rake +6 -0
- data/tasks/version.rake +3 -0
- data/test/sodium/auth/hmacsha256_test.rb +54 -0
- data/test/sodium/auth/hmacsha512256_test.rb +53 -0
- data/test/sodium/auth_test.rb +49 -0
- data/test/sodium/box/curve25519xsalsa20poly1305_test.rb +79 -0
- data/test/sodium/box_test.rb +109 -0
- data/test/sodium/buffer_test.rb +120 -0
- data/test/sodium/delegate_test.rb +44 -0
- data/test/sodium/hash/sha256_test.rb +31 -0
- data/test/sodium/hash/sha512_test.rb +35 -0
- data/test/sodium/hash_test.rb +35 -0
- data/test/sodium/one_time_auth/poly1305_test.rb +54 -0
- data/test/sodium/one_time_auth_test.rb +49 -0
- data/test/sodium/random_test.rb +25 -0
- data/test/sodium/secret_box/xsalsa20poly1305_test.rb +50 -0
- data/test/sodium/secret_box_test.rb +56 -0
- data/test/sodium/sign/ed25519_test.rb +52 -0
- data/test/sodium/sign_test.rb +58 -0
- data/test/test_helper.rb +44 -0
- metadata +117 -8
- checksums.yaml +0 -7
data/lib/sodium/sign.rb
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'sodium'
|
2
|
+
|
3
|
+
class Sodium::Sign
|
4
|
+
include Sodium::Delegate
|
5
|
+
|
6
|
+
def self.keypair
|
7
|
+
public_key = Sodium::Buffer.empty self.implementation[:PUBLICKEYBYTES]
|
8
|
+
secret_key = Sodium::Buffer.empty self.implementation[:SECRETKEYBYTES]
|
9
|
+
|
10
|
+
self.implementation.nacl_keypair(
|
11
|
+
public_key.to_str,
|
12
|
+
secret_key.to_str
|
13
|
+
) or raise Sodium::CryptoError, 'failed to generate a keypair'
|
14
|
+
|
15
|
+
return secret_key, public_key
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.verify(key, message, signature)
|
19
|
+
key = self._public_key(key)
|
20
|
+
signature = self._signature(message, signature)
|
21
|
+
message = Sodium::Buffer.empty(signature.bytesize)
|
22
|
+
mlen = FFI::MemoryPointer.new(:ulong_long, 1, true)
|
23
|
+
|
24
|
+
self.implementation.nacl_open(
|
25
|
+
message.to_str,
|
26
|
+
mlen,
|
27
|
+
signature.to_str,
|
28
|
+
signature.to_str.bytesize,
|
29
|
+
key.to_str
|
30
|
+
)
|
31
|
+
end
|
32
|
+
|
33
|
+
def initialize(key)
|
34
|
+
@key = self.class._secret_key(key)
|
35
|
+
end
|
36
|
+
|
37
|
+
def sign(message)
|
38
|
+
message = self.class._message(message)
|
39
|
+
signature = Sodium::Buffer.empty(message.bytesize + self.implementation[:BYTES])
|
40
|
+
slen = FFI::MemoryPointer.new(:ulong_long, 1, true)
|
41
|
+
|
42
|
+
self.implementation.nacl(
|
43
|
+
signature.to_str,
|
44
|
+
slen,
|
45
|
+
message.to_str,
|
46
|
+
message.to_str.bytesize,
|
47
|
+
@key.to_str
|
48
|
+
) or raise Sodium::CryptoError, 'failed to generate signature'
|
49
|
+
|
50
|
+
# signatures actually encode the message itself at the end, so we
|
51
|
+
# slice off only the signature bytes
|
52
|
+
signature.byteslice(
|
53
|
+
0,
|
54
|
+
slen.read_ulong_long - message.to_str.bytesize
|
55
|
+
)
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
def self._public_key(k)
|
61
|
+
Sodium::Buffer.new k, self.implementation[:PUBLICKEYBYTES]
|
62
|
+
end
|
63
|
+
|
64
|
+
def self._secret_key(k)
|
65
|
+
Sodium::Buffer.new k, self.implementation[:SECRETKEYBYTES]
|
66
|
+
end
|
67
|
+
|
68
|
+
def self._message(m)
|
69
|
+
Sodium::Buffer.new m
|
70
|
+
end
|
71
|
+
|
72
|
+
def self._signature(m, s)
|
73
|
+
Sodium::Buffer.new(s) + m
|
74
|
+
end
|
75
|
+
end
|
data/sodium.gemspec
CHANGED
@@ -1,17 +1,23 @@
|
|
1
1
|
Gem::Specification.new do |gem|
|
2
2
|
gem.name = 'sodium'
|
3
|
-
gem.version = '0.0.0'
|
3
|
+
gem.version = File.read('VERSION') rescue '0.0.0'
|
4
4
|
|
5
5
|
gem.author = 'Stephen Touset'
|
6
6
|
gem.email = 'stephen@touset.org'
|
7
7
|
|
8
8
|
gem.homepage = 'https://github.com/stouset/sodium'
|
9
|
-
gem.summary =
|
10
|
-
gem.description =
|
9
|
+
gem.summary = 'A Ruby binding to the easy-to-use high-speed crypto library libsodium'
|
10
|
+
gem.description = 'A library for performing cryptography based on modern ciphers and protocols'
|
11
11
|
|
12
12
|
gem.bindir = 'bin'
|
13
13
|
gem.files = `git ls-files` .split("\n")
|
14
14
|
gem.extensions = `git ls-files -- ext/*.rb`.split("\n")
|
15
15
|
gem.executables = `git ls-files -- bin/*` .split("\n").map {|e| File.basename(e) }
|
16
16
|
gem.test_files = `git ls-files -- spec/*` .split("\n")
|
17
|
+
|
18
|
+
gem.add_dependency 'ffi', '~> 1'
|
19
|
+
|
20
|
+
gem.add_development_dependency 'rake', '~> 10'
|
21
|
+
gem.add_development_dependency 'minitest', '~> 5'
|
22
|
+
gem.add_development_dependency 'version', '~> 1'
|
17
23
|
end
|
data/sodium.pub.gpg
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
2
|
+
Version: GnuPG v1.4.13 (Darwin)
|
3
|
+
|
4
|
+
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
|
35
|
+
4AA=
|
36
|
+
=JlbY
|
37
|
+
-----END PGP PUBLIC KEY BLOCK-----
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'rake/clean'
|
2
|
+
|
3
|
+
require 'rbconfig'
|
4
|
+
require 'digest/sha2'
|
5
|
+
|
6
|
+
|
7
|
+
LIBSODIUM_MIRROR = ENV['LIBSODIUM_MIRROR'] || "https://github.com/jedisct1/libsodium/tarball/%s"
|
8
|
+
LIBSODIUM_VERSION = ENV['LIBSODIUM_VERSION'] || 'master'
|
9
|
+
LIBSODIUM_DIGEST = ENV['LIBSODIUM_DIGEST'] || nil
|
10
|
+
|
11
|
+
LIBSODIUM_URL = LIBSODIUM_MIRROR % LIBSODIUM_VERSION
|
12
|
+
LIBSODIUM_PATH = "libsodium-#{LIBSODIUM_VERSION}"
|
13
|
+
LIBSODIUM_TARBALL = "build/#{LIBSODIUM_PATH}.tar.gz"
|
14
|
+
LIBSODIUM_BUILD = "build/#{LIBSODIUM_PATH}"
|
15
|
+
LIBSODIUM_LIBDIR = "#{LIBSODIUM_BUILD}/src/libsodium/.libs"
|
16
|
+
LIBSODIUM_LIB = "libsodium.a"
|
17
|
+
LIBSODIUM = "#{LIBSODIUM_LIBDIR}/#{LIBSODIUM_LIB}"
|
18
|
+
|
19
|
+
namespace :libsodium do
|
20
|
+
directory LIBSODIUM_BUILD
|
21
|
+
|
22
|
+
file LIBSODIUM_TARBALL => LIBSODIUM_BUILD do
|
23
|
+
sh %{curl -L -o #{LIBSODIUM_TARBALL} #{LIBSODIUM_URL}}
|
24
|
+
|
25
|
+
next if LIBSODIUM_DIGEST.nil?
|
26
|
+
next if LIBSODIUM_DIGEST == Digest::SHA256.hexdigest(
|
27
|
+
File.read(LIBSODIUM_TARBALL)
|
28
|
+
)
|
29
|
+
|
30
|
+
rm LIBSODIUM_TARBALL
|
31
|
+
raise "#{LIBSODIUM_TARBALL} failed checksum"
|
32
|
+
end
|
33
|
+
|
34
|
+
file "#{LIBSODIUM_BUILD}/autogen.sh" => [
|
35
|
+
LIBSODIUM_BUILD,
|
36
|
+
LIBSODIUM_TARBALL,
|
37
|
+
] do
|
38
|
+
sh %{tar -C #{LIBSODIUM_BUILD} --strip-components 1 -m -xf #{LIBSODIUM_TARBALL}}
|
39
|
+
end
|
40
|
+
|
41
|
+
file "#{LIBSODIUM_BUILD}/configure" => "#{LIBSODIUM_BUILD}/autogen.sh" do
|
42
|
+
sh %{cd #{LIBSODIUM_BUILD} && ./autogen.sh}
|
43
|
+
end
|
44
|
+
|
45
|
+
file "#{LIBSODIUM_BUILD}/Makefile" => "#{LIBSODIUM_BUILD}/configure" do
|
46
|
+
sh %{cd #{LIBSODIUM_BUILD} && ./configure}
|
47
|
+
end
|
48
|
+
|
49
|
+
file LIBSODIUM => "#{LIBSODIUM_BUILD}/Makefile" do
|
50
|
+
sh %{cd #{LIBSODIUM_BUILD} && make}
|
51
|
+
end
|
52
|
+
|
53
|
+
desc 'Compile a local copy of libsodium'
|
54
|
+
task :compile => LIBSODIUM do
|
55
|
+
# allow use of the library by the dynamic linker
|
56
|
+
ENV['DYLD_LIBRARY_PATH'] = LIBSODIUM_LIBDIR
|
57
|
+
ENV[ 'LD_LIBRARY_PATH'] = LIBSODIUM_LIBDIR
|
58
|
+
end
|
59
|
+
|
60
|
+
task :clean do
|
61
|
+
sh %{cd #{LIBSODIUM_BUILD} && make mostlyclean}
|
62
|
+
end
|
63
|
+
|
64
|
+
task :clobber do
|
65
|
+
CLOBBER.add 'build'
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
task :clean => 'libsodium:clean'
|
70
|
+
task :clobber => 'libsodium:clobber'
|
data/tasks/test.rake
ADDED
data/tasks/version.rake
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
describe Sodium::Auth::HMACSHA256 do
|
4
|
+
include SodiumTestHelpers
|
5
|
+
|
6
|
+
subject { self.klass.new(self.key) }
|
7
|
+
|
8
|
+
let(:klass) { Sodium::Auth::HMACSHA256 }
|
9
|
+
let(:primitive) { :hmacsha256 }
|
10
|
+
|
11
|
+
let :constants do
|
12
|
+
{ :BYTES => 32,
|
13
|
+
:KEYBYTES => 32, }
|
14
|
+
end
|
15
|
+
|
16
|
+
let_64(:key) { 'XMfWD8/yrcNDzJyGhxRIwi5tSGKf8D0ul9FyX/djvjg=' }
|
17
|
+
let_64(:authenticator) { '6WDKvxKevcZts0Yc1HWGnylNYEpcxPO9tVtApEK8XWc=' }
|
18
|
+
let_64(:plaintext) { 'bWVzc2FnZQ==' }
|
19
|
+
|
20
|
+
it '::primitive must be correct' do
|
21
|
+
self.klass.primitive.must_equal self.primitive
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'must have correct values for its constants' do
|
25
|
+
self.constants.each_pair do |name, value|
|
26
|
+
self.klass[name].must_equal value
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'must mint keys' do
|
31
|
+
self.klass.key.bytesize.
|
32
|
+
must_equal self.klass[:KEYBYTES]
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'must generate authenticators' do
|
36
|
+
self.subject.auth(
|
37
|
+
self.plaintext
|
38
|
+
).to_str.must_equal self.authenticator
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'must verify authenticators' do
|
42
|
+
self.subject.verify(
|
43
|
+
self.plaintext,
|
44
|
+
self.authenticator
|
45
|
+
).must_equal true
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'must not verify forged authenticators' do
|
49
|
+
self.subject.verify(
|
50
|
+
self.plaintext,
|
51
|
+
self.authenticator.succ
|
52
|
+
).must_equal false
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
describe Sodium::Auth::HMACSHA512256 do
|
4
|
+
include SodiumTestHelpers
|
5
|
+
|
6
|
+
subject { self.klass.new(self.key) }
|
7
|
+
|
8
|
+
let(:klass) { Sodium::Auth::HMACSHA512256 }
|
9
|
+
let(:primitive) { :hmacsha512256 }
|
10
|
+
|
11
|
+
let :constants do
|
12
|
+
{ :BYTES => 32,
|
13
|
+
:KEYBYTES => 32, }
|
14
|
+
end
|
15
|
+
|
16
|
+
let_64(:key) { 'XMfWD8/yrcNDzJyGhxRIwi5tSGKf8D0ul9FyX/djvjg=' }
|
17
|
+
let_64(:authenticator) { '6BN5+HNq0F8skQKkta+CLiBJ7mrrJaGw3G2J7jMT2qA=' }
|
18
|
+
let_64(:plaintext) { 'bWVzc2FnZQ==' }
|
19
|
+
|
20
|
+
it '::primitive must be correct' do
|
21
|
+
self.klass.primitive.must_equal self.primitive
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'must have correct values for its constants' do
|
25
|
+
self.constants.each_pair do |name, value|
|
26
|
+
self.klass[name].must_equal value
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'must mint keys' do
|
31
|
+
self.klass.key.bytesize.must_equal self.klass[:KEYBYTES]
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'must generate authenticators' do
|
35
|
+
self.subject.auth(
|
36
|
+
self.plaintext
|
37
|
+
).to_str.must_equal self.authenticator
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'must verify authenticators' do
|
41
|
+
self.subject.verify(
|
42
|
+
self.plaintext,
|
43
|
+
self.authenticator
|
44
|
+
).must_equal true
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'must not verify forged authenticators' do
|
48
|
+
self.subject.verify(
|
49
|
+
self.plaintext,
|
50
|
+
self.authenticator.succ
|
51
|
+
).must_equal false
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
describe Sodium::Auth do
|
4
|
+
include SodiumTestHelpers
|
5
|
+
|
6
|
+
subject { self.klass.new(self.key) }
|
7
|
+
let(:klass) { Sodium::Auth }
|
8
|
+
let(:key) { self.klass.key }
|
9
|
+
|
10
|
+
it 'must default to the HMACSHA512256 implementation' do
|
11
|
+
self.klass.implementation.
|
12
|
+
must_equal Sodium::Auth::HMACSHA512256
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'must allow access to alternate implementations' do
|
16
|
+
self.klass.implementation(:hmacsha256).
|
17
|
+
must_equal Sodium::Auth::HMACSHA256
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'must instantiate the default implementation' do
|
21
|
+
self.subject.
|
22
|
+
must_be_kind_of Sodium::Auth::HMACSHA512256
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'must mint keys from the default implementation' do
|
26
|
+
sodium_mock_default(self.klass) do |klass, mock|
|
27
|
+
mock.expect :[], 0, [:KEYBYTES]
|
28
|
+
|
29
|
+
klass.key.to_str.must_equal ''
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'must raise when instantiating with an invalid key' do
|
34
|
+
lambda { self.klass.new(self.key.to_str[0..-2]) }.
|
35
|
+
must_raise Sodium::LengthError
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'must raise when verifying an invalid authenticator' do
|
39
|
+
lambda { self.subject.verify('message', 'blaaah') }.
|
40
|
+
must_raise Sodium::LengthError
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'must raise when failing to generate an authenticator' do
|
44
|
+
sodium_stub_failure(self.klass, :nacl) do
|
45
|
+
lambda { self.subject.auth('message') }.
|
46
|
+
must_raise Sodium::CryptoError
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
describe Sodium::Box::Curve25519XSalsa20Poly1305 do
|
4
|
+
include SodiumTestHelpers
|
5
|
+
|
6
|
+
subject { self.klass.new(self.secret_key, self.public_key) }
|
7
|
+
|
8
|
+
let(:klass) { Sodium::Box::Curve25519XSalsa20Poly1305 }
|
9
|
+
let(:primitive) { :curve25519xsalsa20poly1305 }
|
10
|
+
|
11
|
+
let :constants do
|
12
|
+
{ :PUBLICKEYBYTES => 32,
|
13
|
+
:SECRETKEYBYTES => 32,
|
14
|
+
:BEFORENMBYTES => 32,
|
15
|
+
:NONCEBYTES => 24,
|
16
|
+
:ZEROBYTES => 32,
|
17
|
+
:BOXZEROBYTES => 16,
|
18
|
+
:MACBYTES => 16, }
|
19
|
+
end
|
20
|
+
|
21
|
+
let_64(:secret_key) { 'f52WNdyy0r1YA5NCGlcF+vJ5HPG8yfHwzn/HJSJzfQk=' }
|
22
|
+
let_64(:public_key) { 'es8h5AH9GGD7PF10D1txeHAFAB2UNc9OZF+JqFWE9y8=' }
|
23
|
+
let_64(:shared_key) { 'TTp8bQBhIuiiQ0plVcqS3Cj62i/IdAFnopx4t9di2Kg=' }
|
24
|
+
let_64(:nonce) { 'i72xIDJ4tcHCOHGYAzI6PoiVm31PFVgx' }
|
25
|
+
let_64(:ciphertext) { 'lHhCSFzopX4z02nlIuInHe3hFwpHFdA=' }
|
26
|
+
let_64(:plaintext) { 'bWVzc2FnZQ==' }
|
27
|
+
|
28
|
+
it '::primitive must be correct' do
|
29
|
+
self.klass.primitive.must_equal self.primitive
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'must have correct values for its constants' do
|
33
|
+
self.constants.each_pair do |name, value|
|
34
|
+
self.klass[name].must_equal value
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'must mint secret keys' do
|
39
|
+
self.klass.keypair[0].bytesize.must_equal self.klass[:SECRETKEYBYTES]
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'must mint public keys' do
|
43
|
+
self.klass.keypair[1].bytesize.must_equal self.klass[:PUBLICKEYBYTES]
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'must generate closed boxes' do
|
47
|
+
self.subject.box(
|
48
|
+
self.plaintext,
|
49
|
+
self.nonce
|
50
|
+
).to_str.must_equal self.ciphertext
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'must open boxes' do
|
54
|
+
self.subject.open(
|
55
|
+
self.ciphertext,
|
56
|
+
self.nonce
|
57
|
+
).to_str.must_equal self.plaintext
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'must generate shared keys' do
|
61
|
+
self.subject.beforenm.to_str.must_equal self.shared_key
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'must generate closed boxes with shared keys' do
|
65
|
+
self.klass.afternm(
|
66
|
+
self.shared_key,
|
67
|
+
self.plaintext,
|
68
|
+
self.nonce
|
69
|
+
).to_str.must_equal self.ciphertext
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'must open boxes with shared keys' do
|
73
|
+
self.klass.open_afternm(
|
74
|
+
self.shared_key,
|
75
|
+
self.ciphertext,
|
76
|
+
self.nonce
|
77
|
+
).to_str.must_equal self.plaintext
|
78
|
+
end
|
79
|
+
end
|