-
Notifications
You must be signed in to change notification settings - Fork 89
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
rollup of many fixes and improvements, windows-compatible #84
base: main
Are you sure you want to change the base?
Changes from 7 commits
651e932
0aac371
a7678af
6ced7d8
af713df
e563b6a
f1356eb
e77c2c5
5cb5933
4755134
0362917
511154f
6aa64fa
b8e7871
b67d5db
9269942
a74aab5
553a316
1162357
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,12 @@ | ||
import secrets | ||
import base64 | ||
import secp256k1 | ||
from cffi import FFI | ||
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes | ||
from cryptography.hazmat.primitives import padding | ||
from hashlib import sha256 | ||
|
||
import nostr.secp as secp256k1 | ||
|
||
from .delegation import Delegation | ||
from .event import EncryptedDirectMessage, Event, EventKind | ||
from . import bech32 | ||
|
@@ -51,17 +52,18 @@ def from_nsec(cls, nsec: str): | |
raw_secret = bech32.convertbits(data, 5, 8)[:-1] | ||
return cls(bytes(raw_secret)) | ||
|
||
@classmethod | ||
def from_hex(cls, hex: str): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. added from_hex |
||
""" Load a PrivateKey from its bech32/nsec form """ | ||
return cls(bytes.fromhex(hex)) | ||
|
||
def bech32(self) -> str: | ||
converted_bits = bech32.convertbits(self.raw_secret, 8, 5) | ||
return bech32.bech32_encode("nsec", converted_bits, bech32.Encoding.BECH32) | ||
|
||
def hex(self) -> str: | ||
return self.raw_secret.hex() | ||
|
||
def tweak_add(self, scalar: bytes) -> bytes: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. got rid of this because it's not used, and not tested |
||
sk = secp256k1.PrivateKey(self.raw_secret) | ||
return sk.tweak_add(scalar) | ||
|
||
def compute_shared_secret(self, public_key_hex: str) -> bytes: | ||
pk = secp256k1.PublicKey(bytes.fromhex("02" + public_key_hex), True) | ||
return pk.ecdh(self.raw_secret, hashfn=copy_x) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
import json | ||
import time | ||
from dataclasses import dataclass | ||
from dataclasses import dataclass, field | ||
from queue import Queue | ||
from threading import Lock | ||
from typing import Optional | ||
|
@@ -34,7 +34,7 @@ class RelayProxyConnectionConfig: | |
class Relay: | ||
url: str | ||
message_pool: MessagePool | ||
policy: RelayPolicy = RelayPolicy() | ||
policy: RelayPolicy = field(default_factory=RelayPolicy) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. python 3.11 fix |
||
ssl_options: Optional[dict] = None | ||
proxy_config: RelayProxyConnectionConfig = None | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import coincurve | ||
from coincurve._libsecp256k1 import ffi, lib | ||
|
||
### compat with secp256k1 python lib | ||
|
||
class PublicKey: | ||
def __init__(self, pubkey=None, raw=False): | ||
self.cc = coincurve.PublicKey(pubkey) if pubkey else None | ||
self.__compressed = None | ||
|
||
def serialize(self, compressed=True): | ||
if compressed: | ||
if not self.__compressed: | ||
self.__compressed = self.cc.format(compressed=True) | ||
return self.__compressed | ||
else: | ||
return self.cc.format(compressed=False) | ||
|
||
def ecdh(self, scalar, hashfn=ffi.NULL, hasharg=ffi.NULL): | ||
priv = coincurve.PrivateKey(scalar) | ||
result = ffi.new('char [32]') | ||
res = lib.secp256k1_ecdh( | ||
priv.context.ctx, result, self.cc.public_key, priv.secret, hashfn, hasharg | ||
) | ||
if not res: | ||
raise Exception(f'invalid scalar ({res})') | ||
return bytes(ffi.buffer(result, 32)) | ||
|
||
def schnorr_verify(self, msg, schnorr_sig, bip340tag, raw=False): | ||
assert bip340tag is None | ||
assert raw | ||
pk = coincurve.PublicKeyXOnly(self.serialize()[1:]) | ||
try: | ||
return pk.verify(schnorr_sig, msg) | ||
except ValueError: | ||
return False | ||
|
||
class PrivateKey: | ||
def __init__(self, privkey=None, raw=True): | ||
if not raw: | ||
self.cc = coincurve.PrivateKey.from_der(privkey) | ||
else: | ||
self.cc = coincurve.PrivateKey(privkey) | ||
|
||
self.pubkey = PublicKey() | ||
self.pubkey.cc = coincurve.PublicKey.from_valid_secret(self.cc.secret) | ||
|
||
def schnorr_sign(self, hash, bip340tag, raw=True): | ||
assert bip340tag is None | ||
assert raw | ||
return self.cc.sign_schnorr(hash) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
useful!