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

LNbits compatibility: use bip32 from embit if bip32 lib is not available #406

Draft
wants to merge 18 commits into
base: main
Choose a base branch
from
Draft
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
44 changes: 33 additions & 11 deletions cashu/core/crypto/keys.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,15 @@
import random
from typing import Dict

from bip32 import BIP32
# we import bip32 from embit if bip32 is not installed
try:
from bip32 import BIP32

use_bip32_lib = True
except ImportError:
from embit import bip32 # type: ignore

use_bip32_lib = False

from ..settings import settings
from .secp import PrivateKey, PublicKey
Expand All @@ -13,15 +21,28 @@ def derive_keys(mnemonic: str, derivation_path: str):
"""
Deterministic derivation of keys for 2^n values.
"""
bip32 = BIP32.from_seed(mnemonic.encode())
orders_str = [f"/{i}'" for i in range(settings.max_order)]
return {
2**i: PrivateKey(
bip32.get_privkey_from_path(derivation_path + orders_str[i]),
raw=True,
)
for i in range(settings.max_order)
}
if use_bip32_lib:
root = BIP32.from_seed(mnemonic.encode()) # type: ignore
orders_str = [f"/{i}'" for i in range(settings.max_order)]
return {
2
** i: PrivateKey(
root.get_privkey_from_path(derivation_path + orders_str[i]),
raw=True,
)
for i in range(settings.max_order)
}
else:
root = bip32.HDKey.from_seed(mnemonic.encode()) # type: ignore
orders_str = [f"/{i}'" for i in range(settings.max_order)]
return {
2
** i: PrivateKey(
root.derive(derivation_path + orders_str[i]).key.serialize(), # type: ignore
raw=True,
)
for i in range(settings.max_order)
}


def derive_keys_sha256(seed: str, derivation_path: str = ""):
Expand All @@ -30,7 +51,8 @@ def derive_keys_sha256(seed: str, derivation_path: str = ""):
TODO: Implement BIP32.
"""
return {
2**i: PrivateKey(
2
** i: PrivateKey(
hashlib.sha256((seed + derivation_path + str(i)).encode("utf-8")).digest()[
:32
],
Expand Down
3 changes: 3 additions & 0 deletions cashu/mint/migrations.py
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,7 @@ async def m014_proofs_add_Y_column(db: Database):
# we have to drop the balance views first and recreate them later
await drop_balance_views(db, conn)

async with db.connect() as conn:
await conn.execute(
f"ALTER TABLE {table_with_schema(db, 'proofs_used')} ADD COLUMN Y TEXT"
)
Expand Down Expand Up @@ -481,6 +482,7 @@ async def m014_proofs_add_Y_column(db: Database):
)
await conn.execute(f"DROP TABLE {table_with_schema(db, 'proofs_used_old')}")

async with db.connect() as conn:
# add column Y to proofs_pending
await conn.execute(
f"ALTER TABLE {table_with_schema(db, 'proofs_pending')} ADD COLUMN Y TEXT"
Expand Down Expand Up @@ -527,6 +529,7 @@ async def m014_proofs_add_Y_column(db: Database):

await conn.execute(f"DROP TABLE {table_with_schema(db, 'proofs_pending_old')}")

async with db.connect() as conn:
# recreate the balance views
await create_balance_views(db, conn)

Expand Down
Loading