bitcoin-ruby 0.0.19 → 0.0.20

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: 69dc67ff7d6860767e626c22efabed33b86541022b4b490916b061a9b395b210
4
- data.tar.gz: 5aa94333b2635f7f3d7e6e6f7fdf4476938edc448924cafdc3c8553b1f572933
3
+ metadata.gz: e51bd4140526e976852120dfe9344601ad9caf197ff5698830809d806b083e61
4
+ data.tar.gz: 13edf822bb99da797c2f6d14a6da8cf37ef1c5fb0c13da52c41504d368569407
5
5
  SHA512:
6
- metadata.gz: 33c7835ce224e0c6566baa10253b42c7e71ec46ce977c760a6eeef6b89c160e5aa1cd2a3a7b0ba06269e0d8de7acb8989b271a32b30e6b972ecf59488cf8dd2c
7
- data.tar.gz: 77518c65ef050ac247ddb677da8c0725eacc49bd146c24a9805217efbef3124f7edf199535c924749c374b5b55443ab1cb94e4fab48e9046bfd21a2dc1b276e7
6
+ metadata.gz: 17b545b9b7185e214ced2e054083023cc5dbf2913e8dbc070a05cffe6dc2eec302f8c2d7fb06fc66d8f9d045807e06a9dd35f2ed7753a5b68a4ac3d924dcc402
7
+ data.tar.gz: eb8c40b9bda53151c1d564964f35ea695cb02b68fb5856fc720faf9a63674486c1ac116c8d0aa6987efdb3f4f68cd3698c1acb9624c0acaba2b98fcb6826690a
@@ -1,9 +1,8 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 2.2.9
4
- - 2.3.6
5
- - 2.4.3
6
- - 2.5.1
3
+ - 2.4.9
4
+ - 2.5.7
5
+ - 2.6.5
7
6
  script:
8
7
  - bundle exec rake build_libsecp256k1
9
8
  - bundle exec rake rspec
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- bitcoin-ruby (0.0.19)
4
+ bitcoin-ruby (0.0.20)
5
5
  eventmachine
6
6
  ffi
7
7
  scrypt
@@ -13,11 +13,9 @@ Some of the main features are:
13
13
 
14
14
  == Compatible with...
15
15
 
16
- * ruby 1.9.3
17
- * ruby 2.0.0
18
- * ruby 2.1.2
19
- * ruby 2.2.0
20
- * ruby 2.2.2
16
+ * ruby 2.4.x
17
+ * ruby 2.5.x
18
+ * ruby 2.6.x
21
19
 
22
20
  == Installation
23
21
 
@@ -10,16 +10,68 @@ module Bitcoin
10
10
  if FFI::Platform.windows?
11
11
  ffi_lib 'libeay32', 'ssleay32'
12
12
  else
13
- ffi_lib ['libssl.so.1.0.0', 'ssl']
13
+ ffi_lib [
14
+ 'libssl.so.1.1.0', 'libssl.so.1.1',
15
+ 'libssl.so.1.0.0', 'libssl.so.10',
16
+ 'ssl'
17
+ ]
14
18
  end
15
19
 
16
20
  NID_secp256k1 = 714 # rubocop:disable Naming/ConstantName
17
21
  POINT_CONVERSION_COMPRESSED = 2
18
22
  POINT_CONVERSION_UNCOMPRESSED = 4
19
23
 
20
- attach_function :SSL_library_init, [], :int
21
- attach_function :ERR_load_crypto_strings, [], :void
22
- attach_function :SSL_load_error_strings, [], :void
24
+ # OpenSSL 1.1.0 version as a numerical version value as defined in:
25
+ # https://www.openssl.org/docs/man1.1.0/man3/OpenSSL_version.html
26
+ VERSION_1_1_0_NUM = 0x10100000
27
+
28
+ # OpenSSL 1.1.0 engine constants, taken from:
29
+ # https://github.com/openssl/openssl/blob/2be8c56a39b0ec2ec5af6ceaf729df154d784a43/include/openssl/crypto.h
30
+ OPENSSL_INIT_ENGINE_RDRAND = 0x00000200
31
+ OPENSSL_INIT_ENGINE_DYNAMIC = 0x00000400
32
+ OPENSSL_INIT_ENGINE_CRYPTODEV = 0x00001000
33
+ OPENSSL_INIT_ENGINE_CAPI = 0x00002000
34
+ OPENSSL_INIT_ENGINE_PADLOCK = 0x00004000
35
+ OPENSSL_INIT_ENGINE_ALL_BUILTIN = (
36
+ OPENSSL_INIT_ENGINE_RDRAND |
37
+ OPENSSL_INIT_ENGINE_DYNAMIC |
38
+ OPENSSL_INIT_ENGINE_CRYPTODEV |
39
+ OPENSSL_INIT_ENGINE_CAPI |
40
+ OPENSSL_INIT_ENGINE_PADLOCK
41
+ )
42
+
43
+ # OpenSSL 1.1.0 load strings constant, taken from:
44
+ # https://github.com/openssl/openssl/blob/c162c126be342b8cd97996346598ecf7db56130f/include/openssl/ssl.h
45
+ OPENSSL_INIT_LOAD_SSL_STRINGS = 0x00200000
46
+
47
+ # This is the very first function we need to use to determine what version
48
+ # of OpenSSL we are interacting with.
49
+ begin
50
+ attach_function :OpenSSL_version_num, [], :ulong
51
+ rescue FFI::NotFoundError
52
+ attach_function :SSLeay, [], :long
53
+ end
54
+
55
+ # Returns the version of SSL present.
56
+ #
57
+ # @return [Integer] version number as an integer.
58
+ def self.version
59
+ if self.respond_to?(:OpenSSL_version_num)
60
+ OpenSSL_version_num()
61
+ else
62
+ SSLeay()
63
+ end
64
+ end
65
+
66
+ if version >= VERSION_1_1_0_NUM
67
+ # Initialization procedure for the library was changed in OpenSSL 1.1.0
68
+ attach_function :OPENSSL_init_ssl, [:uint64, :pointer], :int
69
+ else
70
+ attach_function :SSL_library_init, [], :int
71
+ attach_function :ERR_load_crypto_strings, [], :void
72
+ attach_function :SSL_load_error_strings, [], :void
73
+ end
74
+
23
75
  attach_function :RAND_poll, [], :int
24
76
 
25
77
  attach_function :BN_CTX_free, [:pointer], :int
@@ -28,7 +80,6 @@ module Bitcoin
28
80
  attach_function :BN_bin2bn, %i[pointer int pointer], :pointer
29
81
  attach_function :BN_bn2bin, %i[pointer pointer], :int
30
82
  attach_function :BN_cmp, %i[pointer pointer], :int
31
- attach_function :BN_copy, %i[pointer pointer], :pointer
32
83
  attach_function :BN_dup, [:pointer], :pointer
33
84
  attach_function :BN_free, [:pointer], :int
34
85
  attach_function :BN_mod_inverse, %i[pointer pointer pointer pointer], :pointer
@@ -51,22 +102,17 @@ module Bitcoin
51
102
  attach_function :EC_KEY_set_private_key, %i[pointer pointer], :int
52
103
  attach_function :EC_KEY_set_public_key, %i[pointer pointer], :int
53
104
  attach_function :EC_POINT_free, [:pointer], :int
54
- attach_function :EC_POINT_is_at_infinity, %i[pointer pointer], :int
55
105
  attach_function :EC_POINT_mul, %i[pointer pointer pointer pointer pointer pointer], :int
56
106
  attach_function :EC_POINT_new, [:pointer], :pointer
57
107
  attach_function :EC_POINT_set_compressed_coordinates_GFp,
58
108
  %i[pointer pointer pointer int pointer], :int
59
- attach_function :d2i_ECPrivateKey, %i[pointer pointer long], :pointer
60
- attach_function :i2d_ECPrivateKey, %i[pointer pointer], :int
61
109
  attach_function :i2o_ECPublicKey, %i[pointer pointer], :uint
62
- attach_function :EC_KEY_check_key, [:pointer], :uint
63
110
  attach_function :ECDSA_do_sign, %i[pointer uint pointer], :pointer
64
111
  attach_function :BN_num_bits, [:pointer], :int
65
112
  attach_function :ECDSA_SIG_free, [:pointer], :void
66
113
  attach_function :EC_POINT_add, %i[pointer pointer pointer pointer pointer], :int
67
114
  attach_function :EC_POINT_point2hex, %i[pointer pointer int pointer], :string
68
115
  attach_function :EC_POINT_hex2point, %i[pointer string pointer pointer], :pointer
69
- attach_function :ECDSA_SIG_new, [], :pointer
70
116
  attach_function :d2i_ECDSA_SIG, %i[pointer pointer long], :pointer
71
117
  attach_function :i2d_ECDSA_SIG, %i[pointer pointer], :int
72
118
  attach_function :OPENSSL_free, :CRYPTO_free, [:pointer], :void
@@ -82,68 +128,17 @@ module Bitcoin
82
128
  private_key = [private_key].pack('H*') if private_key.bytesize >= (32 * 2)
83
129
  private_key_hex = private_key.unpack('H*')[0]
84
130
 
85
- # private_key = FFI::MemoryPointer.new(:uint8, private_key.bytesize)
86
- # .put_bytes(0, private_key, 0, private_key.bytesize)
87
- private_key = FFI::MemoryPointer.from_string(private_key)
88
-
89
- init_ffi_ssl
90
- eckey = EC_KEY_new_by_curve_name(NID_secp256k1)
91
- # priv_key = BN_bin2bn(private_key, private_key.size, BN_new())
92
- priv_key = BN_bin2bn(private_key, private_key.size - 1, BN_new())
93
-
94
- group = EC_KEY_get0_group(eckey)
95
- order = BN_new()
96
- ctx = BN_CTX_new()
97
- EC_GROUP_get_order(group, order, ctx)
98
-
99
- pub_key = EC_POINT_new(group)
100
- EC_POINT_mul(group, pub_key, priv_key, nil, nil, ctx)
101
- EC_KEY_set_private_key(eckey, priv_key)
102
- EC_KEY_set_public_key(eckey, pub_key)
103
-
104
- BN_free(order)
105
- BN_CTX_free(ctx)
106
- EC_POINT_free(pub_key)
107
- BN_free(priv_key)
108
-
109
- length = i2d_ECPrivateKey(eckey, nil)
110
- buf = FFI::MemoryPointer.new(:uint8, length)
111
- ptr = FFI::MemoryPointer.new(:pointer).put_pointer(0, buf)
112
- priv_hex = if i2d_ECPrivateKey(eckey, ptr) == length
113
- size = buf.get_array_of_uint8(8, 1)[0]
114
- buf.get_array_of_uint8(9, size).pack('C*').rjust(32, "\x00").unpack('H*')[0]
115
- # der_to_private_key( ptr.read_pointer.read_string(length).unpack("H*")[0] )
116
- end
131
+ group = OpenSSL::PKey::EC::Group.new('secp256k1')
132
+ key = OpenSSL::PKey::EC.new(group)
133
+ key.private_key = OpenSSL::BN.new(private_key_hex, 16)
134
+ key.public_key = group.generator.mul(key.private_key)
117
135
 
136
+ priv_hex = key.private_key.to_bn.to_s(16).downcase.rjust(64, '0')
118
137
  if priv_hex != private_key_hex
119
138
  raise 'regenerated wrong private_key, raise here before generating a faulty public_key too!'
120
139
  end
121
140
 
122
- length = i2o_ECPublicKey(eckey, nil)
123
- buf = FFI::MemoryPointer.new(:uint8, length)
124
- ptr = FFI::MemoryPointer.new(:pointer).put_pointer(0, buf)
125
- pub_hex = buf.read_string(length).unpack('H*')[0] if i2o_ECPublicKey(eckey, ptr) == length
126
-
127
- EC_KEY_free(eckey)
128
-
129
- [priv_hex, pub_hex]
130
- end
131
-
132
- # extract private key from uncompressed DER format
133
- def self.der_to_private_key(der_hex)
134
- init_ffi_ssl
135
- # k = EC_KEY_new_by_curve_name(NID_secp256k1)
136
- # kp = FFI::MemoryPointer.new(:pointer).put_pointer(0, eckey)
137
-
138
- buf = FFI::MemoryPointer.from_string([der_hex].pack('H*'))
139
- ptr = FFI::MemoryPointer.new(:pointer).put_pointer(0, buf)
140
-
141
- # ec_key = d2i_ECPrivateKey(kp, ptr, buf.size-1)
142
- ec_key = d2i_ECPrivateKey(nil, ptr, buf.size - 1)
143
- return nil if ec_key.null?
144
- bn = EC_KEY_get0_private_key(ec_key)
145
- BN_bn2bin(bn, buf)
146
- buf.read_string(32).unpack('H*')[0]
141
+ [priv_hex, key.public_key.to_bn.to_s(16).downcase]
147
142
  end
148
143
 
149
144
  # Given the components of a signature and a selector value, recover and
@@ -395,9 +390,18 @@ module Bitcoin
395
390
  def self.init_ffi_ssl
396
391
  @ssl_loaded ||= false
397
392
  return if @ssl_loaded
398
- SSL_library_init()
399
- ERR_load_crypto_strings()
400
- SSL_load_error_strings()
393
+
394
+ if version >= VERSION_1_1_0_NUM
395
+ OPENSSL_init_ssl(
396
+ OPENSSL_INIT_LOAD_SSL_STRINGS | OPENSSL_INIT_ENGINE_ALL_BUILTIN,
397
+ nil
398
+ )
399
+ else
400
+ SSL_library_init()
401
+ ERR_load_crypto_strings()
402
+ SSL_load_error_strings()
403
+ end
404
+
401
405
  RAND_poll()
402
406
  @ssl_loaded = true
403
407
  end
@@ -1,3 +1,3 @@
1
1
  module Bitcoin
2
- VERSION = "0.0.19"
2
+ VERSION = "0.0.20"
3
3
  end
@@ -772,82 +772,63 @@ describe Bitcoin do
772
772
  end
773
773
  end
774
774
 
775
- describe '.der_to_private_key' do
776
- it 'extracts the private key from uncompressed DER format' do
777
- der =
778
- '308201130201010420a29fe0f28b2936dbc89f889f74cd1f0662d18a873ac15d6c' \
779
- 'd417b808db1ccd0aa081a53081a2020101302c06072a8648ce3d0101022100ffff' \
780
- 'fffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f300604' \
781
- '010004010704410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959' \
782
- 'f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47' \
783
- 'd08ffb10d4b8022100fffffffffffffffffffffffffffffffebaaedce6af48a03b' \
784
- 'bfd25e8cd0364141020101a14403420004768cfc6c44b927b0e69e9dd343e96132' \
785
- 'f7cd1d360d8cb8d65c83d89d7beaceadfd19918e076606a099344156acdb026b10' \
786
- '65a958e39f098cfd0a34dd976291d6'
787
-
788
- expect(
789
- Bitcoin::OpenSSL_EC.der_to_private_key(der)
790
- ).to eq('a29fe0f28b2936dbc89f889f74cd1f0662d18a873ac15d6cd417b808db1ccd0a')
775
+ describe 'signing and verifying messages' do
776
+ context 'testnet' do
777
+ before { Bitcoin.network = :testnet3 }
778
+
779
+ it 'verifies the signature of a testnet address' do
780
+ expect(
781
+ Bitcoin.verify_message(
782
+ 'mwPVMbZQgkpwJJt2YP3sLSgbEBQw3FWZSc',
783
+ 'H5GER0Nz+L7TPZMQzXtv0hnLSsyfPok9lkdHIv01vksREpEpOhTPTonU1xvy' \
784
+ 'PAOIIKhU3++Ol+LaWKWmsfyxDXk=',
785
+ 'A' * 500
786
+ )
787
+ ).to be true
788
+ end
791
789
  end
792
790
 
793
- describe 'signing and verifying messages' do
794
- context 'testnet' do
795
- before { Bitcoin.network = :testnet3 }
796
-
797
- it 'verifies the signature of a testnet address' do
798
- expect(
799
- Bitcoin.verify_message(
800
- 'mwPVMbZQgkpwJJt2YP3sLSgbEBQw3FWZSc',
801
- 'H5GER0Nz+L7TPZMQzXtv0hnLSsyfPok9lkdHIv01vksREpEpOhTPTonU1xvy' \
802
- 'PAOIIKhU3++Ol+LaWKWmsfyxDXk=',
803
- 'A' * 500
804
- )
805
- ).to be true
806
- end
791
+ context 'mainnet' do
792
+ before { Bitcoin.network = :bitcoin }
793
+ let(:address_and_keys1) do
794
+ %w[
795
+ 1QFqqMUD55ZV3PJEJZtaKCsQmjLT6JkjvJ
796
+ 12b004fff7f4b69ef8650e767f18f11ede158148b425660723b9f9a66e61f747
797
+ 040b4c866585dd868a9d62348a9cd008d6a312937048fff31670e7e920cfc7a7 \
798
+ 447b5f0bba9e01e6fe4735c8383e6e7a3347a0fd72381b8f797a19f694054e5a69
799
+ ]
800
+ end
801
+ let(:address_and_keys2) do
802
+ %w[
803
+ 1NoJrossxPBKfCHuJXT4HadJrXRE9Fxiqs
804
+ 12b004fff7f4b69ef8650e767f18f11ede158148b425660723b9f9a66e61f747
805
+ 030b4c866585dd868a9d62348a9cd008d6a312937048fff31670e7e920cfc7a744
806
+ ]
807
807
  end
808
808
 
809
- context 'mainnet' do
810
- before { Bitcoin.network = :bitcoin }
811
- let(:address_and_keys1) do
812
- %w[
813
- 1QFqqMUD55ZV3PJEJZtaKCsQmjLT6JkjvJ
814
- 12b004fff7f4b69ef8650e767f18f11ede158148b425660723b9f9a66e61f747
815
- 040b4c866585dd868a9d62348a9cd008d6a312937048fff31670e7e920cfc7a7 \
816
- 447b5f0bba9e01e6fe4735c8383e6e7a3347a0fd72381b8f797a19f694054e5a69
817
- ]
818
- end
819
- let(:address_and_keys2) do
820
- %w[
821
- 1NoJrossxPBKfCHuJXT4HadJrXRE9Fxiqs
822
- 12b004fff7f4b69ef8650e767f18f11ede158148b425660723b9f9a66e61f747
823
- 030b4c866585dd868a9d62348a9cd008d6a312937048fff31670e7e920cfc7a744
824
- ]
825
- end
826
-
827
- it 'successfully signs and verifies the message' do
828
- [address_and_keys1, address_and_keys2].each do |_addr, privkey, _pubkey|
829
- key = Bitcoin.open_key(privkey)
830
- 16.times.each do |count|
831
- signature = Bitcoin.sign_message(
832
- key.private_key_hex,
833
- key.public_key_hex,
834
- format('Very secret message %<count>d: 11', count: count)
809
+ it 'successfully signs and verifies the message' do
810
+ [address_and_keys1, address_and_keys2].each do |_addr, privkey, _pubkey|
811
+ key = Bitcoin.open_key(privkey)
812
+ 16.times.each do |count|
813
+ signature = Bitcoin.sign_message(
814
+ key.private_key_hex,
815
+ key.public_key_hex,
816
+ format('Very secret message %<count>d: 11', count: count)
817
+ )
818
+ expect(
819
+ Bitcoin.verify_message(
820
+ signature['address'],
821
+ 'invalid-signature',
822
+ signature['message']
823
+ )
824
+ ).to be false
825
+ expect(
826
+ Bitcoin.verify_message(
827
+ signature['address'],
828
+ signature['signature'],
829
+ signature['message']
835
830
  )
836
- expect(
837
- Bitcoin.verify_message(
838
- signature['address'],
839
- 'invalid-signature',
840
- signature['message']
841
- )
842
- ).to be false
843
- expect(
844
- Bitcoin.verify_message(
845
- signature['address'],
846
- signature['signature'],
847
- signature['message']
848
- )
849
- ).to be true
850
- end
831
+ ).to be true
851
832
  end
852
833
  end
853
834
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bitcoin-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.19
4
+ version: 0.0.20
5
5
  platform: ruby
6
6
  authors:
7
7
  - lian
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-03-12 00:00:00.000000000 Z
11
+ date: 2019-12-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ffi