|
- from cryptography.exceptions import InvalidSignature
-
- from Crypto.PublicKey import ECC
- from Crypto.Protocol.DH import _compute_ecdh
- from Crypto.Signature import DSS
-
- # https://www.pycryptodome.org/src/public_key/ecc#
-
- SECP256R1 = lambda: 'secp256r1'
-
- class ECDSA:
- def __init__(self, algorithm):
- self._algo = algorithm
-
- class ECDH:
- pass
-
- class EllipticCurvePrivateNumbers:
- def __init__(self, key):
- self._key = key
-
- @property
- def public_numbers(self):
- return self._key._ecc.pointQ
-
- @property
- def private_value(self):
- return self._key._ecc.d
-
- class ECCWrapper:
- def __init__(self, ecckey):
- self._ecc = ecckey
-
- def private_numbers(self):
- return EllipticCurvePrivateNumbers(self)
-
- def public_key(self):
- return EllipticCurvePublicKey(self._ecc.public_key())
-
- _format_to_compress = dict(nocompress=False, compress=True)
- def public_bytes(self, encoding, format):
- return self.public_key()._ecc.export_key(format=encoding, compress=self._format_to_compress[format])
-
- def private_bytes(self, encoding, format, encryption_algorithm):
- return self._ecc.export_key(format=encoding, compress=format)
-
- # https://www.pycryptodome.org/src/protocol/dh
- def exchange(self, typ, pubkey):
- assert isinstance(typ, ECDH)
-
- return _compute_ecdh(self._ecc, pubkey._ecc)
-
- @classmethod
- def generate_private_key(cls, keytype, backend=None):
- if callable(keytype):
- keytype = keytype()
-
- return cls(ECC.generate(curve=keytype))
-
- def sign(self, data, signature_algorithm):
- h = signature_algorithm._algo.new(data)
-
- signer = DSS.new(self._ecc, 'fips-186-3', 'der')
-
- return signer.sign(h)
-
- def verify(self, signature, data, signature_algorithm):
- h = signature_algorithm._algo.new(data)
-
- verifier = DSS.new(self._ecc, 'fips-186-3', 'der')
-
- try:
- verifier.verify(h, signature)
- except ValueError:
- raise InvalidSignature
-
- class EllipticCurvePublicKey(ECCWrapper):
- @classmethod
- def from_encoded_point(cls, curve, key):
- return cls(ECC.import_key(key, curve_name=curve))
-
- generate_private_key = ECCWrapper.generate_private_key
-
- def load_der_private_key(key, password, backend=None):
- if password is not None:
- raise ValueError('unsupported')
- return ECCWrapper(ECC.import_key(key))
|