def pointMult(secret): # ctx = OpenSSL.BN_CTX_new() #This value proved to cause Seg Faults on # Linux. It turns out that it really didn't speed up EC_POINT_mul anyway. k = OpenSSL.EC_KEY_new_by_curve_name(OpenSSL.get_curve('secp256k1')) priv_key = OpenSSL.BN_bin2bn(secret, 32, 0) group = OpenSSL.EC_KEY_get0_group(k) pub_key = OpenSSL.EC_POINT_new(group) OpenSSL.EC_POINT_mul(group, pub_key, priv_key, None, None, None) OpenSSL.EC_KEY_set_private_key(k, priv_key) OpenSSL.EC_KEY_set_public_key(k, pub_key) # print 'priv_key',priv_key # print 'pub_key',pub_key size = OpenSSL.i2o_ECPublicKey(k, 0) mb = ctypes.create_string_buffer(size) OpenSSL.i2o_ECPublicKey(k, ctypes.byref(ctypes.pointer(mb))) # print 'mb.raw', mb.raw.encode('hex'), 'length:', len(mb.raw) # print 'mb.raw', mb.raw, 'length:', len(mb.raw) OpenSSL.EC_POINT_free(pub_key) # OpenSSL.BN_CTX_free(ctx) OpenSSL.BN_free(priv_key) OpenSSL.EC_KEY_free(k) return mb.raw
def get_pos_y_for_x(pubkey_x, yneg=0): key = pub_key = pub_key_x = pub_key_y = None try: key = OpenSSL.EC_KEY_new_by_curve_name(OpenSSL.get_curve('secp256k1')) group = OpenSSL.EC_KEY_get0_group(key) pub_key_x = OpenSSL.BN_bin2bn(pubkey_x, len(pubkey_x), 0) pub_key = OpenSSL.EC_POINT_new(group) if OpenSSL.EC_POINT_set_compressed_coordinates_GFp(group, pub_key, pub_key_x, yneg, 0) == 0: raise Exception("[OpenSSL] EC_POINT_set_compressed_coordinates_GFp FAIL ... " + OpenSSL.get_error()) pub_key_y = OpenSSL.BN_new() if (OpenSSL.EC_POINT_get_affine_coordinates_GFp(group, pub_key, pub_key_x, pub_key_y, 0 )) == 0: raise Exception("[OpenSSL] EC_POINT_get_affine_coordinates_GFp FAIL ... " + OpenSSL.get_error()) pubkeyy = OpenSSL.malloc(0, OpenSSL.BN_num_bytes(pub_key_y)) OpenSSL.BN_bn2bin(pub_key_y, pubkeyy) pubkeyy = pubkeyy.raw field_size = OpenSSL.EC_GROUP_get_degree(OpenSSL.EC_KEY_get0_group(key)) secret_len = int((field_size + 7) / 8) if len(pubkeyy) < secret_len: pubkeyy = pubkeyy.rjust(secret_len, b'\0') return pubkeyy finally: if key is not None: OpenSSL.EC_KEY_free(key) if pub_key is not None: OpenSSL.EC_POINT_free(pub_key) if pub_key_x is not None: OpenSSL.BN_free(pub_key_x) if pub_key_y is not None: OpenSSL.BN_free(pub_key_y)
def verify(self, sig, inputb, digest_alg=OpenSSL.digest_ecdsa_sha1): """ Verify the signature with the input and the local public key. Returns a boolean """ # pylint: disable=too-many-branches try: bsig = OpenSSL.malloc(sig, len(sig)) binputb = OpenSSL.malloc(inputb, len(inputb)) digest = OpenSSL.malloc(0, 64) dgst_len = OpenSSL.pointer(OpenSSL.c_int(0)) if OpenSSL._hexversion > 0x10100000 and not OpenSSL._libreSSL: md_ctx = OpenSSL.EVP_MD_CTX_new() else: md_ctx = OpenSSL.EVP_MD_CTX_create() key = OpenSSL.EC_KEY_new_by_curve_name(self.curve) if key == 0: raise Exception("[OpenSSL] EC_KEY_new_by_curve_name FAIL ...") pub_key_x = OpenSSL.BN_bin2bn(self.pubkey_x, len(self.pubkey_x), 0) pub_key_y = OpenSSL.BN_bin2bn(self.pubkey_y, len(self.pubkey_y), 0) group = OpenSSL.EC_KEY_get0_group(key) pub_key = OpenSSL.EC_POINT_new(group) if (OpenSSL.EC_POINT_set_affine_coordinates_GFp( group, pub_key, pub_key_x, pub_key_y, 0)) == 0: raise Exception( "[OpenSSL] EC_POINT_set_affine_coordinates_GFp FAIL ...") if (OpenSSL.EC_KEY_set_public_key(key, pub_key)) == 0: raise Exception("[OpenSSL] EC_KEY_set_public_key FAIL ...") if (OpenSSL.EC_KEY_check_key(key)) == 0: raise Exception("[OpenSSL] EC_KEY_check_key FAIL ...") if OpenSSL._hexversion > 0x10100000 and not OpenSSL._libreSSL: OpenSSL.EVP_MD_CTX_new(md_ctx) else: OpenSSL.EVP_MD_CTX_init(md_ctx) OpenSSL.EVP_DigestInit_ex(md_ctx, digest_alg(), None) if (OpenSSL.EVP_DigestUpdate(md_ctx, binputb, len(inputb))) == 0: raise Exception("[OpenSSL] EVP_DigestUpdate FAIL ...") OpenSSL.EVP_DigestFinal_ex(md_ctx, digest, dgst_len) ret = OpenSSL.ECDSA_verify(0, digest, dgst_len.contents, bsig, len(sig), key) if ret == -1: return False # Fail to Check if ret == 0: return False # Bad signature ! return True # Good finally: OpenSSL.EC_KEY_free(key) OpenSSL.BN_free(pub_key_x) OpenSSL.BN_free(pub_key_y) OpenSSL.EC_POINT_free(pub_key) if OpenSSL._hexversion > 0x10100000 and not OpenSSL._libreSSL: OpenSSL.EVP_MD_CTX_free(md_ctx) else: OpenSSL.EVP_MD_CTX_destroy(md_ctx)
def sign(self, inputb): """ Sign the input with ECDSA method and returns the signature """ try: size = len(inputb) buff = OpenSSL.malloc(inputb, size) digest = OpenSSL.malloc(0, 64) md_ctx = OpenSSL.EVP_MD_CTX_create() dgst_len = OpenSSL.pointer(OpenSSL.c_int(0)) siglen = OpenSSL.pointer(OpenSSL.c_int(0)) sig = OpenSSL.malloc(0, 151) key = OpenSSL.EC_KEY_new_by_curve_name(self.curve) if key == 0: raise Exception("[OpenSSL] EC_KEY_new_by_curve_name FAIL ...") priv_key = OpenSSL.BN_bin2bn(self.privkey, len(self.privkey), 0) pub_key_x = OpenSSL.BN_bin2bn(self.pubkey_x, len(self.pubkey_x), 0) pub_key_y = OpenSSL.BN_bin2bn(self.pubkey_y, len(self.pubkey_y), 0) if (OpenSSL.EC_KEY_set_private_key(key, priv_key)) == 0: raise Exception("[OpenSSL] EC_KEY_set_private_key FAIL ...") group = OpenSSL.EC_KEY_get0_group(key) pub_key = OpenSSL.EC_POINT_new(group) if (OpenSSL.EC_POINT_set_affine_coordinates_GFp( group, pub_key, pub_key_x, pub_key_y, 0)) == 0: raise Exception( "[OpenSSL] EC_POINT_set_affine_coordinates_GFp FAIL ...") if (OpenSSL.EC_KEY_set_public_key(key, pub_key)) == 0: raise Exception("[OpenSSL] EC_KEY_set_public_key FAIL ...") if (OpenSSL.EC_KEY_check_key(key)) == 0: raise Exception("[OpenSSL] EC_KEY_check_key FAIL ...") OpenSSL.EVP_MD_CTX_init(md_ctx) OpenSSL.EVP_DigestInit(md_ctx, OpenSSL.EVP_ecdsa()) if (OpenSSL.EVP_DigestUpdate(md_ctx, buff, size)) == 0: raise Exception("[OpenSSL] EVP_DigestUpdate FAIL ...") OpenSSL.EVP_DigestFinal(md_ctx, digest, dgst_len) OpenSSL.ECDSA_sign(0, digest, dgst_len.contents, sig, siglen, key) if (OpenSSL.ECDSA_verify(0, digest, dgst_len.contents, sig, siglen.contents, key)) != 1: raise Exception("[OpenSSL] ECDSA_verify FAIL ...") return sig.raw[:siglen.contents.value] finally: OpenSSL.EC_KEY_free(key) OpenSSL.BN_free(pub_key_x) OpenSSL.BN_free(pub_key_y) OpenSSL.BN_free(priv_key) OpenSSL.EC_POINT_free(pub_key) OpenSSL.EVP_MD_CTX_destroy(md_ctx)
def verify(self, sig, inputb): """ Verify the signature with the input and the local public key. Returns a boolean """ try: bsig = OpenSSL.malloc(sig, len(sig)) binputb = OpenSSL.malloc(inputb, len(inputb)) digest = OpenSSL.malloc(0, 64) dgst_len = OpenSSL.pointer(OpenSSL.c_int(0)) md_ctx = OpenSSL.EVP_MD_CTX_create() key = OpenSSL.EC_KEY_new_by_curve_name(self.curve) if key == 0: raise Exception("[OpenSSL] EC_KEY_new_by_curve_name FAIL ...") pub_key_x = OpenSSL.BN_bin2bn(self.pubkey_x, len(self.pubkey_x), 0) pub_key_y = OpenSSL.BN_bin2bn(self.pubkey_y, len(self.pubkey_y), 0) group = OpenSSL.EC_KEY_get0_group(key) pub_key = OpenSSL.EC_POINT_new(group) if (OpenSSL.EC_POINT_set_affine_coordinates_GFp( group, pub_key, pub_key_x, pub_key_y, 0)) == 0: raise Exception( "[OpenSSL] EC_POINT_set_affine_coordinates_GFp FAIL ...") if (OpenSSL.EC_KEY_set_public_key(key, pub_key)) == 0: raise Exception("[OpenSSL] EC_KEY_set_public_key FAIL ...") if (OpenSSL.EC_KEY_check_key(key)) == 0: raise Exception("[OpenSSL] EC_KEY_check_key FAIL ...") OpenSSL.EVP_MD_CTX_init(md_ctx) OpenSSL.EVP_DigestInit(md_ctx, OpenSSL.EVP_ecdsa()) if (OpenSSL.EVP_DigestUpdate(md_ctx, binputb, len(inputb))) == 0: raise Exception("[OpenSSL] EVP_DigestUpdate FAIL ...") OpenSSL.EVP_DigestFinal(md_ctx, digest, dgst_len) ret = OpenSSL.ECDSA_verify(0, digest, dgst_len.contents, bsig, len(sig), key) if ret == -1: return False # Fail to Check else: if ret == 0: return False # Bad signature ! else: return True # Good return False finally: OpenSSL.EC_KEY_free(key) OpenSSL.BN_free(pub_key_x) OpenSSL.BN_free(pub_key_y) OpenSSL.EC_POINT_free(pub_key) OpenSSL.EVP_MD_CTX_destroy(md_ctx)
def __add__(self, other): """ Add two EC points together """ if isinstance(other, Point): result = OpenSSL.EC_POINT_new(self.os_group) OpenSSL.EC_POINT_add(self.os_group, result, self.os_point, other.os_point, 0) return Point(self.curve, openssl_point=result) else: return NotImplemented
def raw_get_ecdh_key(self, pubkey_x, pubkey_y): """ECDH key as binary data""" try: ecdh_keybuffer = OpenSSL.malloc(0, 32) other_key = OpenSSL.EC_KEY_new_by_curve_name(self.curve) if other_key == 0: raise Exception("[OpenSSL] EC_KEY_new_by_curve_name FAIL ...") other_pub_key_x = OpenSSL.BN_bin2bn(pubkey_x, len(pubkey_x), 0) other_pub_key_y = OpenSSL.BN_bin2bn(pubkey_y, len(pubkey_y), 0) other_group = OpenSSL.EC_KEY_get0_group(other_key) other_pub_key = OpenSSL.EC_POINT_new(other_group) if (OpenSSL.EC_POINT_set_affine_coordinates_GFp( other_group, other_pub_key, other_pub_key_x, other_pub_key_y, 0)) == 0: raise Exception( "[OpenSSL] EC_POINT_set_affine_coordinates_GFp FAIL ...") if (OpenSSL.EC_KEY_set_public_key(other_key, other_pub_key)) == 0: raise Exception("[OpenSSL] EC_KEY_set_public_key FAIL ...") if (OpenSSL.EC_KEY_check_key(other_key)) == 0: raise Exception("[OpenSSL] EC_KEY_check_key FAIL ...") own_key = OpenSSL.EC_KEY_new_by_curve_name(self.curve) if own_key == 0: raise Exception("[OpenSSL] EC_KEY_new_by_curve_name FAIL ...") own_priv_key = OpenSSL.BN_bin2bn(self.privkey, len(self.privkey), 0) if (OpenSSL.EC_KEY_set_private_key(own_key, own_priv_key)) == 0: raise Exception("[OpenSSL] EC_KEY_set_private_key FAIL ...") if OpenSSL._hexversion > 0x10100000 and not OpenSSL._libreSSL: OpenSSL.EC_KEY_set_method(own_key, OpenSSL.EC_KEY_OpenSSL()) else: OpenSSL.ECDH_set_method(own_key, OpenSSL.ECDH_OpenSSL()) ecdh_keylen = OpenSSL.ECDH_compute_key(ecdh_keybuffer, 32, other_pub_key, own_key, 0) if ecdh_keylen != 32: raise Exception("[OpenSSL] ECDH keylen FAIL ...") return ecdh_keybuffer.raw finally: OpenSSL.EC_KEY_free(other_key) OpenSSL.BN_free(other_pub_key_x) OpenSSL.BN_free(other_pub_key_y) OpenSSL.EC_POINT_free(other_pub_key) OpenSSL.EC_KEY_free(own_key) OpenSSL.BN_free(own_priv_key)
def __mul__(self, other): """ Multiply an EC point by a scalar value and returns the multiplication result """ if isinstance(other, int) or isinstance(other, long): try: o = ec_bignum.BigNum(decval=other) result = OpenSSL.EC_POINT_new(self.os_group) OpenSSL.EC_POINT_mul(self.os_group, result, 0, self.os_point, o.bn, 0) return Point(self.curve, openssl_point=result) finally: del o else: return NotImplemented
def __set_to_coordinates(self, x_val, y_val): try: point = OpenSSL.EC_POINT_new(self.os_group) x, y = ec_bignum.BigNum(decval=x_val), ec_bignum.BigNum( decval=y_val) if self.curve.field_type == 'prime': OpenSSL.EC_POINT_set_affine_coordinates_GFp( self.os_group, point, x.bn, y.bn, None) elif self.curve.field_type == 'characteristic-two': OpenSSL.EC_POINT_set_affine_coordinates_GF2m( self.os_group, point, x.bn, y.bn, None) self.x, self.y = x_val, y_val self.os_point = point finally: del x, y
def pointMul(privKey): ecKey = OpenSSL.EC_KEY_new_by_curve_name(OpenSSL.get_curve('secp256k1')) priv_key = OpenSSL.BN_bin2bn(privKey, 32, 0) group = OpenSSL.EC_KEY_get0_group(ecKey) pub_key = OpenSSL.EC_POINT_new(group) OpenSSL.EC_POINT_mul(group, pub_key, priv_key, None, None, None) OpenSSL.EC_KEY_set_private_key(ecKey, priv_key) OpenSSL.EC_KEY_set_public_key(ecKey, pub_key) size = OpenSSL.i2o_ECPublicKey(ecKey, 0) mb = ctypes.create_string_buffer(size) OpenSSL.i2o_ECPublicKey(ecKey, ctypes.byref(ctypes.pointer(mb))) OpenSSL.EC_POINT_free(pub_key) OpenSSL.BN_free(priv_key) OpenSSL.EC_KEY_free(ecKey) return mb.raw
def raw_check_key(self, privkey, pubkey_x, pubkey_y, curve=None): """Check key validity, key is supplied as binary data""" # pylint: disable=too-many-branches if curve is None: curve = self.curve elif isinstance(curve, str): curve = OpenSSL.get_curve(curve) else: curve = curve try: key = OpenSSL.EC_KEY_new_by_curve_name(curve) if key == 0: raise Exception("[OpenSSL] EC_KEY_new_by_curve_name FAIL ...") if privkey is not None: priv_key = OpenSSL.BN_bin2bn(privkey, len(privkey), 0) pub_key_x = OpenSSL.BN_bin2bn(pubkey_x, len(pubkey_x), 0) pub_key_y = OpenSSL.BN_bin2bn(pubkey_y, len(pubkey_y), 0) if privkey is not None: if (OpenSSL.EC_KEY_set_private_key(key, priv_key)) == 0: raise Exception( "[OpenSSL] EC_KEY_set_private_key FAIL ...") group = OpenSSL.EC_KEY_get0_group(key) pub_key = OpenSSL.EC_POINT_new(group) if (OpenSSL.EC_POINT_set_affine_coordinates_GFp( group, pub_key, pub_key_x, pub_key_y, 0)) == 0: raise Exception( "[OpenSSL] EC_POINT_set_affine_coordinates_GFp FAIL ...") if (OpenSSL.EC_KEY_set_public_key(key, pub_key)) == 0: raise Exception("[OpenSSL] EC_KEY_set_public_key FAIL ...") if (OpenSSL.EC_KEY_check_key(key)) == 0: raise Exception("[OpenSSL] EC_KEY_check_key FAIL ...") return 0 finally: OpenSSL.EC_KEY_free(key) OpenSSL.BN_free(pub_key_x) OpenSSL.BN_free(pub_key_y) OpenSSL.EC_POINT_free(pub_key) if privkey is not None: OpenSSL.BN_free(priv_key)
def ecc_priv_to_pub_key(priv_key, curve=DEFAULT_CURVE): """Does an EC point multiplication to get public key""" k = OpenSSL.EC_KEY_new_by_curve_name(OpenSSL.get_curve(curve)) priv_key = OpenSSL.BN_bin2bn(priv_key, 32, 0) group = OpenSSL.EC_KEY_get0_group(k) pub_key = OpenSSL.EC_POINT_new(group) OpenSSL.EC_POINT_mul(group, pub_key, priv_key, None, None, None) OpenSSL.EC_KEY_set_private_key(k, priv_key) OpenSSL.EC_KEY_set_public_key(k, pub_key) size = OpenSSL.i2o_ECPublicKey(k, 0) mb = ctypes.create_string_buffer(size) OpenSSL.i2o_ECPublicKey(k, ctypes.byref(ctypes.pointer(mb))) OpenSSL.EC_POINT_free(pub_key) OpenSSL.BN_free(priv_key) OpenSSL.EC_KEY_free(k) return mb.raw
def raw_check_key(self, privkey, pubkey_x, pubkey_y, curve=None): if curve is None: curve = self.curve elif type(curve) == str: curve = OpenSSL.get_curve(curve) else: curve = curve try: key = OpenSSL.EC_KEY_new_by_curve_name(curve) if key == 0: raise Exception("[OpenSSL] EC_KEY_new_by_curve_name FAIL ...") if privkey is not None: priv_key = OpenSSL.BN_bin2bn(privkey, len(privkey), 0) pub_key_x = OpenSSL.BN_bin2bn(pubkey_x, len(pubkey_x), 0) pub_key_y = OpenSSL.BN_bin2bn(pubkey_y, len(pubkey_y), 0) if privkey is not None: if (OpenSSL.EC_KEY_set_private_key(key, priv_key)) == 0: raise Exception( "[OpenSSL] EC_KEY_set_private_key FAIL ...") group = OpenSSL.EC_KEY_get0_group(key) pub_key = OpenSSL.EC_POINT_new(group) if (OpenSSL.EC_POINT_set_affine_coordinates_GFp( group, pub_key, pub_key_x, pub_key_y, 0)) == 0: raise Exception( "[OpenSSL] EC_POINT_set_affine_coordinates_GFp FAIL ...") if (OpenSSL.EC_KEY_set_public_key(key, pub_key)) == 0: raise Exception("[OpenSSL] EC_KEY_set_public_key FAIL ...") if (OpenSSL.EC_KEY_check_key(key)) == 0: raise Exception("[OpenSSL] EC_KEY_check_key FAIL ...") return 0 finally: OpenSSL.EC_KEY_free(key) OpenSSL.BN_free(pub_key_x) OpenSSL.BN_free(pub_key_y) OpenSSL.EC_POINT_free(pub_key) if privkey is not None: OpenSSL.BN_free(priv_key)
def ecc_ecdh_key(sec, pub): assert isinstance(sec, ecc.ECC) if isinstance(pub, ecc.ECC): pub = pub.get_pubkey() #return sec.get_ecdh_key(pub) pubkey_x, pubkey_y = ecc.ECC._decode_pubkey(pub, 'binary') other_key = other_pub_key_x = other_pub_key_y = other_pub_key = None own_priv_key = res = res_x = res_y = None try: other_key = OpenSSL.EC_KEY_new_by_curve_name(sec.curve) if other_key == 0: raise Exception("[OpenSSL] EC_KEY_new_by_curve_name FAIL ... " + OpenSSL.get_error()) other_pub_key_x = OpenSSL.BN_bin2bn(pubkey_x, len(pubkey_x), 0) other_pub_key_y = OpenSSL.BN_bin2bn(pubkey_y, len(pubkey_y), 0) other_group = OpenSSL.EC_KEY_get0_group(other_key) other_pub_key = OpenSSL.EC_POINT_new(other_group) if (other_pub_key == None): raise Exception("[OpenSSl] EC_POINT_new FAIL ... " + OpenSSL.get_error()) if (OpenSSL.EC_POINT_set_affine_coordinates_GFp(other_group, other_pub_key, other_pub_key_x, other_pub_key_y, 0)) == 0: raise Exception( "[OpenSSL] EC_POINT_set_affine_coordinates_GFp FAIL ..." + OpenSSL.get_error()) own_priv_key = OpenSSL.BN_bin2bn(sec.privkey, len(sec.privkey), 0) res = OpenSSL.EC_POINT_new(other_group) if (OpenSSL.EC_POINT_mul(other_group, res, 0, other_pub_key, own_priv_key, 0)) == 0: raise Exception( "[OpenSSL] EC_POINT_mul FAIL ..." + OpenSSL.get_error()) res_x = OpenSSL.BN_new() res_y = OpenSSL.BN_new() if (OpenSSL.EC_POINT_get_affine_coordinates_GFp(other_group, res, res_x, res_y, 0 )) == 0: raise Exception( "[OpenSSL] EC_POINT_get_affine_coordinates_GFp FAIL ... " + OpenSSL.get_error()) resx = OpenSSL.malloc(0, OpenSSL.BN_num_bytes(res_x)) resy = OpenSSL.malloc(0, OpenSSL.BN_num_bytes(res_y)) OpenSSL.BN_bn2bin(res_x, resx) resx = resx.raw OpenSSL.BN_bn2bin(res_y, resy) resy = resy.raw return resx, resy finally: if other_key: OpenSSL.EC_KEY_free(other_key) if other_pub_key_x: OpenSSL.BN_free(other_pub_key_x) if other_pub_key_y: OpenSSL.BN_free(other_pub_key_y) if other_pub_key: OpenSSL.EC_POINT_free(other_pub_key) if own_priv_key: OpenSSL.BN_free(own_priv_key) if res: OpenSSL.EC_POINT_free(res) if res_x: OpenSSL.BN_free(res_x) if res_y: OpenSSL.BN_free(res_y)
k = OpenSSL.EC_KEY_new_by_curve_name(OpenSSL.get_curve('secp256k1')) group = OpenSSL.EC_KEY_get0_group(k) for ff in itertools.product(*[[1, f] for f in factors]): a = 1 for f in ff: a *= f if a >= 2**128: continue ahex = '%x' % a if len(ahex) % 2: ahex = '0' + ahex abin = binascii.unhexlify(ahex) priv_key = OpenSSL.BN_bin2bn(abin, len(abin), 0) pub_key = OpenSSL.EC_POINT_new(group) assert OpenSSL.EC_POINT_mul(group, pub_key, priv_key, None, None, None) == 1 pubhex = OpenSSL.EC_POINT_point2hex(group, pub_key, POINT_CONVERSION_COMPRESSED, 0) if ctypes.cast(pubhex, ctypes.c_char_p).value == cp: print 'found it!', ahex key = ahex break OpenSSL.CRYPTO_free(pubhex) OpenSSL.EC_POINT_free(pub_key) OpenSSL.BN_free(priv_key) tried += 1
def sign(self, inputb, digest_alg=OpenSSL.digest_ecdsa_sha1): """ Sign the input with ECDSA method and returns the signature """ # pylint: disable=too-many-branches,too-many-locals try: size = len(inputb) buff = OpenSSL.malloc(inputb, size) digest = OpenSSL.malloc(0, 64) if OpenSSL._hexversion > 0x10100000 and not OpenSSL._libreSSL: md_ctx = OpenSSL.EVP_MD_CTX_new() else: md_ctx = OpenSSL.EVP_MD_CTX_create() dgst_len = OpenSSL.pointer(OpenSSL.c_int(0)) siglen = OpenSSL.pointer(OpenSSL.c_int(0)) sig = OpenSSL.malloc(0, 151) key = OpenSSL.EC_KEY_new_by_curve_name(self.curve) if key == 0: raise Exception("[OpenSSL] EC_KEY_new_by_curve_name FAIL ...") priv_key = OpenSSL.BN_bin2bn(self.privkey, len(self.privkey), 0) pub_key_x = OpenSSL.BN_bin2bn(self.pubkey_x, len(self.pubkey_x), 0) pub_key_y = OpenSSL.BN_bin2bn(self.pubkey_y, len(self.pubkey_y), 0) if (OpenSSL.EC_KEY_set_private_key(key, priv_key)) == 0: raise Exception("[OpenSSL] EC_KEY_set_private_key FAIL ...") group = OpenSSL.EC_KEY_get0_group(key) pub_key = OpenSSL.EC_POINT_new(group) if (OpenSSL.EC_POINT_set_affine_coordinates_GFp( group, pub_key, pub_key_x, pub_key_y, 0)) == 0: raise Exception( "[OpenSSL] EC_POINT_set_affine_coordinates_GFp FAIL ...") if (OpenSSL.EC_KEY_set_public_key(key, pub_key)) == 0: raise Exception("[OpenSSL] EC_KEY_set_public_key FAIL ...") if (OpenSSL.EC_KEY_check_key(key)) == 0: raise Exception("[OpenSSL] EC_KEY_check_key FAIL ...") if OpenSSL._hexversion > 0x10100000 and not OpenSSL._libreSSL: OpenSSL.EVP_MD_CTX_new(md_ctx) else: OpenSSL.EVP_MD_CTX_init(md_ctx) OpenSSL.EVP_DigestInit_ex(md_ctx, digest_alg(), None) if (OpenSSL.EVP_DigestUpdate(md_ctx, buff, size)) == 0: raise Exception("[OpenSSL] EVP_DigestUpdate FAIL ...") OpenSSL.EVP_DigestFinal_ex(md_ctx, digest, dgst_len) OpenSSL.ECDSA_sign(0, digest, dgst_len.contents, sig, siglen, key) if (OpenSSL.ECDSA_verify(0, digest, dgst_len.contents, sig, siglen.contents, key)) != 1: raise Exception("[OpenSSL] ECDSA_verify FAIL ...") return sig.raw[:siglen.contents.value] finally: OpenSSL.EC_KEY_free(key) OpenSSL.BN_free(pub_key_x) OpenSSL.BN_free(pub_key_y) OpenSSL.BN_free(priv_key) OpenSSL.EC_POINT_free(pub_key) if OpenSSL._hexversion > 0x10100000 and not OpenSSL._libreSSL: OpenSSL.EVP_MD_CTX_free(md_ctx) else: OpenSSL.EVP_MD_CTX_destroy(md_ctx)