"""Minimal BIP-340 Schnorr signing + Nostr event builder for tests. Pure Python, no external dependencies beyond stdlib. """ import hashlib import json import os import time # secp256k1 curve parameters. _P = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F _N = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 _G = ( 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798, 0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8, ) def _modinv(a, m): g, x, _ = _egcd(a % m, m) return x % m def _egcd(a, b): if a == 0: return b, 0, 1 g, x, y = _egcd(b % a, a) return g, y - (b // a) * x, x def _point_add(p1, p2): if p1 is None: return p2 if p2 is None: return p1 if p1[0] == p2[0] and p1[1] != p2[1]: return None if p1 == p2: lam = (3 * p1[0] * p1[0] * _modinv(2 * p1[1], _P)) % _P else: lam = ((p2[1] - p1[1]) * _modinv(p2[0] - p1[0], _P)) % _P x = (lam * lam - p1[0] - p2[0]) % _P y = (lam * (p1[0] - x) - p1[1]) % _P return (x, y) def _point_mul(k, point): r = None a = point while k: if k & 1: r = _point_add(r, a) a = _point_add(a, a) k >>= 1 return r def _tagged_hash(tag, msg): t = hashlib.sha256(tag.encode()).digest() return hashlib.sha256(t + t + msg).digest() def _int_from_bytes(b): return int.from_bytes(b, "big") def _bytes_from_int(x): return x.to_bytes(32, "big") def pubkey_from_seckey(seckey: bytes) -> bytes: pt = _point_mul(_int_from_bytes(seckey), _G) return _bytes_from_int(pt[0]) def schnorr_sign(msg: bytes, seckey: bytes) -> bytes: d = _int_from_bytes(seckey) pt = _point_mul(d, _G) if pt[1] % 2 != 0: d = _N - d aux = os.urandom(32) t = bytes( a ^ b for a, b in zip(_bytes_from_int(d), _tagged_hash("BIP0340/aux", aux)) ) rand = _tagged_hash("BIP0340/nonce", t + _bytes_from_int(pt[0]) + msg) k = _int_from_bytes(rand) % _N if k == 0: raise ValueError("bad nonce") r = _point_mul(k, _G) if r[1] % 2 != 0: k = _N - k e = ( _int_from_bytes( _tagged_hash( "BIP0340/challenge", _bytes_from_int(r[0]) + _bytes_from_int(pt[0]) + msg, ) ) % _N ) return _bytes_from_int(r[0]) + _bytes_from_int((k + e * d) % _N) def make_event(seckey: bytes, content: str, kind=1, tags=None, created_at=None): """Create a fully signed Nostr event.""" if tags is None: tags = [] if created_at is None: created_at = int(time.time()) pubkey = pubkey_from_seckey(seckey).hex() serial = json.dumps( [0, pubkey, created_at, kind, tags, content], separators=(",", ":") ) event_id = hashlib.sha256(serial.encode()).digest() sig = schnorr_sign(event_id, seckey) return { "id": event_id.hex(), "pubkey": pubkey, "created_at": created_at, "kind": kind, "tags": tags, "content": content, "sig": sig.hex(), } # Fixed test keypair — deterministic for reproducible tests. TEST_SECKEY = hashlib.sha256(b"smesh-test-key-do-not-use").digest() TEST_PUBKEY = pubkey_from_seckey(TEST_SECKEY).hex()