2 Support for EC keypair operation missing form public libcrypto API
4 from ctypescrypto.pkey import PKey, PKeyError
5 from ctypes import c_void_p,c_char_p,c_int,byref
6 from ctypescrypto import libcrypto
8 def create(curve,data):
10 Creates EC keypair from the just secret key and curve name
12 @param curve - name of elliptic curve
13 @param num - byte array or long number representing key
15 ec=libcrypto.EC_KEY_new_by_curve_name(curve.nid)
17 raise PKeyError("EC_KEY_new_by_curvename")
18 group=libcrypto.EC_KEY_get0_group(ec)
20 raise PKeyError("EC_KEY_get0_group")
21 libcrypto.EC_GROUP_set_asn1_flag(group,1)
22 raw_key=libcrypto.BN_new()
23 if isinstance(data,int):
24 BN_hex2bn(byref(raw_key),hex(data))
27 raise PKeyError("BN_new")
28 if libcrypto.BN_bin2bn(data,len(data),raw_key) is None:
29 raise PKeyError("BN_bin2bn")
30 ctx=libcrypto.BN_CTX_new()
32 raise PKeyError("BN_CTX_new")
33 order=libcrypto.BN_new()
35 raise PKeyError("BN_new")
36 priv_key = libcrypto.BN_new()
38 raise PKeyError("BN_new")
39 if libcrypto.EC_GROUP_get_order(group,order,ctx) <=0:
40 raise PKeyError("EC_GROUP_get_order")
41 if libcrypto.BN_nnmod(priv_key,raw_key,order,ctx) <=0:
42 raise PKeyError("BN_nnmod")
43 if libcrypto.EC_KEY_set_private_key(ec,priv_key)<=0:
44 raise PKeyError("EC_KEY_set_private_key")
45 pub_key=libcrypto.EC_POINT_new(group)
47 raise PKeyError("EC_POINT_new")
48 if libcrypto.EC_POINT_mul(group,pub_key,priv_key,None,None,ctx)<=0:
49 raise PKeyError("EC_POINT_mul")
50 if libcrypto.EC_KEY_set_public_key(ec,pub_key)<=0:
51 raise PKeyError("EC_KEY_set_public_key")
52 libcrypto.BN_free(raw_key)
53 libcrypto.BN_free(order)
54 libcrypto.BN_free(priv_key)
55 libcrypto.BN_CTX_free(ctx)
56 p=libcrypto.EVP_PKEY_new()
58 raise PKeyError("EVP_PKEY_new")
59 if libcrypto.EVP_PKEY_set1_EC_KEY(p,ec)<=0:
60 raise PKeyError("EVP_PKEY_set1_EC_KEY")
61 libcrypto.EC_KEY_free(ec)
62 return PKey(ptr=p,cansign=True)
65 libcrypto.EVP_PKEY_new.restype=c_void_p
66 libcrypto.BN_new.restype=c_void_p
67 libcrypto.BN_free.argtypes=(c_void_p,)
68 libcrypto.BN_CTX_new.restype=c_void_p
69 libcrypto.BN_CTX_free.argtypes=(c_void_p,)
70 libcrypto.BN_bin2bn.argtypes=(c_char_p,c_int,c_void_p)
71 libcrypto.EC_KEY_set_private_key.argtypes=(c_void_p,c_void_p)
72 libcrypto.EC_POINT_new.argtypes=(c_void_p,)
73 libcrypto.EC_POINT_new.restype=c_void_p
74 libcrypto.EC_POINT_mul.argtypes=(c_void_p,c_void_p,c_void_p,c_void_p,c_void_p,c_void_p)
75 libcrypto.EC_KEY_set_public_key.argtypes=(c_void_p,c_void_p)