Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

core/seed: Add SLIP-0077 derivation to Keychain #398

Merged
merged 1 commit into from
Aug 31, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion core/src/apps/common/seed.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from trezor import wire
from trezor.crypto import bip32, hashlib, hmac
from trezor.crypto.curve import secp256k1

from apps.common import HARDENED, cache, mnemonic, storage
from apps.common.request_passphrase import protect_by_passphrase
Expand Down Expand Up @@ -48,7 +49,7 @@ def __init__(self, seed: bytes, namespaces: list):

def __del__(self) -> None:
for root in self.roots:
if root is not None:
if root is not None and hasattr(root, "__del__"):
root.__del__()
del self.roots
del self.seed
Expand Down Expand Up @@ -93,6 +94,17 @@ def derive(
node.derive_path(suffix)
return node

def derive_slip77_blinding_private_key(self, script: bytes) -> bytes:
"""Following the derivation by Elements/Liquid."""
master_node = self.derive(node_path=[b"SLIP-0077"], curve_name="slip21")
return hmac.new(
key=master_node.key(), msg=script, digestmod=hashlib.sha256
).digest()

def derive_slip77_blinding_public_key(self, script: bytes) -> bytes:
private_key = self.derive_slip77_blinding_private_key(script)
return secp256k1.publickey(private_key)


async def get_keychain(ctx: wire.Context, namespaces: list) -> Keychain:
if not storage.is_initialized():
Expand Down
20 changes: 18 additions & 2 deletions core/tests/test_apps.common.seed.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
from common import *
from apps.common import HARDENED
from apps.common import HARDENED, coins
from apps.common.seed import Keychain, Slip21Node, _path_hardened
from apps.wallet.sign_tx import scripts, addresses
from trezor import wire
from trezor.crypto import bip39

from trezor.crypto.curve import secp256k1

class TestKeychain(unittest.TestCase):

Expand Down Expand Up @@ -115,6 +116,21 @@ def test_slip21(self):
with self.assertRaises(wire.DataError):
keychain.derive([b"SLIP-9999", b"Authentication key"], "slip21").key()

def test_slip77(self):
seed = bip39.seed("alcohol woman abuse must during monitor noble actual mixed trade anger aisle", "")
keychain = Keychain(seed, [["slip21", b"SLIP-0077"], ["secp256k1"]])

node = keychain.derive([44 | HARDENED, 1 | HARDENED, 0 | HARDENED, 0, 0])
coin = coins.by_name('Elements')
pubkey_hash = addresses.ecdsa_hash_pubkey(node.public_key(), coin)
script = scripts.output_script_p2pkh(pubkey_hash)

private_key = keychain.derive_slip77_blinding_private_key(script)
self.assertEqual(private_key, unhexlify(b"26f1dc2c52222394236d76e0809516255cfcca94069fd5187c0f090d18f42ad6"))
public_key = keychain.derive_slip77_blinding_public_key(script)
self.assertEqual(public_key, unhexlify(b"03e84cd853fea825bd94f5d2d46580ae0d059c734707fa7a08f5e2f612a51c1acb"))
self.assertEqual(secp256k1.publickey(private_key), public_key)


if __name__ == '__main__':
unittest.main()