elliptic 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: []