mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-12-18 20:38:10 +00:00
feat(core): Support ownership proofs for Taproot addresses.
This commit is contained in:
parent
b0f2d43884
commit
ef5994d9f3
1
core/.changelog.d/1944.added
Normal file
1
core/.changelog.d/1944.added
Normal file
@ -0,0 +1 @@
|
|||||||
|
Support ownership proofs for Taproot addresses.
|
@ -56,6 +56,8 @@ def generate_proof(
|
|||||||
InputScriptType.SPENDP2SHWITNESS,
|
InputScriptType.SPENDP2SHWITNESS,
|
||||||
):
|
):
|
||||||
signature = common.ecdsa_sign(node, sighash.digest())
|
signature = common.ecdsa_sign(node, sighash.digest())
|
||||||
|
elif script_type == InputScriptType.SPENDTAPROOT:
|
||||||
|
signature = common.bip340_sign(node, sighash.digest())
|
||||||
else:
|
else:
|
||||||
raise wire.DataError("Unsupported script type.")
|
raise wire.DataError("Unsupported script type.")
|
||||||
public_key = node.public_key()
|
public_key = node.public_key()
|
||||||
|
@ -609,7 +609,9 @@ def write_bip322_signature_proof(
|
|||||||
w, script_type, multisig, coin, SigHashType.SIGHASH_ALL, public_key, signature
|
w, script_type, multisig, coin, SigHashType.SIGHASH_ALL, public_key, signature
|
||||||
)
|
)
|
||||||
|
|
||||||
if script_type in common.SEGWIT_INPUT_SCRIPT_TYPES:
|
if script_type == InputScriptType.SPENDTAPROOT:
|
||||||
|
write_witness_p2tr(w, signature, SigHashType.SIGHASH_ALL_TAPROOT)
|
||||||
|
elif script_type in common.SEGWIT_INPUT_SCRIPT_TYPES:
|
||||||
if multisig:
|
if multisig:
|
||||||
# find the place of our signature based on the public key
|
# find the place of our signature based on the public key
|
||||||
signature_index = multisig_pubkey_index(multisig, public_key)
|
signature_index = multisig_pubkey_index(multisig, public_key)
|
||||||
|
@ -8,7 +8,7 @@ from apps.common import coins
|
|||||||
from apps.common.keychain import Keychain
|
from apps.common.keychain import Keychain
|
||||||
from apps.common.paths import HARDENED, AlwaysMatchingSchema
|
from apps.common.paths import HARDENED, AlwaysMatchingSchema
|
||||||
from apps.bitcoin import ownership, scripts
|
from apps.bitcoin import ownership, scripts
|
||||||
from apps.bitcoin.addresses import address_p2wpkh, address_p2wpkh_in_p2sh, address_multisig_p2wsh, address_multisig_p2wsh_in_p2sh, address_multisig_p2sh
|
from apps.bitcoin.addresses import address_p2tr, address_p2wpkh, address_p2wpkh_in_p2sh, address_multisig_p2wsh, address_multisig_p2wsh_in_p2sh, address_multisig_p2sh
|
||||||
from apps.bitcoin.multisig import multisig_get_pubkeys
|
from apps.bitcoin.multisig import multisig_get_pubkeys
|
||||||
|
|
||||||
|
|
||||||
@ -67,6 +67,32 @@ class TestOwnershipProof(unittest.TestCase):
|
|||||||
self.assertEqual(proof, unhexlify("534c0019000192caf0b8daf78f1d388dbbceaec34bd2dabc31b217e32343663667f6694a3f4617160014e0cffbee1925a411844f44c3b8d81365ab51d03602483045022100a37330dca699725db613dd1b30059843d1248340642162a0adef114509c9849402201126c9044b998065d40b44fd2399b52c409794bbc3bfdd358cd5fb450c94316d012103a961687895a78da9aef98eed8e1f2a3e91cfb69d2f3cf11cbd0bb1773d951928"))
|
self.assertEqual(proof, unhexlify("534c0019000192caf0b8daf78f1d388dbbceaec34bd2dabc31b217e32343663667f6694a3f4617160014e0cffbee1925a411844f44c3b8d81365ab51d03602483045022100a37330dca699725db613dd1b30059843d1248340642162a0adef114509c9849402201126c9044b998065d40b44fd2399b52c409794bbc3bfdd358cd5fb450c94316d012103a961687895a78da9aef98eed8e1f2a3e91cfb69d2f3cf11cbd0bb1773d951928"))
|
||||||
self.assertFalse(ownership.verify_nonownership(proof, script_pubkey, commitment_data, keychain, coin))
|
self.assertFalse(ownership.verify_nonownership(proof, script_pubkey, commitment_data, keychain, coin))
|
||||||
|
|
||||||
|
def test_p2tr_gen_proof(self):
|
||||||
|
coin = coins.by_name('Bitcoin')
|
||||||
|
seed = bip39.seed(' '.join(['all'] * 12), '')
|
||||||
|
keychain = Keychain(seed, coin.curve_name, [AlwaysMatchingSchema], slip21_namespaces=[[b"SLIP-0019"]])
|
||||||
|
commitment_data = b""
|
||||||
|
|
||||||
|
node = keychain.derive([86 | HARDENED, 0 | HARDENED, 0 | HARDENED, 1, 0])
|
||||||
|
address = address_p2tr(node.public_key(), coin)
|
||||||
|
script_pubkey = scripts.output_derive_script(address, coin)
|
||||||
|
ownership_id = ownership.get_identifier(script_pubkey, keychain)
|
||||||
|
self.assertEqual(ownership_id, unhexlify("dc18066224b9e30e306303436dc18ab881c7266c13790350a3fe415e438135ec"))
|
||||||
|
|
||||||
|
proof, signature = ownership.generate_proof(
|
||||||
|
node=node,
|
||||||
|
script_type=InputScriptType.SPENDTAPROOT,
|
||||||
|
multisig=None,
|
||||||
|
coin=coin,
|
||||||
|
user_confirmed=False,
|
||||||
|
ownership_ids=[ownership_id],
|
||||||
|
script_pubkey=script_pubkey,
|
||||||
|
commitment_data=commitment_data,
|
||||||
|
)
|
||||||
|
self.assertEqual(signature, unhexlify("6cd08474ea019c9ab4b9b7b76ec03c4dd4db76abc3a460434a91cfc1b190174949eb7111c8e762407730a215421a0da0b5e01f48de62d7ccea0abea046e2a496"))
|
||||||
|
self.assertEqual(proof, unhexlify("534c00190001dc18066224b9e30e306303436dc18ab881c7266c13790350a3fe415e438135ec0001406cd08474ea019c9ab4b9b7b76ec03c4dd4db76abc3a460434a91cfc1b190174949eb7111c8e762407730a215421a0da0b5e01f48de62d7ccea0abea046e2a496"))
|
||||||
|
self.assertFalse(ownership.verify_nonownership(proof, script_pubkey, commitment_data, keychain, coin))
|
||||||
|
|
||||||
def test_p2pkh_gen_proof(self):
|
def test_p2pkh_gen_proof(self):
|
||||||
coin = coins.by_name('Bitcoin')
|
coin = coins.by_name('Bitcoin')
|
||||||
seed = bip39.seed(' '.join(['all'] * 12), 'TREZOR')
|
seed = bip39.seed(' '.join(['all'] * 12), 'TREZOR')
|
||||||
@ -104,6 +130,17 @@ class TestOwnershipProof(unittest.TestCase):
|
|||||||
proof = unhexlify("534c00190001a122407efc198211c81af4450f40b235d54775efd934d16b9e31c6ce9bad57070002483045022100e5eaf2cb0a473b4545115c7b85323809e75cb106175ace38129fd62323d73df30220363dbc7acb7afcda022b1f8d97acb8f47c42043cfe0595583aa26e30bc8b3bb50121032ef68318c8f6aaa0adec0199c69901f0db7d3485eb38d9ad235221dc3d61154b")
|
proof = unhexlify("534c00190001a122407efc198211c81af4450f40b235d54775efd934d16b9e31c6ce9bad57070002483045022100e5eaf2cb0a473b4545115c7b85323809e75cb106175ace38129fd62323d73df30220363dbc7acb7afcda022b1f8d97acb8f47c42043cfe0595583aa26e30bc8b3bb50121032ef68318c8f6aaa0adec0199c69901f0db7d3485eb38d9ad235221dc3d61154b")
|
||||||
self.assertTrue(ownership.verify_nonownership(proof, script_pubkey, commitment_data, keychain, coin))
|
self.assertTrue(ownership.verify_nonownership(proof, script_pubkey, commitment_data, keychain, coin))
|
||||||
|
|
||||||
|
def test_p2tr_verify_proof(self):
|
||||||
|
coin = coins.by_name('Bitcoin')
|
||||||
|
seed = bip39.seed(' '.join(['all'] * 12), 'TREZOR')
|
||||||
|
keychain = Keychain(seed, coin.curve_name, [AlwaysMatchingSchema], slip21_namespaces=[[b"SLIP-0019"]])
|
||||||
|
commitment_data = b""
|
||||||
|
|
||||||
|
# Proof for "all all ... all" seed without passphrase.
|
||||||
|
script_pubkey = unhexlify("51204102897557de0cafea0a8401ea5b59668eccb753e4b100aebe6a19609f3cc79f")
|
||||||
|
proof = unhexlify("534c00190001dc18066224b9e30e306303436dc18ab881c7266c13790350a3fe415e438135ec0001406cd08474ea019c9ab4b9b7b76ec03c4dd4db76abc3a460434a91cfc1b190174949eb7111c8e762407730a215421a0da0b5e01f48de62d7ccea0abea046e2a496")
|
||||||
|
self.assertTrue(ownership.verify_nonownership(proof, script_pubkey, commitment_data, keychain, coin))
|
||||||
|
|
||||||
def test_p2wsh_gen_proof(self):
|
def test_p2wsh_gen_proof(self):
|
||||||
coin = coins.by_name('Bitcoin')
|
coin = coins.by_name('Bitcoin')
|
||||||
seed = bip39.seed(' '.join(['all'] * 12), '')
|
seed = bip39.seed(' '.join(['all'] * 12), '')
|
||||||
|
Loading…
Reference in New Issue
Block a user