diff --git a/nostr/event.py b/nostr/event.py index 9743e9f..b903e0e 100644 --- a/nostr/event.py +++ b/nostr/event.py @@ -3,7 +3,7 @@ import json from dataclasses import dataclass, field from enum import IntEnum from typing import List -from secp256k1 import PrivateKey, PublicKey +from secp256k1 import PublicKey from hashlib import sha256 from .message_type import ClientMessageType diff --git a/nostr/key.py b/nostr/key.py index 350c72d..d34697f 100644 --- a/nostr/key.py +++ b/nostr/key.py @@ -6,8 +6,8 @@ from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes from cryptography.hazmat.primitives import padding from hashlib import sha256 -from nostr.delegation import Delegation -from nostr.event import EncryptedDirectMessage, Event, EventKind +from .delegation import Delegation +from .event import EncryptedDirectMessage, Event, EventKind from . import bech32 @@ -28,14 +28,14 @@ class PublicKey: @classmethod def from_npub(cls, npub: str): - """ Load a PublicKey from its bech32/npub form """ + """Load a PublicKey from its bech32/npub form""" hrp, data, spec = bech32.bech32_decode(npub) raw_public_key = bech32.convertbits(data, 5, 8)[:-1] return cls(bytes(raw_public_key)) class PrivateKey: - def __init__(self, raw_secret: bytes=None) -> None: + def __init__(self, raw_secret: bytes = None) -> None: if not raw_secret is None: self.raw_secret = raw_secret else: @@ -46,7 +46,7 @@ class PrivateKey: @classmethod def from_nsec(cls, nsec: str): - """ Load a PrivateKey from its bech32/nsec form """ + """Load a PrivateKey from its bech32/nsec form""" hrp, data, spec = bech32.bech32_decode(nsec) raw_secret = bech32.convertbits(data, 5, 8)[:-1] return cls(bytes(raw_secret)) @@ -71,22 +71,28 @@ class PrivateKey: padded_data = padder.update(message.encode()) + padder.finalize() iv = secrets.token_bytes(16) - cipher = Cipher(algorithms.AES(self.compute_shared_secret(public_key_hex)), modes.CBC(iv)) + cipher = Cipher( + algorithms.AES(self.compute_shared_secret(public_key_hex)), modes.CBC(iv) + ) encryptor = cipher.encryptor() encrypted_message = encryptor.update(padded_data) + encryptor.finalize() return f"{base64.b64encode(encrypted_message).decode()}?iv={base64.b64encode(iv).decode()}" - + def encrypt_dm(self, dm: EncryptedDirectMessage) -> None: - dm.content = self.encrypt_message(message=dm.cleartext_content, public_key_hex=dm.recipient_pubkey) + dm.content = self.encrypt_message( + message=dm.cleartext_content, public_key_hex=dm.recipient_pubkey + ) def decrypt_message(self, encoded_message: str, public_key_hex: str) -> str: - encoded_data = encoded_message.split('?iv=') + encoded_data = encoded_message.split("?iv=") encoded_content, encoded_iv = encoded_data[0], encoded_data[1] iv = base64.b64decode(encoded_iv) - cipher = Cipher(algorithms.AES(self.compute_shared_secret(public_key_hex)), modes.CBC(iv)) + cipher = Cipher( + algorithms.AES(self.compute_shared_secret(public_key_hex)), modes.CBC(iv) + ) encrypted_content = base64.b64decode(encoded_content) decryptor = cipher.decryptor() @@ -110,7 +116,9 @@ class PrivateKey: event.signature = self.sign_message_hash(bytes.fromhex(event.id)) def sign_delegation(self, delegation: Delegation) -> None: - delegation.signature = self.sign_message_hash(sha256(delegation.delegation_token.encode()).digest()) + delegation.signature = self.sign_message_hash( + sha256(delegation.delegation_token.encode()).digest() + ) def __eq__(self, other): return self.raw_secret == other.raw_secret @@ -122,9 +130,12 @@ def mine_vanity_key(prefix: str = None, suffix: str = None) -> PrivateKey: while True: sk = PrivateKey() - if prefix is not None and not sk.public_key.bech32()[5:5+len(prefix)] == prefix: + if ( + prefix is not None + and not sk.public_key.bech32()[5 : 5 + len(prefix)] == prefix + ): continue - if suffix is not None and not sk.public_key.bech32()[-len(suffix):] == suffix: + if suffix is not None and not sk.public_key.bech32()[-len(suffix) :] == suffix: continue break @@ -132,7 +143,11 @@ def mine_vanity_key(prefix: str = None, suffix: str = None) -> PrivateKey: ffi = FFI() -@ffi.callback("int (unsigned char *, const unsigned char *, const unsigned char *, void *)") + + +@ffi.callback( + "int (unsigned char *, const unsigned char *, const unsigned char *, void *)" +) def copy_x(output, x32, y32, data): ffi.memmove(output, x32, 32) return 1