schnorr_sig 0.0.0.4 → 0.2.0.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9cd55fdf9335f6ea817837d76d3ce130f9752ab7cbf582c822e061dc68574583
4
- data.tar.gz: dbc20c45aac2f0d9443d278a93ff6e7ae88cea2fc26b68eaf5226c6dd47979bc
3
+ metadata.gz: 37ba87126b971e1e74099bbed572cb7e088902db0cba9fdf38ef5de96ab75f69
4
+ data.tar.gz: 9001aae50944fcf3daf558db01a44c6b5f4ee7e74f729292026c83fe38c1367d
5
5
  SHA512:
6
- metadata.gz: e180ad80feddacf2ee05dd4a66d8518a53233ac56ba393917bac45e19e5cae25530e87aacdcd330523ce6751e2fb754efc5359571a564db21197d7063bb3e737
7
- data.tar.gz: fc67524a97a42b517efff14b7c4bcc21732d8f6e83a353d51220f3e7627aab646edce9e25fd9676f6f7e13bc62eceb3d52062bdbc234a0d640dfe3eba7f78086
6
+ metadata.gz: a85306c995daa8ce6b30b303e530892a4014f367854dccda5a3f119dc2170087e04fd069d6a8516f30bfe5d1b2e5e351ae495f331b65d1ab920ec767d60f154b
7
+ data.tar.gz: e7abe94145d870f072924e555e7510e886159aef5119375892ac10243abd08ccf72ff078f545b68b3502a9d09f644f38d5512220796e71b138b24f642813bc78
data/README.md CHANGED
@@ -14,6 +14,24 @@ and specifications similar to
14
14
  [IETF RFCs](https://en.wikipedia.org/wiki/Request_for_Comments).
15
15
  BIP340 specifies elliptic curve `secp256k1` for use with Schnorr signatures.
16
16
 
17
+ Two separate implementations are provided.
18
+
19
+ ## Ruby Implementation
20
+
21
+ This is the default implementation: entirely Ruby code within this library,
22
+ with mostly-Ruby dependencies:
23
+
24
+ * [ecdsa_ext](https://github.com/azuchi/ruby_ecdsa_ext)
25
+ - [ecdsa](https://github.com/DavidEGrayson/ruby_ecdsa/)
26
+
27
+ ## "Fast" Implementation
28
+
29
+ This is based on the [rbsecp256k1](https://github.com/etscrivner/rbsecp256k1)
30
+ gem, which is not installed by default. The gem wraps the
31
+ [secp256k1](https://github.com/bitcoin-core/secp256k1) library from the
32
+ Bitcoin project, which provides battle-tested performance, correctness, and
33
+ security guarantees.
34
+
17
35
  # Usage
18
36
 
19
37
  This library is provided as a RubyGem. It has a single dependency on
@@ -77,9 +95,9 @@ require 'schnorr_sig/fast' # not 'schnorr_sig'
77
95
  # Elliptic Curves
78
96
 
79
97
  Note that [elliptic curves](https://en.wikipedia.org/wiki/Elliptic_curve)
80
- are not ellipses, but can instead be described by cubic equations of
98
+ are not ellipses, but are instead described by cubic equations of
81
99
  the form: `y^2 = x^3 + ax + b` where `a` and `b` are the parameters of the
82
- resulting curve. All points `(x, y)` which satisfy a given parameterized
100
+ resulting equation. All points `(x, y)` which satisfy a given parameterized
83
101
  equation provide the exact definition of an elliptic curve.
84
102
 
85
103
  ## Curve `secp256k1`
@@ -104,11 +122,11 @@ Here is one
104
122
  }
105
123
  ```
106
124
 
107
- * `p` is the prime for the Field, below INTMAX(32) (256^32)
125
+ * `p` is the prime for the Field, below `INTMAX(32)` (256^32)
108
126
  * `a` is zero, as above
109
127
  * `b` is seven, as above
110
- * `g` is the generator point: [x, y]
111
- * `n` is the Group order, significantly below INTMAX(32)
128
+ * `g` is the generator point: `[x, y]`
129
+ * `n` is the Group order, significantly below `INTMAX(32)`
112
130
 
113
131
  Elliptic curves have algebraic structures called
114
132
  [Groups](https://en.wikipedia.org/wiki/Group_\(mathematics\)) and
@@ -224,6 +242,7 @@ required.
224
242
  * For any given x-value on the curve, the y-value is easily generated
225
243
  * For most curves, there are two different y-values for an x-value
226
244
  * We are always dealing with 32-byte integers: **Bignums**
245
+ * Bignum math can be expensive
227
246
  * Converting between integer format and 32-byte strings can be expensive
228
247
  * The Schnorr algorithm requires lots of `string <--> integer` conversion
229
248
  * Hex strings are never used internally
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.0.4
1
+ 0.2.0.1
@@ -1,5 +1,5 @@
1
- require 'schnorr_sig/util'
2
- require 'rbsecp256k1' # gem, C extension
1
+ require 'schnorr_sig/util' # project
2
+ require 'rbsecp256k1' # gem, C extension
3
3
 
4
4
  # re-open SchnorrSig to add more functions, errors, and constants
5
5
  module SchnorrSig
@@ -0,0 +1,221 @@
1
+ require 'schnorr_sig/util' # project
2
+ require 'ecdsa_ext' # gem
3
+ autoload :SecureRandom, 'securerandom' # stdlib
4
+
5
+ # This implementation is based on the BIP340 spec: https://bips.xyz/340
6
+ # re-open SchnorrSig to add more functions, errors, and constants
7
+ module SchnorrSig
8
+ class Error < RuntimeError; end
9
+ class BoundsError < Error; end
10
+ class SanityCheck < Error; end
11
+ class VerifyFail < Error; end
12
+ class InfinityPoint < Error; end
13
+
14
+ GROUP = ECDSA::Group::Secp256k1
15
+ P = GROUP.field.prime # smaller than 256**32
16
+ N = GROUP.order # smaller than P
17
+ B = GROUP.byte_length # 32
18
+
19
+ # val (dot) G, returns ECDSA::Point
20
+ def self.dot_group(val)
21
+ # ecdsa_ext uses jacobian projection: 10x faster than GROUP.generator * val
22
+ (GROUP.generator.to_jacobian * val).to_affine
23
+ end
24
+
25
+ # returns even_val or N - even_val
26
+ def self.select_even_y(point, even_val)
27
+ point.y.even? ? even_val : N - even_val
28
+ end
29
+
30
+ # int(x) function signature matches BIP340, returns a bignum (presumably)
31
+ class << self
32
+ alias_method :int, :bin2big
33
+ end
34
+
35
+ # bytes(val) function signature matches BIP340, returns a binary string
36
+ def self.bytes(val)
37
+ case val
38
+ when Integer
39
+ # BIP340: The function bytes(x), where x is an integer,
40
+ # returns the 32-byte encoding of x, most significant byte first.
41
+ big2bin(val)
42
+ when ECDSA::Point
43
+ # BIP340: The function bytes(P), where P is a point, returns bytes(x(P)).
44
+ val.infinity? ? raise(InfinityPoint, va.inspect) : big2bin(val.x)
45
+ else
46
+ raise(SanityCheck, val.inspect)
47
+ end
48
+ end
49
+
50
+ # Input
51
+ # The secret key, sk: 32 bytes binary
52
+ # The message, m: binary / UTF-8 / agnostic
53
+ # Auxiliary random data, a: 32 bytes binary
54
+ # Output
55
+ # The signature, sig: 64 bytes binary
56
+ def self.sign(sk, m, a = Random.bytes(B))
57
+ bytestring!(sk, B) and string!(m) and bytestring!(a, B)
58
+
59
+ # BIP340: Let d' = int(sk)
60
+ # BIP340: Fail if d' = 0 or d' >= n
61
+ d0 = int(sk)
62
+ raise(BoundsError, "d0") if !d0.positive? or d0 >= N
63
+
64
+ # BIP340: Let P = d' . G
65
+ p = dot_group(d0) # this is a point on the elliptic curve
66
+ bytes_p = bytes(p)
67
+
68
+ # BIP340: Let d = d' if has_even_y(P), otherwise let d = n - d'
69
+ d = select_even_y(p, d0)
70
+
71
+ # BIP340: Let t be the bytewise xor of bytes(d) and hash[BIP0340/aux](a)
72
+ t = d ^ int(tagged_hash('BIP0340/aux', a))
73
+
74
+ # BIP340: Let rand = hash[BIP0340/nonce](t || bytes(P) || m)
75
+ nonce = tagged_hash('BIP0340/nonce', bytes(t) + bytes_p + m)
76
+
77
+ # BIP340: Let k' = int(rand) mod n
78
+ # BIP340: Fail if k' = 0
79
+ k0 = int(nonce) % N
80
+ raise(BoundsError, "k0") if !k0.positive?
81
+
82
+ # BIP340: Let R = k' . G
83
+ r = dot_group(k0) # this is a point on the elliptic curve
84
+ bytes_r = bytes(r)
85
+
86
+ # BIP340: Let k = k' if has_even_y(R), otherwise let k = n - k'
87
+ k = select_even_y(r, k0)
88
+
89
+ # BIP340:
90
+ # Let e = int(hash[BIP0340/challenge](bytes(R) || bytes(P) || m)) mod n
91
+ e = int(tagged_hash('BIP0340/challenge', bytes_r + bytes_p + m)) % N
92
+
93
+ # BIP340: Let sig = bytes(R) || bytes((k + ed) mod n)
94
+ # BIP340: Fail unless Verify(bytes(P), m, sig)
95
+ # BIP340: Return the signature sig
96
+ sig = bytes_r + bytes((k + e * d) % N)
97
+ raise(VerifyFail) unless verify?(bytes_p, m, sig)
98
+ sig
99
+ end
100
+
101
+ # see https://bips.xyz/340#design (Tagged hashes)
102
+ # Input
103
+ # A tag: UTF-8 > binary > agnostic
104
+ # The payload, msg: UTF-8 / binary / agnostic
105
+ # Output
106
+ # 32 bytes binary
107
+ def self.tagged_hash(tag, msg)
108
+ string!(tag) and string!(msg)
109
+ warn("tag expected to be UTF-8") unless tag.encoding == Encoding::UTF_8
110
+
111
+ # BIP340: The function hash[name](x) where x is a byte array
112
+ # returns the 32-byte hash
113
+ # SHA256(SHA256(tag) || SHA256(tag) || x)
114
+ # where tag is the UTF-8 encoding of name.
115
+ tag_hash = Digest::SHA256.digest(tag)
116
+ Digest::SHA256.digest(tag_hash + tag_hash + msg)
117
+ end
118
+
119
+ # Input
120
+ # The public key, pk: 32 bytes binary
121
+ # The message, m: UTF-8 / binary / agnostic
122
+ # A signature, sig: 64 bytes binary
123
+ # Output
124
+ # Boolean
125
+ def self.verify?(pk, m, sig)
126
+ bytestring!(pk, B) and string!(m) and bytestring!(sig, B * 2)
127
+
128
+ # BIP340: Let P = lift_x(int(pk))
129
+ p = lift_x(int(pk))
130
+
131
+ # BIP340: Let r = int(sig[0:32]) fail if r >= p
132
+ r = int(sig[0..B-1])
133
+ raise(BoundsError, "r >= p") if r >= P
134
+
135
+ # BIP340: Let s = int(sig[32:64]); fail if s >= n
136
+ s = int(sig[B..-1])
137
+ raise(BoundsError, "s >= n") if s >= N
138
+
139
+ # BIP340:
140
+ # Let e = int(hash[BIP0340/challenge](bytes(r) || bytes(P) || m)) mod n
141
+ e = bytes(r) + bytes(p) + m
142
+ e = int(tagged_hash('BIP0340/challenge', e)) % N
143
+
144
+ # BIP340: Let R = s . G - e . P
145
+ # BIP340: Fail if is_infinite(R)
146
+ # BIP340: Fail if not has_even_y(R)
147
+ # BIP340: Fail if x(R) != r
148
+ # BIP340: Return success iff no failure occurred before reaching this point
149
+ big_r = dot_group(s) + p.multiply_by_scalar(e).negate
150
+ !big_r.infinity? and big_r.y.even? and big_r.x == r
151
+ end
152
+
153
+ # BIP340: The function lift_x(x), where x is a 256-bit unsigned integer,
154
+ # returns the point P for which x(P) = x and has_even_y(P),
155
+ # or fails if x is greater than p-1 or no such point exists.
156
+ # Input
157
+ # A large integer, x
158
+ # Output
159
+ # ECDSA::Point
160
+ def self.lift_x(x)
161
+ integer!(x)
162
+
163
+ # BIP340: Fail if x >= p
164
+ raise(BoundsError, "x") if x >= P or x <= 0
165
+
166
+ # BIP340: Let c = x^3 + 7 mod p
167
+ c = (x.pow(3, P) + 7) % P
168
+
169
+ # BIP340: Let y = c ^ ((p + 1) / 4) mod p
170
+ y = c.pow((P + 1) / 4, P) # use pow to avoid Bignum overflow
171
+
172
+ # BIP340: Fail if c != y^2 mod p
173
+ raise(SanityCheck, "c != y^2 mod p") if c != y.pow(2, P)
174
+
175
+ # BIP340: Return the unique point P such that:
176
+ # x(P) = x and y(P) = y if y mod 2 = 0
177
+ # y(P) = p - y otherwise
178
+ GROUP.new_point [x, y.even? ? y : P - y]
179
+ end
180
+
181
+ # Input
182
+ # The secret key, sk: 32 bytes binary
183
+ # Output
184
+ # 32 bytes binary (represents P.x for point P on the curve)
185
+ def self.pubkey(sk)
186
+ bytestring!(sk, B)
187
+
188
+ # BIP340: Let d' = int(sk)
189
+ # BIP340: Fail if d' = 0 or d' >= n
190
+ # BIP340: Return bytes(d' . G)
191
+ d0 = int(sk)
192
+ raise(BoundsError, "d0") if !d0.positive? or d0 >= N
193
+ bytes(dot_group(d0))
194
+ end
195
+
196
+ # generate a new keypair based on random data
197
+ def self.keypair
198
+ sk = Random.bytes(B)
199
+ [sk, pubkey(sk)]
200
+ end
201
+
202
+ # as above, but using SecureRandom
203
+ def self.secure_keypair
204
+ sk = SecureRandom.bytes(B)
205
+ [sk, pubkey(sk)]
206
+ end
207
+ end
208
+
209
+ if __FILE__ == $0
210
+ msg = 'hello world'
211
+ sk, pk = SchnorrSig.keypair
212
+ puts "Message: #{msg}"
213
+ puts "Secret key: #{SchnorrSig.bin2hex(sk)}"
214
+ puts "Public key: #{SchnorrSig.bin2hex(pk)}"
215
+
216
+ sig = SchnorrSig.sign(sk, msg)
217
+ puts
218
+ puts "Verified signature: #{SchnorrSig.bin2hex(sig)}"
219
+ puts "Encoding: #{sig.encoding}"
220
+ puts "Length: #{sig.length}"
221
+ end
@@ -18,7 +18,7 @@ module SchnorrSig
18
18
  def self.bytestring!(str, size)
19
19
  string!(str)
20
20
  raise(EncodingError, str.encoding) unless str.encoding == Encoding::BINARY
21
- str.size == size or raise(SizeError, str.size)
21
+ str.bytesize == size or raise(SizeError, str.bytesize)
22
22
  end
23
23
 
24
24
  # likely returns a Bignum, larger than a 64-bit hardware integer
data/lib/schnorr_sig.rb CHANGED
@@ -1,220 +1,5 @@
1
- require 'schnorr_sig/util'
2
- require 'ecdsa_ext' # gem
3
- autoload :SecureRandom, 'securerandom' # stdlib
4
-
5
- # This implementation is based on the BIP340 spec: https://bips.xyz/340
6
- # re-open SchnorrSig to add more functions, errors, and constants
7
- module SchnorrSig
8
- class Error < RuntimeError; end
9
- class BoundsError < Error; end
10
- class SanityCheck < Error; end
11
- class VerifyFail < Error; end
12
-
13
- GROUP = ECDSA::Group::Secp256k1
14
- P = GROUP.field.prime # smaller than 256**32
15
- N = GROUP.order # smaller than P
16
- B = GROUP.byte_length # 32
17
-
18
- # val (dot) G, returns ECDSA::Point
19
- def self.dot_group(val)
20
- # ecdsa_ext uses jacobian projection: 10x faster than GROUP.generator * val
21
- (GROUP.generator.to_jacobian * val).to_affine
22
- end
23
-
24
- # returns even_val or N - even_val
25
- def self.select_even_y(point, even_val)
26
- point.y.even? ? even_val : N - even_val
27
- end
28
-
29
- # int(x) function signature matches BIP340, returns a bignum (presumably)
30
- class << self
31
- alias_method :int, :bin2big
32
- end
33
-
34
- # bytes(val) function signature matches BIP340, returns a binary string
35
- def self.bytes(val)
36
- case val
37
- when Integer
38
- # BIP340: The function bytes(x), where x is an integer,
39
- # returns the 32-byte encoding of x, most significant byte first.
40
- big2bin(val)
41
- when ECDSA::Point
42
- # BIP340: The function bytes(P), where P is a point, returns bytes(x(P)).
43
- val.infinity? ? ("\x00" * B).b : big2bin(val.x)
44
- else
45
- raise(SanityCheck, val.inspect)
46
- end
47
- end
48
-
49
- # Input
50
- # The secret key, sk: 32 bytes binary
51
- # The message, m: binary / UTF-8 / agnostic
52
- # Auxiliary random data, a: 32 bytes binary
53
- # Output
54
- # The signature, sig: 64 bytes binary
55
- def self.sign(sk, m, a = Random.bytes(B))
56
- bytestring!(sk, B) and string!(m) and bytestring!(a, B)
57
-
58
- # BIP340: Let d' = int(sk)
59
- # BIP340: Fail if d' = 0 or d' >= n
60
- d0 = int(sk)
61
- raise(BoundsError, "d0") if !d0.positive? or d0 >= N
62
-
63
- # BIP340: Let P = d' . G
64
- p = dot_group(d0) # this is a point on the elliptic curve
65
- bytes_p = bytes(p)
66
-
67
- # BIP340: Let d = d' if has_even_y(P), otherwise let d = n - d'
68
- d = select_even_y(p, d0)
69
-
70
- # BIP340: Let t be the bytewise xor of bytes(d) and hash[BIP0340/aux](a)
71
- t = d ^ int(tagged_hash('BIP0340/aux', a))
72
-
73
- # BIP340: Let rand = hash[BIP0340/nonce](t || bytes(P) || m)
74
- nonce = tagged_hash('BIP0340/nonce', bytes(t) + bytes_p + m)
75
-
76
- # BIP340: Let k' = int(rand) mod n
77
- # BIP340: Fail if k' = 0
78
- k0 = int(nonce) % N
79
- raise(BoundsError, "k0") if !k0.positive?
80
-
81
- # BIP340: Let R = k' . G
82
- r = dot_group(k0) # this is a point on the elliptic curve
83
- bytes_r = bytes(r)
84
-
85
- # BIP340: Let k = k' if has_even_y(R), otherwise let k = n - k'
86
- k = select_even_y(r, k0)
87
-
88
- # BIP340:
89
- # Let e = int(hash[BIP0340/challenge](bytes(R) || bytes(P) || m)) mod n
90
- e = int(tagged_hash('BIP0340/challenge', bytes_r + bytes_p + m)) % N
91
-
92
- # BIP340: Let sig = bytes(R) || bytes((k + ed) mod n)
93
- # BIP340: Fail unless Verify(bytes(P), m, sig)
94
- # BIP340: Return the signature sig
95
- sig = bytes_r + bytes((k + e * d) % N)
96
- raise(VerifyFail) unless verify?(bytes_p, m, sig)
97
- sig
98
- end
99
-
100
- # see https://bips.xyz/340#design (Tagged hashes)
101
- # Input
102
- # A tag: UTF-8 > binary > agnostic
103
- # The payload, msg: UTF-8 / binary / agnostic
104
- # Output
105
- # 32 bytes binary
106
- def self.tagged_hash(tag, msg)
107
- string!(tag) and string!(msg)
108
- warn("tag expected to be UTF-8") unless tag.encoding == Encoding::UTF_8
109
-
110
- # BIP340: The function hash[name](x) where x is a byte array
111
- # returns the 32-byte hash
112
- # SHA256(SHA256(tag) || SHA256(tag) || x)
113
- # where tag is the UTF-8 encoding of name.
114
- tag_hash = Digest::SHA256.digest(tag)
115
- Digest::SHA256.digest(tag_hash + tag_hash + msg)
116
- end
117
-
118
- # Input
119
- # The public key, pk: 32 bytes binary
120
- # The message, m: UTF-8 / binary / agnostic
121
- # A signature, sig: 64 bytes binary
122
- # Output
123
- # Boolean
124
- def self.verify?(pk, m, sig)
125
- bytestring!(pk, B) and string!(m) and bytestring!(sig, B * 2)
126
-
127
- # BIP340: Let P = lift_x(int(pk))
128
- p = lift_x(int(pk))
129
-
130
- # BIP340: Let r = int(sig[0:32]) fail if r >= p
131
- r = int(sig[0..B-1])
132
- raise(BoundsError, "r >= p") if r >= P
133
-
134
- # BIP340: Let s = int(sig[32:64]); fail if s >= n
135
- s = int(sig[B..-1])
136
- raise(BoundsError, "s >= n") if s >= N
137
-
138
- # BIP340:
139
- # Let e = int(hash[BIP0340/challenge](bytes(r) || bytes(P) || m)) mod n
140
- e = bytes(r) + bytes(p) + m
141
- e = int(tagged_hash('BIP0340/challenge', e)) % N
142
-
143
- # BIP340: Let R = s . G - e . P
144
- # BIP340: Fail if is_infinite(R)
145
- # BIP340: Fail if not has_even_y(R)
146
- # BIP340: Fail if x(R) != r
147
- # BIP340: Return success iff no failure occurred before reaching this point
148
- big_r = dot_group(s) + p.multiply_by_scalar(e).negate
149
- !big_r.infinity? and big_r.y.even? and big_r.x == r
150
- end
151
-
152
- # BIP340: The function lift_x(x), where x is a 256-bit unsigned integer,
153
- # returns the point P for which x(P) = x[10] and has_even_y(P),
154
- # or fails if x is greater than p-1 or no such point exists.
155
- # Input
156
- # A large integer, x
157
- # Output
158
- # ECDSA::Point
159
- def self.lift_x(x)
160
- integer!(x)
161
-
162
- # BIP340: Fail if x >= p
163
- raise(BoundsError, "x") if x >= P or x <= 0
164
-
165
- # BIP340: Let c = x^3 + 7 mod p
166
- c = (x.pow(3, P) + 7) % P
167
-
168
- # BIP340: Let y = c ^ ((p + 1) / 4) mod p
169
- y = c.pow((P + 1) / 4, P) # use pow to avoid Bignum overflow
170
-
171
- # BIP340: Fail if c != y^2 mod p
172
- raise(SanityCheck, "c != y^2 mod p") if c != y.pow(2, P)
173
-
174
- # BIP340: Return the unique point P such that:
175
- # x(P) = x and y(P) = y if y mod 2 = 0
176
- # y(P) = p - y otherwise
177
- GROUP.new_point [x, y.even? ? y : P - y]
178
- end
179
-
180
- # Input
181
- # The secret key, sk: 32 bytes binary
182
- # Output
183
- # 32 bytes binary (represents P.x for point P on the curve)
184
- def self.pubkey(sk)
185
- bytestring!(sk, B)
186
-
187
- # BIP340: Let d' = int(sk)
188
- # BIP340: Fail if d' = 0 or d' >= n
189
- # BIP340: Return bytes(d' . G)
190
- d0 = int(sk)
191
- raise(BoundsError, "d0") if !d0.positive? or d0 >= N
192
- bytes(dot_group(d0))
193
- end
194
-
195
- # generate a new keypair based on random data
196
- def self.keypair
197
- sk = Random.bytes(B)
198
- [sk, pubkey(sk)]
199
- end
200
-
201
- # as above, but using SecureRandom
202
- def self.secure_keypair
203
- sk = SecureRandom.bytes(B)
204
- [sk, pubkey(sk)]
205
- end
206
- end
207
-
208
- if __FILE__ == $0
209
- msg = 'hello world'
210
- sk, pk = SchnorrSig.keypair
211
- puts "Message: #{msg}"
212
- puts "Secret key: #{SchnorrSig.bin2hex(sk)}"
213
- puts "Public key: #{SchnorrSig.bin2hex(pk)}"
214
-
215
- sig = SchnorrSig.sign(sk, msg)
216
- puts
217
- puts "Verified signature: #{SchnorrSig.bin2hex(sig)}"
218
- puts "Encoding: #{sig.encoding}"
219
- puts "Length: #{sig.length}"
1
+ if ENV['SCHNORR_SIG']&.downcase == 'fast'
2
+ require 'schnorr_sig/fast'
3
+ else
4
+ require 'schnorr_sig/pure'
220
5
  end
data/test/vectors.rb CHANGED
@@ -1,5 +1,4 @@
1
- require ENV['SCHNORR_SIG']&.downcase == 'fast' ?
2
- 'schnorr_sig/fast' : 'schnorr_sig'
1
+ require 'schnorr_sig'
3
2
  require 'csv'
4
3
 
5
4
  path = File.join(__dir__, 'vectors.csv')
@@ -29,4 +28,4 @@ puts "Failure: #{failure.count}"
29
28
 
30
29
  puts failure unless failure.empty?
31
30
 
32
- exit failure.count
31
+ # exit failure.count
@@ -1,5 +1,4 @@
1
- require ENV['SCHNORR_SIG']&.downcase == 'fast' ?
2
- 'schnorr_sig/fast' : 'schnorr_sig'
1
+ require 'schnorr_sig'
3
2
  require 'csv'
4
3
 
5
4
  path = File.join(__dir__, 'vectors.csv')
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: schnorr_sig
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.0.4
4
+ version: 0.2.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rick Hull
@@ -35,6 +35,7 @@ files:
35
35
  - VERSION
36
36
  - lib/schnorr_sig.rb
37
37
  - lib/schnorr_sig/fast.rb
38
+ - lib/schnorr_sig/pure.rb
38
39
  - lib/schnorr_sig/util.rb
39
40
  - schnorr_sig.gemspec
40
41
  - test/vectors.rb