bitcoin-ruby 0.0.19 → 0.0.20

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: 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