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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a9a8ff4b8548f802c19f9529c15034fc4c1329ab
4
- data.tar.gz: 56e3a1befb6c39b8c8205e49f167598fd3fc0bfa
3
+ metadata.gz: e795d6a45bee9ade9568ff3585a5571860ee23a4
4
+ data.tar.gz: 226ad82f45cd1c0037c7e0b91b7c0704308433a8
5
5
  SHA512:
6
- metadata.gz: d07e37c8ea67cceb18a6eca210cb03ce3c29381a3fe627ed24994a83e3b1093107521cc2b9588f76d26c4469aad9cd9eb266f80e34edfadb80b999d986fb1434
7
- data.tar.gz: 594217e061216f7e336827112e9ed01bb35772ba6b6547173eb673d3d79dd385bdd920a6c38231b21134a2e4333a8375440130d6e28b044aa95a3f4d32867305
6
+ metadata.gz: 20d0ea38c3d96edc5cb36675ebf32e7319a24bbac4c97667c52fc0ebfcb6c5c7deef20a5079ba92f84f002bc95404d27dcb94f064d1e1eef03fa12317542a58c
7
+ data.tar.gz: a8b6ece0da50a41ebee70fd6d4405f1c7a48347d0a235c76efbd008fcaf26bae16333b02b8d4f4c03c55741c9bf1efd374368db0deeae2aa76f68119a65ce42b
@@ -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
@@ -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
- # Continuously hashes until a value less than the group's order is found.
35
+ # Uniformly hashes a string to a number between 0 and the group's order.
24
36
  #
25
- # @param s (String) The value to be hashed.
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 < @group.order
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 input point.
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 suffle.
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
@@ -1,4 +1,4 @@
1
1
  module RingSig
2
2
  # This gem's version.
3
- VERSION = '0.3.0'
3
+ VERSION = '0.4.0'
4
4
  end
@@ -50,10 +50,10 @@ describe RingSig::Hasher do
50
50
  end
51
51
  end
52
52
 
53
- context 'Simple hasher, simple group' do
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: 1, a: 1, b: 1, g: [0, 1], n: 200, h: 1)
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
- [(OpenSSL::Digest::SHA256.hexdigest(s).to_i(16) % 256).to_s(16)].pack('H*')
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", "\xD0" # 208
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 21' do
89
- expect(hasher.hash_string('0')).to eq 21
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
@@ -106,12 +106,12 @@ describe RingSig::PrivateKey do
106
106
  end
107
107
  end
108
108
 
109
- context 'alternate hasher' do
109
+ context 'Secp384r1_Sha384 hasher' do
110
110
  before(:all) do
111
- @key = RingSig::PrivateKey.new(1, RingSig::Hasher::Secp160k1_Ripemd160)
111
+ @key = RingSig::PrivateKey.new(1, RingSig::Hasher::Secp384r1_Sha384)
112
112
  @foreign_keys = [
113
- RingSig::PrivateKey.new(2, RingSig::Hasher::Secp160k1_Ripemd160).public_key,
114
- RingSig::PrivateKey.new(3, RingSig::Hasher::Secp160k1_Ripemd160).public_key,
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 '3081a004150335d6eb01d7c658c2aae34e1e910e1b44c993069d30430214685baa33eacec37ff3530d710ca852731e1ac7b0021500881bf1e9c67d05c7a8a6ef93552a7852466034360214211b72b5e3a934d0e096441c5208b4322a83b7a130420214098d90e6e0a5e08186815be4a20a41480d55d7c202141cd9f8cc0df48519ecd6ad6e354ca634c8b604c2021415019f51cc2480ef6148dcd35a4be28037bf8899'
122
+ expect(sig.to_hex).to eq '3082016904310303c438f3cfc6d9b4d3da7ee4f23429387a3e9da42f87ac611ee390c007a81662e146a865f288111b758231917ce94436308197023100811608759c6a1a0afb245ffa6f15bcea8e6e02e6364371a232f74afbec60874770f66c2f87ad9dd9c851b80d38809bbe023063f90482db5f68dae8c8a45354189103ba3ff6c96d2114f1591300e17845e81e859dfb6996ae6ba9a011a20f820522b102307cb090c3788667d0bbf612853b2fb80856af833a26197a16df9b14a02e734a7bd8539e7d21e4ffd355a39dd9286e4898308199023100a803ebf9a67eb5fa91907d70bb53d93b192a206961e920afc99d8f3e3bbb8a8a2ece89c5a3dcd24dbc9a08a8f61c40bf02310097f561a1c60e7692a50c6e5be6a1ce8b52d88e228de552492351c845bc96180d9ac1578e0dc3b2a775a33d87b58f6155023100f670b730d0b719f1aced4dfbeeb027299f2b58b3297563b50dfb7e0e0fa67b04ce5a8c15b163227b7bdcd42bf8b6f572'
123
123
 
124
- expected_public_keys = [2, 1, 0].map{|i| ([@key] + @foreign_keys)[i].public_key}
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.3.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-15 00:00:00.000000000 Z
11
+ date: 2014-09-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler