bitcoinrb 1.2.0 → 1.3.0

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: cbc1459b87de8addec350661eb84c3a8bd87503eff03d6bad50c329660fc2749
4
- data.tar.gz: ccb70c6d406a1b4f7134c7c8b8f13f536ba8197d3479b4fca635c073cccd6f11
3
+ metadata.gz: 23f677d00426b94e0bdcee887901bb1e89a98c65ae61b0a025c7d95467dcb484
4
+ data.tar.gz: 7426638ec33999d466026a09a91517fe698adc0a55f32db6d416dc3f4ad6a386
5
5
  SHA512:
6
- metadata.gz: 5ed8400e197cb53d7232265b87f201174e60dae37952e075dae4e4f961b41e9967a24fa2998845100212747493a0dc2bd0b03a79ca208a2beb824cfd48f4a9bf
7
- data.tar.gz: 7585bf0a8179d1144a6f6310a63817538075a111ca92a248c2469df962c2fb913f091abffacdf57096cfb183ebe40406080ce807deca3c052c1a63b1934d895c
6
+ metadata.gz: 960aada8b3db4c610a2b206254f878af9c149f81ce42a53a2ebe8441e0a5179964a9a505807ae2b7519349c4a48125397acb20b412cfb84ea59d58957acd84e4
7
+ data.tar.gz: 493c6e06d7fb686dda65fd4bc4075e3716004427beab0cce9e040060711ad4a7197d0fdece2838d130ed6b1b64cdc94a37957a8354d7629bf9bd68fc02d326e4
@@ -19,7 +19,7 @@ jobs:
19
19
  runs-on: ubuntu-latest
20
20
  strategy:
21
21
  matrix:
22
- ruby-version: ['2.6', '2.7', '3.0', '3.1']
22
+ ruby-version: ['3.0', '3.1', '3.2']
23
23
 
24
24
  steps:
25
25
  - uses: actions/checkout@v2
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- ruby-3.1.2
1
+ ruby-3.2.0
data/README.md CHANGED
@@ -67,6 +67,8 @@ And then add to your .rb file:
67
67
 
68
68
  ## Usage
69
69
 
70
+ Examples can be found on the [wiki](https://github.com/chaintope/bitcoinrb/wiki).
71
+
70
72
  ### Chain selection
71
73
 
72
74
  The parameters of the blockchain are managed by `Bitcoin::ChainParams`. Switch chain parameters as follows:
data/bitcoinrb.gemspec CHANGED
@@ -20,10 +20,10 @@ Gem::Specification.new do |spec|
20
20
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
21
21
  spec.require_paths = ["lib"]
22
22
 
23
- spec.add_runtime_dependency 'ecdsa'
23
+ spec.add_runtime_dependency 'ecdsa_ext', '~> 0.5.0'
24
24
  spec.add_runtime_dependency 'eventmachine'
25
25
  spec.add_runtime_dependency 'murmurhash3'
26
- spec.add_runtime_dependency 'bech32', '~> 1.1.0'
26
+ spec.add_runtime_dependency 'bech32', '>= 1.3.0'
27
27
  spec.add_runtime_dependency 'daemon-spawn'
28
28
  spec.add_runtime_dependency 'thor'
29
29
  spec.add_runtime_dependency 'ffi'
@@ -33,7 +33,7 @@ Gem::Specification.new do |spec|
33
33
  spec.add_runtime_dependency 'siphash'
34
34
  spec.add_runtime_dependency 'protobuf', '3.8.5'
35
35
  spec.add_runtime_dependency 'json_pure', '>= 2.3.1'
36
- spec.add_runtime_dependency 'bip-schnorr', '>= 0.4.0'
36
+ spec.add_runtime_dependency 'bip-schnorr', '>= 0.5.0'
37
37
  spec.add_runtime_dependency 'base32', '>= 0.3.4'
38
38
 
39
39
  # for options
@@ -57,9 +57,8 @@ module Bitcoin
57
57
  SCRIPT_VERIFY_CONST_SCRIPTCODE = (1 << 16) # Making OP_CODESEPARATOR and FindAndDelete fail any non-segwit scripts
58
58
  SCRIPT_VERIFY_TAPROOT = (1 << 17) # Taproot/Tapscript validation (BIPs 341 & 342)
59
59
  SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_TAPROOT_VERSION = (1 << 18) # Making unknown Taproot leaf versions non-standard
60
- SCRIPT_VERIFY_DISCOURAGE_UNKNOWN_ANNEX = (1 << 19) # Making the use of (unknown) annexes non-standard (currently no annexes are known)
61
- SCRIPT_VERIFY_DISCOURAGE_OP_SUCCESS = (1 << 20) # Making unknown OP_SUCCESS non-standard
62
- SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_PUBKEYTYPE = (1 << 21) # Making unknown public key versions (in BIP 342 scripts) non-standard
60
+ SCRIPT_VERIFY_DISCOURAGE_OP_SUCCESS = (1 << 19) # Making unknown OP_SUCCESS non-standard
61
+ SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_PUBKEYTYPE = (1 << 20) # Making unknown public key versions (in BIP 342 scripts) non-standard
63
62
 
64
63
  MANDATORY_SCRIPT_VERIFY_FLAGS = SCRIPT_VERIFY_P2SH
65
64
 
@@ -27,7 +27,8 @@ module Bitcoin
27
27
  l = Bitcoin.hmac_sha512('Bitcoin seed', seed.htb)
28
28
  left = l[0..31].bth.to_i(16)
29
29
  raise 'invalid key' if left >= CURVE_ORDER || left == 0
30
- ext_key.key = Bitcoin::Key.new(priv_key: l[0..31].bth, key_type: Bitcoin::Key::TYPES[:compressed])
30
+ l_priv = ECDSA::Format::IntegerOctetString.encode(left, 32)
31
+ ext_key.key = Bitcoin::Key.new(priv_key: l_priv.bth, key_type: Bitcoin::Key::TYPES[:compressed])
31
32
  ext_key.chain_code = l[32..-1]
32
33
  ext_key
33
34
  end
@@ -110,8 +111,8 @@ module Bitcoin
110
111
  raise 'invalid key' if left >= CURVE_ORDER
111
112
  child_priv = (left + key.priv_key.to_i(16)) % CURVE_ORDER
112
113
  raise 'invalid key ' if child_priv >= CURVE_ORDER
113
- new_key.key = Bitcoin::Key.new(
114
- priv_key: child_priv.to_even_length_hex.rjust(64, '0'), key_type: key_type)
114
+ child_priv = ECDSA::Format::IntegerOctetString.encode(child_priv, 32)
115
+ new_key.key = Bitcoin::Key.new(priv_key: child_priv.bth, key_type: key_type)
115
116
  new_key.chain_code = l[32..-1]
116
117
  new_key.ver = version
117
118
  new_key
@@ -280,7 +281,8 @@ module Bitcoin
280
281
  l = Bitcoin.hmac_sha512(chain_code, data)
281
282
  left = l[0..31].bth.to_i(16)
282
283
  raise 'invalid key' if left >= CURVE_ORDER
283
- p1 = Bitcoin::Key.new(priv_key: left.to_s(16), key_type: Bitcoin::Key::TYPES[:uncompressed]).to_point
284
+ l_priv = ECDSA::Format::IntegerOctetString.encode(left, 32)
285
+ p1 = Bitcoin::Key.new(priv_key: l_priv.bth, key_type: Bitcoin::Key::TYPES[:uncompressed]).to_point
284
286
  p2 = Bitcoin::Key.new(pubkey: pubkey, key_type: key_type).to_point
285
287
  new_key.pubkey = (p1 + p2).to_hex
286
288
  new_key.chain_code = l[32..-1]
data/lib/bitcoin/key.rb CHANGED
@@ -39,6 +39,7 @@ module Bitcoin
39
39
  @secp256k1_module = Bitcoin.secp_impl
40
40
  @priv_key = priv_key
41
41
  if @priv_key
42
+ raise ArgumentError, 'Private key must be 32 bytes.' unless priv_key.htb.bytesize == 32
42
43
  raise ArgumentError, Errors::Messages::INVALID_PRIV_KEY unless validate_private_key_range(@priv_key)
43
44
  end
44
45
  if pubkey
@@ -6,14 +6,42 @@ module Bitcoin
6
6
 
7
7
  module_function
8
8
 
9
+ FORMAT_LEGACY = :legacy
10
+ FORMAT_SIMPLE = :simple
11
+ FORMAT_FULL = :full
12
+
9
13
  # Sign a message.
10
- # @param [Bitcoin::Key] key Private key to sign with.
11
- # @param [String] message The message to sign.
14
+ # @param [Bitcoin::Key] key Private key to sign.
15
+ # @param [String] message The message to be signed.
16
+ # @param [String] address An address of the key used for signing (required for full or simple format).
17
+ # @param [String] format Format of signature data. Default is +FORMAT_LEGACY+.
18
+ # @param [String] prefix (Optional) Prefix used in legacy format.
12
19
  # @return [String] Signature, base64 encoded.
13
- def sign_message(key, message, prefix: Bitcoin.chain_params.message_magic)
14
- digest = message_hash(message, prefix: prefix)
15
- compact_sig = key.sign_compact(digest)
16
- Base64.strict_encode64(compact_sig)
20
+ def sign_message(key, message, prefix: Bitcoin.chain_params.message_magic, format: FORMAT_LEGACY, address: nil)
21
+ validate_format!(format)
22
+ digest = message_hash(message, prefix: prefix, legacy: format == FORMAT_LEGACY)
23
+ sig = case format
24
+ when FORMAT_LEGACY
25
+ key.sign_compact(digest)
26
+ else
27
+ validate_address!(address)
28
+ addr = Bitcoin::Script.parse_from_addr(address)
29
+ sig_ver, algo = if addr.p2wpkh?
30
+ [:witness_v0, :ecdsa]
31
+ elsif addr.p2tr?
32
+ [:taproot, :schnorr]
33
+ else
34
+ raise ArgumentError "#{address} dose not supported."
35
+ end
36
+ tx = to_sign_tx(digest, address)
37
+ prev_out = Bitcoin::TxOut.new(script_pubkey: addr)
38
+ sighash = tx.sighash_for_input(0, addr, sig_version: sig_ver, amount: 0, prevouts: [prev_out])
39
+ sig = key.sign(sighash, algo: algo) + [Bitcoin::SIGHASH_TYPE[:all]].pack('C')
40
+ tx.in[0].script_witness.stack << sig
41
+ tx.in[0].script_witness.stack << key.pubkey.htb
42
+ format == FORMAT_SIMPLE ? tx.in[0].script_witness.to_payload : tx.to_payload
43
+ end
44
+ Base64.strict_encode64(sig)
17
45
  end
18
46
 
19
47
  # Verify a signed message.
@@ -23,25 +51,72 @@ module Bitcoin
23
51
  # @return [Boolean] Verification result.
24
52
  def verify_message(address, signature, message, prefix: Bitcoin.chain_params.message_magic)
25
53
  validate_address!(address)
26
- sig = Base64.decode64(signature)
27
- raise ArgumentError, 'Invalid signature length' unless sig.bytesize == Bitcoin::Key::COMPACT_SIGNATURE_SIZE
28
- digest = message_hash(message, prefix: prefix)
29
- pubkey = Bitcoin::Key.recover_compact(digest, sig)
30
- return false unless pubkey
31
- pubkey.to_p2pkh == address
54
+ begin
55
+ sig = Base64.strict_decode64(signature)
56
+ rescue ArgumentError
57
+ raise ArgumentError, 'Invalid signature'
58
+ end
59
+ begin
60
+ # Legacy verification
61
+ pubkey = Bitcoin::Key.recover_compact(message_hash(message, prefix: prefix, legacy: true), sig)
62
+ return false unless pubkey
63
+ pubkey.to_p2pkh == address
64
+ rescue ArgumentError
65
+ # BIP322 verification
66
+ tx = to_sign_tx(message_hash(message, prefix: prefix, legacy: false), address)
67
+ tx.in[0].script_witness = Bitcoin::ScriptWitness.parse_from_payload(sig)
68
+ script_pubkey = Bitcoin::Script.parse_from_addr(address)
69
+ tx_out = Bitcoin::TxOut.new(script_pubkey: script_pubkey)
70
+ interpreter = Bitcoin::ScriptInterpreter.new(checker: Bitcoin::TxChecker.new(tx: tx, input_index: 0, prevouts: [tx_out]))
71
+ interpreter.verify_script(Bitcoin::Script.new, script_pubkey, tx.in[0].script_witness)
72
+ end
32
73
  end
33
74
 
34
75
  # Hashes a message for signing and verification.
35
- def message_hash(message, prefix: Bitcoin.chain_params.message_magic)
36
- Bitcoin.double_sha256(Bitcoin.pack_var_string(prefix) << Bitcoin.pack_var_string(message))
76
+ def message_hash(message, prefix: Bitcoin.chain_params.message_magic, legacy: true)
77
+ if legacy
78
+ Bitcoin.double_sha256(Bitcoin.pack_var_string(prefix) << Bitcoin.pack_var_string(message))
79
+ else
80
+ Bitcoin.tagged_hash('BIP0322-signed-message', message)
81
+ end
37
82
  end
38
83
 
39
84
  def validate_address!(address)
40
85
  raise ArgumentError, 'Invalid address' unless Bitcoin.valid_address?(address)
41
86
  script = Bitcoin::Script.parse_from_addr(address)
42
- raise ArgumentError, 'Address has no key' unless script.p2pkh?
87
+ raise ArgumentError, 'This address unsupported' if script.p2sh? || script.p2wsh?
88
+ end
89
+
90
+ def validate_format!(format)
91
+ unless [FORMAT_LEGACY, FORMAT_FULL, FORMAT_SIMPLE].include?(format)
92
+ raise ArgumentError "Invalid format specified."
93
+ end
94
+ end
95
+
96
+ def to_spend_tx(digest, addr)
97
+ validate_address!(addr)
98
+ message_challenge = Bitcoin::Script.parse_from_addr(addr)
99
+ tx = Bitcoin::Tx.new
100
+ tx.version = 0
101
+ tx.lock_time = 0
102
+ prev_out = Bitcoin::OutPoint.create_coinbase_outpoint
103
+ script_sig = Bitcoin::Script.new << Bitcoin::Opcodes::OP_0 << digest
104
+ tx.in << Bitcoin::TxIn.new(out_point: prev_out, sequence: 0, script_sig: script_sig)
105
+ tx.out << Bitcoin::TxOut.new(script_pubkey: message_challenge)
106
+ tx
107
+ end
108
+
109
+ def to_sign_tx(digest, addr)
110
+ tx = Bitcoin::Tx.new
111
+ tx.version = 0
112
+ tx.lock_time = 0
113
+ prev_out = Bitcoin::OutPoint.from_txid(to_spend_tx(digest, addr).txid, 0)
114
+ tx.in << Bitcoin::TxIn.new(out_point: prev_out, sequence: 0)
115
+ tx.out << Bitcoin::TxOut.new(script_pubkey: Bitcoin::Script.new << Bitcoin::Opcodes::OP_RETURN)
116
+ tx
43
117
  end
44
118
 
45
119
  private_class_method :validate_address!
120
+ private_class_method :validate_format!
46
121
  end
47
122
  end
@@ -9,6 +9,12 @@ module Bitcoin
9
9
 
10
10
  class_option :network, aliases: '-n', default: :mainnet
11
11
 
12
+ desc 'decodepsbt <base64 psbt string>', "Return a JSON object representing the serialized, base64-encoded partially signed Bitcoin transaction."
13
+ def decodepsbt(base64)
14
+ psbt = Bitcoin::PSBT::Tx.parse_from_base64(base64)
15
+ puts JSON.pretty_generate(psbt.to_h)
16
+ end
17
+
12
18
  desc 'getblockchaininfo', 'Returns an object containing various state info regarding blockchain processing.'
13
19
  def getblockchaininfo
14
20
  request('getblockchaininfo')
@@ -61,7 +61,7 @@ module Bitcoin
61
61
  raise ArgumentError, 'invalid version byte' unless hex[0..1] == VERSION_BYTE
62
62
  raise ArgumentError, 'invalid version' unless PaymentCode.support_version?(version)
63
63
  raise ArgumentError, 'invalid sign' unless PaymentCode.support_sign?(sign)
64
- raise ArgumentError, Errors::Messages::INVALID_PUBLIC_KEY unless Bitcoin::Key.new(priv_key: nil, pubkey: sign + public_key).fully_valid_pubkey?
64
+ raise ArgumentError, Errors::Messages::INVALID_PUBLIC_KEY unless Bitcoin::Key.new(pubkey: sign + public_key).fully_valid_pubkey?
65
65
  raise ArgumentError, Errors::Messages::INVALID_CHECKSUM unless Bitcoin.calc_checksum(payment_code) == hex[-8..-1]
66
66
 
67
67
  x_value = payment_code[8..71]
@@ -283,6 +283,32 @@ module Bitcoin
283
283
  self
284
284
  end
285
285
 
286
+ def to_h
287
+ h = {}
288
+ h[:non_witness_utxo] = non_witness_utxo.to_h if non_witness_utxo
289
+ h[:witness_utxo] = witness_utxo.to_h if witness_utxo
290
+ h[:redeem_script] = redeem_script.to_h if redeem_script
291
+ h[:witness_script] = witness_script.to_h if redeem_script
292
+ h[:final_script_sig] = final_script_sig.to_h if final_script_sig
293
+ h[:final_script_witness] = final_script_witness.to_h if final_script_witness
294
+ h[:bip32_derivs] = hd_key_paths.values.map(&:to_h) unless hd_key_paths.empty?
295
+ h[:partial_signatures] = partial_sigs.map {|k, v| {"#{k}": v.bth}} unless partial_sigs.empty?
296
+ h[:sighash_type] = sighash_type if sighash_type
297
+ h[:ripemd160_preimages] = ripemd160_preimages.map {|k, v| {"#{k}": v}} unless ripemd160_preimages.empty?
298
+ h[:sha256_preimages] = sha256_preimages.map {|k, v| {"#{k}": v}} unless sha256_preimages.empty?
299
+ h[:hash160_preimages] = hash160_preimages.map {|k, v| {"#{k}": v}} unless hash160_preimages.empty?
300
+ h[:hash256_preimages] = hash256_preimages.map {|k, v| {"#{k}": v}} unless hash256_preimages.empty?
301
+ h[:proprietary] = proprietaries.map(&:to_h) unless proprietaries.empty?
302
+ h[:tap_key_sig] = tap_key_sig if tap_key_sig
303
+ h[:tap_script_sig] = tap_script_sigs.map {|k, v| {"#{k}": v}} unless tap_script_sigs.empty?
304
+ h[:tap_leaf_script] = tap_leaf_scripts.map {|k, v| {"#{k}": v}} unless tap_leaf_scripts.empty?
305
+ h[:tap_bip32_derivs] = tap_bip32_derivations.map{|k, v| {"#{k}": v}} unless tap_bip32_derivations.empty?
306
+ h[:tap_internal_key] = tap_internal_key if tap_internal_key
307
+ h[:tap_merkle_root] = tap_merkle_root if tap_merkle_root
308
+ h[:unknown] = unknowns.map {|k, v| {"#{k}": v.bth}} unless unknowns.empty?
309
+ h
310
+ end
311
+
286
312
  end
287
313
 
288
314
  end
@@ -100,7 +100,18 @@ module Bitcoin
100
100
  combined
101
101
  end
102
102
 
103
+ def to_h
104
+ h = {}
105
+ h[:redeem_script] = redeem_script.bth if redeem_script
106
+ h[:witness_script] = witness_script.bth if witness_script
107
+ h[:bip32_derivs] = hd_key_paths.values.map(&:to_h) unless hd_key_paths.empty?
108
+ h[:proprietary] = proprietaries.map(&:to_h) unless proprietaries.empty?
109
+ h[:tap_internal_key] = tap_internal_key if tap_internal_key
110
+ h[:tap_tree] = tap_tree if tap_tree
111
+ h[:tap_bip32_derivs] = tap_bip32_derivations.map{|k, v| {"#{k}": v}} unless tap_bip32_derivations.empty?
112
+ h[:unknown] = unknowns.map {|k, v| {"#{k}": v.bth}} unless unknowns.empty?
113
+ h
114
+ end
103
115
  end
104
-
105
116
  end
106
117
  end
@@ -39,6 +39,10 @@ module Bitcoin
39
39
  k = key
40
40
  Bitcoin.pack_var_int(k.bytesize) + k + Bitcoin.pack_var_int(value.bytesize) + value
41
41
  end
42
+
43
+ def to_h
44
+ {identifier: identifier.bth, sub_type: sub_type, value: value.bth}
45
+ end
42
46
  end
43
47
  end
44
48
  end
@@ -177,6 +177,18 @@ module Bitcoin
177
177
  end
178
178
  end
179
179
 
180
+ def to_h
181
+ {
182
+ tx: tx.to_h,
183
+ global_xpubs: xpubs.map(&:to_h),
184
+ psbt_version: version,
185
+ proprietary: proprietaries.map(&:to_h),
186
+ unknown: unknowns.map {|k, v| {"#{k}": v}},
187
+ inputs: inputs.map(&:to_h),
188
+ outputs: outputs.map(&:to_h)
189
+ }
190
+ end
191
+
180
192
  # update input key-value maps.
181
193
  # @param [Bitcoin::Tx] prev_tx previous tx reference by input.
182
194
  # @param [Bitcoin::Script] redeem_script redeem script to set input.
@@ -543,11 +543,8 @@ module Bitcoin
543
543
 
544
544
  def to_h
545
545
  h = {asm: to_s, hex: to_hex, type: type}
546
- addrs = addresses
547
- unless addrs.empty?
548
- h[:req_sigs] = multisig? ? Bitcoin::Opcodes.opcode_to_small_int(chunks[0].bth.to_i(16)) :addrs.size
549
- h[:addresses] = addrs
550
- end
546
+ addr = to_addr
547
+ h[:address] = addr if addr
551
548
  h
552
549
  end
553
550
 
@@ -1,3 +1,6 @@
1
+ require 'ecdsa_ext'
2
+ require 'ecdsa/ext/sign_verify'
3
+
1
4
  module Bitcoin
2
5
  module Secp256k1
3
6
 
@@ -10,9 +13,9 @@ module Bitcoin
10
13
  # generate ec private key and public key
11
14
  def generate_key_pair(compressed: true)
12
15
  private_key = 1 + SecureRandom.random_number(GROUP.order - 1)
13
- public_key = GROUP.generator.multiply_by_scalar(private_key)
16
+ public_key = GROUP.generator.to_jacobian * private_key
14
17
  privkey = ECDSA::Format::IntegerOctetString.encode(private_key, 32)
15
- pubkey = public_key.to_hex(compressed)
18
+ pubkey = public_key.to_affine.to_hex(compressed)
16
19
  [privkey.bth, pubkey]
17
20
  end
18
21
 
@@ -23,8 +26,8 @@ module Bitcoin
23
26
  end
24
27
 
25
28
  def generate_pubkey(privkey, compressed: true)
26
- public_key = ECDSA::Group::Secp256k1.generator.multiply_by_scalar(privkey.to_i(16))
27
- public_key.to_hex(compressed)
29
+ public_key = GROUP.generator.to_jacobian * privkey.to_i(16)
30
+ public_key.to_affine.to_hex(compressed)
28
31
  end
29
32
 
30
33
  # Check whether valid x-only public key or not.
@@ -132,7 +135,7 @@ module Bitcoin
132
135
  nonce = RFC6979.generate_rfc6979_nonce(privkey + data, extra_entropy)
133
136
 
134
137
  # port form ecdsa gem.
135
- r_point = GROUP.new_point(nonce)
138
+ r_point = (GROUP.generator.to_jacobian * nonce).to_affine
136
139
 
137
140
  point_field = ECDSA::PrimeField.new(GROUP.order)
138
141
  r = point_field.mod(r_point.x)
@@ -40,7 +40,9 @@ module Bitcoin
40
40
  private_key = p.has_even_y? ? internal_private_key.priv_key.to_i(16) :
41
41
  ECDSA::Group::Secp256k1.order - internal_private_key.priv_key.to_i(16)
42
42
  t = tweak(internal_private_key, merkle_root)
43
- Bitcoin::Key.new(priv_key: ((t.bti + private_key) % ECDSA::Group::Secp256k1.order).to_even_length_hex)
43
+ private_key = ECDSA::Format::IntegerOctetString.encode(
44
+ (t.bti + private_key) % ECDSA::Group::Secp256k1.order, 32)
45
+ Bitcoin::Key.new(priv_key: private_key.bth)
44
46
  end
45
47
  end
46
48
  end
@@ -1,3 +1,3 @@
1
1
  module Bitcoin
2
- VERSION = "1.2.0"
2
+ VERSION = "1.3.0"
3
3
  end
metadata CHANGED
@@ -1,29 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bitcoinrb
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - azuchi
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-10-24 00:00:00.000000000 Z
11
+ date: 2023-04-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: ecdsa
14
+ name: ecdsa_ext
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '0'
19
+ version: 0.5.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ">="
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '0'
26
+ version: 0.5.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: eventmachine
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -56,16 +56,16 @@ dependencies:
56
56
  name: bech32
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - "~>"
59
+ - - ">="
60
60
  - !ruby/object:Gem::Version
61
- version: 1.1.0
61
+ version: 1.3.0
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - "~>"
66
+ - - ">="
67
67
  - !ruby/object:Gem::Version
68
- version: 1.1.0
68
+ version: 1.3.0
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: daemon-spawn
71
71
  requirement: !ruby/object:Gem::Requirement
@@ -198,14 +198,14 @@ dependencies:
198
198
  requirements:
199
199
  - - ">="
200
200
  - !ruby/object:Gem::Version
201
- version: 0.4.0
201
+ version: 0.5.0
202
202
  type: :runtime
203
203
  prerelease: false
204
204
  version_requirements: !ruby/object:Gem::Requirement
205
205
  requirements:
206
206
  - - ">="
207
207
  - !ruby/object:Gem::Version
208
- version: 0.4.0
208
+ version: 0.5.0
209
209
  - !ruby/object:Gem::Dependency
210
210
  name: base32
211
211
  requirement: !ruby/object:Gem::Requirement
@@ -517,7 +517,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
517
517
  - !ruby/object:Gem::Version
518
518
  version: '0'
519
519
  requirements: []
520
- rubygems_version: 3.3.23
520
+ rubygems_version: 3.4.1
521
521
  signing_key:
522
522
  specification_version: 4
523
523
  summary: The implementation of Bitcoin Protocol for Ruby.