mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-11-30 11:28:21 +00:00
303 lines
11 KiB
Python
303 lines
11 KiB
Python
from common import *
|
|
from trezor import wire
|
|
from trezor.crypto import cardano
|
|
from trezor.enums import CardanoNativeScriptType
|
|
from trezor.messages import CardanoNativeScript
|
|
|
|
if not utils.BITCOIN_ONLY:
|
|
from apps.cardano.seed import Keychain
|
|
from apps.cardano.native_script import get_native_script_hash, validate_native_script
|
|
|
|
VALID_NATIVE_SCRIPTS = [
|
|
# PUB_KEY
|
|
[
|
|
CardanoNativeScript(
|
|
type=CardanoNativeScriptType.PUB_KEY,
|
|
key_hash=unhexlify(
|
|
"c4b9265645fde9536c0795adbcc5291767a0c61fd62448341d7e0386"
|
|
),
|
|
),
|
|
b"29fb5fd4aa8cadd6705acc8263cee0fc62edca5ac38db593fec2f9fd",
|
|
],
|
|
# PUB_KEY with path
|
|
[
|
|
CardanoNativeScript(
|
|
type=CardanoNativeScriptType.PUB_KEY,
|
|
key_path=[1854 | HARDENED, 1815 | HARDENED, 0 | HARDENED, 0, 0],
|
|
),
|
|
b"29fb5fd4aa8cadd6705acc8263cee0fc62edca5ac38db593fec2f9fd",
|
|
],
|
|
# ALL
|
|
[
|
|
CardanoNativeScript(
|
|
type=CardanoNativeScriptType.ALL,
|
|
scripts=[
|
|
CardanoNativeScript(
|
|
type=CardanoNativeScriptType.PUB_KEY,
|
|
key_path=[1854 | HARDENED, 1815 | HARDENED, 0 | HARDENED, 0, 0],
|
|
),
|
|
CardanoNativeScript(
|
|
type=CardanoNativeScriptType.PUB_KEY,
|
|
key_hash=unhexlify(
|
|
"0241f2d196f52a92fbd2183d03b370c30b6960cfdeae364ffabac889"
|
|
),
|
|
),
|
|
],
|
|
),
|
|
b"af5c2ce476a6ede1c879f7b1909d6a0b96cb2081391712d4a355cef6",
|
|
],
|
|
# ALL with 1855 path
|
|
[
|
|
CardanoNativeScript(
|
|
type=CardanoNativeScriptType.ALL,
|
|
scripts=[
|
|
CardanoNativeScript(
|
|
type=CardanoNativeScriptType.PUB_KEY,
|
|
key_path=[1855 | HARDENED, 1815 | HARDENED, 0 | HARDENED],
|
|
),
|
|
CardanoNativeScript(
|
|
type=CardanoNativeScriptType.PUB_KEY,
|
|
key_hash=unhexlify(
|
|
"0241f2d196f52a92fbd2183d03b370c30b6960cfdeae364ffabac889"
|
|
),
|
|
),
|
|
],
|
|
),
|
|
b"fbf6672eb655c29b0f148fa1429be57c2174b067a7b3e3942e967fe8",
|
|
],
|
|
# ALL scripts are empty
|
|
[
|
|
CardanoNativeScript(type=CardanoNativeScriptType.ALL, scripts=[]),
|
|
b"d441227553a0f1a965fee7d60a0f724b368dd1bddbc208730fccebcf"
|
|
],
|
|
# ANY
|
|
[
|
|
CardanoNativeScript(
|
|
type=CardanoNativeScriptType.ANY,
|
|
scripts=[
|
|
CardanoNativeScript(
|
|
type=CardanoNativeScriptType.PUB_KEY,
|
|
key_path=[1854 | HARDENED, 1815 | HARDENED, 0 | HARDENED, 0, 0],
|
|
),
|
|
CardanoNativeScript(
|
|
type=CardanoNativeScriptType.PUB_KEY,
|
|
key_hash=unhexlify(
|
|
"0241f2d196f52a92fbd2183d03b370c30b6960cfdeae364ffabac889"
|
|
),
|
|
),
|
|
],
|
|
),
|
|
b"d6428ec36719146b7b5fb3a2d5322ce702d32762b8c7eeeb797a20db",
|
|
],
|
|
# ANY scripts are empty
|
|
[
|
|
CardanoNativeScript(type=CardanoNativeScriptType.ANY, scripts=[]),
|
|
b"52dc3d43b6d2465e96109ce75ab61abe5e9c1d8a3c9ce6ff8a3af528"
|
|
],
|
|
# N OF K
|
|
[
|
|
CardanoNativeScript(
|
|
type=CardanoNativeScriptType.N_OF_K,
|
|
required_signatures_count=2,
|
|
scripts=[
|
|
CardanoNativeScript(
|
|
type=CardanoNativeScriptType.PUB_KEY,
|
|
key_path=[1854 | HARDENED, 1815 | HARDENED, 0 | HARDENED, 0, 0],
|
|
),
|
|
CardanoNativeScript(
|
|
type=CardanoNativeScriptType.PUB_KEY,
|
|
key_hash=unhexlify(
|
|
"0241f2d196f52a92fbd2183d03b370c30b6960cfdeae364ffabac889"
|
|
),
|
|
),
|
|
CardanoNativeScript(
|
|
type=CardanoNativeScriptType.PUB_KEY,
|
|
key_hash=unhexlify(
|
|
"cecb1d427c4ae436d28cc0f8ae9bb37501a5b77bcc64cd1693e9ae20"
|
|
),
|
|
),
|
|
],
|
|
),
|
|
b"2b2b17fd18e18acae4601d4818a1dee00a917ff72e772fa8482e36c9",
|
|
],
|
|
# N_OF_K scripts are empty
|
|
[
|
|
CardanoNativeScript(type=CardanoNativeScriptType.N_OF_K, required_signatures_count=0, scripts=[]),
|
|
b"3530cc9ae7f2895111a99b7a02184dd7c0cea7424f1632d73951b1d7"
|
|
],
|
|
# INVALID BEFORE
|
|
[
|
|
CardanoNativeScript(
|
|
type=CardanoNativeScriptType.ALL,
|
|
scripts=[
|
|
CardanoNativeScript(
|
|
type=CardanoNativeScriptType.PUB_KEY,
|
|
key_hash=unhexlify(
|
|
"c4b9265645fde9536c0795adbcc5291767a0c61fd62448341d7e0386"
|
|
),
|
|
),
|
|
CardanoNativeScript(
|
|
type=CardanoNativeScriptType.INVALID_BEFORE, invalid_before=100
|
|
),
|
|
],
|
|
),
|
|
b"c6262ef9bb2b1291c058d93b46dabf458e2d135f803f60713f84b0b7",
|
|
],
|
|
# INVALID HEREAFTER
|
|
[
|
|
CardanoNativeScript(
|
|
type=CardanoNativeScriptType.ALL,
|
|
scripts=[
|
|
CardanoNativeScript(
|
|
type=CardanoNativeScriptType.PUB_KEY,
|
|
key_hash=unhexlify(
|
|
"c4b9265645fde9536c0795adbcc5291767a0c61fd62448341d7e0386"
|
|
),
|
|
),
|
|
CardanoNativeScript(
|
|
type=CardanoNativeScriptType.INVALID_HEREAFTER,
|
|
invalid_hereafter=200,
|
|
),
|
|
],
|
|
),
|
|
b"b12ac304f89f4cd4d23f59a2b90d2b2697f7540b8f470d6aa05851b5",
|
|
],
|
|
# NESTED SCRIPT
|
|
[
|
|
CardanoNativeScript(
|
|
type=CardanoNativeScriptType.ALL,
|
|
scripts=[
|
|
CardanoNativeScript(
|
|
type=CardanoNativeScriptType.PUB_KEY,
|
|
key_hash=unhexlify(
|
|
"c4b9265645fde9536c0795adbcc5291767a0c61fd62448341d7e0386"
|
|
),
|
|
),
|
|
CardanoNativeScript(
|
|
type=CardanoNativeScriptType.PUB_KEY,
|
|
key_path=[1854 | HARDENED, 1815 | HARDENED, 0 | HARDENED, 0, 0],
|
|
),
|
|
CardanoNativeScript(
|
|
type=CardanoNativeScriptType.ANY,
|
|
scripts=[
|
|
CardanoNativeScript(
|
|
type=CardanoNativeScriptType.PUB_KEY,
|
|
key_path=[1854 | HARDENED, 1815 | HARDENED, 0 | HARDENED, 0, 0],
|
|
),
|
|
CardanoNativeScript(
|
|
type=CardanoNativeScriptType.PUB_KEY,
|
|
key_hash=unhexlify(
|
|
"0241f2d196f52a92fbd2183d03b370c30b6960cfdeae364ffabac889"
|
|
),
|
|
),
|
|
],
|
|
),
|
|
CardanoNativeScript(
|
|
type=CardanoNativeScriptType.N_OF_K,
|
|
required_signatures_count=2,
|
|
scripts=[
|
|
CardanoNativeScript(
|
|
type=CardanoNativeScriptType.PUB_KEY,
|
|
key_path=[1854 | HARDENED, 1815 | HARDENED, 0 | HARDENED, 0, 0],
|
|
),
|
|
CardanoNativeScript(
|
|
type=CardanoNativeScriptType.PUB_KEY,
|
|
key_hash=unhexlify(
|
|
"0241f2d196f52a92fbd2183d03b370c30b6960cfdeae364ffabac889"
|
|
),
|
|
),
|
|
CardanoNativeScript(
|
|
type=CardanoNativeScriptType.PUB_KEY,
|
|
key_hash=unhexlify(
|
|
"cecb1d427c4ae436d28cc0f8ae9bb37501a5b77bcc64cd1693e9ae20"
|
|
),
|
|
),
|
|
],
|
|
),
|
|
CardanoNativeScript(
|
|
type=CardanoNativeScriptType.INVALID_BEFORE, invalid_before=100
|
|
),
|
|
CardanoNativeScript(
|
|
type=CardanoNativeScriptType.INVALID_HEREAFTER,
|
|
invalid_hereafter=200,
|
|
),
|
|
],
|
|
),
|
|
b"4a6b4288459bf34668c0b281f922691460caf0c7c09caee3a726c27a",
|
|
],
|
|
]
|
|
|
|
INVALID_SCRIPTS = [
|
|
# PUB_KEY key_hash has invalid length
|
|
CardanoNativeScript(
|
|
type=CardanoNativeScriptType.PUB_KEY,
|
|
key_hash=unhexlify("3a55d9f68255dfbefa1efd711f82d005fae1be2e145d616c90cf0f"),
|
|
),
|
|
# PUB_KEY key_path is not multisig or mint
|
|
CardanoNativeScript(
|
|
type=CardanoNativeScriptType.PUB_KEY,
|
|
key_path=[1852 | HARDENED, 1815 | HARDENED, 0 | HARDENED, 0, 0],
|
|
),
|
|
# PUB_KEY mint key_path is too long
|
|
CardanoNativeScript(
|
|
type=CardanoNativeScriptType.PUB_KEY,
|
|
key_path=[1855 | HARDENED, 1815 | HARDENED, 0 | HARDENED, 0],
|
|
),
|
|
# N_OF_K required_signatures_count is not set
|
|
CardanoNativeScript(
|
|
type=CardanoNativeScriptType.N_OF_K,
|
|
scripts=[
|
|
CardanoNativeScript(
|
|
type=CardanoNativeScriptType.PUB_KEY,
|
|
key_hash=unhexlify(
|
|
"3a55d9f68255dfbefa1efd711f82d005fae1be2e145d616c90cf0fa9"
|
|
),
|
|
),
|
|
],
|
|
),
|
|
# N_OF_K N is larger than K
|
|
CardanoNativeScript(
|
|
type=CardanoNativeScriptType.N_OF_K,
|
|
required_signatures_count=2,
|
|
scripts=[
|
|
CardanoNativeScript(
|
|
type=CardanoNativeScriptType.PUB_KEY,
|
|
key_hash=unhexlify(
|
|
"3a55d9f68255dfbefa1efd711f82d005fae1be2e145d616c90cf0fa9"
|
|
),
|
|
),
|
|
],
|
|
),
|
|
# INVALID_BEFORE invalid_before is not set
|
|
CardanoNativeScript(type=CardanoNativeScriptType.INVALID_BEFORE),
|
|
# INVALID_HEREAFTER invalid_hereafter is not set
|
|
CardanoNativeScript(type=CardanoNativeScriptType.INVALID_HEREAFTER),
|
|
]
|
|
|
|
|
|
@unittest.skipUnless(not utils.BITCOIN_ONLY, "altcoin")
|
|
class TestCardanoNativeScript(unittest.TestCase):
|
|
def test_get_native_script_hash(self):
|
|
mnemonic = "all all all all all all all all all all all all"
|
|
passphrase = ""
|
|
secret = cardano.derive_icarus(mnemonic, passphrase, False)
|
|
node = cardano.from_secret(secret)
|
|
keychain = Keychain(node)
|
|
|
|
for script, expected_hash in VALID_NATIVE_SCRIPTS:
|
|
actual_hash = get_native_script_hash(keychain, script)
|
|
self.assertEqual(hexlify(actual_hash), expected_hash)
|
|
|
|
def test_validate_native_script(self):
|
|
for script, _ in VALID_NATIVE_SCRIPTS:
|
|
validate_native_script(script)
|
|
|
|
def test_validate_native_script_invalid(self):
|
|
for script in INVALID_SCRIPTS:
|
|
with self.assertRaises(wire.ProcessError):
|
|
validate_native_script(script)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|