parent
54909681a8
commit
dd9652cd07
@ -0,0 +1,321 @@
|
||||
{
|
||||
"setup": {
|
||||
"mnemonic": "all all all all all all all all all all all all",
|
||||
"passphrase": ""
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "PUB_KEY script",
|
||||
"parameters": {
|
||||
"type": 0,
|
||||
"key_hash": "c4b9265645fde9536c0795adbcc5291767a0c61fd62448341d7e0386"
|
||||
},
|
||||
"result": {
|
||||
"expected_hash": "29fb5fd4aa8cadd6705acc8263cee0fc62edca5ac38db593fec2f9fd"
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "PUB_KEY script containing a path",
|
||||
"parameters": {
|
||||
"type": 0,
|
||||
"key_path": "m/1854'/1815'/0'/0/0"
|
||||
},
|
||||
"result": {
|
||||
"expected_hash": "29fb5fd4aa8cadd6705acc8263cee0fc62edca5ac38db593fec2f9fd"
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "ALL script",
|
||||
"parameters": {
|
||||
"type": 1,
|
||||
"scripts": [
|
||||
{
|
||||
"type": 0,
|
||||
"key_hash": "c4b9265645fde9536c0795adbcc5291767a0c61fd62448341d7e0386"
|
||||
},
|
||||
{
|
||||
"type": 0,
|
||||
"key_hash": "0241f2d196f52a92fbd2183d03b370c30b6960cfdeae364ffabac889"
|
||||
}
|
||||
]
|
||||
},
|
||||
"result": {
|
||||
"expected_hash": "af5c2ce476a6ede1c879f7b1909d6a0b96cb2081391712d4a355cef6"
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "ALL script containing a path",
|
||||
"parameters": {
|
||||
"type": 1,
|
||||
"scripts": [
|
||||
{
|
||||
"type": 0,
|
||||
"key_path": "m/1854'/1815'/0'/0/0"
|
||||
},
|
||||
{
|
||||
"type": 0,
|
||||
"key_hash": "0241f2d196f52a92fbd2183d03b370c30b6960cfdeae364ffabac889"
|
||||
}
|
||||
]
|
||||
},
|
||||
"result": {
|
||||
"expected_hash": "af5c2ce476a6ede1c879f7b1909d6a0b96cb2081391712d4a355cef6"
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "ALL script containing a 1855 path",
|
||||
"parameters": {
|
||||
"type": 1,
|
||||
"scripts": [
|
||||
{
|
||||
"type": 0,
|
||||
"key_path": "m/1855'/1815'/0'"
|
||||
},
|
||||
{
|
||||
"type": 0,
|
||||
"key_hash": "0241f2d196f52a92fbd2183d03b370c30b6960cfdeae364ffabac889"
|
||||
}
|
||||
]
|
||||
},
|
||||
"result": {
|
||||
"expected_hash": "fbf6672eb655c29b0f148fa1429be57c2174b067a7b3e3942e967fe8"
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "ANY script",
|
||||
"parameters": {
|
||||
"type": 2,
|
||||
"scripts": [
|
||||
{
|
||||
"type": 0,
|
||||
"key_hash": "c4b9265645fde9536c0795adbcc5291767a0c61fd62448341d7e0386"
|
||||
},
|
||||
{
|
||||
"type": 0,
|
||||
"key_hash": "0241f2d196f52a92fbd2183d03b370c30b6960cfdeae364ffabac889"
|
||||
}
|
||||
]
|
||||
},
|
||||
"result": {
|
||||
"expected_hash": "d6428ec36719146b7b5fb3a2d5322ce702d32762b8c7eeeb797a20db"
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "ANY script with a nested script containing a path",
|
||||
"parameters": {
|
||||
"type": 2,
|
||||
"scripts": [
|
||||
{
|
||||
"type": 0,
|
||||
"key_path": "m/1854'/1815'/0'/0/0"
|
||||
},
|
||||
{
|
||||
"type": 0,
|
||||
"key_hash": "0241f2d196f52a92fbd2183d03b370c30b6960cfdeae364ffabac889"
|
||||
}
|
||||
]
|
||||
},
|
||||
"result": {
|
||||
"expected_hash": "d6428ec36719146b7b5fb3a2d5322ce702d32762b8c7eeeb797a20db"
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "N_OF_K script",
|
||||
"parameters": {
|
||||
"type": 3,
|
||||
"required_signatures_count": 2,
|
||||
"scripts": [
|
||||
{
|
||||
"type": 0,
|
||||
"key_hash": "c4b9265645fde9536c0795adbcc5291767a0c61fd62448341d7e0386"
|
||||
},
|
||||
{
|
||||
"type": 0,
|
||||
"key_hash": "0241f2d196f52a92fbd2183d03b370c30b6960cfdeae364ffabac889"
|
||||
},
|
||||
{
|
||||
"type": 0,
|
||||
"key_hash": "cecb1d427c4ae436d28cc0f8ae9bb37501a5b77bcc64cd1693e9ae20"
|
||||
}
|
||||
]
|
||||
},
|
||||
"result": {
|
||||
"expected_hash": "2b2b17fd18e18acae4601d4818a1dee00a917ff72e772fa8482e36c9"
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "N_OF_K script containing a path",
|
||||
"parameters": {
|
||||
"type": 3,
|
||||
"required_signatures_count": 2,
|
||||
"scripts": [
|
||||
{
|
||||
"type": 0,
|
||||
"key_path": "m/1854'/1815'/0'/0/0"
|
||||
},
|
||||
{
|
||||
"type": 0,
|
||||
"key_hash": "0241f2d196f52a92fbd2183d03b370c30b6960cfdeae364ffabac889"
|
||||
},
|
||||
{
|
||||
"type": 0,
|
||||
"key_hash": "cecb1d427c4ae436d28cc0f8ae9bb37501a5b77bcc64cd1693e9ae20"
|
||||
}
|
||||
]
|
||||
},
|
||||
"result": {
|
||||
"expected_hash": "2b2b17fd18e18acae4601d4818a1dee00a917ff72e772fa8482e36c9"
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "INVALID_BEFORE script",
|
||||
"parameters": {
|
||||
"type": 1,
|
||||
"scripts": [
|
||||
{
|
||||
"type": 0,
|
||||
"key_hash": "c4b9265645fde9536c0795adbcc5291767a0c61fd62448341d7e0386"
|
||||
},
|
||||
{
|
||||
"type": 4,
|
||||
"invalid_before": 100
|
||||
}
|
||||
]
|
||||
},
|
||||
"result": {
|
||||
"expected_hash": "c6262ef9bb2b1291c058d93b46dabf458e2d135f803f60713f84b0b7"
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "INVALID_HEREAFTER script",
|
||||
"parameters": {
|
||||
"type": 1,
|
||||
"scripts": [
|
||||
{
|
||||
"type": 0,
|
||||
"key_hash": "c4b9265645fde9536c0795adbcc5291767a0c61fd62448341d7e0386"
|
||||
},
|
||||
{
|
||||
"type": 5,
|
||||
"invalid_hereafter": 200
|
||||
}
|
||||
]
|
||||
},
|
||||
"result": {
|
||||
"expected_hash": "b12ac304f89f4cd4d23f59a2b90d2b2697f7540b8f470d6aa05851b5"
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "Nested script",
|
||||
"parameters": {
|
||||
"type": 1,
|
||||
"scripts": [
|
||||
{
|
||||
"type": 0,
|
||||
"key_hash": "c4b9265645fde9536c0795adbcc5291767a0c61fd62448341d7e0386"
|
||||
},
|
||||
{
|
||||
"type": 0,
|
||||
"key_path": "m/1854'/1815'/0'/0/0"
|
||||
},
|
||||
{
|
||||
"type": 2,
|
||||
"scripts": [
|
||||
{
|
||||
"type": 0,
|
||||
"key_path": "m/1854'/1815'/0'/0/0"
|
||||
},
|
||||
{
|
||||
"type": 0,
|
||||
"key_hash": "0241f2d196f52a92fbd2183d03b370c30b6960cfdeae364ffabac889"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": 3,
|
||||
"required_signatures_count": 2,
|
||||
"scripts": [
|
||||
{
|
||||
"type": 0,
|
||||
"key_path": "m/1854'/1815'/0'/0/0"
|
||||
},
|
||||
{
|
||||
"type": 0,
|
||||
"key_hash": "0241f2d196f52a92fbd2183d03b370c30b6960cfdeae364ffabac889"
|
||||
},
|
||||
{
|
||||
"type": 0,
|
||||
"key_hash": "cecb1d427c4ae436d28cc0f8ae9bb37501a5b77bcc64cd1693e9ae20"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": 4,
|
||||
"invalid_before": 100
|
||||
},
|
||||
{
|
||||
"type": 5,
|
||||
"invalid_hereafter": 200
|
||||
}
|
||||
]
|
||||
},
|
||||
"result": {
|
||||
"expected_hash": "4a6b4288459bf34668c0b281f922691460caf0c7c09caee3a726c27a"
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "Nested script without paths and shared with Ledger",
|
||||
"parameters": {
|
||||
"type": 1,
|
||||
"scripts": [
|
||||
{
|
||||
"type": 0,
|
||||
"key_hash": "c4b9265645fde9536c0795adbcc5291767a0c61fd62448341d7e0386"
|
||||
},
|
||||
{
|
||||
"type": 2,
|
||||
"scripts": [
|
||||
{
|
||||
"type": 0,
|
||||
"key_hash": "c4b9265645fde9536c0795adbcc5291767a0c61fd62448341d7e0386"
|
||||
},
|
||||
{
|
||||
"type": 0,
|
||||
"key_hash": "0241f2d196f52a92fbd2183d03b370c30b6960cfdeae364ffabac889"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": 3,
|
||||
"required_signatures_count": 2,
|
||||
"scripts": [
|
||||
{
|
||||
"type": 0,
|
||||
"key_hash": "c4b9265645fde9536c0795adbcc5291767a0c61fd62448341d7e0386"
|
||||
},
|
||||
{
|
||||
"type": 0,
|
||||
"key_hash": "0241f2d196f52a92fbd2183d03b370c30b6960cfdeae364ffabac889"
|
||||
},
|
||||
{
|
||||
"type": 0,
|
||||
"key_hash": "cecb1d427c4ae436d28cc0f8ae9bb37501a5b77bcc64cd1693e9ae20"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": 4,
|
||||
"invalid_before": 100
|
||||
},
|
||||
{
|
||||
"type": 5,
|
||||
"invalid_hereafter": 200
|
||||
}
|
||||
]
|
||||
},
|
||||
"result": {
|
||||
"expected_hash": "0d63e8d2c5a00cbcffbdf9112487c443466e1ea7d8c834df5ac5c425"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
from trezor import wire
|
||||
from trezor.enums import CardanoNativeScriptHashDisplayFormat
|
||||
from trezor.messages import CardanoNativeScriptHash
|
||||
|
||||
from . import native_script, seed
|
||||
from .layout import show_native_script, show_script_hash
|
||||
|
||||
if False:
|
||||
from trezor.messages import CardanoGetNativeScriptHash
|
||||
|
||||
|
||||
@seed.with_keychain
|
||||
async def get_native_script_hash(
|
||||
ctx: wire.Context, msg: CardanoGetNativeScriptHash, keychain: seed.Keychain
|
||||
) -> CardanoNativeScriptHash:
|
||||
native_script.validate_native_script(msg.script)
|
||||
|
||||
script_hash = native_script.get_native_script_hash(keychain, msg.script)
|
||||
|
||||
if msg.display_format != CardanoNativeScriptHashDisplayFormat.HIDE:
|
||||
await show_native_script(ctx, msg.script)
|
||||
await show_script_hash(ctx, script_hash, msg.display_format)
|
||||
|
||||
return CardanoNativeScriptHash(script_hash=script_hash)
|
@ -0,0 +1,171 @@
|
||||
from trezor.crypto import hashlib
|
||||
from trezor.enums import CardanoAddressType, CardanoNativeScriptType
|
||||
|
||||
from apps.cardano.helpers import (
|
||||
ADDRESS_KEY_HASH_SIZE,
|
||||
INVALID_NATIVE_SCRIPT,
|
||||
SCRIPT_HASH_SIZE,
|
||||
)
|
||||
from apps.common import cbor
|
||||
|
||||
from .helpers.paths import SCHEMA_MINT
|
||||
from .helpers.utils import get_public_key_hash
|
||||
from .seed import Keychain, is_multisig_path
|
||||
|
||||
if False:
|
||||
from typing import Any
|
||||
|
||||
from trezor.messages import CardanoNativeScript
|
||||
|
||||
from apps.common.cbor import CborSequence
|
||||
|
||||
SCRIPT_ADDRESS_TYPES = (
|
||||
CardanoAddressType.BASE_SCRIPT_KEY,
|
||||
CardanoAddressType.BASE_KEY_SCRIPT,
|
||||
CardanoAddressType.BASE_SCRIPT_SCRIPT,
|
||||
CardanoAddressType.POINTER_SCRIPT,
|
||||
CardanoAddressType.ENTERPRISE_SCRIPT,
|
||||
CardanoAddressType.REWARD_SCRIPT,
|
||||
)
|
||||
|
||||
|
||||
def validate_native_script(script: CardanoNativeScript | None) -> None:
|
||||
if not script:
|
||||
raise INVALID_NATIVE_SCRIPT
|
||||
|
||||
_validate_native_script_structure(script)
|
||||
|
||||
if script.type == CardanoNativeScriptType.PUB_KEY:
|
||||
if script.key_hash and script.key_path:
|
||||
raise INVALID_NATIVE_SCRIPT
|
||||
if script.key_hash:
|
||||
if len(script.key_hash) != ADDRESS_KEY_HASH_SIZE:
|
||||
raise INVALID_NATIVE_SCRIPT
|
||||
elif script.key_path:
|
||||
if not is_multisig_path(script.key_path) and not SCHEMA_MINT.match(
|
||||
script.key_path
|
||||
):
|
||||
raise INVALID_NATIVE_SCRIPT
|
||||
else:
|
||||
raise INVALID_NATIVE_SCRIPT
|
||||
elif script.type == CardanoNativeScriptType.ALL:
|
||||
for sub_script in script.scripts:
|
||||
validate_native_script(sub_script)
|
||||
elif script.type == CardanoNativeScriptType.ANY:
|
||||
for sub_script in script.scripts:
|
||||
validate_native_script(sub_script)
|
||||
elif script.type == CardanoNativeScriptType.N_OF_K:
|
||||
if script.required_signatures_count is None:
|
||||
raise INVALID_NATIVE_SCRIPT
|
||||
if script.required_signatures_count > len(script.scripts):
|
||||
raise INVALID_NATIVE_SCRIPT
|
||||
for sub_script in script.scripts:
|
||||
validate_native_script(sub_script)
|
||||
elif script.type == CardanoNativeScriptType.INVALID_BEFORE:
|
||||
if script.invalid_before is None:
|
||||
raise INVALID_NATIVE_SCRIPT
|
||||
elif script.type == CardanoNativeScriptType.INVALID_HEREAFTER:
|
||||
if script.invalid_hereafter is None:
|
||||
raise INVALID_NATIVE_SCRIPT
|
||||
|
||||
|
||||
def _validate_native_script_structure(script: CardanoNativeScript) -> None:
|
||||
key_hash = script.key_hash
|
||||
key_path = script.key_path
|
||||
scripts = script.scripts
|
||||
required_signatures_count = script.required_signatures_count
|
||||
invalid_before = script.invalid_before
|
||||
invalid_hereafter = script.invalid_hereafter
|
||||
|
||||
fields_to_be_empty: dict[CardanoNativeScriptType, tuple[Any, ...]] = {
|
||||
CardanoNativeScriptType.PUB_KEY: (
|
||||
scripts,
|
||||
required_signatures_count,
|
||||
invalid_before,
|
||||
invalid_hereafter,
|
||||
),
|
||||
CardanoNativeScriptType.ALL: (
|
||||
key_hash,
|
||||
key_path,
|
||||
required_signatures_count,
|
||||
invalid_before,
|
||||
invalid_hereafter,
|
||||
),
|
||||
CardanoNativeScriptType.ANY: (
|
||||
key_hash,
|
||||
key_path,
|
||||
required_signatures_count,
|
||||
invalid_before,
|
||||
invalid_hereafter,
|
||||
),
|
||||
CardanoNativeScriptType.N_OF_K: (
|
||||
key_hash,
|
||||
key_path,
|
||||
invalid_before,
|
||||
invalid_hereafter,
|
||||
),
|
||||
CardanoNativeScriptType.INVALID_BEFORE: (
|
||||
key_hash,
|
||||
key_path,
|
||||
required_signatures_count,
|
||||
invalid_hereafter,
|
||||
),
|
||||
CardanoNativeScriptType.INVALID_HEREAFTER: (
|
||||
key_hash,
|
||||
key_path,
|
||||
required_signatures_count,
|
||||
invalid_before,
|
||||
),
|
||||
}
|
||||
|
||||
if script.type not in fields_to_be_empty or any(fields_to_be_empty[script.type]):
|
||||
raise INVALID_NATIVE_SCRIPT
|
||||
|
||||
|
||||
def get_native_script_hash(keychain: Keychain, script: CardanoNativeScript) -> bytes:
|
||||
script_cbor = cbor.encode(cborize_native_script(keychain, script))
|
||||
prefixed_script_cbor = b"\00" + script_cbor
|
||||
return hashlib.blake2b(data=prefixed_script_cbor, outlen=SCRIPT_HASH_SIZE).digest()
|
||||
|
||||
|
||||
def cborize_native_script(
|
||||
keychain: Keychain, script: CardanoNativeScript
|
||||
) -> CborSequence:
|
||||
script_content: CborSequence
|
||||
if script.type == CardanoNativeScriptType.PUB_KEY:
|
||||
if script.key_hash:
|
||||
script_content = (script.key_hash,)
|
||||
elif script.key_path:
|
||||
script_content = (get_public_key_hash(keychain, script.key_path),)
|
||||
else:
|
||||
raise INVALID_NATIVE_SCRIPT
|
||||
elif script.type == CardanoNativeScriptType.ALL:
|
||||
script_content = (
|
||||
tuple(
|
||||
cborize_native_script(keychain, sub_script)
|
||||
for sub_script in script.scripts
|
||||
),
|
||||
)
|
||||
elif script.type == CardanoNativeScriptType.ANY:
|
||||
script_content = (
|
||||
tuple(
|
||||
cborize_native_script(keychain, sub_script)
|
||||
for sub_script in script.scripts
|
||||
),
|
||||
)
|
||||
elif script.type == CardanoNativeScriptType.N_OF_K:
|
||||
script_content = (
|
||||
script.required_signatures_count,
|
||||
tuple(
|
||||
cborize_native_script(keychain, sub_script)
|
||||
for sub_script in script.scripts
|
||||
),
|
||||
)
|
||||
elif script.type == CardanoNativeScriptType.INVALID_BEFORE:
|
||||
script_content = (script.invalid_before,)
|
||||
elif script.type == CardanoNativeScriptType.INVALID_HEREAFTER:
|
||||
script_content = (script.invalid_hereafter,)
|
||||
else:
|
||||
raise INVALID_NATIVE_SCRIPT
|
||||
|
||||
return (script.type,) + script_content
|
@ -0,0 +1,7 @@
|
||||
# Automatically generated by pb2py
|
||||
# fmt: off
|
||||
# isort:skip_file
|
||||
|
||||
HIDE = 0
|
||||
BECH32 = 1
|
||||
POLICY_ID = 2
|
@ -0,0 +1,10 @@
|
||||
# Automatically generated by pb2py
|
||||
# fmt: off
|
||||
# isort:skip_file
|
||||
|
||||
PUB_KEY = 0
|
||||
ALL = 1
|
||||
ANY = 2
|
||||
N_OF_K = 3
|
||||
INVALID_BEFORE = 4
|
||||
INVALID_HEREAFTER = 5
|
@ -0,0 +1,301 @@
|
||||
from common import *
|
||||
from trezor import wire
|
||||
from trezor.crypto import bip32
|
||||
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 = ""
|
||||
node = bip32.from_mnemonic_cardano(mnemonic, passphrase)
|
||||
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()
|
@ -0,0 +1,28 @@
|
||||
# This file is part of the Trezor project.
|
||||
#
|
||||
# Copyright (C) 2012-2019 SatoshiLabs and contributors
|
||||
#
|
||||
# This library is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License version 3
|
||||
# as published by the Free Software Foundation.
|
||||
#
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the License along with this library.
|
||||
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
|
||||
|
||||
from trezorlib.cardano import get_native_script_hash, parse_native_script
|
||||
|
||||
from ...common import parametrize_using_common_fixtures
|
||||
|
||||
|
||||
@parametrize_using_common_fixtures(
|
||||
"cardano/get_native_script_hash.json",
|
||||
)
|
||||
def test_cardano_get_native_script_hash(client, parameters, result):
|
||||
native_script = parse_native_script(parameters)
|
||||
native_script_hash = get_native_script_hash(client, native_script).script_hash
|
||||
assert native_script_hash.hex() == result["expected_hash"]
|
Loading…
Reference in new issue