tapyrus 0.2.8 → 0.2.13
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 +4 -4
- data/.ruby-version +1 -1
- data/lib/schnorr/sign_to_contract.rb +51 -0
- data/lib/schnorr.rb +12 -6
- data/lib/tapyrus/bip175.rb +78 -0
- data/lib/tapyrus/ext_key.rb +8 -0
- data/lib/tapyrus/key.rb +1 -1
- data/lib/tapyrus/merkle_tree.rb +8 -5
- data/lib/tapyrus/network/peer_discovery.rb +10 -7
- data/lib/tapyrus/rpc/request_handler.rb +23 -26
- data/lib/tapyrus/rpc/tapyrus_core_client.rb +37 -12
- data/lib/tapyrus/rpc.rb +1 -0
- data/lib/tapyrus/script/script.rb +27 -23
- data/lib/tapyrus/slip39/sss.rb +17 -18
- data/lib/tapyrus/tx_builder.rb +2 -0
- data/lib/tapyrus/version.rb +1 -1
- data/lib/tapyrus.rb +1 -0
- metadata +8 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 82146cdd150374b76b593273e44c31f4f578d38a1b7dcabea0b0d1fd9acbbb5f
|
4
|
+
data.tar.gz: 8895de33dd2b36412f509c4e35465d513d3d6c98a0bcfc0e7db241a77acd8b3b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e386ac9d8578846437902e78d79b3d4419c85df861c831c92641da94d2d46a37c4793efaafa8e28a1da4466e5347fbe79f66beb0d925fe2bfc83cca1d1e90c99
|
7
|
+
data.tar.gz: a34fa0709093aafb118356b7736b409c733e1185a22538f7e2ed4392dac0ac661a652a31853f652d988860ee66c8b57124815b0fc28dd795b7bea97ad44182c5
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
3.0.2
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Schnorr
|
2
|
+
module SignToContract
|
3
|
+
module_function
|
4
|
+
|
5
|
+
GROUP = ECDSA::Group::Secp256k1
|
6
|
+
|
7
|
+
# Generate schnorr signature for sign-to-signature.
|
8
|
+
# @param message [String] A message to be signed with binary format.
|
9
|
+
# @param private_key [Integer] The private key.
|
10
|
+
# @param contract [String] A contract information with 32-bytes binary format.
|
11
|
+
# @return [(Schnorr::Signature, ECDSA::Point)] signature and point to prove the commitment to contract.
|
12
|
+
def sign(message, private_key, contract)
|
13
|
+
raise 'The message must be a 32-byte array.' unless message.bytesize == 32
|
14
|
+
raise 'private_key is zero or over the curve order.' if private_key == 0 || private_key >= GROUP.order
|
15
|
+
raise 'The contract must be a 32-byte binary string.' unless contract.bytesize == 32
|
16
|
+
|
17
|
+
p = GROUP.new_point(private_key)
|
18
|
+
k0 = Schnorr.deterministic_nonce(message, private_key)
|
19
|
+
|
20
|
+
k1, r = tweak(k0, contract)
|
21
|
+
|
22
|
+
q = GROUP.new_point(k1)
|
23
|
+
k = ECDSA::PrimeField.jacobi(q.y, GROUP.field.prime) == 1 ? k1 : GROUP.order - k1
|
24
|
+
|
25
|
+
e = Schnorr.create_challenge(q.x, p, message)
|
26
|
+
|
27
|
+
[Schnorr::Signature.new(q.x, (k + e * private_key) % GROUP.order), r]
|
28
|
+
end
|
29
|
+
|
30
|
+
def tweak(k, contract)
|
31
|
+
r = GROUP.new_point(k)
|
32
|
+
rx = ECDSA::Format::IntegerOctetString.encode(r.x, GROUP.byte_length)
|
33
|
+
h = Tapyrus.sha256(rx + contract)
|
34
|
+
k1 = (k + h.bth.to_i(16)) % GROUP.order
|
35
|
+
raise 'Creation of signature failed. k + h(R || c) is zero' if k1.zero?
|
36
|
+
[k1, r]
|
37
|
+
end
|
38
|
+
|
39
|
+
# Validate contract
|
40
|
+
# @param r [ECDSA::Point] point to prove the commitment.
|
41
|
+
# @param signature [Schnorr::Signature] signature.
|
42
|
+
# @param contract [String] A contract information with 32-bytes binary format.
|
43
|
+
# @return true if commitment for contract is valid, otherwise false
|
44
|
+
def valid_contract?(r, signature, contract)
|
45
|
+
rx = ECDSA::Format::IntegerOctetString.encode(r.x, GROUP.byte_length)
|
46
|
+
commitment = Tapyrus.sha256(rx + contract).bth.to_i(16) % GROUP.order
|
47
|
+
point = r + GROUP.generator.multiply_by_scalar(commitment)
|
48
|
+
signature.r == point.x
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
data/lib/schnorr.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
module Schnorr
|
2
2
|
autoload :Signature, 'schnorr/signature'
|
3
|
+
autoload :SignToContract, 'schnorr/sign_to_contract'
|
3
4
|
|
4
5
|
module_function
|
5
6
|
|
@@ -16,12 +17,7 @@ module Schnorr
|
|
16
17
|
raise 'private_key is zero or over the curve order.' if private_key == 0 || private_key >= GROUP.order
|
17
18
|
|
18
19
|
p = GROUP.new_point(private_key)
|
19
|
-
|
20
|
-
secret = secret + message + ALGO16
|
21
|
-
nonce = Tapyrus::Secp256k1::RFC6979.generate_rfc6979_nonce(secret, '')
|
22
|
-
|
23
|
-
k0 = nonce % GROUP.order
|
24
|
-
raise 'Creation of signature failed. k is zero' if k0.zero?
|
20
|
+
k0 = deterministic_nonce(message, private_key)
|
25
21
|
|
26
22
|
r = GROUP.new_point(k0)
|
27
23
|
k = ECDSA::PrimeField.jacobi(r.y, GROUP.field.prime) == 1 ? k0 : GROUP.order - k0
|
@@ -31,6 +27,16 @@ module Schnorr
|
|
31
27
|
Schnorr::Signature.new(r.x, (k + e * private_key) % GROUP.order)
|
32
28
|
end
|
33
29
|
|
30
|
+
def deterministic_nonce(message, private_key)
|
31
|
+
secret = ECDSA::Format::IntegerOctetString.encode(private_key, GROUP.byte_length)
|
32
|
+
secret = secret + message + ALGO16
|
33
|
+
nonce = Tapyrus::Secp256k1::RFC6979.generate_rfc6979_nonce(secret, '')
|
34
|
+
|
35
|
+
k0 = nonce % GROUP.order
|
36
|
+
raise 'Creation of signature failed. k is zero' if k0.zero?
|
37
|
+
k0
|
38
|
+
end
|
39
|
+
|
34
40
|
# Verifies the given {Signature} and returns true if it is valid.
|
35
41
|
# @param message (String) A message to be signed with binary format.
|
36
42
|
# @param public_key (String) The public key with binary format.
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module Tapyrus
|
2
|
+
# Key generation based on BIP-175
|
3
|
+
#
|
4
|
+
# @example
|
5
|
+
#
|
6
|
+
# master = Tapyrus::ExtKey.from_base58('xprv9s21ZrQH143K2JF8RafpqtKiTbsbaxEeUaMnNHsm5o6wCW3z8ySyH4UxFVSfZ8n7ESu7fgir8imbZKLYVBxFPND1pniTZ81vKfd45EHKX73')
|
7
|
+
# bip175 = Tapyrus::BIP175.from_private_key(master)
|
8
|
+
# bip175 << "foo"
|
9
|
+
# bip175 << "bar"
|
10
|
+
# bip175.addr
|
11
|
+
# > 1C7f322izqMqLzZzfzkPAjxBzprxDi47Yf
|
12
|
+
#
|
13
|
+
# @see https://github.com/bitcoin/bips/blob/master/bip-0175.mediawiki
|
14
|
+
class BIP175
|
15
|
+
PURPOSE_TYPE = 175
|
16
|
+
|
17
|
+
attr_accessor :master_ext_key, :payment_base
|
18
|
+
|
19
|
+
def initialize
|
20
|
+
@contracts = []
|
21
|
+
end
|
22
|
+
|
23
|
+
# @param key [Tapyrus::ExtKey] master private extended key
|
24
|
+
def self.from_ext_key(key)
|
25
|
+
raise ArgumentError, 'key should be Tapyrus::ExtKey' unless key.is_a?(Tapyrus::ExtKey)
|
26
|
+
raise ArgumentError, 'key should be master private extended key' unless key.master?
|
27
|
+
new.tap do |bip175|
|
28
|
+
bip175.master_ext_key = key
|
29
|
+
bip175.payment_base =
|
30
|
+
key.derive(PURPOSE_TYPE, true).derive(Tapyrus.chain_params.bip44_coin_type, true).ext_pubkey
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# @param key [Tapyrus::ExtPubkey] contract base public key
|
35
|
+
def self.from_ext_pubkey(key)
|
36
|
+
raise ArgumentError, 'key should be Tapyrus::ExtPubkey' unless key.is_a?(Tapyrus::ExtPubkey)
|
37
|
+
new.tap { |bip175| bip175.payment_base = key }
|
38
|
+
end
|
39
|
+
|
40
|
+
# Add value of hashed contract
|
41
|
+
# @param contract [String] contract information
|
42
|
+
def add(contract)
|
43
|
+
@contracts << Tapyrus.sha256(contract)
|
44
|
+
self
|
45
|
+
end
|
46
|
+
alias << add
|
47
|
+
|
48
|
+
# Return combined hash consist of payment_base and contract hashes
|
49
|
+
# @return [String] contract_hash
|
50
|
+
def combined_hash
|
51
|
+
hashes = @contracts.map { |c| c.bth }.sort
|
52
|
+
concatenated_hash = [payment_base.to_base58].concat(hashes).join
|
53
|
+
Tapyrus.sha256(concatenated_hash)
|
54
|
+
end
|
55
|
+
|
56
|
+
# Return pay-to-contract extended private key
|
57
|
+
# @return [Tapyrus::ExtKey] extended private key
|
58
|
+
def priv_key
|
59
|
+
key = master_ext_key.derive(PURPOSE_TYPE, true).derive(Tapyrus.chain_params.bip44_coin_type, true)
|
60
|
+
|
61
|
+
# Split every 2 bytes
|
62
|
+
paths = combined_hash.unpack('S>*')
|
63
|
+
paths.inject(key) { |key, p| key.derive(p) }
|
64
|
+
end
|
65
|
+
|
66
|
+
# Return pay-to-contract extended public key
|
67
|
+
# @return [Tapyrus::ExtPubkey] extended public key
|
68
|
+
def pubkey
|
69
|
+
# Split every 2 bytes
|
70
|
+
paths = combined_hash.unpack('S>*')
|
71
|
+
paths.inject(payment_base) { |key, p| key.derive(p) }
|
72
|
+
end
|
73
|
+
|
74
|
+
def addr
|
75
|
+
pubkey.addr
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
data/lib/tapyrus/ext_key.rb
CHANGED
@@ -196,6 +196,10 @@ module Tapyrus
|
|
196
196
|
Tapyrus.chain_params.extended_pubkey_version
|
197
197
|
end
|
198
198
|
end
|
199
|
+
|
200
|
+
def master?
|
201
|
+
depth == 0 && number == 0 && parent_fingerprint == '00000000'
|
202
|
+
end
|
199
203
|
end
|
200
204
|
|
201
205
|
# BIP-32 Extended public key
|
@@ -356,5 +360,9 @@ module Tapyrus
|
|
356
360
|
p = Tapyrus.chain_params
|
357
361
|
[p.bip49_pubkey_p2wpkh_p2sh_version, p.bip84_pubkey_p2wpkh_version, p.extended_pubkey_version].include?(version)
|
358
362
|
end
|
363
|
+
|
364
|
+
def master?
|
365
|
+
depth == 0 && number == 0 && parent_fingerprint == '00000000'
|
366
|
+
end
|
359
367
|
end
|
360
368
|
end
|
data/lib/tapyrus/key.rb
CHANGED
@@ -31,7 +31,7 @@ module Tapyrus
|
|
31
31
|
# @return [Tapyrus::Key] a key object.
|
32
32
|
def initialize(priv_key: nil, pubkey: nil, key_type: nil, compressed: true, allow_hybrid: false)
|
33
33
|
if key_type.nil? && !compressed.nil? && pubkey.nil?
|
34
|
-
|
34
|
+
warn('Use key_type parameter instead of compressed. compressed parameter removed in the future.')
|
35
35
|
end
|
36
36
|
if key_type
|
37
37
|
@key_type = key_type
|
data/lib/tapyrus/merkle_tree.rb
CHANGED
@@ -16,11 +16,14 @@ module Tapyrus
|
|
16
16
|
nodes = [Node.new(txids.first)]
|
17
17
|
else
|
18
18
|
nodes =
|
19
|
-
txids
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
19
|
+
txids
|
20
|
+
.each_slice(2)
|
21
|
+
.map do |m|
|
22
|
+
left = Node.new(m[0])
|
23
|
+
right = Node.new(m[1] ? m[1] : m[0])
|
24
|
+
[left, right]
|
25
|
+
end
|
26
|
+
.flatten
|
24
27
|
end
|
25
28
|
new(build_initial_tree(nodes))
|
26
29
|
end
|
@@ -26,14 +26,17 @@ module Tapyrus
|
|
26
26
|
|
27
27
|
def find_from_dns_seeds
|
28
28
|
logger.debug 'discover peer address from DNS seeds.'
|
29
|
-
dns_seeds
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
29
|
+
dns_seeds
|
30
|
+
.map do |seed|
|
31
|
+
begin
|
32
|
+
Socket.getaddrinfo(seed, Tapyrus.chain_params.default_port).map { |a| a[2] }.uniq
|
33
|
+
rescue SocketError => e
|
34
|
+
logger.error "SocketError occurred when load DNS seed: #{seed}, error: #{e.message}"
|
35
|
+
nil
|
36
|
+
end
|
35
37
|
end
|
36
|
-
|
38
|
+
.flatten
|
39
|
+
.compact
|
37
40
|
end
|
38
41
|
end
|
39
42
|
end
|
@@ -47,32 +47,29 @@ module Tapyrus
|
|
47
47
|
|
48
48
|
# Returns connected peer information.
|
49
49
|
def getpeerinfo
|
50
|
-
node
|
51
|
-
.
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
best_height: peer.best_height
|
74
|
-
}
|
75
|
-
end
|
50
|
+
node.pool.peers.map do |peer|
|
51
|
+
local_addr = "#{peer.remote_version.remote_addr.ip}:18333"
|
52
|
+
{
|
53
|
+
id: peer.id,
|
54
|
+
addr: "#{peer.host}:#{peer.port}",
|
55
|
+
addrlocal: local_addr,
|
56
|
+
services: peer.remote_version.services.to_even_length_hex.rjust(16, '0'),
|
57
|
+
relaytxes: peer.remote_version.relay,
|
58
|
+
lastsend: peer.last_send,
|
59
|
+
lastrecv: peer.last_recv,
|
60
|
+
bytessent: peer.bytes_sent,
|
61
|
+
bytesrecv: peer.bytes_recv,
|
62
|
+
conntime: peer.conn_time,
|
63
|
+
pingtime: peer.ping_time,
|
64
|
+
minping: peer.min_ping,
|
65
|
+
version: peer.remote_version.version,
|
66
|
+
subver: peer.remote_version.user_agent,
|
67
|
+
inbound: !peer.outbound?,
|
68
|
+
startingheight: peer.remote_version.start_height,
|
69
|
+
best_hash: peer.best_hash,
|
70
|
+
best_height: peer.best_height
|
71
|
+
}
|
72
|
+
end
|
76
73
|
end
|
77
74
|
|
78
75
|
# broadcast transaction
|
@@ -16,22 +16,36 @@ module Tapyrus
|
|
16
16
|
# end
|
17
17
|
# end
|
18
18
|
class Error < StandardError
|
19
|
-
attr_reader :
|
19
|
+
attr_reader :response_code, :response_msg, :rpc_error
|
20
20
|
|
21
|
-
def initialize(
|
22
|
-
|
21
|
+
def initialize(response_code, response_msg, rpc_error)
|
22
|
+
@response_code = response_code
|
23
|
+
@response_msg = response_msg
|
24
|
+
@rpc_error = rpc_error
|
25
|
+
end
|
23
26
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
27
|
+
# Return response object as Hash
|
28
|
+
# @return [Hash] response
|
29
|
+
# @option response_code [Integer] HTTP status code
|
30
|
+
# @option response_msg [String] HTTP response body
|
31
|
+
# @option rpc_error [String] error message received from Tapyrus Core
|
32
|
+
def response
|
33
|
+
@response ||=
|
34
|
+
begin
|
35
|
+
m = { response_code: response_code, response_msg: response_msg }
|
36
|
+
m.merge!(rpc_error: rpc_error) if rpc_error
|
37
|
+
m
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# Return string that represents error message.
|
42
|
+
# @return [String] error message
|
43
|
+
def message
|
44
|
+
response.to_json
|
31
45
|
end
|
32
46
|
|
33
47
|
def to_s
|
34
|
-
|
48
|
+
message
|
35
49
|
end
|
36
50
|
end
|
37
51
|
|
@@ -83,10 +97,21 @@ module Tapyrus
|
|
83
97
|
request.content_type = 'application/json'
|
84
98
|
request.body = data.to_json
|
85
99
|
response = http.request(request)
|
86
|
-
raise
|
100
|
+
raise error!(response) unless response.is_a? Net::HTTPOK
|
87
101
|
response = Tapyrus::RPC.response_body2json(response.body)
|
88
102
|
response['result']
|
89
103
|
end
|
104
|
+
|
105
|
+
def error!(response)
|
106
|
+
rpc_error =
|
107
|
+
begin
|
108
|
+
Tapyrus::RPC.response_body2json(response.body)['error']
|
109
|
+
rescue JSON::ParserError => _
|
110
|
+
# if RPC server don't send error message.
|
111
|
+
end
|
112
|
+
|
113
|
+
raise Error.new(response.code, response.msg, rpc_error)
|
114
|
+
end
|
90
115
|
end
|
91
116
|
|
92
117
|
def response_body2json(body)
|
data/lib/tapyrus/rpc.rb
CHANGED
@@ -281,10 +281,12 @@ module Tapyrus
|
|
281
281
|
# get public keys in the stack.
|
282
282
|
# @return[Array[String]] an array of the pubkeys with hex format.
|
283
283
|
def get_pubkeys
|
284
|
-
chunks
|
285
|
-
|
286
|
-
|
287
|
-
|
284
|
+
chunks
|
285
|
+
.select do |c|
|
286
|
+
c.pushdata? && [33, 65].include?(c.pushed_data.bytesize) &&
|
287
|
+
[2, 3, 4, 6, 7].include?(c.pushed_data[0].bth.to_i(16))
|
288
|
+
end
|
289
|
+
.map { |c| c.pushed_data.bth }
|
288
290
|
end
|
289
291
|
|
290
292
|
# returns the self payload. ScriptInterpreter does not use this.
|
@@ -349,30 +351,32 @@ module Tapyrus
|
|
349
351
|
end
|
350
352
|
|
351
353
|
def to_s
|
352
|
-
chunks
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
v
|
362
|
-
|
363
|
-
data = c.pushed_data
|
364
|
-
if data.bytesize <= 4
|
365
|
-
Script.decode_number(data.bth) # for scriptnum
|
354
|
+
chunks
|
355
|
+
.map do |c|
|
356
|
+
case c
|
357
|
+
when Integer
|
358
|
+
opcode_to_name(c)
|
359
|
+
when String
|
360
|
+
return c if c.empty?
|
361
|
+
if c.pushdata?
|
362
|
+
v = Opcodes.opcode_to_small_int(c.ord)
|
363
|
+
if v
|
364
|
+
v
|
366
365
|
else
|
367
|
-
data.
|
366
|
+
data = c.pushed_data
|
367
|
+
if data.bytesize <= 4
|
368
|
+
Script.decode_number(data.bth) # for scriptnum
|
369
|
+
else
|
370
|
+
data.bth
|
371
|
+
end
|
368
372
|
end
|
373
|
+
else
|
374
|
+
opcode = Opcodes.opcode_to_name(c.ord)
|
375
|
+
opcode ? opcode : 'OP_UNKNOWN [error]'
|
369
376
|
end
|
370
|
-
else
|
371
|
-
opcode = Opcodes.opcode_to_name(c.ord)
|
372
|
-
opcode ? opcode : 'OP_UNKNOWN [error]'
|
373
377
|
end
|
374
378
|
end
|
375
|
-
|
379
|
+
.join(' ')
|
376
380
|
end
|
377
381
|
|
378
382
|
# generate sha-256 hash for payload
|
data/lib/tapyrus/slip39/sss.rb
CHANGED
@@ -190,9 +190,15 @@ module Tapyrus
|
|
190
190
|
shares.each do |share|
|
191
191
|
log_basis_eval = (log_prod - LOG_TABLE[share[0] ^ x] - shares.sum { |s| LOG_TABLE[share[0] ^ s[0]] }) % 255
|
192
192
|
result =
|
193
|
-
share[1]
|
194
|
-
|
195
|
-
|
193
|
+
share[1]
|
194
|
+
.htb
|
195
|
+
.bytes
|
196
|
+
.each
|
197
|
+
.map
|
198
|
+
.with_index do |v, i|
|
199
|
+
(result[i].bti ^ (v == 0 ? 0 : (EXP_TABLE[(LOG_TABLE[v] + log_basis_eval) % 255]))).itb
|
200
|
+
end
|
201
|
+
.join
|
196
202
|
end
|
197
203
|
result.bth
|
198
204
|
end
|
@@ -206,14 +212,10 @@ module Tapyrus
|
|
206
212
|
l, r = ems[0...(ems.length / 2)].htb, ems[(ems.length / 2)..-1].htb
|
207
213
|
salt = get_salt(id)
|
208
214
|
e = (Tapyrus::SLIP39::BASE_ITERATION_COUNT << exp) / Tapyrus::SLIP39::ROUND_COUNT
|
209
|
-
Tapyrus::SLIP39::ROUND_COUNT
|
210
|
-
.
|
211
|
-
.
|
212
|
-
|
213
|
-
.each do |i|
|
214
|
-
f = OpenSSL::PKCS5.pbkdf2_hmac((i.itb + passphrase), salt + r, e, r.bytesize, 'sha256')
|
215
|
-
l, r = padding_zero(r, r.bytesize), padding_zero((l.bti ^ f.bti).itb, r.bytesize)
|
216
|
-
end
|
215
|
+
Tapyrus::SLIP39::ROUND_COUNT.times.to_a.reverse.each do |i|
|
216
|
+
f = OpenSSL::PKCS5.pbkdf2_hmac((i.itb + passphrase), salt + r, e, r.bytesize, 'sha256')
|
217
|
+
l, r = padding_zero(r, r.bytesize), padding_zero((l.bti ^ f.bti).itb, r.bytesize)
|
218
|
+
end
|
217
219
|
(r + l).bth
|
218
220
|
end
|
219
221
|
|
@@ -228,13 +230,10 @@ module Tapyrus
|
|
228
230
|
l, r = s[0...(s.bytesize / 2)], s[(s.bytesize / 2)..-1]
|
229
231
|
salt = get_salt(id)
|
230
232
|
e = (Tapyrus::SLIP39::BASE_ITERATION_COUNT << exp) / Tapyrus::SLIP39::ROUND_COUNT
|
231
|
-
Tapyrus::SLIP39::ROUND_COUNT
|
232
|
-
.
|
233
|
-
.
|
234
|
-
|
235
|
-
f = OpenSSL::PKCS5.pbkdf2_hmac((i.itb + passphrase), salt + r, e, r.bytesize, 'sha256')
|
236
|
-
l, r = padding_zero(r, r.bytesize), padding_zero((l.bti ^ f.bti).itb, r.bytesize)
|
237
|
-
end
|
233
|
+
Tapyrus::SLIP39::ROUND_COUNT.times.to_a.each do |i|
|
234
|
+
f = OpenSSL::PKCS5.pbkdf2_hmac((i.itb + passphrase), salt + r, e, r.bytesize, 'sha256')
|
235
|
+
l, r = padding_zero(r, r.bytesize), padding_zero((l.bti ^ f.bti).itb, r.bytesize)
|
236
|
+
end
|
238
237
|
(r + l).bth
|
239
238
|
end
|
240
239
|
|
data/lib/tapyrus/tx_builder.rb
CHANGED
data/lib/tapyrus/version.rb
CHANGED
data/lib/tapyrus.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tapyrus
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.13
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- azuchi
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-02-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ecdsa
|
@@ -306,9 +306,11 @@ files:
|
|
306
306
|
- lib/openassets/payload.rb
|
307
307
|
- lib/openassets/util.rb
|
308
308
|
- lib/schnorr.rb
|
309
|
+
- lib/schnorr/sign_to_contract.rb
|
309
310
|
- lib/schnorr/signature.rb
|
310
311
|
- lib/tapyrus.rb
|
311
312
|
- lib/tapyrus/base58.rb
|
313
|
+
- lib/tapyrus/bip175.rb
|
312
314
|
- lib/tapyrus/block.rb
|
313
315
|
- lib/tapyrus/block_header.rb
|
314
316
|
- lib/tapyrus/bloom_filter.rb
|
@@ -423,7 +425,7 @@ homepage: https://github.com/chaintope/tapyrusrb
|
|
423
425
|
licenses:
|
424
426
|
- MIT
|
425
427
|
metadata: {}
|
426
|
-
post_install_message:
|
428
|
+
post_install_message:
|
427
429
|
rdoc_options: []
|
428
430
|
require_paths:
|
429
431
|
- lib
|
@@ -438,8 +440,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
438
440
|
- !ruby/object:Gem::Version
|
439
441
|
version: '0'
|
440
442
|
requirements: []
|
441
|
-
rubygems_version: 3.
|
442
|
-
signing_key:
|
443
|
+
rubygems_version: 3.2.22
|
444
|
+
signing_key:
|
443
445
|
specification_version: 4
|
444
446
|
summary: The implementation of Tapyrus Protocol for Ruby.
|
445
447
|
test_files: []
|