digix-eth 0.5.6 → 0.5.7

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
- SHA1:
3
- metadata.gz: da499545215301e15a8de2cdc5e9126fe64ea118
4
- data.tar.gz: 01a0aa3dd050ee349b627904e95c98c96ba78b26
2
+ SHA256:
3
+ metadata.gz: 43a5e80aa64d950c81657c85b61b4a0babc7851241f6d17d85034638f1bb6e9a
4
+ data.tar.gz: 3a5bb0b47309bd0b9f581eed6bce46586cc11dfa097c83eca69de2a74c9dc3c0
5
5
  SHA512:
6
- metadata.gz: e1357b4a3db96ba745bba5f4962c88f8485fb9b987c291c57ebef94ffff7f19224b4a7c0f3884d3076dbdc7553de1ecd8302e27df1bdcb46cd4bc3afbfd30ad8
7
- data.tar.gz: ecb0c0143f762b5528e1c137ee648ccb02d4e448ec989215bfd97b0736277e133fa4ff00fe9c86379b64d1751d568124a6da8c00a8efcbe2ea62a0f907009459
6
+ metadata.gz: da241931604056061eede8aa5b522fc1d3edba48114539259d58b018b279da6720aed6be4042e81ddfd5a1a14882f295f0a7a7e715991a10b2160a1cd9b786f2
7
+ data.tar.gz: 157c851f34a50f92d2114748658c2c4fce00126e423a8810932bac218097dd8aed887536d0d7f30b1b699a3e8e80d51d776cc586a78f8e0df0a7bf9675862960
data/lib/eth.rb CHANGED
@@ -4,6 +4,7 @@ require 'money-tree'
4
4
  require 'rlp'
5
5
  require 'bitcoin'
6
6
  require 'rbnacl'
7
+ require 'pry'
7
8
  require 'active_support'
8
9
  require 'active_support/core_ext'
9
10
 
@@ -85,24 +85,6 @@ module Eth
85
85
  public_hex == OpenSsl.recover_compact(hash, signature)
86
86
  end
87
87
 
88
- def get_signer_key(message, signature)
89
- hash = message_hash(message)
90
- signer_public_hex = OpenSsl.recover_compact(hash, signature)
91
- signer_public_key = MoneyTree::PublicKey.new(signer_public_hex, compressed: false)
92
- signer_key = Eth::Key.new
93
- signer_key.public_key = signer_public_key
94
- return signer_key
95
- end
96
-
97
- def verify_rpc_signature(message, signature, signer_address)
98
- signer = get_signer_key(message, signature)
99
- signer.address == signer_address
100
- end
101
-
102
- def verify_rpc_signature_no_prefix(message, signature, signer_address)
103
- prefixed_message = Eth::Utils.prefix_message(message)
104
- verify_rpc_signature(prefixed_message, signature, signer_address)
105
- end
106
88
 
107
89
  private
108
90
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # originally lifted from https://github.com/lian/bitcoin-ruby
2
4
  # thanks to everyone there for figuring this out
3
5
 
@@ -8,50 +10,101 @@ module Eth
8
10
  if FFI::Platform.windows?
9
11
  ffi_lib 'libeay32', 'ssleay32'
10
12
  else
11
- 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
+ ]
12
18
  end
13
19
 
14
20
  NID_secp256k1 = 714
15
21
  POINT_CONVERSION_COMPRESSED = 2
16
22
  POINT_CONVERSION_UNCOMPRESSED = 4
17
23
 
18
- attach_function :SSL_library_init, [], :int
19
- attach_function :ERR_load_crypto_strings, [], :void
20
- attach_function :SSL_load_error_strings, [], :void
21
- attach_function :RAND_poll, [], :int
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 respond_to?(:OpenSSL_version_num)
60
+ OpenSSL_version_num()
61
+ else
62
+ SSLeay()
63
+ end
64
+ end
22
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, %i[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
+
75
+ attach_function :RAND_poll, [], :int
23
76
  attach_function :BN_CTX_free, [:pointer], :int
24
77
  attach_function :BN_CTX_new, [], :pointer
25
- attach_function :BN_add, [:pointer, :pointer, :pointer], :int
26
- attach_function :BN_bin2bn, [:pointer, :int, :pointer], :pointer
27
- attach_function :BN_bn2bin, [:pointer, :pointer], :int
28
- attach_function :BN_cmp, [:pointer, :pointer], :int
78
+ attach_function :BN_add, %i[pointer pointer pointer], :int
79
+ attach_function :BN_bin2bn, %i[pointer int pointer], :pointer
80
+ attach_function :BN_bn2bin, %i[pointer pointer], :int
81
+ attach_function :BN_cmp, %i[pointer pointer], :int
29
82
  attach_function :BN_dup, [:pointer], :pointer
30
83
  attach_function :BN_free, [:pointer], :int
31
- attach_function :BN_mod_inverse, [:pointer, :pointer, :pointer, :pointer], :pointer
32
- attach_function :BN_mod_mul, [:pointer, :pointer, :pointer, :pointer, :pointer], :int
33
- attach_function :BN_mod_sub, [:pointer, :pointer, :pointer, :pointer, :pointer], :int
34
- attach_function :BN_mul_word, [:pointer, :int], :int
84
+ attach_function :BN_mod_inverse, %i[pointer pointer pointer pointer], :pointer
85
+ attach_function :BN_mod_mul, %i[pointer pointer pointer pointer pointer], :int
86
+ attach_function :BN_mod_sub, %i[pointer pointer pointer pointer pointer], :int
87
+ attach_function :BN_mul_word, %i[pointer int], :int
35
88
  attach_function :BN_new, [], :pointer
36
89
  attach_function :BN_num_bits, [:pointer], :int
37
- attach_function :BN_rshift, [:pointer, :pointer, :int], :int
38
- attach_function :BN_set_word, [:pointer, :int], :int
90
+ attach_function :BN_rshift, %i[pointer pointer int], :int
91
+ attach_function :BN_set_word, %i[pointer int], :int
39
92
  attach_function :ECDSA_SIG_free, [:pointer], :void
40
- attach_function :ECDSA_do_sign, [:pointer, :uint, :pointer], :pointer
41
- attach_function :EC_GROUP_get_curve_GFp, [:pointer, :pointer, :pointer, :pointer, :pointer], :int
93
+ attach_function :ECDSA_do_sign, %i[pointer uint pointer], :pointer
94
+ attach_function :EC_GROUP_get_curve_GFp, %i[pointer pointer pointer pointer pointer], :int
42
95
  attach_function :EC_GROUP_get_degree, [:pointer], :int
43
- attach_function :EC_GROUP_get_order, [:pointer, :pointer, :pointer], :int
96
+ attach_function :EC_GROUP_get_order, %i[pointer pointer pointer], :int
44
97
  attach_function :EC_KEY_free, [:pointer], :int
45
98
  attach_function :EC_KEY_get0_group, [:pointer], :pointer
46
99
  attach_function :EC_KEY_new_by_curve_name, [:int], :pointer
47
- attach_function :EC_KEY_set_conv_form, [:pointer, :int], :void
48
- attach_function :EC_KEY_set_private_key, [:pointer, :pointer], :int
49
- attach_function :EC_KEY_set_public_key, [:pointer, :pointer], :int
100
+ attach_function :EC_KEY_set_conv_form, %i[pointer int], :void
101
+ attach_function :EC_KEY_set_private_key, %i[pointer pointer], :int
102
+ attach_function :EC_KEY_set_public_key, %i[pointer pointer], :int
50
103
  attach_function :EC_POINT_free, [:pointer], :int
51
- attach_function :EC_POINT_mul, [:pointer, :pointer, :pointer, :pointer, :pointer, :pointer], :int
104
+ attach_function :EC_POINT_mul, %i[pointer pointer pointer pointer pointer pointer], :int
52
105
  attach_function :EC_POINT_new, [:pointer], :pointer
53
- attach_function :EC_POINT_set_compressed_coordinates_GFp, [:pointer, :pointer, :pointer, :int, :pointer], :int
54
- attach_function :i2o_ECPublicKey, [:pointer, :pointer], :uint
106
+ attach_function :EC_POINT_set_compressed_coordinates_GFp, %i[pointer pointer pointer int pointer], :int
107
+ attach_function :i2o_ECPublicKey, %i[pointer pointer], :uint
55
108
 
56
109
  class << self
57
110
  def BN_num_bytes(ptr)
@@ -59,14 +112,16 @@ module Eth
59
112
  end
60
113
 
61
114
  def sign_compact(hash, private_key, public_key_hex)
62
- private_key = [private_key].pack("H*") if private_key.bytesize >= 64
115
+ private_key = [private_key].pack('H*') if private_key.bytesize >= 64
63
116
  pubkey_compressed = false
64
117
 
65
118
  init_ffi_ssl
66
119
  eckey = EC_KEY_new_by_curve_name(NID_secp256k1)
67
120
  priv_key = BN_bin2bn(private_key, private_key.bytesize, BN_new())
68
121
 
69
- group, order, ctx = EC_KEY_get0_group(eckey), BN_new(), BN_CTX_new()
122
+ group = EC_KEY_get0_group(eckey)
123
+ order = BN_new()
124
+ ctx = BN_CTX_new()
70
125
  EC_GROUP_get_order(group, order, ctx)
71
126
 
72
127
  pub_key = EC_POINT_new(group)
@@ -82,32 +137,36 @@ module Eth
82
137
  BN_free(priv_key)
83
138
  EC_KEY_free(eckey)
84
139
 
85
- buf, rec_id, head = FFI::MemoryPointer.new(:uint8, 32), nil, nil
86
- r, s = signature.get_array_of_pointer(0, 2).map{|i| BN_bn2bin(i, buf); buf.read_string(BN_num_bytes(i)).rjust(32, "\x00") }
140
+ buf = FFI::MemoryPointer.new(:uint8, 32)
141
+ rec_id = nil
142
+ head = nil
143
+ r, s = signature.get_array_of_pointer(0, 2).map { |i| BN_bn2bin(i, buf); buf.read_string(BN_num_bytes(i)).rjust(32, "\x00") }
87
144
 
88
- if signature.get_array_of_pointer(0, 2).all?{|i| BN_num_bits(i) <= 256 }
89
- 4.times{|i|
90
- head = [ Eth.v_base + i ].pack("C")
145
+ if signature.get_array_of_pointer(0, 2).all? { |i| BN_num_bits(i) <= 256 }
146
+ 4.times do |i|
147
+ head = [Eth.v_base + i].pack('C')
91
148
  if public_key_hex == recover_public_key_from_signature(hash, [head, r, s].join, i, pubkey_compressed)
92
149
  rec_id = i; break
93
150
  end
94
- }
151
+ end
95
152
  end
96
153
 
97
154
  ECDSA_SIG_free(signature)
98
155
 
99
- [ head, [r,s] ].join if rec_id
156
+ [head, [r, s]].join if rec_id
100
157
  end
101
158
 
102
159
  def recover_public_key_from_signature(message_hash, signature, rec_id, is_compressed)
103
- return nil if rec_id < 0 or signature.bytesize != 65
160
+ return nil if (rec_id < 0) || (signature.bytesize != 65)
161
+
104
162
  init_ffi_ssl
105
163
 
106
164
  signature = FFI::MemoryPointer.from_string(signature)
107
165
  r = BN_bin2bn(signature[1], 32, BN_new())
108
166
  s = BN_bin2bn(signature[33], 32, BN_new())
109
167
 
110
- _n, i = 0, rec_id / 2
168
+ _n = 0
169
+ i = rec_id / 2
111
170
  eckey = EC_KEY_new_by_curve_name(NID_secp256k1)
112
171
 
113
172
  EC_KEY_set_conv_form(eckey, POINT_CONVERSION_COMPRESSED) if is_compressed
@@ -137,7 +196,10 @@ module Eth
137
196
  BN_rshift(e, e, 8 - (n & 7)) if 8 * message_hash.bytesize > n
138
197
 
139
198
  ctx = BN_CTX_new()
140
- zero, rr, sor, eor = BN_new(), BN_new(), BN_new(), BN_new()
199
+ zero = BN_new()
200
+ rr = BN_new()
201
+ sor = BN_new()
202
+ eor = BN_new()
141
203
  BN_set_word(zero, 0)
142
204
  BN_mod_sub(e, zero, e, order, ctx)
143
205
  BN_mod_inverse(rr, r, order, ctx)
@@ -148,7 +210,7 @@ module Eth
148
210
  BN_CTX_free(ctx)
149
211
 
150
212
  bn_free_each r, s, order, x, field, e, zero, rr, sor, eor
151
- [big_r, big_q].each{|j| EC_POINT_free(j) }
213
+ [big_r, big_q].each { |j| EC_POINT_free(j) }
152
214
 
153
215
  recover_public_hex eckey
154
216
  end
@@ -165,18 +227,26 @@ module Eth
165
227
 
166
228
  def init_ffi_ssl
167
229
  return if @ssl_loaded
168
- SSL_library_init()
169
- ERR_load_crypto_strings()
170
- SSL_load_error_strings()
230
+
231
+ if version >= VERSION_1_1_0_NUM
232
+ OPENSSL_init_ssl(
233
+ OPENSSL_INIT_LOAD_SSL_STRINGS | OPENSSL_INIT_ENGINE_ALL_BUILTIN,
234
+ nil
235
+ )
236
+ else
237
+ SSL_library_init()
238
+ ERR_load_crypto_strings()
239
+ SSL_load_error_strings()
240
+ end
241
+
171
242
  RAND_poll()
172
243
  @ssl_loaded = true
173
244
  end
174
245
 
175
-
176
246
  private
177
247
 
178
248
  def bn_free_each(*list)
179
- list.each{|j| BN_free(j) }
249
+ list.each { |j| BN_free(j) }
180
250
  end
181
251
 
182
252
  def recover_public_hex(eckey)
@@ -184,14 +254,13 @@ module Eth
184
254
  buf = FFI::MemoryPointer.new(:uint8, length)
185
255
  ptr = FFI::MemoryPointer.new(:pointer).put_pointer(0, buf)
186
256
  pub_hex = if i2o_ECPublicKey(eckey, ptr) == length
187
- buf.read_string(length).unpack("H*")[0]
188
- end
257
+ buf.read_string(length).unpack('H*')[0]
258
+ end
189
259
 
190
260
  EC_KEY_free(eckey)
191
261
 
192
262
  pub_hex
193
263
  end
194
264
  end
195
-
196
265
  end
197
266
  end
@@ -1,6 +1,7 @@
1
1
  module Eth
2
2
  class RpcSigner
3
3
 
4
+
4
5
  attr_accessor :key
5
6
 
6
7
  def initialize(key)
@@ -9,27 +10,17 @@ module Eth
9
10
 
10
11
  def sign_message(message)
11
12
  payload = Eth::Signature.new(message)
12
- payload.signer = @key.address
13
- payload.padded_message = Eth::Utils.prefix_message(message)
14
- payload.hash = Eth::Utils.keccak256(payload.padded_message)
15
- payload.signature = @key.sign_hash(payload.hash)
13
+ payload.prefixed_message = Eth::Utils.prefix_message(message)
14
+ payload.hash = Eth::Utils.keccak256(payload.prefixed_message)
15
+ payload.hash_hex = Eth::Utils.bin_to_prefixed_hex(payload.hash)
16
+ payload.signature = @key.sign(payload.prefixed_message)
17
+ payload.signature_hex = Eth::Utils.bin_to_prefixed_hex(payload.signature)
16
18
  payload.v, payload.r, payload.s = Eth::Utils.v_r_s_for(payload.signature)
17
- payload.rpc_signature = Eth::Utils.zpad_int(payload.r, 32) + Eth::Utils.zpad_int(payload.s, 32) + [(payload.v - 27)].pack('C')
19
+ payload.rpc = Eth::Utils.zpad_int(payload.r, 32) + Eth::Utils.zpad_int(payload.s, 32) + [(payload.v - 27)].pack('C')
20
+ payload.rpc_hex = Eth::Utils.bin_to_prefixed_hex(payload.rpc)
18
21
  return payload
19
22
  end
20
23
 
21
- class << self
22
-
23
-
24
- def ecrecover_address(message_hash_hex, signature_hex)
25
- message_hash = Eth::Utils.hex_to_bin(message_hash_hex)
26
- signature = Eth::Utils.hex_to_bin(signature_hex)
27
- public_key = Eth::OpenSsl.recover_compact(message_hash, signature)
28
- signer = Eth::Utils.public_key_to_address(public_key)
29
- return signer
30
- end
31
- end
32
-
33
24
  end
34
25
 
35
26
 
@@ -1,43 +1,7 @@
1
- class String
2
-
3
- def to_urlsafe_base64
4
- if is_hex?
5
- Base64.urlsafe_encode64(Eth::Utils.hex_to_bin(self))
6
- else
7
- Base64.urlsafe_encode64(self)
8
- end
9
- end
10
-
11
- def from_urlsafe_base64
12
- Base64.urlsafe_decode64(self)
13
- end
14
-
15
- def to_hex
16
- if self.is_hex?
17
- return self
18
- else
19
- Eth::Utils.bin_to_prefixed_hex(self)
20
- end
21
- end
22
-
23
- def is_hex?
24
- !self.gsub("0x", '')[/\H/]
25
- end
26
-
27
- end
28
-
29
1
  module Eth
30
2
  class Signature
31
3
 
32
- attr_accessor :message,
33
- :signer,
34
- :padded_message,
35
- :hash,
36
- :signature,
37
- :rpc_signature,
38
- :v,
39
- :r,
40
- :s
4
+ attr_accessor :message, :signer, :prefixed_message, :hash, :hash_hex, :signature, :signature_hex, :rpc, :rpc_hex, :v, :r, :s
41
5
 
42
6
  def initialize(message)
43
7
  @message = message
@@ -37,21 +37,6 @@ module Eth
37
37
  RLP::Sedes.big_endian_int.serialize int
38
38
  end
39
39
 
40
- def from_rpc_signature_hex(signature)
41
- buffer = Eth::Utils.hex_to_bin(signature).bytes
42
- if buffer.length != 65
43
- raise ArgumentError.new('Invalid signature length')
44
- end
45
- v = buffer[64]
46
- v += 27 if v < 27
47
- r = buffer[0..32]
48
- s = buffer[33..64]
49
- signature = [v, r, s].flatten.pack('C*')
50
- signature_hex = Eth::Utils.bin_to_prefixed_hex(signature)
51
- payload = {v: v, r: r, s: s, signature: signature, signature_hex: signature_hex}
52
- return payload
53
- end
54
-
55
40
  def v_r_s_for(signature)
56
41
  [
57
42
  signature[0].bytes[0],
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Eth
2
- VERSION = "0.5.6"
4
+ VERSION = '0.5.7'
3
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: digix-eth
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.6
4
+ version: 0.5.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Steve Ellis
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2018-03-13 00:00:00.000000000 Z
12
+ date: 2019-08-21 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: digest-sha3
@@ -221,8 +221,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
221
221
  - !ruby/object:Gem::Version
222
222
  version: '0'
223
223
  requirements: []
224
- rubyforge_project:
225
- rubygems_version: 2.6.12
224
+ rubygems_version: 3.0.3
226
225
  signing_key:
227
226
  specification_version: 4
228
227
  summary: Simple API to sign Ethereum transactions.