42 lines
1.3 KiB
Python
42 lines
1.3 KiB
Python
|
|
import hashlib
|
||
|
|
import json
|
||
|
|
import time
|
||
|
|
|
||
|
|
from coincurve import PrivateKey, PublicKeyXOnly
|
||
|
|
|
||
|
|
|
||
|
|
def sign_event(sk: bytes, pubkey: str, kind: int, content: str, tags: list[list[str]]) -> dict:
|
||
|
|
event = {
|
||
|
|
"pubkey": pubkey,
|
||
|
|
"created_at": int(time.time()),
|
||
|
|
"kind": kind,
|
||
|
|
"tags": tags,
|
||
|
|
"content": content,
|
||
|
|
}
|
||
|
|
serialized = json.dumps(
|
||
|
|
[0, event["pubkey"], event["created_at"], event["kind"], event["tags"], event["content"]],
|
||
|
|
separators=(",", ":"),
|
||
|
|
ensure_ascii=False,
|
||
|
|
)
|
||
|
|
event["id"] = hashlib.sha256(serialized.encode()).hexdigest()
|
||
|
|
pk = PrivateKey(sk)
|
||
|
|
sig = pk.sign_schnorr(bytes.fromhex(event["id"]))
|
||
|
|
event["sig"] = sig.hex() if isinstance(sig, bytes) else sig
|
||
|
|
return event
|
||
|
|
|
||
|
|
|
||
|
|
def verify_event(event: dict) -> bool:
|
||
|
|
try:
|
||
|
|
serialized = json.dumps(
|
||
|
|
[0, event["pubkey"], event["created_at"], event["kind"], event["tags"], event["content"]],
|
||
|
|
separators=(",", ":"),
|
||
|
|
ensure_ascii=False,
|
||
|
|
)
|
||
|
|
expected_id = hashlib.sha256(serialized.encode()).hexdigest()
|
||
|
|
if expected_id != event.get("id", ""):
|
||
|
|
return False
|
||
|
|
xonly = PublicKeyXOnly(bytes.fromhex(event["pubkey"]))
|
||
|
|
return xonly.verify(bytes.fromhex(event["sig"]), bytes.fromhex(event["id"]))
|
||
|
|
except Exception:
|
||
|
|
return False
|