A wrapper to present a cryptography api but use the pycryptodome module.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

88 lines
2.2 KiB

  1. from cryptography.exceptions import InvalidSignature
  2. from Crypto.PublicKey import ECC
  3. from Crypto.Protocol.DH import _compute_ecdh
  4. from Crypto.Signature import DSS
  5. # https://www.pycryptodome.org/src/public_key/ecc#
  6. SECP256R1 = lambda: 'secp256r1'
  7. class ECDSA:
  8. def __init__(self, algorithm):
  9. self._algo = algorithm
  10. class ECDH:
  11. pass
  12. class EllipticCurvePrivateNumbers:
  13. def __init__(self, key):
  14. self._key = key
  15. @property
  16. def public_numbers(self):
  17. return self._key._ecc.pointQ
  18. @property
  19. def private_value(self):
  20. return self._key._ecc.d
  21. class ECCWrapper:
  22. def __init__(self, ecckey):
  23. self._ecc = ecckey
  24. def private_numbers(self):
  25. return EllipticCurvePrivateNumbers(self)
  26. def public_key(self):
  27. return EllipticCurvePublicKey(self._ecc.public_key())
  28. _format_to_compress = dict(nocompress=False, compress=True)
  29. def public_bytes(self, encoding, format):
  30. return self.public_key()._ecc.export_key(format=encoding, compress=self._format_to_compress[format])
  31. def private_bytes(self, encoding, format, encryption_algorithm):
  32. return self._ecc.export_key(format=encoding, compress=format)
  33. # https://www.pycryptodome.org/src/protocol/dh
  34. def exchange(self, typ, pubkey):
  35. assert isinstance(typ, ECDH)
  36. return _compute_ecdh(self._ecc, pubkey._ecc)
  37. @classmethod
  38. def generate_private_key(cls, keytype, backend=None):
  39. if callable(keytype):
  40. keytype = keytype()
  41. return cls(ECC.generate(curve=keytype))
  42. def sign(self, data, signature_algorithm):
  43. h = signature_algorithm._algo.new(data)
  44. signer = DSS.new(self._ecc, 'fips-186-3', 'der')
  45. return signer.sign(h)
  46. def verify(self, signature, data, signature_algorithm):
  47. h = signature_algorithm._algo.new(data)
  48. verifier = DSS.new(self._ecc, 'fips-186-3', 'der')
  49. try:
  50. verifier.verify(h, signature)
  51. except ValueError:
  52. raise InvalidSignature
  53. class EllipticCurvePublicKey(ECCWrapper):
  54. @classmethod
  55. def from_encoded_point(cls, curve, key):
  56. return cls(ECC.import_key(key, curve_name=curve))
  57. generate_private_key = ECCWrapper.generate_private_key
  58. def load_der_private_key(key, password, backend=None):
  59. if password is not None:
  60. raise ValueError('unsupported')
  61. return ECCWrapper(ECC.import_key(key))