import sage.all from sage.rings.integer import Integer from sage.functions.other import floor, ceil from sage.misc.misc_c import prod from sage.rings.fast_arith import prime_range from sage.arith.misc import GCD, gcd from sage.rings.integer_ring import Z, ZZ from sage.rings.finite_rings.finite_field_constructor import FiniteField from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing class TestPairingFriendlyCurve(): def __init__(self, PFCurve, test_vector_PFCurve): self._PFCurve = PFCurve # name of the class, BN, BLS12, KSS16, KSS18, BLS24 self._tvPFCurve = test_vector_PFCurve # name of list of test vectors self._Ei = [] # list of initialized curves self._Ei_ab = [] # list of initialized curves from params a,b in the test vector item self._Ei_b = [] # list of initialized curves from param b in the test vector item self._Ei_a = [] # list of initialized curves from param a in the test vector item def test_init_with_a_i_ht_hy_dict(self): # for CocksPinch8 curves print("test_init_with_a_i_ht_hy_dict") for v in self._tvPFCurve: # CocksPinch8 version: dictionary u,hy,ht,exp_tr,p,r,c,tr,y,a,pnbits = v['T'],v['hy'],v['ht'],v['i'],v['p'],v['r'],(v['p']+1-v['tr'])//v['r'],v['tr'],v['y'],v['a'],v['pnbits'] try: Ei_a = self._PFCurve(u=u, ht=ht, hy=hy, exp_tr=exp_tr, p=p, r=r, c=c, tr=tr, y=y, a=a) except ValueError as err: print ("Error init(u={},a={},ht={},hy={},exp_tr={}\np={}\nr={}\nc={}\ntr={}\ny={}\n)".format(u,a,ht,hy,exp_tr,p,r,c,tr,y)) print("{}".format(err)) raise print Ei_a self._Ei_a.append(Ei_a) print("OK") return True def test_init_with_b_i_ht_hy_dict(self): # for CocksPinch6 curves print("test_init_with_b_i_ht_hy_dict") for v in self._tvPFCurve: # CocksPinch6 version: dictionary u,hy,ht,exp_tr,p,r,c,tr,y,b,pnbits = v['T'],v['hy'],v['ht'],v['i'],v['p'],v['r'],(v['p']+1-v['tr'])//v['r'],v['tr'],v['y'],v['b'],v['pnbits'] try: Ei_b = self._PFCurve(u=u, ht=ht, hy=hy, exp_tr=exp_tr, p=p, r=r, c=c, tr=tr, y=y, b=b) except ValueError as err: print ("Error init(u={},b={},ht={},hy={},exp_tr={}\np={}\nr={}\nc={}\ntr={}\ny={}\n)".format(u,b,ht,hy,exp_tr,p,r,c,tr,y)) print("{}".format(err)) raise print Ei_b self._Ei_b.append(Ei_b) print("OK") return True def test_init_with_abcD(self): # for MNT curves print("test_init_with_abcD") for tup in self._tvPFCurve: #u, (a,b), pbits, cost, label = tup u,D,c,a,b = tup[0:5] try: Ei_ab = self._PFCurve(u, a=a, b=b, c=c, D=D) except ValueError as err: print ("Error init({},a={},b={},c={},D={})".format(u,a,b,c,D)) print("{}".format(err)) raise print Ei_ab self._Ei_ab.append(Ei_ab) print("OK") return True # for CocksPinch k=5,7 curves def test_init_with_all_params(self): print("test_init_with_all_params") for v in self._tvPFCurve: k,u,D,hy,ht,exp_tr,p,r,c,t0,tr,y0,y,a,b,pnbits = v['k'],v['T'],v['D'],v['hy'],v['ht'],v['i'],v['p'],v['r'],(v['p']+1-v['tr'])//v['r'],v['t0'],v['tr'],v['y0'],v['y'],v['a'],v['b'],v['pnbits'] try: Ei_ab = self._PFCurve(k,u,D,exp_tr,p,r,tr,y,a,b) except ValueError as err: print ("Error init(k={},T={},D={},i={},a={},b={})".format(k,u,D,exp_tr,a,b)) print("{}".format(err)) raise print Ei_ab self._Ei_ab.append(Ei_ab) print("OK") return True def test_init_with_b(self): print("test_init_with_b") for tup in self._tvPFCurve: #u, b, pbits, cost, label = tup u = tup[0]; b= tup[1] try: Ei_b = self._PFCurve(u, b=b) except ValueError as err: print ("Error init({},b={})".format(u,b)) print("{}".format(err)) raise print Ei_b self._Ei_b.append(Ei_b) print("OK") return True def test_init_with_a(self): print("test_init_with_a") for tup in self._tvPFCurve: #u, a, pbits, cost, label = tup u = tup[0]; a= tup[1] try: Ei_a = self._PFCurve(u, a=a) except ValueError as err: print ("Error init({},a={})".format(u,a)) print("{}".format(err)) raise print Ei_a self._Ei_a.append(Ei_a) print("OK") return True def test_init(self): print("test_init") for tup in self._tvPFCurve: #u, a or b, pbits, cost, deg_h, label = tup u=tup[0] try: Ei = self._PFCurve(u) except ValueError as err: print ("Error init ({})".format(u)) print("{}".format(err)) raise print Ei self._Ei.append(Ei) print("OK") return True def _test_beta_lamb_sigma_j0(self, E): G = E.G() r = E.r() if not r.is_prime(): print("Error r is not prime") if not r*G == E(0): print ("Error generator G is not of order r, r*G = {}".format(r*G)) beta = E.beta() sigmaG = E(G[0]*beta, G[1]) sigma2G = E(sigmaG[0]*beta, sigmaG[1]) if r*sigmaG != E(0): print ("Error r*sigma(G) != 0, obtained: {}".format(r*sigmaG)) if r*sigma2G != E(0): print ("Error r*sigma^2(G) != 0, obtained: {}".format(r*sigma2G)) if sigma2G + sigmaG + G != E(0): print ("Error sigma^2(G) + sigma(G) + G != 0, obtained: {}".format(sigma2G + sigmaG + G)) lamb = E.lamb() if lamb*G != sigmaG: print("Error lamb*G != sigma(G)") print("lamb*G = {}".format(lamb*G)) print("sigma(G) = {}".format(sigmaG)) def test_beta_lamb_sigma_j0(self): print("test_beta_lamb_sigma_j0") for Ei in self._Ei: #print Ei self._test_beta_lamb_sigma_j0(Ei) print("") for Ei_b in self._Ei_b: #print Ei_b self._test_beta_lamb_sigma_j0(Ei_b) print("OK") return True def _test_beta_lamb_sigma_j1728(self, E): G = E.G() r = E.r() if not r.is_prime(): print("Error r is not prime") if not r*G == E(0): print ("Error generator G is not of order r, r*G = {}".format(r*G)) beta = E.beta() sigmaG = E(-G[0], G[1]*beta) sigma2G = E(-sigmaG[0], sigmaG[1]*beta) if r*sigmaG != E(0): print ("Error r*sigma(G) != 0, obtained: {}".format(r*sigmaG)) if r*sigma2G != E(0): print ("Error r*sigma^2(G) != 0, obtained: {}".format(r*sigma2G)) if sigma2G + G != E(0): print ("Error sigma^2(G) + G != 0, obtained: {}".format(sigma2G + G)) lamb = E.lamb() if lamb*G != sigmaG: print("Error lamb*G != sigma(G)") print("lamb*G = {}".format(lamb*G)) print("sigma(G) = {}".format(sigmaG)) def test_beta_lamb_sigma_j1728(self): print("test_beta_lamb_sigma_j1728") for Ei in self._Ei: #print Ei self._test_beta_lamb_sigma_j1728(Ei) print("") for Ei_a in self._Ei_a: #print Ei_a self._test_beta_lamb_sigma_j1728(Ei_a) print("OK") return True def test_print_parameters(self): print("test_print_parameters") for Ei in self._Ei: print Ei Ei.print_parameters() Ei.print_parameters_for_RELIC() for Ei_ab in self._Ei_ab: # list may is empty print Ei_ab Ei_ab.print_parameters() Ei_ab.print_parameters_for_RELIC() for Ei_a in self._Ei_a: # list is empty if j != 1728 print Ei_a Ei_a.print_parameters() Ei_a.print_parameters_for_RELIC() for Ei_b in self._Ei_b: # list is empty if j != 0 print Ei_b Ei_b.print_parameters() Ei_b.print_parameters_for_RELIC() print("OK") return True # outside the class def generate_parameters_high(pnbits, poly_p, poly_r, polys_cofact_twist=[], u_mod_m=0, m=1,verbose=False): """ Generate parameters: find u s.t. p=poly_p(u), r=poly_r(u), tw=poly_r_twist(u) are prime, and p is pnbits long.""" lc = poly_p.leading_coefficient() deg_p = poly_p.degree() u_min = floor((2**(pnbits-1)/lc)**(1/deg_p)) u_min = (u_min-(u_min % m) + u_mod_m) while (ceil(poly_p(u_min))).nbits() < pnbits: u_min+=m while (ceil(poly_p(u_min))).nbits() > pnbits: u_min-=m u_max = floor((2**pnbits/lc)**(1/deg_p)) u_max = (u_max-(u_max % m) + u_mod_m) while (ceil(poly_p(u_max))).nbits() > pnbits: u_max-=m while (ceil(poly_p(u_max))).nbits() < pnbits: u_max+=m u = u_max p = ZZ(poly_p(u)) r = ZZ(poly_r(u)) tw= [ZZ(c_i(u)) for c_i in polys_cofact_twist] if pnbits < 1024: prod_primes = prod(prime_range(10**5)) else: prod_primes = prod(prime_range(10**7)) i = 0 # save the gcd of parameters to detect possible systematic cofactor gcd_p = 0 gcd_r = 0 gcd_ci = [0 for j in range(len(tw))] gcd_pi = gcd(prod_primes, p) gcd_ri = gcd(prod_primes, r) cond = gcd_pi > 1 or gcd_ri > 1 j = 0 for ci in tw: gcd_cii = gcd(prod_primes, ci) gcd_ci[j] = gcd_cii cond = cond or gcd_ci[j] > 1 j += 1 cond = cond or not p.is_pseudoprime() or not r.is_pseudoprime() for ci in tw: cond = cond or not ci.is_pseudoprime() while u >= u_min and cond: u -=m p = ZZ(poly_p(u)) r = ZZ(poly_r(u)) tw= [ZZ(c_i(u)) for c_i in polys_cofact_twist] gcd_pi = gcd(prod_primes, p) gcd_ri = gcd(prod_primes, r) gcd_p = gcd(gcd_p, gcd_pi) gcd_r = gcd(gcd_r, gcd_ri) cond = gcd_pi > 1 or gcd_ri > 1 j = 0 for ci in tw: gcd_cii = gcd(prod_primes, ci) gcd_ci[j] = gcd(gcd_ci[j], gcd_cii) cond = cond or gcd_cii > 1 j += 1 cond = cond or not p.is_pseudoprime() or not r.is_pseudoprime() for ci in tw: cond = cond or not ci.is_pseudoprime() i +=1 if verbose and (i % 10**5) == 0: print i print("gcd all p: {} gcd all r: {} gcd all ci: {}".format(gcd_p, gcd_r, gcd_ci)) # reset gcd_p = 0 gcd_r = 0 gcd_ci = [0 for j in range(len(tw))] if u >= u_min: print("u={}, i = {}".format(u,i)) return u, p, r, tw, u_min, u_max, i # else return None from CocksPinch6 import CocksPinch6 from CocksPinch8 import CocksPinch8 from CocksPinch_k import CocksPinch_k from MNT6 import MNT6 from BN import BN from BLS12 import BLS12 from KSS16 import KSS16 from TestVectorPairingFriendlyCurve import * def test_CocksPinch6_i1(): print("Test CocksPinch6 curves, tr = T+1 (i=1)") Test_CP6 = TestPairingFriendlyCurve(CocksPinch6, test_vector_CocksPinch6_i1) Test_CP6.test_init_with_b_i_ht_hy_dict() Test_CP6.test_beta_lamb_sigma_j0() Test_CP6.test_print_parameters() print("end test CocksPinch6") def test_CocksPinch6_i5(): print("Test CocksPinch6 curves, tr = -T+2 (i=5)") Test_CP6 = TestPairingFriendlyCurve(CocksPinch6, test_vector_CocksPinch6_i5) Test_CP6.test_init_with_b_i_ht_hy_dict() Test_CP6.test_beta_lamb_sigma_j0() Test_CP6.test_print_parameters() print("end test CocksPinch6") def test_CocksPinch8_i1(): print("Test CocksPinch8 curves, tr = T+1 (i=1), ht=-1") Test_CP8 = TestPairingFriendlyCurve(CocksPinch8, test_vector_CocksPinch8_i1) Test_CP8.test_init_with_a_i_ht_hy_dict() Test_CP8.test_beta_lamb_sigma_j1728() Test_CP8.test_print_parameters() print("end test CocksPinch8") def test_CocksPinch8_i5(): print("Test CocksPinch8 curves, tr = -T+1 (i=5), ht=-1") Test_CP8 = TestPairingFriendlyCurve(CocksPinch8, test_vector_CocksPinch8_i5) Test_CP8.test_init_with_a_i_ht_hy_dict() Test_CP8.test_beta_lamb_sigma_j1728() Test_CP8.test_print_parameters() print("end test CocksPinch8") def test_CocksPinch5(): print("Test CocksPinch_k curves with k=5") Test_CP5 = TestPairingFriendlyCurve(CocksPinch_k, test_vector_CocksPinch5) Test_CP5.test_init_with_all_params() Test_CP5.test_print_parameters() print("end test CocksPinch_k with k=5") def test_CocksPinch7(): print("Test CocksPinch_k curves wit k=7") Test_CP7 = TestPairingFriendlyCurve(CocksPinch_k, test_vector_CocksPinch7) Test_CP7.test_init_with_all_params() Test_CP7.test_print_parameters() print("end test CocksPinch_k with k=7") def test_MNT6(): print("Test MNT6 curves") Test_MNT6 = TestPairingFriendlyCurve(MNT6, test_vector_MNT6) Test_MNT6.test_init_with_abcD() Test_MNT6.test_print_parameters() print("end test MNT6") def test_BN(): print("Test BN curves") Test_BN = TestPairingFriendlyCurve(BN, test_vector_BN) Test_BN.test_init() Test_BN.test_init_with_b() Test_BN.test_beta_lamb_sigma_j0() Test_BN.test_print_parameters() print("end test BN") def test_BLS12(): print("Test BLS12 curves") Test_BLS12 = TestPairingFriendlyCurve(BLS12, test_vector_BLS12) Test_BLS12.test_init() Test_BLS12.test_init_with_b() Test_BLS12.test_beta_lamb_sigma_j0() Test_BLS12.test_print_parameters() print("end test BLS12") def test_KSS16(): print("Test KSS16 curves") Test_KSS16 = TestPairingFriendlyCurve(KSS16, test_vector_KSS16) Test_KSS16.test_init() Test_KSS16.test_init_with_a() Test_KSS16.test_beta_lamb_sigma_j1728() Test_KSS16.test_print_parameters() print("end test KSS16")