Wrapper around OpenSSL's EC_KEY
| 243 | ("s", ctypes.c_void_p)] |
| 244 | |
| 245 | class CECKey: |
| 246 | """Wrapper around OpenSSL's EC_KEY""" |
| 247 | |
| 248 | POINT_CONVERSION_COMPRESSED = 2 |
| 249 | POINT_CONVERSION_UNCOMPRESSED = 4 |
| 250 | |
| 251 | def __init__(self): |
| 252 | self.k = _ssl.EC_KEY_new_by_curve_name(_NID_secp256k1) |
| 253 | |
| 254 | def __del__(self): |
| 255 | if _ssl: |
| 256 | _ssl.EC_KEY_free(self.k) |
| 257 | self.k = None |
| 258 | |
| 259 | def set_secretbytes(self, secret): |
| 260 | if(len(secret) != 32): |
| 261 | raise ValueError("Secret bytes must be exactly 32 bytes") |
| 262 | priv_key = _ssl.BN_bin2bn(secret, 32, None) |
| 263 | group = _ssl.EC_KEY_get0_group(self.k) |
| 264 | pub_key = _ssl.EC_POINT_new(group) |
| 265 | ctx = _ssl.BN_CTX_new() |
| 266 | if not _ssl.EC_POINT_mul(group, pub_key, priv_key, None, None, ctx): |
| 267 | raise ValueError("Could not derive public key from the supplied secret.") |
| 268 | _ssl.EC_KEY_set_private_key(self.k, priv_key) |
| 269 | _ssl.EC_KEY_set_public_key(self.k, pub_key) |
| 270 | _ssl.EC_POINT_free(pub_key) |
| 271 | _ssl.BN_free(priv_key) |
| 272 | _ssl.BN_CTX_free(ctx) |
| 273 | return self.k |
| 274 | |
| 275 | def set_privkey(self, key): |
| 276 | self.mb = ctypes.create_string_buffer(key) |
| 277 | return _ssl.d2i_ECPrivateKey(ctypes.byref(self.k), ctypes.byref(ctypes.pointer(self.mb)), len(key)) |
| 278 | |
| 279 | def set_pubkey(self, key): |
| 280 | self.mb = ctypes.create_string_buffer(key) |
| 281 | return _ssl.o2i_ECPublicKey(ctypes.byref(self.k), ctypes.byref(ctypes.pointer(self.mb)), len(key)) |
| 282 | |
| 283 | def get_privkey(self): |
| 284 | size = _ssl.i2d_ECPrivateKey(self.k, 0) |
| 285 | mb_pri = ctypes.create_string_buffer(size) |
| 286 | _ssl.i2d_ECPrivateKey(self.k, ctypes.byref(ctypes.pointer(mb_pri))) |
| 287 | return mb_pri.raw |
| 288 | |
| 289 | def get_pubkey(self): |
| 290 | size = _ssl.i2o_ECPublicKey(self.k, 0) |
| 291 | mb = ctypes.create_string_buffer(size) |
| 292 | _ssl.i2o_ECPublicKey(self.k, ctypes.byref(ctypes.pointer(mb))) |
| 293 | return mb.raw |
| 294 | |
| 295 | def get_raw_ecdh_key(self, other_pubkey): |
| 296 | ecdh_keybuffer = ctypes.create_string_buffer(32) |
| 297 | r = _ssl.ECDH_compute_key(ctypes.pointer(ecdh_keybuffer), 32, |
| 298 | _ssl.EC_KEY_get0_public_key(other_pubkey.k), |
| 299 | self.k, 0) |
| 300 | if r != 32: |
| 301 | raise Exception('CKey.get_ecdh_key(): ECDH_compute_key() failed') |
| 302 | return ecdh_keybuffer.raw |
no outgoing calls
no test coverage detected