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)