ring_sig 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +21 -0
- data/lib/ring_sig/hasher.rb +20 -8
- data/lib/ring_sig/version.rb +1 -1
- data/spec/hasher_spec.rb +42 -8
- data/spec/private_key_spec.rb +6 -6
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e795d6a45bee9ade9568ff3585a5571860ee23a4
|
4
|
+
data.tar.gz: 226ad82f45cd1c0037c7e0b91b7c0704308433a8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 20d0ea38c3d96edc5cb36675ebf32e7319a24bbac4c97667c52fc0ebfcb6c5c7deef20a5079ba92f84f002bc95404d27dcb94f064d1e1eef03fa12317542a58c
|
7
|
+
data.tar.gz: a8b6ece0da50a41ebee70fd6d4405f1c7a48347d0a235c76efbd008fcaf26bae16333b02b8d4f4c03c55741c9bf1efd374368db0deeae2aa76f68119a65ce42b
|
data/CHANGELOG.md
CHANGED
@@ -5,6 +5,27 @@ This gem follows [Semantic Versioning 2.0.0](http://semver.org/spec/v2.0.0.html)
|
|
5
5
|
All classes and public methods are part of the public API, unless explicitly
|
6
6
|
noted otherwise in their documentation.
|
7
7
|
|
8
|
+
0.4.0
|
9
|
+
----
|
10
|
+
Release on 2014-09-18
|
11
|
+
|
12
|
+
This release maintains API compatibility with version 0.3.0, except for the two
|
13
|
+
constants that were removed.
|
14
|
+
|
15
|
+
Signatures produced with prior versions may be incompatible with signatures from
|
16
|
+
this version.
|
17
|
+
|
18
|
+
- Change the `Hasher#hash_string` method so that it can handle ECDSA groups
|
19
|
+
that have a much smaller order than the number of bits they have (such as
|
20
|
+
Curve25519).
|
21
|
+
- `Hasher` now validates that its group's byte-length is equal to its hash
|
22
|
+
algorithm's byte-length.
|
23
|
+
- Remove support for ECDSA groups that have an order larger than the number of
|
24
|
+
bits they have. Secp160k1 and Secp160r1 fall into this category because their
|
25
|
+
order is larger than 2^160.
|
26
|
+
- Remove the `Secp160k1_Ripemd160` and `Secp160r1_Ripemd160` constants, since
|
27
|
+
their groups are no longer supported.
|
28
|
+
|
8
29
|
0.3.0
|
9
30
|
----
|
10
31
|
Released on 2014-09-15
|
data/lib/ring_sig/hasher.rb
CHANGED
@@ -18,20 +18,32 @@ module RingSig
|
|
18
18
|
def initialize(group, algorithm)
|
19
19
|
@group = group
|
20
20
|
@algorithm = algorithm
|
21
|
+
|
22
|
+
algorithm_byte_length = algorithm.digest('a').size
|
23
|
+
if group.byte_length != algorithm_byte_length
|
24
|
+
raise ArgumentError, "Group's byte length (#{group.byte_length}), does not match hash algorithm's byte length (#{algorithm_byte_length})"
|
25
|
+
end
|
26
|
+
|
27
|
+
digest_max = 2 ** (algorithm_byte_length * 8) - 1
|
28
|
+
if digest_max < group.order
|
29
|
+
raise ArgumentError, "Invalid ECDSA group. Group's order must be less than the hash algorithm's maximum value"
|
30
|
+
end
|
31
|
+
|
32
|
+
@hash_cieling = digest_max - digest_max % group.order
|
21
33
|
end
|
22
34
|
|
23
|
-
#
|
35
|
+
# Uniformly hashes a string to a number between 0 and the group's order.
|
24
36
|
#
|
25
|
-
# @param s (String) The
|
37
|
+
# @param s (String) The string to be hashed.
|
26
38
|
# @return (Integer) A number between 0 and the group's order.
|
27
39
|
def hash_string(s)
|
28
40
|
n = nil
|
29
41
|
loop do
|
30
42
|
s = algorithm.digest(s)
|
31
43
|
n = s.unpack('H*').first.to_i(16)
|
32
|
-
break if n < @
|
44
|
+
break if n < @hash_cieling
|
33
45
|
end
|
34
|
-
n
|
46
|
+
n % group.order
|
35
47
|
end
|
36
48
|
|
37
49
|
# Hashes an array. Converts the Array to an OpenSSL::ASN1::Sequence der
|
@@ -59,7 +71,8 @@ module RingSig
|
|
59
71
|
# Hashes a point to another point.
|
60
72
|
#
|
61
73
|
# @param point [ECDSA::Point] The point to be hashed.
|
62
|
-
# @return [ECDSA::Point] A new point, deterministically computed from the
|
74
|
+
# @return [ECDSA::Point] A new point, deterministically computed from the
|
75
|
+
# input point.
|
63
76
|
def hash_point(point)
|
64
77
|
@group.generator * hash_array(point.coords)
|
65
78
|
end
|
@@ -67,7 +80,8 @@ module RingSig
|
|
67
80
|
# Shuffles an array in a deterministic manner.
|
68
81
|
#
|
69
82
|
# @param array (Array) The array to be shuffled.
|
70
|
-
# @param seed (Integer) A random seed which determines the outcome of the
|
83
|
+
# @param seed (Integer) A random seed which determines the outcome of the
|
84
|
+
# shuffle.
|
71
85
|
# @return (Array) The shuffled array.
|
72
86
|
def shuffle(array, seed)
|
73
87
|
seed_array = [seed, 0]
|
@@ -102,7 +116,5 @@ module RingSig
|
|
102
116
|
Secp256k1_Sha256 = new(ECDSA::Group::Secp256k1, OpenSSL::Digest::SHA256)
|
103
117
|
Secp256r1_Sha256 = new(ECDSA::Group::Secp256r1, OpenSSL::Digest::SHA256)
|
104
118
|
Secp384r1_Sha384 = new(ECDSA::Group::Secp384r1, OpenSSL::Digest::SHA384)
|
105
|
-
Secp160k1_Ripemd160 = new(ECDSA::Group::Secp160k1, OpenSSL::Digest::RIPEMD160)
|
106
|
-
Secp160r1_Ripemd160 = new(ECDSA::Group::Secp160r1, OpenSSL::Digest::RIPEMD160)
|
107
119
|
end
|
108
120
|
end
|
data/lib/ring_sig/version.rb
CHANGED
data/spec/hasher_spec.rb
CHANGED
@@ -50,10 +50,10 @@ describe RingSig::Hasher do
|
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
53
|
-
context 'Simple
|
53
|
+
context 'Simple hash algorithm, simple group' do
|
54
54
|
let(:group) do
|
55
|
-
# A simple group with order equal to 200
|
56
|
-
ECDSA::Group.new(name: 'simple', p:
|
55
|
+
# A simple 8-bit group with order equal to 200
|
56
|
+
ECDSA::Group.new(name: 'simple', p: 211, a: 1, b: 1, g: [0, 1], n: 200, h: 1)
|
57
57
|
end
|
58
58
|
|
59
59
|
let(:hash_algorithm) do
|
@@ -61,7 +61,7 @@ describe RingSig::Hasher do
|
|
61
61
|
stub_const 'SimpleHashAlgorithm', Class.new
|
62
62
|
SimpleHashAlgorithm.class_eval do
|
63
63
|
def self.digest(s)
|
64
|
-
[
|
64
|
+
[OpenSSL::Digest::SHA256.hexdigest(s)[-2,2]].pack('H*')
|
65
65
|
end
|
66
66
|
end
|
67
67
|
SimpleHashAlgorithm
|
@@ -77,17 +77,51 @@ describe RingSig::Hasher do
|
|
77
77
|
end
|
78
78
|
it_behaves_like 'hash algorithm', 'a', "\xBB" # 187
|
79
79
|
it_behaves_like 'hash algorithm', '0', "\xE9" # 233
|
80
|
-
it_behaves_like 'hash algorithm', "\xE9", "\
|
81
|
-
it_behaves_like 'hash algorithm', "\xD0", "\x15" # 21
|
80
|
+
it_behaves_like 'hash algorithm', "\xE9", "\r" # 13
|
82
81
|
|
83
82
|
describe '#hash_string' do
|
84
83
|
it 'hashes "a" to 187' do
|
85
84
|
expect(hasher.hash_string('a')).to eq 187
|
86
85
|
end
|
87
86
|
|
88
|
-
it 'hashes "0" to
|
89
|
-
expect(hasher.hash_string('0')).to eq
|
87
|
+
it 'hashes "0" to 13' do
|
88
|
+
expect(hasher.hash_string('0')).to eq 13
|
90
89
|
end
|
91
90
|
end
|
92
91
|
end
|
92
|
+
|
93
|
+
context 'Curve25519-like group' do
|
94
|
+
# This gem is not yet compatible with Curve25519, but we still test the
|
95
|
+
# hasher against it. Curve25519 has a distinct characteristic: its
|
96
|
+
# order is much smaller than its prime.
|
97
|
+
let(:group) do
|
98
|
+
ECDSA::Group.new(name: 'Curve25519-like', p: 2**255-19, a: 1, b: 1, g: [0, 1], n: 2**252+27742317777372353535851937790883648493, h: 1)
|
99
|
+
end
|
100
|
+
|
101
|
+
let(:hasher) { RingSig::Hasher.new(group, OpenSSL::Digest::SHA256) }
|
102
|
+
|
103
|
+
describe '#hash_string' do
|
104
|
+
it 'hashes "a"' do
|
105
|
+
expect(hasher.hash_string('a')).to eq 4790813224456470967164382530524007151295684942355166730955189790754105481631
|
106
|
+
end
|
107
|
+
|
108
|
+
it 'hashes "0"' do
|
109
|
+
expect(hasher.hash_string('0')).to eq 7203293323279838689554303289673273753938185156274697627287051646710131340360
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
114
|
+
|
115
|
+
context 'Non-matching byte-lengths' do
|
116
|
+
it 'raises an ArgumentError if group byte length does not match the hash algorithm byte length' do
|
117
|
+
expect { RingSig::Hasher.new(ECDSA::Group::Secp256k1, OpenSSL::Digest::SHA224) }.to raise_error(ArgumentError)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
context 'ECDSA group with an order larger than the maximum digest size' do
|
122
|
+
it 'raises an ArgumentError' do
|
123
|
+
expect { RingSig::Hasher.new(ECDSA::Group::Secp160k1, OpenSSL::Digest::RIPEMD160) }.to raise_error(ArgumentError)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
93
127
|
end
|
data/spec/private_key_spec.rb
CHANGED
@@ -106,12 +106,12 @@ describe RingSig::PrivateKey do
|
|
106
106
|
end
|
107
107
|
end
|
108
108
|
|
109
|
-
context '
|
109
|
+
context 'Secp384r1_Sha384 hasher' do
|
110
110
|
before(:all) do
|
111
|
-
@key = RingSig::PrivateKey.new(1, RingSig::Hasher::
|
111
|
+
@key = RingSig::PrivateKey.new(1, RingSig::Hasher::Secp384r1_Sha384)
|
112
112
|
@foreign_keys = [
|
113
|
-
RingSig::PrivateKey.new(2, RingSig::Hasher::
|
114
|
-
RingSig::PrivateKey.new(3, RingSig::Hasher::
|
113
|
+
RingSig::PrivateKey.new(2, RingSig::Hasher::Secp384r1_Sha384).public_key,
|
114
|
+
RingSig::PrivateKey.new(3, RingSig::Hasher::Secp384r1_Sha384).public_key,
|
115
115
|
]
|
116
116
|
end
|
117
117
|
|
@@ -119,9 +119,9 @@ describe RingSig::PrivateKey do
|
|
119
119
|
it 'signs and verifies' do
|
120
120
|
sig, public_keys = @key.sign(message, @foreign_keys)
|
121
121
|
|
122
|
-
expect(sig.to_hex).to eq '
|
122
|
+
expect(sig.to_hex).to eq '3082016904310303c438f3cfc6d9b4d3da7ee4f23429387a3e9da42f87ac611ee390c007a81662e146a865f288111b758231917ce94436308197023100811608759c6a1a0afb245ffa6f15bcea8e6e02e6364371a232f74afbec60874770f66c2f87ad9dd9c851b80d38809bbe023063f90482db5f68dae8c8a45354189103ba3ff6c96d2114f1591300e17845e81e859dfb6996ae6ba9a011a20f820522b102307cb090c3788667d0bbf612853b2fb80856af833a26197a16df9b14a02e734a7bd8539e7d21e4ffd355a39dd9286e4898308199023100a803ebf9a67eb5fa91907d70bb53d93b192a206961e920afc99d8f3e3bbb8a8a2ece89c5a3dcd24dbc9a08a8f61c40bf02310097f561a1c60e7692a50c6e5be6a1ce8b52d88e228de552492351c845bc96180d9ac1578e0dc3b2a775a33d87b58f6155023100f670b730d0b719f1aced4dfbeeb027299f2b58b3297563b50dfb7e0e0fa67b04ce5a8c15b163227b7bdcd42bf8b6f572'
|
123
123
|
|
124
|
-
expected_public_keys = [2,
|
124
|
+
expected_public_keys = [2, 0, 1].map{|i| ([@key] + @foreign_keys)[i].public_key}
|
125
125
|
expect(public_keys).to eq expected_public_keys
|
126
126
|
|
127
127
|
expect(sig.verify(message, public_keys)).to be true
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ring_sig
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stephen McCarthy
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-09-
|
11
|
+
date: 2014-09-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|