46 lines
1.5 KiB
Python
46 lines
1.5 KiB
Python
from . import _curve25519
|
|
from hashlib import sha256
|
|
import os
|
|
|
|
# the curve25519 functions are really simple, and could be used without an
|
|
# OOP layer, but it's a bit too easy to accidentally swap the private and
|
|
# public keys that way.
|
|
|
|
def _hash_shared(shared):
|
|
return sha256(b"curve25519-shared:"+shared).digest()
|
|
|
|
class Private:
|
|
def __init__(self, secret=None, seed=None):
|
|
if secret is None:
|
|
if seed is None:
|
|
secret = os.urandom(32)
|
|
else:
|
|
secret = sha256(b"curve25519-private:"+seed).digest()
|
|
else:
|
|
assert seed is None, "provide secret, seed, or neither, not both"
|
|
if not isinstance(secret, bytes) or len(secret) != 32:
|
|
raise TypeError("secret= must be 32-byte string")
|
|
self.private = _curve25519.make_private(secret)
|
|
|
|
def serialize(self):
|
|
return self.private
|
|
|
|
def get_public(self):
|
|
return Public(_curve25519.make_public(self.private))
|
|
|
|
def get_shared_key(self, public, hashfunc=None):
|
|
if not isinstance(public, Public):
|
|
raise ValueError("'public' must be an instance of Public")
|
|
if hashfunc is None:
|
|
hashfunc = _hash_shared
|
|
shared = _curve25519.make_shared(self.private, public.public)
|
|
return hashfunc(shared)
|
|
|
|
class Public:
|
|
def __init__(self, public):
|
|
assert isinstance(public, bytes)
|
|
assert len(public) == 32
|
|
self.public = public
|
|
|
|
def serialize(self):
|
|
return self.public
|