elliptic 1.0.0 → 1.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: 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