digix-eth 0.5.6 → 0.5.7

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