Wrapper around OpenSSL's EC_KEY
| 84 | ssl.EC_KEY_new_by_curve_name.errcheck = _check_result |
| 85 | |
| 86 | class CECKey(): |
| 87 | """Wrapper around OpenSSL's EC_KEY""" |
| 88 | |
| 89 | POINT_CONVERSION_COMPRESSED = 2 |
| 90 | POINT_CONVERSION_UNCOMPRESSED = 4 |
| 91 | |
| 92 | def __init__(self): |
| 93 | self.k = ssl.EC_KEY_new_by_curve_name(NID_secp256k1) |
| 94 | |
| 95 | def __del__(self): |
| 96 | if ssl: |
| 97 | ssl.EC_KEY_free(self.k) |
| 98 | self.k = None |
| 99 | |
| 100 | def set_secretbytes(self, secret): |
| 101 | priv_key = ssl.BN_bin2bn(secret, 32, ssl.BN_new()) |
| 102 | group = ssl.EC_KEY_get0_group(self.k) |
| 103 | pub_key = ssl.EC_POINT_new(group) |
| 104 | ctx = ssl.BN_CTX_new() |
| 105 | if not ssl.EC_POINT_mul(group, pub_key, priv_key, None, None, ctx): |
| 106 | raise ValueError("Could not derive public key from the supplied secret.") |
| 107 | ssl.EC_POINT_mul(group, pub_key, priv_key, None, None, ctx) |
| 108 | ssl.EC_KEY_set_private_key(self.k, priv_key) |
| 109 | ssl.EC_KEY_set_public_key(self.k, pub_key) |
| 110 | ssl.EC_POINT_free(pub_key) |
| 111 | ssl.BN_CTX_free(ctx) |
| 112 | return self.k |
| 113 | |
| 114 | def set_privkey(self, key): |
| 115 | self.mb = ctypes.create_string_buffer(key) |
| 116 | return ssl.d2i_ECPrivateKey(ctypes.byref(self.k), ctypes.byref(ctypes.pointer(self.mb)), len(key)) |
| 117 | |
| 118 | def set_pubkey(self, key): |
| 119 | self.mb = ctypes.create_string_buffer(key) |
| 120 | return ssl.o2i_ECPublicKey(ctypes.byref(self.k), ctypes.byref(ctypes.pointer(self.mb)), len(key)) |
| 121 | |
| 122 | def get_privkey(self): |
| 123 | size = ssl.i2d_ECPrivateKey(self.k, 0) |
| 124 | mb_pri = ctypes.create_string_buffer(size) |
| 125 | ssl.i2d_ECPrivateKey(self.k, ctypes.byref(ctypes.pointer(mb_pri))) |
| 126 | return mb_pri.raw |
| 127 | |
| 128 | def get_pubkey(self): |
| 129 | size = ssl.i2o_ECPublicKey(self.k, 0) |
| 130 | mb = ctypes.create_string_buffer(size) |
| 131 | ssl.i2o_ECPublicKey(self.k, ctypes.byref(ctypes.pointer(mb))) |
| 132 | return mb.raw |
| 133 | |
| 134 | def get_raw_ecdh_key(self, other_pubkey): |
| 135 | ecdh_keybuffer = ctypes.create_string_buffer(32) |
| 136 | r = ssl.ECDH_compute_key(ctypes.pointer(ecdh_keybuffer), 32, |
| 137 | ssl.EC_KEY_get0_public_key(other_pubkey.k), |
| 138 | self.k, 0) |
| 139 | if r != 32: |
| 140 | raise Exception('CKey.get_ecdh_key(): ECDH_compute_key() failed') |
| 141 | return ecdh_keybuffer.raw |
| 142 | |
| 143 | def get_ecdh_key(self, other_pubkey, kdf=lambda k: hashlib.sha256(k).digest()): |
no outgoing calls