1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-11-16 04:29:08 +00:00
trezor-firmware/src/apps/common/seed.py

89 lines
2.5 KiB
Python
Raw Normal View History

from trezor import wire
2018-02-27 15:35:21 +00:00
from trezor.crypto import bip32, bip39
2018-07-03 14:20:26 +00:00
2018-02-27 15:35:21 +00:00
from apps.common import cache, storage
from apps.common.request_passphrase import protect_by_passphrase
2018-11-14 18:58:07 +00:00
allow = list
2018-11-13 16:09:52 +00:00
class Keychain:
2018-11-14 18:58:07 +00:00
"""
Keychain provides an API for deriving HD keys from previously allowed
key-spaces.
"""
2018-11-13 16:09:52 +00:00
2018-11-14 18:58:07 +00:00
def __init__(self, paths: list, roots: list):
self.paths = paths
self.roots = roots
def derive(self, node_path: list, curve_name: str = "secp256k1") -> bip32.HDNode:
# find the root node
root_index = 0
for curve, *path in self.paths:
prefix = node_path[: len(path)]
suffix = node_path[len(path) :]
if curve == curve_name and path == prefix:
break
root_index += 1
else:
raise wire.DataError("Forbidden key path")
# derive child node from the root
node = self.roots[root_index].clone()
node.derive_path(suffix)
2018-11-13 16:09:52 +00:00
return node
2018-11-14 18:58:07 +00:00
async def get_keychain(ctx: wire.Context, paths: list = None) -> Keychain:
if not storage.is_initialized():
2018-07-03 14:20:58 +00:00
raise wire.ProcessError("Device is not initialized")
2018-11-13 16:09:52 +00:00
seed = cache.get_seed()
if seed is None:
2018-11-14 18:58:07 +00:00
# derive seed from mnemonic and passphrase
2018-11-13 16:09:52 +00:00
passphrase = cache.get_passphrase()
if passphrase is None:
passphrase = await protect_by_passphrase(ctx)
cache.set_passphrase(passphrase)
seed = bip39.seed(storage.get_mnemonic(), passphrase)
cache.set_seed(seed)
2018-11-14 18:58:07 +00:00
if paths is None:
# allow the whole keyspace by default
paths = [
["curve25519"],
["ed25519"],
["ed25519-keccak"],
["nist256p1"],
["secp256k1"],
["secp256k1-decred"],
["secp256k1-groestl"],
["secp256k1-smart"],
]
# derive namespaced root nodes
roots = []
for curve, *path in paths:
node = bip32.from_seed(seed, curve)
node.derive_path(path)
roots.append(node)
keychain = Keychain(paths, roots)
2018-11-13 16:09:52 +00:00
return keychain
2018-07-03 14:20:58 +00:00
def derive_node_without_passphrase(
2018-11-14 18:58:07 +00:00
path: list, curve_name: str = "secp256k1"
2018-07-03 14:20:58 +00:00
) -> bip32.HDNode:
if not storage.is_initialized():
2018-07-03 14:20:58 +00:00
raise Exception("Device is not initialized")
seed = bip39.seed(storage.get_mnemonic(), "")
node = bip32.from_seed(seed, curve_name)
node.derive_path(path)
return node
2018-05-11 13:31:53 +00:00
def remove_ed25519_prefix(pubkey: bytes) -> bytes:
2018-05-11 13:31:53 +00:00
# 0x01 prefix is not part of the actual public key, hence removed
return pubkey[1:]