elliptic 1.0.0 → 1.0.1

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
  SHA256:
3
- metadata.gz: b669851bc198139a145ad4e0fcec669c63e5510836322db51787ceb8d09362c5
4
- data.tar.gz: 1a125a73561286cf5670085f910e8c37c0ed48c9564400219885a24526dbe0de
3
+ metadata.gz: ff30ac78fc3b9f3528bec550afdfffc4bdc7c4f7049edf67280ba48150d6ce95
4
+ data.tar.gz: bb13fa5c43a30149dab2457a7ef78ec3c6478122e80c8fd450b99ed8e6998f31
5
5
  SHA512:
6
- metadata.gz: 9f1ed708148cf5c8dd47ab00c22dfeee9ce43f3967c1626b7f1ed90947d0fb01512e2dbbd6ce0e43ef49a913a59abec48c80c86ba95854d89d62f9061c0daaa8
7
- data.tar.gz: bb86040e5624540f3f66368b0f1c1759fe2d0e1eaf0bc2c882f0c14d0e72b4cb685de6baebd84008262fb5f07cfe9775fa40394bf79fcef0142642113bab26ad
6
+ metadata.gz: 48c3b6ffda0ee6f94aa43fe31fc963be9228aba19adff661ad63bbfc8737be084d8db2c412cee9fa85e7cb9d8fee97fb6e46eb0d752dfdc2bbf6ba0dcf6d322b
7
+ data.tar.gz: fb14d75d44756fe762f86b81425d6e13796bca980a3b8a5bbecef824fe363085366d3af51a6fffbd5de28d113af304960de1b6a06289cf3138c89a2e7915dc3c
@@ -4,7 +4,12 @@ README.md
4
4
  Rakefile
5
5
  i/secp256k1.png
6
6
  lib/elliptic.rb
7
+ lib/elliptic/private_key.rb
8
+ lib/elliptic/public_key.rb
9
+ lib/elliptic/signature.rb
7
10
  lib/elliptic/version.rb
8
11
  test/helper.rb
12
+ test/test_decode.rb
13
+ test/test_openssl.rb
9
14
  test/test_sign.rb
10
15
  test/test_version.rb
@@ -0,0 +1,82 @@
1
+ module EC
2
+
3
+ class PrivateKey
4
+ def self.convert( *args, **kwargs )
5
+ if args.size==1 && args[0].is_a?( PrivateKey )
6
+ args[0] ## pass through as is (already a private key)
7
+ else
8
+ new( args[0], group: kwargs[:group] )
9
+ end
10
+ end
11
+
12
+
13
+ def self.decode_pem( str ) new( str ); end
14
+ def self.decode_der( str ) new( str ); end
15
+
16
+ ## todo/check: only use (allow) base64 for
17
+ ## der (binary)-encoded? why? why not?
18
+ def self.decode_base64( str ) new( Base64.decode64(str)); end
19
+
20
+ class << self
21
+ alias_method :from_pem, :decode_pem
22
+ alias_method :from_der, :decode_der
23
+ alias_method :from_base64, :decode_base64
24
+ end
25
+
26
+
27
+ def self.generate( group: nil ) new( group: group ); end
28
+
29
+
30
+ def initialize( input=nil, group: nil )
31
+ if input.nil? ## auto-generate new key
32
+ ec_group = GROUP[ group || 'secp256k1' ]
33
+ @pkey = OpenSSL::PKey::EC.new( ec_group )
34
+ @pkey.generate_key # note: will generate private/public key pair
35
+ elsif input.is_a?( Integer )
36
+ ec_group = GROUP[ group || 'secp256k1' ]
37
+ @pkey = OpenSSL::PKey::EC.new( ec_group )
38
+ @pkey.private_key = OpenSSL::BN.new( input )
39
+ ## auto-calculate public key too
40
+ @pkey.public_key = @pkey.group.generator.mul( @pkey.private_key )
41
+ else ## assume string with possible der/pem/etc. encoding
42
+ ## todo/check: add hex-string auto-detect too - why? why not?
43
+ @pkey = OpenSSL::PKey::EC.new( input )
44
+ ## todo/check: make sure public key gets restored too with pem/der-encoding??
45
+ end
46
+ end
47
+
48
+
49
+ def to_i() @pkey.private_key.to_i; end
50
+ ## todo/check/fix: make it always a 32 byte (64 hex chars) string
51
+ ## even with leading zeros !!! - why? why not?
52
+ def to_s() @pkey.private_key.to_i.to_s(16); end
53
+
54
+
55
+ def to_pem() @pkey.to_pem; end
56
+ def to_der() @pkey.to_der; end
57
+ def to_base64() Base64.encode64( to_der ); end
58
+
59
+
60
+
61
+ def public_key
62
+ ## cache returned public key - why? why not?
63
+ @pub ||= PublicKey.new( @pkey.public_key )
64
+ @pub
65
+ end
66
+
67
+
68
+ def sign( message )
69
+ signature_der = @pkey.dsa_sign_asn1( message )
70
+ Signature.decode_der( signature_der )
71
+ end
72
+
73
+
74
+ ################
75
+ ## more helpers for debugging / internals
76
+ def group() @pkey.group; end
77
+ def to_text() @pkey.to_text; end
78
+ def private?() @pkey.private?; end ## todo/check: keep - needed? - why? why not?
79
+ def public?() @pkey.public?; end ## todo/check: keep - needed? - why? why not?
80
+ end # class PrivateKey
81
+
82
+ end ## module EC
@@ -0,0 +1,85 @@
1
+ module EC
2
+
3
+
4
+ class PublicKey
5
+ def self.convert( *args, **kwargs )
6
+ if args.size==1 && args[0].is_a?( PublicKey )
7
+ args[0] ## pass through as is (already a public key)
8
+ else
9
+ new( *args, group: kwargs[:group] )
10
+ end
11
+ end
12
+
13
+
14
+
15
+ def self.decode_pem( str ) new( str ); end
16
+ def self.decode_der( str ) new( str ); end
17
+
18
+ ## todo/check: only use (allow) base64 for
19
+ ## der (binary)-encoded? why? why not?
20
+ def self.decode_base64( str ) new( Base64.decode64(str)); end
21
+
22
+ class << self
23
+ alias_method :from_pem, :decode_pem
24
+ alias_method :from_der, :decode_der
25
+ alias_method :from_base64, :decode_base64
26
+ end
27
+
28
+
29
+ def initialize( *args, group: nil )
30
+ if args.size == 2 ## assume (x,y) raw integer points
31
+ @pt = Point.new( *args, group: group )
32
+ point = @pt.to_ec_point ## convert point to openssl (native) class
33
+ @pkey = OpenSSL::PKey::EC.new( point.group )
34
+ @pkey.public_key = point
35
+ elsif args[0].is_a?( Point ) ||
36
+ args[0].is_a?( OpenSSL::PKey::EC::Point )
37
+ ## "restore" public key (only) from point for verify
38
+ ## - OpenSSL::PKey::EC::Point ## assume public key only (restore pkey object for verify?)
39
+ ## - Point
40
+ point = if args[0].is_a?( Point )
41
+ @pt = args[0]
42
+ @pt.to_ec_point
43
+ else
44
+ args[0] ## assume it is already OpenSSL::PKey::EC::Point
45
+ end
46
+
47
+ ## note: (auto)get group from point
48
+ @pkey = OpenSSL::PKey::EC.new( point.group )
49
+ @pkey.public_key = point
50
+ else ## assume string in pem/der/base64
51
+ @pkey = OpenSSL::PKey::EC.new( args[0] )
52
+ end
53
+ end
54
+
55
+
56
+
57
+ def point
58
+ ## cache returned point - why? why not?
59
+ @pt ||= Point.new( @pkey.public_key )
60
+ @pt
61
+ end
62
+
63
+
64
+ def to_pem() @pkey.to_pem; end
65
+ def to_der() @pkey.to_der; end
66
+ def to_base64() Base64.encode64( to_der ); end
67
+
68
+
69
+ def verify?( message, signature )
70
+ signature_der = signature.to_der
71
+ @pkey.dsa_verify_asn1( message, signature_der )
72
+ end
73
+ alias_method :valid_signature?, :verify?
74
+
75
+
76
+ ###
77
+ ## more helpers for debugging / internals
78
+ def group() @pkey.group; end
79
+ def to_text() @pkey.to_text; end
80
+ def private?() @pkey.private?; end ## todo/check: keep - needed? - why? why not?
81
+ def public?() @pkey.public?; end ## todo/check: keep - needed? - why? why not?
82
+ end # class PublicKey
83
+
84
+
85
+ end ## module EC
@@ -0,0 +1,41 @@
1
+ module EC
2
+
3
+ class Signature
4
+
5
+ def self.decode_der( der )
6
+ asn1 = OpenSSL::ASN1.decode( der )
7
+ r = asn1.value[0].value.to_i
8
+ s = asn1.value[1].value.to_i
9
+ new(r, s)
10
+ end
11
+
12
+ def self.decode_base64( str )
13
+ decode_der( Base64.decode64( str ) )
14
+ end
15
+
16
+ class << self
17
+ alias_method :from_der, :decode_der
18
+ alias_method :from_base64, :decode_base64
19
+ end
20
+
21
+
22
+
23
+ attr_reader :r, :s
24
+ def initialize(r, s)
25
+ @r, @s = r, s
26
+ end
27
+
28
+ def to_der
29
+ asn1 = OpenSSL::ASN1::Sequence.new [
30
+ OpenSSL::ASN1::Integer.new( @r ),
31
+ OpenSSL::ASN1::Integer.new( @s ),
32
+ ]
33
+ asn1.to_der
34
+ end
35
+
36
+ def to_base64
37
+ Base64.encode64( to_der ).gsub("\n", '' )
38
+ end
39
+ end ## class Signature
40
+
41
+ end ## module EC
@@ -5,7 +5,7 @@ module EC
5
5
 
6
6
  MAJOR = 1
7
7
  MINOR = 0
8
- PATCH = 0
8
+ PATCH = 1
9
9
  VERSION = [MAJOR,MINOR,PATCH].join('.')
10
10
 
11
11
  def self.version
@@ -0,0 +1,85 @@
1
+ ###
2
+ # to run use
3
+ # ruby -I ./lib -I ./test test/test_decode.rb
4
+
5
+
6
+ require 'helper'
7
+
8
+
9
+ class TestDecode < MiniTest::Test
10
+
11
+
12
+ def test_import_export
13
+
14
+ private_key = EC::PrivateKey.generate
15
+ puts "PrivateKey#to_i:"
16
+ puts private_key.to_i
17
+ puts "PrivateKey#to_s:"
18
+ puts private_key.to_s
19
+ puts "PrivateKey#to_pem:"
20
+ puts private_key.to_pem
21
+ puts "PrivateKey#to_der (binary / asn1):"
22
+ puts private_key.to_der
23
+ pp private_key.to_der
24
+ puts "PrivateKey#to_base64:"
25
+ puts private_key.to_base64
26
+
27
+ public_key = private_key.public_key
28
+ assert_equal false, public_key.private? ## make sure (derived) public key has no private key included/attached
29
+
30
+ puts "PublicKey#point:"
31
+ pp public_key.point
32
+ puts "PublicKey#point.to_s:"
33
+ puts public_key.point.to_s
34
+ puts "PublicKey#to_pem:"
35
+ puts public_key.to_pem
36
+ puts "PublicKey#to_der (binary / asn1):"
37
+ puts public_key.to_der
38
+ pp public_key.to_der
39
+ puts "PublicKey#to_base64:"
40
+ puts public_key.to_base64
41
+
42
+
43
+
44
+ [
45
+ EC::PrivateKey.new( private_key.to_i ),
46
+
47
+ EC::PrivateKey.new( private_key.to_pem ),
48
+ EC::PrivateKey.decode_pem( private_key.to_pem ),
49
+
50
+ EC::PrivateKey.new( private_key.to_der ),
51
+ EC::PrivateKey.decode_der( private_key.to_der ),
52
+
53
+ EC::PrivateKey.decode_base64( private_key.to_base64 ),
54
+ ].each do |private_key_decoded|
55
+ assert_equal private_key_decoded.to_i, private_key.to_i
56
+ assert private_key_decoded.private?
57
+ assert private_key_decoded.public?
58
+
59
+ assert_equal false, private_key_decoded.public_key.private?
60
+ assert_equal private_key_decoded.public_key.point.to_s, public_key.point.to_s
61
+ assert_equal private_key_decoded.public_key.point.x, public_key.point.x
62
+ assert_equal private_key_decoded.public_key.point.y, public_key.point.y
63
+ end
64
+
65
+
66
+ [
67
+ EC::PublicKey.new( public_key.point ),
68
+
69
+ EC::PublicKey.new( public_key.to_pem ),
70
+ EC::PublicKey.decode_pem( public_key.to_pem ),
71
+
72
+ EC::PublicKey.new( public_key.to_der ),
73
+ EC::PublicKey.decode_der( public_key.to_der ),
74
+
75
+ EC::PublicKey.decode_base64( public_key.to_base64 ),
76
+ ].each do |public_key_decoded|
77
+ assert_equal public_key_decoded.point.to_s, public_key.point.to_s
78
+ assert_equal public_key_decoded.point.x, public_key.point.x
79
+ assert_equal public_key_decoded.point.y, public_key.point.y
80
+ assert public_key_decoded.public?
81
+ assert_equal false, public_key_decoded.private?
82
+ end
83
+ end
84
+
85
+ end # class TestDecode
@@ -0,0 +1,40 @@
1
+ ###
2
+ # to run use
3
+ # ruby -I ./lib -I ./test test/test_openssl.rb
4
+
5
+
6
+ require 'helper'
7
+
8
+
9
+ ## test some "basic" openssl (binding) machinery
10
+ ## for source, see https://github.com/ruby/openssl
11
+
12
+ class TestOpenssl < MiniTest::Test
13
+
14
+ def test_version
15
+ puts "OPENSSL_VERSION: #{OpenSSL::OPENSSL_VERSION}"
16
+ puts "OPENSSL_LIBRARY_VERSION: #{OpenSSL::OPENSSL_LIBRARY_VERSION}"
17
+ end
18
+
19
+
20
+ def test_bn
21
+ [999,
22
+ -999,
23
+ 2**107-1,
24
+ -(2**107-1)].each do |num|
25
+ assert_equal OpenSSL::BN.new( num ), num.to_bn
26
+ end
27
+ end
28
+
29
+ def test_bn_to_hex
30
+ [
31
+ [999, "03E7"],
32
+ [-999, "-03E7"],
33
+ [2**107-1, "07FFFFFFFFFFFFFFFFFFFFFFFFFF"],
34
+ [-(2**107-1), "-07FFFFFFFFFFFFFFFFFFFFFFFFFF"]
35
+ ].each do |item|
36
+ assert_equal item[1], item[0].to_bn.to_s(16)
37
+ end
38
+ end
39
+
40
+ end # class TestOpenssl
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: elliptic
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gerald Bauer
@@ -60,8 +60,13 @@ files:
60
60
  - Rakefile
61
61
  - i/secp256k1.png
62
62
  - lib/elliptic.rb
63
+ - lib/elliptic/private_key.rb
64
+ - lib/elliptic/public_key.rb
65
+ - lib/elliptic/signature.rb
63
66
  - lib/elliptic/version.rb
64
67
  - test/helper.rb
68
+ - test/test_decode.rb
69
+ - test/test_openssl.rb
65
70
  - test/test_sign.rb
66
71
  - test/test_version.rb
67
72
  homepage: https://github.com/rubycoco/blockchain