mirror of
https://github.com/PR0M3TH3AN/SeedPass.git
synced 2025-09-09 07:48:57 +00:00
update
This commit is contained in:
@@ -1,105 +1,127 @@
|
||||
# nostr/key_manager.py
|
||||
|
||||
import hashlib
|
||||
import logging
|
||||
import traceback
|
||||
from bip_utils import Bip39SeedGenerator
|
||||
from cryptography.fernet import Fernet, InvalidToken
|
||||
from bech32 import bech32_encode, convertbits
|
||||
|
||||
from .logging_config import configure_logging
|
||||
from utils.key_derivation import derive_key_from_parent_seed
|
||||
from local_bip85.bip85 import BIP85
|
||||
from bip_utils import Bip39SeedGenerator
|
||||
from monstr.encrypt import Keys
|
||||
|
||||
from monstr.encrypt import Keys, NIP4Encrypt # Ensure monstr.encrypt is installed and accessible
|
||||
|
||||
# Configure logging at the start of the module
|
||||
configure_logging()
|
||||
|
||||
# Initialize the logger for this module
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
def encode_bech32(prefix: str, key_hex: str) -> str:
|
||||
try:
|
||||
key_bytes = bytes.fromhex(key_hex)
|
||||
data = convertbits(key_bytes, 8, 5, pad=True)
|
||||
return bech32_encode(prefix, data)
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to encode {prefix}: {e}")
|
||||
logger.error(traceback.format_exc())
|
||||
raise
|
||||
|
||||
class KeyManager:
|
||||
"""
|
||||
Manages key generation, encoding, and derivation for NostrClient.
|
||||
"""
|
||||
|
||||
def __init__(self, parent_seed: str):
|
||||
def __init__(self, parent_seed: str, fingerprint: str):
|
||||
"""
|
||||
Initializes the KeyManager with the provided parent_seed.
|
||||
|
||||
Initializes the KeyManager with the provided parent_seed and fingerprint.
|
||||
|
||||
Parameters:
|
||||
parent_seed (str): The parent seed used for key derivation.
|
||||
fingerprint (str): The fingerprint to differentiate key derivations.
|
||||
"""
|
||||
try:
|
||||
if not isinstance(parent_seed, str):
|
||||
raise TypeError(f"Parent seed must be a string, got {type(parent_seed)}")
|
||||
|
||||
if not isinstance(fingerprint, str):
|
||||
raise TypeError(f"Fingerprint must be a string, got {type(fingerprint)}")
|
||||
|
||||
self.parent_seed = parent_seed
|
||||
logger.debug(f"KeyManager initialized with parent_seed: {self.parent_seed} (type: {type(self.parent_seed)})")
|
||||
|
||||
# Derive the encryption key from parent_seed
|
||||
derived_key = self.derive_encryption_key()
|
||||
derived_key_hex = derived_key.hex()
|
||||
logger.debug(f"Derived encryption key (hex): {derived_key_hex}")
|
||||
|
||||
# Initialize Keys with the derived hexadecimal key
|
||||
self.keys = Keys(priv_k=derived_key_hex) # Pass hex string
|
||||
self.fingerprint = fingerprint
|
||||
logger.debug(f"KeyManager initialized with parent_seed and fingerprint.")
|
||||
|
||||
# Initialize BIP85
|
||||
self.bip85 = self.initialize_bip85()
|
||||
|
||||
# Generate Nostr keys using the fingerprint
|
||||
self.keys = self.generate_nostr_keys()
|
||||
logger.debug("Nostr Keys initialized successfully.")
|
||||
|
||||
# Generate bech32-encoded keys
|
||||
self.nsec = encode_bech32('nsec', self.keys.private_key_hex())
|
||||
logger.debug(f"Nostr Private Key (nsec): {self.nsec}")
|
||||
|
||||
public_key_hex = self.keys.public_key_hex()
|
||||
self.npub = encode_bech32('npub', public_key_hex)
|
||||
logger.debug(f"Nostr Public Key (npub): {self.npub}")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Key initialization failed: {e}")
|
||||
logger.error(traceback.format_exc())
|
||||
raise
|
||||
|
||||
def derive_encryption_key(self) -> bytes:
|
||||
def initialize_bip85(self):
|
||||
"""
|
||||
Derives the encryption key using the parent seed.
|
||||
Initializes BIP85 with the parent seed.
|
||||
|
||||
Returns:
|
||||
bytes: The derived encryption key.
|
||||
|
||||
Raises:
|
||||
Exception: If key derivation fails.
|
||||
BIP85: An instance of the BIP85 class.
|
||||
"""
|
||||
try:
|
||||
key = derive_key_from_parent_seed(self.parent_seed)
|
||||
logger.debug("Encryption key derived successfully.")
|
||||
return key # Now returns raw bytes
|
||||
seed_bytes = Bip39SeedGenerator(self.parent_seed).Generate()
|
||||
bip85 = BIP85(seed_bytes)
|
||||
logger.debug("BIP85 initialized successfully.")
|
||||
return bip85
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to derive encryption key: {e}")
|
||||
logger.error(f"Failed to initialize BIP85: {e}")
|
||||
logger.error(traceback.format_exc())
|
||||
raise
|
||||
|
||||
def get_npub(self) -> str:
|
||||
def generate_nostr_keys(self) -> Keys:
|
||||
"""
|
||||
Returns the Nostr public key (npub).
|
||||
Derives a unique Nostr key pair for the given fingerprint using BIP-85.
|
||||
|
||||
Returns:
|
||||
str: The npub as a string.
|
||||
|
||||
Raises:
|
||||
ValueError: If npub is not available.
|
||||
Keys: An instance of Keys containing the Nostr key pair.
|
||||
"""
|
||||
if self.npub:
|
||||
logger.debug(f"Returning npub: {self.npub}")
|
||||
return self.npub
|
||||
else:
|
||||
logger.error("Nostr public key (npub) is not available.")
|
||||
raise ValueError("Nostr public key (npub) is not available.")
|
||||
try:
|
||||
# Convert fingerprint to an integer index (using a hash function)
|
||||
index = int(hashlib.sha256(self.fingerprint.encode()).hexdigest(), 16) % (2**31)
|
||||
|
||||
# Derive entropy for Nostr key (32 bytes)
|
||||
entropy_bytes = self.bip85.derive_entropy(
|
||||
index=index,
|
||||
bytes_len=32 # Adjust parameter name and value as per your method signature
|
||||
)
|
||||
|
||||
# Generate Nostr key pair from entropy
|
||||
private_key_hex = entropy_bytes.hex()
|
||||
keys = Keys(priv_k=private_key_hex)
|
||||
logger.debug(f"Nostr keys generated for fingerprint {self.fingerprint}.")
|
||||
return keys
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to generate Nostr keys: {e}")
|
||||
logger.error(traceback.format_exc())
|
||||
raise
|
||||
|
||||
def get_public_key_hex(self) -> str:
|
||||
"""
|
||||
Returns the public key in hexadecimal format.
|
||||
|
||||
Returns:
|
||||
str: The public key in hex.
|
||||
"""
|
||||
return self.keys.public_key_hex()
|
||||
|
||||
def get_private_key_hex(self) -> str:
|
||||
"""
|
||||
Returns the private key in hexadecimal format.
|
||||
|
||||
Returns:
|
||||
str: The private key in hex.
|
||||
"""
|
||||
return self.keys.private_key_hex()
|
||||
|
||||
def get_npub(self) -> str:
|
||||
"""
|
||||
Returns the npub (Bech32 encoded public key).
|
||||
|
||||
Returns:
|
||||
str: The npub string.
|
||||
"""
|
||||
try:
|
||||
pub_key_hex = self.get_public_key_hex()
|
||||
pub_key_bytes = bytes.fromhex(pub_key_hex)
|
||||
data = convertbits(pub_key_bytes, 8, 5, True)
|
||||
npub = bech32_encode('npub', data)
|
||||
return npub
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to generate npub: {e}")
|
||||
logger.error(traceback.format_exc())
|
||||
raise
|
||||
|
Reference in New Issue
Block a user