mirror of
https://github.com/aljazceru/nutshell.git
synced 2025-12-29 22:44:30 +01:00
* auth server * cleaning up * auth ledger class * class variables -> instance variables * annotations * add models and api route * custom amount and api prefix * add auth db * blind auth token working * jwt working * clean up * JWT works * using openid connect server * use oauth server with password flow * new realm * add keycloak docker * hopefully not garbage * auth works * auth kinda working * fix cli * auth works for send and receive * pass auth_db to Wallet * auth in info * refactor * fix supported * cache mint info * fix settings and endpoints * add description to .env.example * track changes for openid connect client * store mint in db * store credentials * clean up v1_api.py * load mint info into auth wallet * fix first login * authenticate if refresh token fails * clear auth also middleware * use regex * add cli command * pw works * persist keyset amounts * add errors.py * do not start auth server if disabled in config * upadte poetry * disvoery url * fix test * support device code flow * adopt latest spec changes * fix code flow * mint max bat dynamic * mypy ignore * fix test * do not serialize amount in authproof * all auth flows working * fix tests * submodule * refactor * test * dont sleep * test * add wallet auth tests * test differently * test only keycloak for now * fix creds * daemon * fix test * install everything * install jinja * delete wallet for every test * auth: use global rate limiter * test auth rate limit * keycloak hostname * move keycloak test data * reactivate all tests * add readme * load proofs * remove unused code * remove unused code * implement change suggestions by ok300 * add error codes * test errors
81 lines
2.3 KiB
Python
81 lines
2.3 KiB
Python
import base64
|
|
import hashlib
|
|
import random
|
|
from typing import Dict, List
|
|
|
|
from bip32 import BIP32
|
|
|
|
from .secp import PrivateKey, PublicKey
|
|
|
|
|
|
def derive_keys(mnemonic: str, derivation_path: str, amounts: List[int]):
|
|
"""
|
|
Deterministic derivation of keys for 2^n values.
|
|
"""
|
|
bip32 = BIP32.from_seed(mnemonic.encode())
|
|
orders_str = [f"/{a}'" for a in range(len(amounts))]
|
|
return {
|
|
a: PrivateKey(
|
|
bip32.get_privkey_from_path(derivation_path + orders_str[i]),
|
|
raw=True,
|
|
)
|
|
for i, a in enumerate(amounts)
|
|
}
|
|
|
|
|
|
def derive_keys_deprecated_pre_0_15(
|
|
seed: str, amounts: List[int], derivation_path: str = ""
|
|
):
|
|
"""
|
|
Deterministic derivation of keys for 2^n values.
|
|
"""
|
|
return {
|
|
a: PrivateKey(
|
|
hashlib.sha256((seed + derivation_path + str(i)).encode("utf-8")).digest()[
|
|
:32
|
|
],
|
|
raw=True,
|
|
)
|
|
for i, a in enumerate(amounts)
|
|
}
|
|
|
|
|
|
def derive_pubkey(seed: str) -> PublicKey:
|
|
pubkey = PrivateKey(
|
|
hashlib.sha256((seed).encode("utf-8")).digest()[:32],
|
|
raw=True,
|
|
).pubkey
|
|
assert pubkey
|
|
return pubkey
|
|
|
|
|
|
def derive_pubkeys(keys: Dict[int, PrivateKey], amounts: List[int]):
|
|
return {amt: keys[amt].pubkey for amt in amounts}
|
|
|
|
|
|
def derive_keyset_id(keys: Dict[int, PublicKey]):
|
|
"""Deterministic derivation keyset_id from set of public keys."""
|
|
# sort public keys by amount
|
|
sorted_keys = dict(sorted(keys.items()))
|
|
pubkeys_concat = b"".join([p.serialize() for _, p in sorted_keys.items()])
|
|
return f"00{hashlib.sha256(pubkeys_concat).hexdigest()[:14]}"
|
|
|
|
|
|
def derive_keyset_id_deprecated(keys: Dict[int, PublicKey]):
|
|
"""DEPRECATED 0.15.0: Deterministic derivation keyset_id from set of public keys.
|
|
DEPRECATION: This method produces base64 keyset ids. Use `derive_keyset_id` instead.
|
|
"""
|
|
# sort public keys by amount
|
|
sorted_keys = dict(sorted(keys.items()))
|
|
pubkeys_concat = "".join([p.serialize().hex() for _, p in sorted_keys.items()])
|
|
return base64.b64encode(
|
|
hashlib.sha256((pubkeys_concat).encode("utf-8")).digest()
|
|
).decode()[:12]
|
|
|
|
|
|
def random_hash() -> str:
|
|
"""Returns a base64-urlsafe encoded random hash."""
|
|
return base64.urlsafe_b64encode(
|
|
bytes([random.getrandbits(8) for i in range(30)])
|
|
).decode()
|