rbnacl 1.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.
- data/.coveralls.yml +1 -0
- data/.gitignore +19 -0
- data/.rspec +4 -0
- data/.travis.yml +21 -0
- data/.yardopts +1 -0
- data/CHANGES.md +4 -0
- data/Gemfile +9 -0
- data/LICENSE.txt +23 -0
- data/README.md +179 -0
- data/Rakefile +5 -0
- data/images/dragons.png +0 -0
- data/images/ed25519.png +0 -0
- data/images/logo.png +0 -0
- data/lib/rbnacl.rb +46 -0
- data/lib/rbnacl/auth.rb +78 -0
- data/lib/rbnacl/auth/one_time.rb +38 -0
- data/lib/rbnacl/box.rb +141 -0
- data/lib/rbnacl/encoder.rb +44 -0
- data/lib/rbnacl/encoders/base32.rb +33 -0
- data/lib/rbnacl/encoders/base64.rb +30 -0
- data/lib/rbnacl/encoders/hex.rb +30 -0
- data/lib/rbnacl/encoders/raw.rb +12 -0
- data/lib/rbnacl/hash.rb +48 -0
- data/lib/rbnacl/hmac/sha256.rb +32 -0
- data/lib/rbnacl/hmac/sha512256.rb +35 -0
- data/lib/rbnacl/keys/key_comparator.rb +59 -0
- data/lib/rbnacl/keys/private_key.rb +62 -0
- data/lib/rbnacl/keys/public_key.rb +38 -0
- data/lib/rbnacl/keys/signing_key.rb +74 -0
- data/lib/rbnacl/keys/verify_key.rb +76 -0
- data/lib/rbnacl/nacl.rb +132 -0
- data/lib/rbnacl/point.rb +67 -0
- data/lib/rbnacl/rake_tasks.rb +56 -0
- data/lib/rbnacl/random.rb +19 -0
- data/lib/rbnacl/random_nonce_box.rb +109 -0
- data/lib/rbnacl/secret_box.rb +86 -0
- data/lib/rbnacl/self_test.rb +118 -0
- data/lib/rbnacl/serializable.rb +23 -0
- data/lib/rbnacl/test_vectors.rb +69 -0
- data/lib/rbnacl/util.rb +137 -0
- data/lib/rbnacl/version.rb +5 -0
- data/rbnacl.gemspec +28 -0
- data/rbnacl.gpg +30 -0
- data/spec/rbnacl/auth/one_time_spec.rb +8 -0
- data/spec/rbnacl/box_spec.rb +42 -0
- data/spec/rbnacl/encoder_spec.rb +14 -0
- data/spec/rbnacl/encoders/base32_spec.rb +16 -0
- data/spec/rbnacl/encoders/base64_spec.rb +15 -0
- data/spec/rbnacl/encoders/hex_spec.rb +15 -0
- data/spec/rbnacl/hash_spec.rb +52 -0
- data/spec/rbnacl/hmac/sha256_spec.rb +8 -0
- data/spec/rbnacl/hmac/sha512256_spec.rb +8 -0
- data/spec/rbnacl/keys/private_key_spec.rb +68 -0
- data/spec/rbnacl/keys/public_key_spec.rb +45 -0
- data/spec/rbnacl/keys/signing_key_spec.rb +40 -0
- data/spec/rbnacl/keys/verify_key_spec.rb +51 -0
- data/spec/rbnacl/point_spec.rb +29 -0
- data/spec/rbnacl/random_nonce_box_spec.rb +78 -0
- data/spec/rbnacl/random_spec.rb +9 -0
- data/spec/rbnacl/secret_box_spec.rb +24 -0
- data/spec/rbnacl/util_spec.rb +119 -0
- data/spec/shared/authenticator.rb +114 -0
- data/spec/shared/box.rb +51 -0
- data/spec/shared/key_equality.rb +26 -0
- data/spec/spec_helper.rb +14 -0
- data/tasks/ci.rake +11 -0
- data/tasks/rspec.rake +7 -0
- metadata +187 -0
data/lib/rbnacl/util.rb
ADDED
@@ -0,0 +1,137 @@
|
|
1
|
+
# encoding: binary
|
2
|
+
module Crypto
|
3
|
+
# Various utility functions
|
4
|
+
module Util
|
5
|
+
module_function
|
6
|
+
# Returns a string of n zeros
|
7
|
+
#
|
8
|
+
# Lots of the functions require us to create strings to pass into functions of a specified size.
|
9
|
+
#
|
10
|
+
# @param [Integer] n the size of the string to make
|
11
|
+
#
|
12
|
+
# @return [String] A nice collection of zeros
|
13
|
+
def zeros(n=32)
|
14
|
+
zeros = "\0" * n
|
15
|
+
# make sure they're 8-bit zeros, not 7-bit zeros. Otherwise we might get
|
16
|
+
# encoding errors later
|
17
|
+
zeros.respond_to?(:force_encoding) ? zeros.force_encoding('ASCII-8BIT') : zeros
|
18
|
+
end
|
19
|
+
|
20
|
+
# Prepends a message with zeros
|
21
|
+
#
|
22
|
+
# Many functions require a string with some zeros prepended.
|
23
|
+
#
|
24
|
+
# @param [Integer] n The number of zeros to prepend
|
25
|
+
# @param [String] message The string to be prepended
|
26
|
+
#
|
27
|
+
# @return [String] a bunch of zeros
|
28
|
+
def prepend_zeros(n, message)
|
29
|
+
zeros(n) + message
|
30
|
+
end
|
31
|
+
|
32
|
+
# Remove zeros from the start of a message
|
33
|
+
#
|
34
|
+
# Many functions require a string with some zeros prepended, then need them removing after. Note, this modifies the passed in string
|
35
|
+
#
|
36
|
+
# @param [Integer] n The number of zeros to remove
|
37
|
+
# @param [String] message The string to be slice
|
38
|
+
#
|
39
|
+
# @return [String] less a bunch of zeros
|
40
|
+
def remove_zeros(n, message)
|
41
|
+
message.slice!(n, message.bytesize - n)
|
42
|
+
end
|
43
|
+
|
44
|
+
# Check the length of the passed in string
|
45
|
+
#
|
46
|
+
# In several places through the codebase we have to be VERY strict with
|
47
|
+
# what length of string we accept. This method supports that.
|
48
|
+
#
|
49
|
+
# @raise [Crypto::LengthError] If the string is not the right length
|
50
|
+
#
|
51
|
+
# @param string [String] The string to compare
|
52
|
+
# @param length [Integer] The desired length
|
53
|
+
# @param description [String] Description of the string (used in the error)
|
54
|
+
def check_length(string, length, description)
|
55
|
+
if string.nil?
|
56
|
+
raise LengthError,
|
57
|
+
"#{description} was nil (Expected #{length.to_int})",
|
58
|
+
caller
|
59
|
+
end
|
60
|
+
|
61
|
+
if string.bytesize != length.to_int
|
62
|
+
raise LengthError,
|
63
|
+
"#{description} was #{string.bytesize} bytes (Expected #{length.to_int})",
|
64
|
+
caller
|
65
|
+
end
|
66
|
+
true
|
67
|
+
end
|
68
|
+
|
69
|
+
|
70
|
+
# Compare two 32 byte strings in constant time
|
71
|
+
#
|
72
|
+
# This should help to avoid timing attacks for string comparisons in your
|
73
|
+
# application. Note that many of the functions (such as HmacSha256#verify)
|
74
|
+
# use this method under the hood already.
|
75
|
+
#
|
76
|
+
# @param [String] one String #1
|
77
|
+
# @param [String] two String #2
|
78
|
+
#
|
79
|
+
# @return [Boolean] Well, are they equal?
|
80
|
+
def verify32(one, two)
|
81
|
+
return false unless two.bytesize == 32 && one.bytesize == 32
|
82
|
+
NaCl.crypto_verify_32(one, two)
|
83
|
+
end
|
84
|
+
|
85
|
+
# Compare two 32 byte strings in constant time
|
86
|
+
#
|
87
|
+
# This should help to avoid timing attacks for string comparisons in your
|
88
|
+
# application. Note that many of the functions (such as HmacSha256#verify)
|
89
|
+
# use this method under the hood already.
|
90
|
+
#
|
91
|
+
# @param [String] one String #1
|
92
|
+
# @param [String] two String #2
|
93
|
+
#
|
94
|
+
# @raise [ArgumentError] If the strings are not equal in length
|
95
|
+
#
|
96
|
+
# @return [Boolean] Well, are they equal?
|
97
|
+
def verify32!(one, two)
|
98
|
+
check_length(one, 32, "First message")
|
99
|
+
check_length(two, 32, "Second message")
|
100
|
+
NaCl.crypto_verify_32(one, two)
|
101
|
+
end
|
102
|
+
|
103
|
+
# Compare two 16 byte strings in constant time
|
104
|
+
#
|
105
|
+
# This should help to avoid timing attacks for string comparisons in your
|
106
|
+
# application. Note that many of the functions (such as OneTime#verify)
|
107
|
+
# use this method under the hood already.
|
108
|
+
#
|
109
|
+
# @param [String] one String #1
|
110
|
+
# @param [String] two String #2
|
111
|
+
#
|
112
|
+
# @return [Boolean] Well, are they equal?
|
113
|
+
def verify16(one, two)
|
114
|
+
return false unless two.bytesize == 16 && one.bytesize == 16
|
115
|
+
NaCl.crypto_verify_16(one, two)
|
116
|
+
end
|
117
|
+
|
118
|
+
# Compare two 16 byte strings in constant time
|
119
|
+
#
|
120
|
+
# This should help to avoid timing attacks for string comparisons in your
|
121
|
+
# application. Note that many of the functions (such as OneTime#verify)
|
122
|
+
# use this method under the hood already.
|
123
|
+
#
|
124
|
+
# @param [String] one String #1
|
125
|
+
# @param [String] two String #2
|
126
|
+
#
|
127
|
+
# @raise [ArgumentError] If the strings are not equal in length
|
128
|
+
#
|
129
|
+
# @return [Boolean] Well, are they equal?
|
130
|
+
def verify16!(one, two)
|
131
|
+
check_length(one, 16, "First message")
|
132
|
+
check_length(two, 16, "Second message")
|
133
|
+
NaCl.crypto_verify_16(one, two)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
data/rbnacl.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'rbnacl/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "rbnacl"
|
8
|
+
gem.version = Crypto::VERSION
|
9
|
+
gem.authors = ["Tony Arcieri"]
|
10
|
+
gem.email = ["tony.arcieri@gmail.com"]
|
11
|
+
gem.description = "Ruby binding to the Networking and Cryptography (NaCl) library"
|
12
|
+
gem.summary = "The Networking and Cryptography (NaCl) library provides a high-level toolkit for building cryptographic systems and protocols"
|
13
|
+
gem.homepage = "https://github.com/tarcieri/rbnacl"
|
14
|
+
|
15
|
+
gem.files = `git ls-files`.split($/)
|
16
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
|
+
gem.require_paths = ["lib"]
|
19
|
+
|
20
|
+
if defined? JRUBY_VERSION
|
21
|
+
gem.platform = "jruby"
|
22
|
+
end
|
23
|
+
|
24
|
+
gem.add_runtime_dependency 'ffi'
|
25
|
+
|
26
|
+
gem.add_development_dependency "rake"
|
27
|
+
gem.add_development_dependency "rspec"
|
28
|
+
end
|
data/rbnacl.gpg
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
2
|
+
Version: GnuPG v1.4.12 (Darwin)
|
3
|
+
|
4
|
+
mQENBFE2gC4BCADG/9ea48mbfT4Odzi6JLXQMt2z4Md6zO52O1w8RvA32hgx+Sm4
|
5
|
+
4amvwMGb44WXQkSCp//X4YWcZ+WAefZDz8VSfsvQ11CLAnnGPuKiItFCkmDCL0iV
|
6
|
+
2PrHQ3oZ8kfd3/f8qKPZI+TcPmJw1ttF/ugcly7zndCQq+17G/nMYNIxltegtfxm
|
7
|
+
AHGeuzgfG6r/IbvBrMgvAmV2+0/CnCpuuuIiSqkp9TnBH3rYl2x4ewwGrgp3GrGT
|
8
|
+
OLm/qEKNHbQGa8Q+yaHJczTJ5fNxEdVllEAfVhYPuEoBLDm4fjkgGS98nr9+T7pF
|
9
|
+
9M1IfmszfyenWut6RF1lfRrZQD7v02K7XOIXABEBAAG0JVRvbnkgQXJjaWVyaSA8
|
10
|
+
dG9ueS5hcmNpZXJpQGdtYWlsLmNvbT6JAT4EEwECACgFAlE2gC4CGwMFCQHhM4AG
|
11
|
+
CwkIBwMCBhUIAgkKCwQWAgMBAh4BAheAAAoJELIQJp27LYeHjwQH/jktme/Uzxhp
|
12
|
+
jodHv9iTUbaNi3PSjmNZJAzmtvsJzavrP2EuYomOK2Z0K387HbWPQpRGNxMzF85X
|
13
|
+
71YYRCGCsja6sFFaiVE5EOzbQVAdT0gyE7U/iPImbqtXAH9WdbxqgjrvnECwDsod
|
14
|
+
WyzGaanfbcF9E3b+od/CcjSpcsOJkuxZXwrZKxP9ehvy5dobYrLfageXVxJdj1rs
|
15
|
+
4tuD5IsIQnqW3uUzfaAOLS0oh6e4faDV5232Gva/y7j2fs235ceuHGv24iYf2NAE
|
16
|
+
c7rfnOpqT2/3ezNwqpNqE1RH2p1LgtmNkOn7z0iyck171WpCNUaDzT2QVMW1sVEQ
|
17
|
+
OQzIVvzM6DC5AQ0EUTaALgEIALCnnwjepJiWFYy6iSMDOZ4g6ifxOPdmlQp0SF83
|
18
|
+
BqbEuhr19EBb8Z3BTewIeszwiozCrYyE3Z/hXwJX9JcsTd+YlNE93IMXWq0Dvr2u
|
19
|
+
YPhXg4z7Ni9geJaCuQVu4R6pGHI9Irw2F/+xBvccS8nf+xzPsqcqZkFnal5ohCR2
|
20
|
+
Z4eXUI26La9qq9j5K6SGMemGwt9FKLXDuInOWSWpiztQBpEo66d8LGqvvHGUUTYH
|
21
|
+
LEsJzItLFTHOxTySvjt+9bVWgtXl5iLiR+dAL03Yf6J6E+Dzu12ELoq1kI/M6c0f
|
22
|
+
cczmhGT9+9PJfqg2A6MjAF5JEQUVa1HlDH9vnfwSc8nm0qUAEQEAAYkBJQQYAQIA
|
23
|
+
DwUCUTaALgIbDAUJAeEzgAAKCRCyECaduy2Hh19aB/93WEEPqVAFzo04f8P27KTw
|
24
|
+
n+UiVTTxLkEBNbUHqNDBwWZLBUhzDxoEI21OyAxMzJEj80GXyFtLBMO+lbzz8MvI
|
25
|
+
IcfLS3zXaeEFO+fofKbfilvzezSzslPTjxFx0He8C/SjggWVIRPfv5hpoyyx4FXW
|
26
|
+
a6ZmA5G29O2J85VhZr8EQuykB10K9tIGIgfpuvjfeL8K30rgPGPfwbZP7/U33Yxs
|
27
|
+
qwAwsd6Ej98U8TGUr/tTSVztjg7inWwkL84I3DnfedOn4ofVDetDvtjuaJcc16Z5
|
28
|
+
QspnbOIn+KGOcdodZQKglj4Esal0W3kg56Du9M5xzmfEB2UeK5aMTL5akoCjs9aK
|
29
|
+
=64l+
|
30
|
+
-----END PGP PUBLIC KEY BLOCK-----
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# encoding: binary
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe Crypto::Box do
|
5
|
+
let(:alicepk_hex) { Crypto::TestVectors[:alice_public] }
|
6
|
+
let(:bobsk_hex) { Crypto::TestVectors[:bob_private] }
|
7
|
+
|
8
|
+
let(:alicepk) { Crypto::Encoder[:hex].decode(alicepk_hex) }
|
9
|
+
let(:bobsk) { Crypto::Encoder[:hex].decode(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 nil \(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 nil \(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
|
@@ -0,0 +1,14 @@
|
|
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
|
@@ -0,0 +1,16 @@
|
|
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
|
@@ -0,0 +1,15 @@
|
|
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
|
@@ -0,0 +1,15 @@
|
|
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
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# encoding: binary
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe Crypto::Hash do
|
5
|
+
context "sha256" do
|
6
|
+
let(:reference_string) { hex2bytes Crypto::TestVectors[:sha256_message] }
|
7
|
+
let(:reference_string_hash) { hex2bytes Crypto::TestVectors[:sha256_digest] }
|
8
|
+
let(:empty_string_hash) { "\xE3\xB0\xC4B\x98\xFC\x1C\x14\x9A\xFB\xF4\xC8\x99o\xB9$'\xAEA\xE4d\x9B\x93L\xA4\x95\x99\exR\xB8U" }
|
9
|
+
let(:reference_string_hash_hex) { reference_string_hash.unpack('H*').first }
|
10
|
+
let(:empty_string_hash_hex) { empty_string_hash.unpack('H*').first }
|
11
|
+
|
12
|
+
it "calculates the correct hash for a reference string" do
|
13
|
+
Crypto::Hash.sha256(reference_string).should eq reference_string_hash
|
14
|
+
end
|
15
|
+
|
16
|
+
it "calculates the correct hash for an empty string" do
|
17
|
+
Crypto::Hash.sha256("").should eq empty_string_hash
|
18
|
+
end
|
19
|
+
|
20
|
+
it "calculates the correct hash for a reference string and returns it in hex" do
|
21
|
+
Crypto::Hash.sha256(reference_string, :hex).should eq reference_string_hash_hex
|
22
|
+
end
|
23
|
+
|
24
|
+
it "calculates the correct hash for an empty string and returns it in hex" do
|
25
|
+
Crypto::Hash.sha256("", :hex).should eq empty_string_hash_hex
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context "sha512" do
|
30
|
+
let(:reference_string) { "The quick brown fox jumps over the lazy dog." }
|
31
|
+
let(:reference_string_hash) { "\x91\xEA\x12E\xF2\rF\xAE\x9A\x03z\x98\x9FT\xF1\xF7\x90\xF0\xA4v\a\xEE\xB8\xA1M\x12\x89\f\xEAw\xA1\xBB\xC6\xC7\xED\x9C\xF2\x05\xE6{\x7F+\x8F\xD4\xC7\xDF\xD3\xA7\xA8a~E\xF3\xC4c\xD4\x81\xC7\xE5\x86\xC3\x9A\xC1\xED" }
|
32
|
+
let(:empty_string_hash) { "\xCF\x83\xE15~\xEF\xB8\xBD\xF1T(P\xD6m\x80\a\xD6 \xE4\x05\vW\x15\xDC\x83\xF4\xA9!\xD3l\xE9\xCEG\xD0\xD1<]\x85\xF2\xB0\xFF\x83\x18\xD2\x87~\xEC/c\xB91\xBDGAz\x81\xA582z\xF9'\xDA>" }
|
33
|
+
let(:reference_string_hash_hex) { reference_string_hash.unpack('H*').first }
|
34
|
+
let(:empty_string_hash_hex) { empty_string_hash.unpack('H*').first }
|
35
|
+
|
36
|
+
it "calculates the correct hash for a reference string" do
|
37
|
+
Crypto::Hash.sha512(reference_string).should eq reference_string_hash
|
38
|
+
end
|
39
|
+
|
40
|
+
it "calculates the correct hash for an empty string" do
|
41
|
+
Crypto::Hash.sha512("").should eq empty_string_hash
|
42
|
+
end
|
43
|
+
|
44
|
+
it "calculates the correct hash for a reference string and returns it in hex" do
|
45
|
+
Crypto::Hash.sha512(reference_string, :hex).should eq reference_string_hash_hex
|
46
|
+
end
|
47
|
+
|
48
|
+
it "calculates the correct hash for an empty string and returns it in hex" do
|
49
|
+
Crypto::Hash.sha512("", :hex).should eq empty_string_hash_hex
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
# encoding: binary
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe Crypto::PrivateKey do
|
5
|
+
let(:bobsk) { Crypto::TestVectors[:bob_private] }
|
6
|
+
let(:bobsk_raw) { Crypto::Encoder[:hex].decode(bobsk) }
|
7
|
+
let(:bobpk) { Crypto::TestVectors[:bob_public] }
|
8
|
+
let(:bobpk_raw) { Crypto::Encoder[:hex].decode(bobpk) }
|
9
|
+
|
10
|
+
subject { Crypto::PrivateKey.new(bobsk, :hex) }
|
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_raw) }.not_to raise_error
|
27
|
+
end
|
28
|
+
it "accepts a hex encoded key" do
|
29
|
+
expect { Crypto::PrivateKey.new(bobsk, :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
|
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
|
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
|
57
|
+
end
|
58
|
+
it "returns the raw bytes of the key" do
|
59
|
+
subject.to_bytes.should eq bobsk_raw
|
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, :hex) }
|
67
|
+
end
|
68
|
+
end
|