mirror of
https://github.com/aljazceru/nutshell.git
synced 2026-01-08 03:14:18 +01:00
[Mint] Fix key derivation (#187)
* fix private key derivation * add backwards compatilibity for old keysets * bump version * test pubkeys and private keys * make format * reset keys for tests * fix cli tests
This commit is contained in:
@@ -3,9 +3,15 @@ import json
|
||||
from sqlite3 import Row
|
||||
from typing import Any, Dict, List, Optional, TypedDict, Union
|
||||
|
||||
from loguru import logger
|
||||
from pydantic import BaseModel
|
||||
|
||||
from ..core.crypto import derive_keys, derive_keyset_id, derive_pubkeys
|
||||
from ..core.crypto import (
|
||||
derive_keys,
|
||||
derive_keys_backwards_compatible_0_11_insecure,
|
||||
derive_keyset_id,
|
||||
derive_pubkeys,
|
||||
)
|
||||
from ..core.secp import PrivateKey, PublicKey
|
||||
|
||||
# ------- PROOFS -------
|
||||
@@ -241,6 +247,8 @@ class WalletKeyset:
|
||||
if public_keys:
|
||||
self.public_keys = public_keys
|
||||
self.id = derive_keyset_id(self.public_keys)
|
||||
if id:
|
||||
assert id == self.id, "id must match derived id from public keys"
|
||||
|
||||
|
||||
class MintKeyset:
|
||||
@@ -267,7 +275,7 @@ class MintKeyset:
|
||||
active=None,
|
||||
seed: str = "",
|
||||
derivation_path: str = "",
|
||||
version: str = "",
|
||||
version: str = "1",
|
||||
):
|
||||
self.derivation_path = derivation_path
|
||||
self.id = id
|
||||
@@ -282,16 +290,26 @@ class MintKeyset:
|
||||
|
||||
def generate_keys(self, seed):
|
||||
"""Generates keys of a keyset from a seed."""
|
||||
self.private_keys = derive_keys(seed, self.derivation_path)
|
||||
backwards_compatibility_pre_0_12 = False
|
||||
if (
|
||||
self.version
|
||||
and len(self.version.split(".")) > 1
|
||||
and int(self.version.split(".")[0]) == 0
|
||||
and int(self.version.split(".")[1]) <= 11
|
||||
):
|
||||
backwards_compatibility_pre_0_12 = True
|
||||
# WARNING: Broken key derivation for backwards compatibility with < 0.12
|
||||
self.private_keys = derive_keys_backwards_compatible_0_11_insecure(
|
||||
seed, self.derivation_path
|
||||
)
|
||||
else:
|
||||
self.private_keys = derive_keys(seed, self.derivation_path)
|
||||
self.public_keys = derive_pubkeys(self.private_keys) # type: ignore
|
||||
self.id = derive_keyset_id(self.public_keys) # type: ignore
|
||||
|
||||
def get_keybase(self):
|
||||
assert self.id is not None
|
||||
return {
|
||||
k: KeyBase(id=self.id, amount=k, pubkey=v.serialize().hex())
|
||||
for k, v in self.public_keys.items() # type: ignore
|
||||
}
|
||||
if backwards_compatibility_pre_0_12:
|
||||
logger.warning(
|
||||
f"WARNING: Using weak key derivation for keyset {self.id} (backwards compatibility < 0.12)"
|
||||
)
|
||||
|
||||
|
||||
class MintKeysets:
|
||||
|
||||
@@ -19,6 +19,24 @@ def derive_keys(master_key: str, derivation_path: str = ""):
|
||||
Deterministic derivation of keys for 2^n values.
|
||||
TODO: Implement BIP32.
|
||||
"""
|
||||
return {
|
||||
2
|
||||
** i: PrivateKey(
|
||||
hashlib.sha256(
|
||||
(master_key + derivation_path + str(i)).encode("utf-8")
|
||||
).digest()[:32],
|
||||
raw=True,
|
||||
)
|
||||
for i in range(settings.max_order)
|
||||
}
|
||||
|
||||
|
||||
def derive_keys_backwards_compatible_0_11_insecure(
|
||||
master_key: str, derivation_path: str = ""
|
||||
):
|
||||
"""
|
||||
WARNING: Broken key derivation for backwards compatibility with 0.11.
|
||||
"""
|
||||
return {
|
||||
2
|
||||
** i: PrivateKey(
|
||||
@@ -33,7 +51,7 @@ def derive_keys(master_key: str, derivation_path: str = ""):
|
||||
|
||||
def derive_pubkey(master_key: str):
|
||||
return PrivateKey(
|
||||
hashlib.sha256((master_key).encode("utf-8")).hexdigest().encode("utf-8")[:32],
|
||||
hashlib.sha256((master_key).encode("utf-8")).digest()[:32],
|
||||
raw=True,
|
||||
).pubkey
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ from pydantic import BaseSettings, Extra, Field, validator
|
||||
|
||||
env = Env()
|
||||
|
||||
VERSION = "0.11.2"
|
||||
VERSION = "0.12.0"
|
||||
|
||||
|
||||
def find_env_file():
|
||||
|
||||
@@ -116,7 +116,7 @@ class LedgerAPI:
|
||||
"""Returns proofs of promise from promises. Wants secrets and blinding factors rs."""
|
||||
proofs: List[Proof] = []
|
||||
for promise, secret, r in zip(promises, secrets, rs):
|
||||
logger.trace(f"Creating proof with keyset {self.keyset_id} =+ {promise.id}")
|
||||
logger.trace(f"Creating proof with keyset {self.keyset_id} = {promise.id}")
|
||||
assert (
|
||||
self.keyset_id == promise.id
|
||||
), "our keyset id does not match promise id."
|
||||
@@ -278,7 +278,7 @@ class LedgerAPI:
|
||||
int(amt): PublicKey(bytes.fromhex(val), raw=True)
|
||||
for amt, val in keys.items()
|
||||
}
|
||||
keyset = WalletKeyset(public_keys=keyset_keys, mint_url=url)
|
||||
keyset = WalletKeyset(id=keyset_id, public_keys=keyset_keys, mint_url=url)
|
||||
return keyset
|
||||
|
||||
@async_set_requests
|
||||
|
||||
Reference in New Issue
Block a user