elliptic 0.1.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: ef1dcaf22384ecedc56973cf3e2a75bb5da817bb6d5dcaa65f5559e48d4731d4
4
+ data.tar.gz: a4b7cf7b207cddae72ddd7a5a2cd848fe41e824d56284f46ffb65e3332f96d50
5
+ SHA512:
6
+ metadata.gz: f78242b719f4871949419099adde1cb3f209d11f176f761aefba7d7828a597ff30f1e4b75fae8ed1048612a226f9dabc4758f21be01466c486851ee483f00a84
7
+ data.tar.gz: e4561b2707ec6c5dce8e5e09d7dbc516dc5434dbbce7e03e773f6ef8ff0aff7610c9998da0e9c27b9baec976b71e97dccc853c8e9c548a5904476a5297822475
@@ -0,0 +1,3 @@
1
+ ### 0.0.1 / 2021-01-22
2
+
3
+ * Everything is new. First release
@@ -0,0 +1,10 @@
1
+ CHANGELOG.md
2
+ Manifest.txt
3
+ README.md
4
+ Rakefile
5
+ i/secp256k1.png
6
+ lib/elliptic.rb
7
+ lib/elliptic/version.rb
8
+ test/helper.rb
9
+ test/test_sign.rb
10
+ test/test_version.rb
@@ -0,0 +1,293 @@
1
+ # elliptic - elliptic curve digital signature algorithm (ECDSA) cryptography with OpenSSL made easy (incl. secp256k1 curve)
2
+
3
+
4
+ * home :: [github.com/rubycoco/blockchain](https://github.com/rubycoco/blockchain)
5
+ * bugs :: [github.com/rubycoco/blockchain/issues](https://github.com/rubycoco/blockchain/issues)
6
+ * gem :: [rubygems.org/gems/elliptic](https://rubygems.org/gems/elliptic)
7
+ * rdoc :: [rubydoc.info/gems/elliptic](http://rubydoc.info/gems/elliptic)
8
+
9
+
10
+
11
+
12
+ ## Usage
13
+
14
+
15
+ ### Intro
16
+
17
+ Did you know? All you need to open up a new account on a blockchain
18
+ is an (unsigned) 256-bit / 32-byte integer number.
19
+ Yes, that's it. No questions asked.
20
+ The private key is the secret "magic" that unlocks your own bank.
21
+
22
+
23
+ Q: What's the maximum value for a 256-bit / 32-byte integer number
24
+ (hint 2^256-1)?
25
+
26
+ Maximum value of 2^256-1 =
27
+
28
+ ``` ruby
29
+ 2**256-1
30
+ #=> 115792089237316195423570985008687907853269984665640564039457584007913129639935
31
+ (2**256-1).to_s.length
32
+ #=> 78
33
+ ```
34
+
35
+ Yes, that's 78 (!) decimal digits.
36
+
37
+
38
+ Let's (re)try the maximum value for a 256-bit (32-byte) integer number
39
+ in hexadecimal (base 16) and binary (base 2) format?
40
+
41
+ ``` ruby
42
+ (2**256-1).to_s(16)
43
+ #=> "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
44
+ (2**256-1).to_s(16).length
45
+ #=> 64
46
+
47
+ (2**256-1).to_s(2)
48
+ #=> "1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"
49
+ (2**256-1).to_s(2).length
50
+ #=> 256
51
+ ```
52
+
53
+ Surprise - a 256-bit number has 256 binary digits (0 and 1s).
54
+
55
+
56
+
57
+ BEWARE - Blockchain Bandits!
58
+ If you use a low integer number e.g. 1, 2, etc.
59
+ your account is guaranteed to get robbed by blockchain bandits in
60
+ seconds.
61
+
62
+ (See [A "Blockchain Bandit" Is Guessing Private Keys and Scoring Millions](https://www.wired.com/story/blockchain-bandit-ethereum-weak-private-keys/)
63
+ by Andy Greenberg, Wired Magazine, April 2019)
64
+
65
+
66
+
67
+
68
+ ### Private Key
69
+
70
+ An ECDSA (Elliptic Curve Digital Signature Algorithm) private key is a random number between 1 and the order of the elliptic curve group.
71
+
72
+
73
+ ``` ruby
74
+ require 'elliptic'
75
+
76
+ # note: Algo will auto-generate (random) private key if no private key passed in
77
+ algo = EC::Algo.new # by default uses Secp256k1 curve (used in Bitcoin and Ethereum)
78
+
79
+ algo.private_key
80
+ #=> 72190737707147846840353520312904745954595478835413056312168022784020322830309
81
+ ```
82
+
83
+
84
+ ### (Auto-)Calculate the Public Key - Enter Elliptic Curve (EC) Cryptography
85
+
86
+ The public key are two numbers (that is, a point with the coordinates x and y) computed by multiplying
87
+ the generator point (`G`) of the curve with the private key.
88
+ This is equivalent to adding the generator to itself `private_key` times.
89
+ Magic?
90
+ Let's try:
91
+
92
+
93
+ ``` ruby
94
+ # This private key is just an example. It should be much more secure!
95
+ privatekey = 1234
96
+
97
+ # Elliptic curve (EC) machinery - pass in our own key
98
+ algo = EC::Algo.new( privatekey ) # by default uses Secp256k1 curve (used in Bitcoin and Ethereum)
99
+ point = algo.public_key ## the "magic" one-way K=k*G curve multiplication (K=public key,k=private key, G=generator point)
100
+
101
+ point.x
102
+ #=> 102884003323827292915668239759940053105992008087520207150474896054185180420338
103
+ point.y
104
+ #=> 49384988101491619794462775601349526588349137780292274540231125201115197157452
105
+
106
+ point.x.to_s(16)
107
+ #=> "e37648435c60dcd181b3d41d50857ba5b5abebe279429aa76558f6653f1658f2"
108
+ point.y.to_s(16)
109
+ #=> "6d2ee9a82d4158f164ae653e9c6fa7f982ed8c94347fc05c2d068ff1d38b304c"
110
+ ```
111
+
112
+
113
+ ### Sign & Verify Transactions
114
+
115
+ Sign a transaction with an (elliptic curve) private key:
116
+
117
+ ``` ruby
118
+ # Step 1 - Calculate the Transaction (tx) Hash
119
+ tx = 'from: Alice to: Bob cryptos: 43_000_000_000'
120
+ txhash = Digest::SHA256.digest( tx )
121
+
122
+ # Step 2 - Get the Signer's Private key
123
+ privatekey = 1234 # This private key is just an example. It should be much more secure!
124
+
125
+ # Sign!
126
+ signature = EC.sign( txhash, privatekey )
127
+
128
+ signature.r
129
+ #=> 80563021554295584320113598933963644829902821722081604563031030942154621916407
130
+ signature.s
131
+ #=> 58316177618967642068351252425530175807242657664855230973164972803783751708604
132
+
133
+ signature.r.to_s(16)
134
+ #=> "3306a2f81ad2b2f62ebe0faec129545bc772babe1ca5e70f6e56556b406464c0"
135
+ signature.s.to_s(16)
136
+ #=> "4fe202bb0835758f514cd4a0787986f8f6bf303df629dc98c5b1a438a426f49a"
137
+ ```
138
+
139
+
140
+ Verify a signed transaction with an (elliptic curve) public key:
141
+
142
+ ``` ruby
143
+ # Step 1 - Calculate the Transaction (tx) Hash
144
+ tx = 'from: Alice to: Bob cryptos: 43_000_000_000'
145
+ txhash = Digest::SHA256.digest( tx )
146
+
147
+ # Step 2 - Get the Signer's Public Key
148
+ pubkey = EC::Point.new(
149
+ 102884003323827292915668239759940053105992008087520207150474896054185180420338,
150
+ 49384988101491619794462775601349526588349137780292274540231125201115197157452
151
+ )
152
+
153
+ # Step 3 - Get the Transaction's Signature
154
+ signature = EC::Signature.new(
155
+ 80563021554295584320113598933963644829902821722081604563031030942154621916407,
156
+ 58316177618967642068351252425530175807242657664855230973164972803783751708604
157
+ )
158
+
159
+ # Don't Trust - Verify
160
+ EC.valid_signature?( txhash, pubkey, signature )
161
+ #=> true
162
+
163
+
164
+ # or using hexadecimal numbers
165
+
166
+ pubkey = EC::Point.new(
167
+ 0xe37648435c60dcd181b3d41d50857ba5b5abebe279429aa76558f6653f1658f2,
168
+ 0x6d2ee9a82d4158f164ae653e9c6fa7f982ed8c94347fc05c2d068ff1d38b304c
169
+ )
170
+
171
+ signature = EC::Signature.new(
172
+ 0x3306a2f81ad2b2f62ebe0faec129545bc772babe1ca5e70f6e56556b406464c0,
173
+ 0x4fe202bb0835758f514cd4a0787986f8f6bf303df629dc98c5b1a438a426f49a
174
+ )
175
+
176
+ EC.valid_signature?( txhash, pubkey, signature )
177
+ #=> true
178
+ ```
179
+
180
+
181
+ To sum up:
182
+
183
+ - The (raw) private key is a 256-bit unsigned integer number
184
+ - The (raw) public key is a point (x,y), that is, two 256-bit unsigned integer numbers - derived (calculated) from the private key
185
+ - A (raw) signature is composed of (r,s), that is, two 256-bit unsigned integer numbers
186
+
187
+ That's all the magic.
188
+
189
+
190
+
191
+
192
+ ## Public Key Formats
193
+
194
+ To get the all-in-one-string
195
+ public key from a point with the coordinates x and y
196
+ use the
197
+ Standards for Efficient Cryptography (SEC) 1) uncompressed format
198
+ or the 2) compressed format:
199
+
200
+
201
+ ``` ruby
202
+ # 1) Uncompressed format (with prefix 04)
203
+ # Convert to 64 hexstring characters (32 bytes) in length
204
+
205
+ prefix = '04'
206
+ pubkey = prefix + "%064x" % point.x + "%064x" % point.y
207
+ #=> "04e37648435c60dcd181b3d41d50857ba5b5abebe279429aa76558f6653f1658f26d2ee9a82d4158f164ae653e9c6fa7f982ed8c94347fc05c2d068ff1d38b304c"
208
+
209
+ # 2) Compressed format (with prefix - 02 = even / 03 = odd)
210
+ # Instead of using both x and y coordinates,
211
+ # just use the x-coordinate and whether y is even/odd
212
+
213
+ prefix = point.y % 2 == 0 ? '02' : '03'
214
+ pubkey = prefix + "%064x" % point.x
215
+ #=> "02e37648435c60dcd181b3d41d50857ba5b5abebe279429aa76558f6653f1658f2"
216
+ ```
217
+
218
+ or use the builtin helpers:
219
+
220
+ ``` ruby
221
+ # 1) Uncompressed format (with prefix 04)
222
+ # Convert to 64 hexstring characters (32 bytes) in length
223
+
224
+ point.to_s # or point.to_s( :uncompressed )
225
+ #=> "04e37648435c60dcd181b3d41d50857ba5b5abebe279429aa76558f6653f1658f26d2ee9a82d4158f164ae653e9c6fa7f982ed8c94347fc05c2d068ff1d38b304c"
226
+
227
+ # 2) Compressed format (with prefix - 02 = even / 03 = odd)
228
+ # Instead of using both x and y coordinates,
229
+ # just use the x-coordinate and whether y is even/odd
230
+
231
+ point.to_s( :compressed )
232
+ #=> "02e37648435c60dcd181b3d41d50857ba5b5abebe279429aa76558f6653f1658f2"
233
+ ```
234
+
235
+
236
+ That's it.
237
+
238
+
239
+
240
+
241
+ ## Aside - Elliptic What?
242
+
243
+ > Elliptic-curve cryptography (ECC) is
244
+ > an approach to public-key cryptography based
245
+ > on the algebraic structure of elliptic curves over finite fields.
246
+ >
247
+ > (Source: [Elliptic-curve cryptography @ Wikipedia](https://en.wikipedia.org/wiki/Elliptic-curve_cryptography))
248
+
249
+
250
+ What's an Elliptic Curve?
251
+
252
+ ![](i/secp256k1.png)
253
+
254
+ > This is a graph of secp256k1's elliptic curve `y² = x³ + 7`
255
+ > over the real numbers.
256
+ > Note that because secp256k1 is actually defined over the field Zₚ,
257
+ > its graph will in reality look like random scattered points,
258
+ > not anything like this.
259
+ >
260
+ > (Source: [Secp256k1 @ Bitcoin Wiki](https://en.bitcoin.it/wiki/Secp256k1))
261
+
262
+
263
+
264
+
265
+ **Bitcon Public Service Announcement:**
266
+
267
+ > If we all buy Bitcoin from one another at ever higher
268
+ > prices we'll all be rich beyond our wildest dreams.
269
+ >
270
+ > -- Trolly McTrollface
271
+
272
+ **[BEWARE: Yes, Bitcoin Is a Ponzi - Learn How the Investment Fraud Works »](https://github.com/openblockchains/bitcoin-ponzi)**
273
+
274
+
275
+
276
+
277
+ ## Install
278
+
279
+ Just install the gem:
280
+
281
+ $ gem install elliptic
282
+
283
+
284
+ ## License
285
+
286
+ The scripts are dedicated to the public domain.
287
+ Use it as you please with no restrictions whatsoever.
288
+
289
+
290
+ ## Questions? Comments?
291
+
292
+ Send them along to the [wwwmake forum](http://groups.google.com/group/wwwmake).
293
+ Thanks!
@@ -0,0 +1,29 @@
1
+ require 'hoe'
2
+ require './lib/elliptic/version.rb'
3
+
4
+ Hoe.spec 'elliptic' do
5
+
6
+ self.version = EC::VERSION
7
+
8
+ self.summary = "elliptic - elliptic curve digital signature algorithm (ECDSA) cryptography with OpenSSL made easy (incl. secp256k1 curve)"
9
+ self.description = summary
10
+
11
+ self.urls = { home: 'https://github.com/rubycoco/blockchain' }
12
+
13
+ self.author = 'Gerald Bauer'
14
+ self.email = 'wwwmake@googlegroups.com'
15
+
16
+ # switch extension to .markdown for gihub formatting
17
+ self.readme_file = 'README.md'
18
+ self.history_file = 'CHANGELOG.md'
19
+
20
+ self.extra_deps = [
21
+ ]
22
+
23
+ self.licenses = ['Public Domain']
24
+
25
+ self.spec_extras = {
26
+ required_ruby_version: '>= 2.3'
27
+ }
28
+
29
+ end
Binary file
@@ -0,0 +1,186 @@
1
+ require 'pp'
2
+ require 'digest'
3
+ require 'base64'
4
+ require 'openssl'
5
+
6
+ ## our own code
7
+ require 'elliptic/version' # note: let version always go first
8
+
9
+
10
+
11
+ module EC
12
+
13
+
14
+
15
+ class Signature
16
+
17
+ def self.decode_der( der )
18
+ asn1 = OpenSSL::ASN1.decode(der )
19
+ r = asn1.value[0].value.to_i
20
+ s = asn1.value[1].value.to_i
21
+ new(r, s)
22
+ end
23
+
24
+ attr_reader :r, :s
25
+ def initialize(r, s)
26
+ @r, @s = r, s
27
+ end
28
+
29
+ def to_der
30
+ asn1 = OpenSSL::ASN1::Sequence.new [
31
+ OpenSSL::ASN1::Integer.new( @r ),
32
+ OpenSSL::ASN1::Integer.new( @s ),
33
+ ]
34
+ asn1.to_der
35
+ end
36
+ end ## class Signature
37
+
38
+
39
+
40
+
41
+ ## "cached" / available groups for now include:
42
+ GROUP = {
43
+ ## todo/check: is there a more direct way to get a group object?
44
+ 'secp256k1' => OpenSSL::PKey::EC.new( 'secp256k1' ).group
45
+ }
46
+
47
+
48
+ class Point
49
+
50
+ def initialize( *args, group: nil )
51
+ ## case 1) assume OpenSSL::PKey::EC::Point
52
+ if args.size == 1 && args[0].is_a?( OpenSSL::PKey::EC::Point )
53
+ @pt = args[0]
54
+
55
+ ## todo/check: is there a "better" way to get the x/y numbers?
56
+ hex = @pt.to_octet_string( :uncompressed ).unpack( 'H*' )[0]
57
+
58
+ ## todo/fix: check for infinity / 0 !!!!
59
+ @x = hex[2,64].to_i(16) ## skip leading 0x04 marker
60
+ @y = hex[2+64,64].to_i(16)
61
+ else ## assume x,y with group
62
+ ## rebuild openssl point from octet
63
+
64
+ @x = args[0]
65
+ @y = args[1]
66
+
67
+ ## encoded_point is the octet string representation of the point.
68
+ ## This must be either a String or an OpenSSL::BN
69
+ prefix = '04'
70
+ hex = prefix + ("%064x" % @x) + ("%064x" % @y)
71
+ bin = [hex].pack( 'H*' )
72
+
73
+ ec_group = GROUP[ group || 'secp256k1' ]
74
+ @pt = OpenSSL::PKey::EC::Point.new( ec_group, bin )
75
+ end
76
+ end
77
+
78
+ def x() @x; end
79
+ def y() @y; end
80
+ def group() @pt.group; end
81
+
82
+ ## formats - :compressed | :uncompressed
83
+ def to_bin( format=:uncompressed ) ## todo/check add alias .b too - why? why not?
84
+ @pt.to_octet_string( format )
85
+ end
86
+
87
+ def to_s( format=:uncompressed )
88
+ to_bin( format ).unpack( 'H*' )[0]
89
+ end
90
+
91
+ ## return OpenSSL::PKey::EC::Point - find a better name? e.g. to_raw/native or such - why? why not?
92
+ def to_point() @pt; end
93
+ end
94
+
95
+
96
+
97
+
98
+ class Algo
99
+ def initialize( input=nil, group: nil )
100
+
101
+ ## case 1) "restore" public key (only) from point for verify
102
+ if input.is_a?( OpenSSL::PKey::EC::Point ) || ## assume public key only (restore pkey object for verify?)
103
+ input.is_a?( Point )
104
+
105
+ point = input.is_a?( Point ) ? input.to_point : input
106
+
107
+ ## note: (auto)get group from point
108
+ @pkey = OpenSSL::PKey::EC.new( point.group )
109
+ @pkey.public_key = point
110
+ else ## case 2) build a private/public key pair
111
+
112
+ ec_group = GROUP[ group || 'secp256k1' ]
113
+ @pkey = OpenSSL::PKey::EC.new( ec_group )
114
+
115
+ if input.nil? ## auto-generate new key
116
+ @pkey.generate_key
117
+ else
118
+ num = if input.is_a?( String )
119
+ input.to_i( 16 )
120
+ else ## assume (big) integer
121
+ input
122
+ end
123
+ @pkey.private_key = OpenSSL::BN.new( num )
124
+ ## auto-calculate public key too
125
+ @pkey.public_key = @pkey.group.generator.mul( @pkey.private_key )
126
+ end
127
+ end
128
+ end
129
+
130
+
131
+ def group() @pkey.group; end
132
+
133
+ def public?() @pkey.public?; end
134
+ def private?() @pkey.private?; end
135
+
136
+
137
+ ## todo/check/fix: fix case with no private_key if passed in point/public key for verify!!!
138
+ def private_key() @pkey.private_key.to_i; end
139
+ alias_method :priv_key, :private_key ## add signing_key alias too?
140
+
141
+ def public_key() @public_key ||= Point.new( @pkey.public_key ); end
142
+
143
+
144
+ def sign( message )
145
+ signature_der = @pkey.dsa_sign_asn1( message )
146
+ Signature.decode_der( signature_der )
147
+ end
148
+
149
+ def verify?( message, signature )
150
+ signature_der = signature.to_der
151
+ @pkey.dsa_verify_asn1( message, signature_der )
152
+ end
153
+ alias_method :valid_signature?, :verify?
154
+
155
+
156
+ def to_text() @pkey.to_text; end
157
+ end
158
+
159
+
160
+
161
+ def self.sign( message, priv_key )
162
+ algo = Algo.new( priv_key )
163
+ algo.sign( message )
164
+ end
165
+
166
+ def self.verify?( message, pub_key, signature )
167
+ algo = Algo.new( pub_key )
168
+ algo.verify?( message, signature )
169
+ end
170
+
171
+ class << self
172
+ alias_method :valid_signature?, :verify?
173
+ end
174
+
175
+
176
+
177
+
178
+ def self.builtin_curves
179
+ OpenSSL::PKey::EC.builtin_curves
180
+ end
181
+ end ## module EC
182
+
183
+
184
+
185
+
186
+ puts EC.banner ## say hello
@@ -0,0 +1,23 @@
1
+ # encoding: utf-8
2
+
3
+
4
+ module EC
5
+
6
+ MAJOR = 0
7
+ MINOR = 1
8
+ PATCH = 0
9
+ VERSION = [MAJOR,MINOR,PATCH].join('.')
10
+
11
+ def self.version
12
+ VERSION
13
+ end
14
+
15
+ def self.banner
16
+ "elliptic/#{VERSION} on Ruby #{RUBY_VERSION} (#{RUBY_RELEASE_DATE}) [#{RUBY_PLATFORM}] in (#{root})"
17
+ end
18
+
19
+ def self.root
20
+ File.expand_path( File.dirname(File.dirname(File.dirname(__FILE__))) )
21
+ end
22
+
23
+ end # module EC
@@ -0,0 +1,11 @@
1
+ ## $:.unshift(File.dirname(__FILE__))
2
+
3
+ ## minitest setup
4
+
5
+ require 'minitest/autorun'
6
+
7
+
8
+ ## our own code
9
+
10
+ require 'elliptic'
11
+
@@ -0,0 +1,87 @@
1
+ ###
2
+ # to run use
3
+ # ruby -I ./lib -I ./test test/test_sign.rb
4
+
5
+
6
+ require 'helper'
7
+
8
+
9
+ class TestSign < MiniTest::Test
10
+
11
+
12
+ def test_keys
13
+ algo = EC::Algo.new( 1234 )
14
+ assert_equal 1234, algo.private_key
15
+ assert_equal "secp256k1", algo.group.curve_name
16
+
17
+ public_key = algo.public_key
18
+ assert_equal 102884003323827292915668239759940053105992008087520207150474896054185180420338,
19
+ public_key.x
20
+
21
+ assert_equal 49384988101491619794462775601349526588349137780292274540231125201115197157452,
22
+ public_key.y
23
+
24
+ assert_equal "e37648435c60dcd181b3d41d50857ba5b5abebe279429aa76558f6653f1658f2",
25
+ public_key.x.to_s(16)
26
+ assert_equal "6d2ee9a82d4158f164ae653e9c6fa7f982ed8c94347fc05c2d068ff1d38b304c",
27
+ public_key.y.to_s(16)
28
+
29
+ assert_equal "02e37648435c60dcd181b3d41d50857ba5b5abebe279429aa76558f6653f1658f2",
30
+ public_key.to_s( :compressed )
31
+
32
+ assert_equal "04e37648435c60dcd181b3d41d50857ba5b5abebe279429aa76558f6653f1658f26d2ee9a82d4158f164ae653e9c6fa7f982ed8c94347fc05c2d068ff1d38b304c",
33
+ public_key.to_s
34
+ end
35
+
36
+ def test_sign
37
+ algo = EC::Algo.new( 1234 )
38
+ priv_key = algo.private_key
39
+
40
+ message = Digest::SHA256.digest( "hello" )
41
+
42
+ ## note: sign uses a secure random generated temp key
43
+ ## every signature is different!!!
44
+ signature = EC.sign( message, priv_key )
45
+ pp signature.to_der
46
+
47
+ signature = EC.sign( message, priv_key )
48
+ pp signature.to_der
49
+
50
+ signature = EC.sign( message, priv_key )
51
+ pp signature.to_der
52
+
53
+ pp algo.sign( message )
54
+
55
+
56
+ ### verify
57
+ public_key = algo.public_key
58
+
59
+ assert EC.verify?( message, public_key, signature )
60
+ assert EC.valid_signature?( message, public_key, signature )
61
+
62
+ assert algo.verify?( message, signature )
63
+ assert algo.valid_signature?( message, signature )
64
+
65
+ ## public key from point (x,y)
66
+ point = EC::Point.new(
67
+ 102884003323827292915668239759940053105992008087520207150474896054185180420338,
68
+ 49384988101491619794462775601349526588349137780292274540231125201115197157452)
69
+ assert EC.verify?( message, point, signature )
70
+
71
+ ## signature from r,s values
72
+ signature = EC::Signature.new(
73
+ 17435452009115387225781053203681496505351828576563920844344513414624978140095,
74
+ 57357162317582879484266879619863223941116872722080991745355058707843528515381)
75
+ assert EC.verify?( message, point, signature )
76
+
77
+
78
+
79
+ ## tamper with message
80
+ message = Digest::SHA256.digest( "hellox" )
81
+ assert_equal false, EC.verify?( message, public_key, signature )
82
+ assert_equal false, algo.verify?( message, signature )
83
+ end
84
+
85
+
86
+
87
+ end # class TestSign
@@ -0,0 +1,19 @@
1
+ ###
2
+ # to run use
3
+ # ruby -I ./lib -I ./test test/test_version.rb
4
+
5
+
6
+ require 'helper'
7
+
8
+
9
+ class TestVersion < MiniTest::Test
10
+
11
+ def test_version
12
+ pp EC.version
13
+ pp EC.banner
14
+ pp EC.root
15
+
16
+ assert true ## (for now) everything ok if we get here
17
+ end
18
+
19
+ end # class TestVersion
metadata ADDED
@@ -0,0 +1,93 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: elliptic
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Gerald Bauer
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2021-01-22 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rdoc
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '4.0'
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '7'
23
+ type: :development
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: '4.0'
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '7'
33
+ - !ruby/object:Gem::Dependency
34
+ name: hoe
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '3.22'
40
+ type: :development
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '3.22'
47
+ description: elliptic - elliptic curve digital signature algorithm (ECDSA) cryptography
48
+ with OpenSSL made easy (incl. secp256k1 curve)
49
+ email: wwwmake@googlegroups.com
50
+ executables: []
51
+ extensions: []
52
+ extra_rdoc_files:
53
+ - CHANGELOG.md
54
+ - Manifest.txt
55
+ - README.md
56
+ files:
57
+ - CHANGELOG.md
58
+ - Manifest.txt
59
+ - README.md
60
+ - Rakefile
61
+ - i/secp256k1.png
62
+ - lib/elliptic.rb
63
+ - lib/elliptic/version.rb
64
+ - test/helper.rb
65
+ - test/test_sign.rb
66
+ - test/test_version.rb
67
+ homepage: https://github.com/rubycoco/blockchain
68
+ licenses:
69
+ - Public Domain
70
+ metadata: {}
71
+ post_install_message:
72
+ rdoc_options:
73
+ - "--main"
74
+ - README.md
75
+ require_paths:
76
+ - lib
77
+ required_ruby_version: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '2.3'
82
+ required_rubygems_version: !ruby/object:Gem::Requirement
83
+ requirements:
84
+ - - ">="
85
+ - !ruby/object:Gem::Version
86
+ version: '0'
87
+ requirements: []
88
+ rubygems_version: 3.1.4
89
+ signing_key:
90
+ specification_version: 4
91
+ summary: elliptic - elliptic curve digital signature algorithm (ECDSA) cryptography
92
+ with OpenSSL made easy (incl. secp256k1 curve)
93
+ test_files: []