def DLogOptim(x,a,dic={}): ''' Return y such as a**y = x using optimized methods in Fp12 to perform multiplications. The algorithm is base on the baby-step / giant-step method. The dictionnary dic stores the precomputed values of a needed for the algo. This dictionnary can be computed with the method self.giantSteps ''' Pair = self.PPATSpp.Pair Fpk = Pair.Fpk gamma = Pair.gamma if x == x.F.one(): return 0 elif a == x : return 1 order = self.PPATSpp.order b = oEC.toTupleFp12(a) xp = oEC.toTupleFp12(x) if dic == {}: if self.giantStepsDict == {}: dic = self.giantSteps(b) self.giantStepsDict = dic else : dic = self.giantStepsDict t = dic['t'] # baby-step / giant-step algo for i in range(0,t+1): ai = dic['e1'][i] bi = oEC.tmulFp12(Fpk,xp,ai,gamma) if bi in dic['e2'].keys(): j = dic['e2'][bi] return (j*t-i)%order #y return None # in case the value y is not found
def make_Ftable(Field, elt): #This function makes a multiplication table to aid in computing discrete #logarithims to speed up decryption of multiple messages encrypted with the #same public/private key baby_steps = {} gt = oEC.toTupleFp12(Field.one()) for j in xrange(2**16): gt = oEC.tmulFp12(Fp12, gt, oEC.toTupleFp12(elt), Gamma) baby_steps[gt] = j + 1 return baby_steps
def __init__(self,PPATSpp,g1,h1,maxexp=16): self.PPATSpp = PPATSpp self.g1 = g1 # in G2' self.h1 = h1 # in G1 self.maxexp = maxexp Jcoord = self.PPATSpp.Jcoord if Jcoord : self.g1.toJcoord() self.h1.toJcoord() self.ehg = self.PPATSpp.e(self.PPATSpp.h,self.PPATSpp.psi(self.PPATSpp.g),self.PPATSpp.Pair,Jcoord) self.ehgt = oEC.toTupleFp12(self.ehg) # tuple version of egh1 #self.tripletsList = [] #lkq = len(bin(self.h1.EFq.F.q)) w = 10 m = len(utils.binn(self.PPATSpp.order)) #m = 160 d = int(math.ceil(float(m)/w)) e = int(math.ceil(float(d)/2)) # Precomputed tables to fasten the scalr multiplication with the generators self.precomp_g = oEC.prec_comb2_EFp2(w,m,self.PPATSpp.g,Jcoord),w,m,d,e self.precomp_h = oEC.prec_comb2_EFp(w,m,self.PPATSpp.h,Jcoord),w,m,d,e self.precomp_g1 = oEC.prec_comb2_EFp2(w,m,self.g1,Jcoord),w,m,d,e self.precomp_h1 = oEC.prec_comb2_EFp(w,m,self.h1,Jcoord),w,m,d,e self.to_fingerprint = ["PPATSpp","g1","h1"] self.to_export = {"fingerprint": [],"value": ["PPATSpp","g1","h1"]}
def test_ExpFp12_opt(self): mul = oEC.tmulFp12 sqrt = oEC.tsqrtFp12 sqmu = oEC.squareAndMultiply tgt = oEC.toTupleFp12(gt) tgtr = sqmu(Fp12, tgt, r, mul, sqrt, gamma) t = time.time() - self.startTime print "%s: %.4f" % ("Fp12 point exponentiation -- optimized", t) self.assertEqual(oEC.toFp12elem(Fp12, tgtr), gt**r, 'Optimised Fp12 exp gives inconsistent results')
def log_field( a, b, Field, table={} ): # Computes x such that a^x = b over a field of order p using baby step-giant step #baby_steps = {} x = oEC.toTupleFp12(a.invert()**(2**16)) gamma = oEC.toTupleFp12(b) if table == {}: print 'No Table Found' table = make_Ftable(Field, a) for i in range(2**16): if gamma in table: return (i) * (2**16) + table[gamma] else: gamma = oEC.tmulFp12(Fp12, gamma, x, Gamma) return "No Match"
def giantSteps(self,a): ''' This method computes a series of exponentiations of a. Assuming a is in Fq12. maxi is the maximum value of the possible discrete log to be found (by default 2**16). The method will precompute exponentiation of a at each of the t steps where t is the square root of maxi : a^0, a^t, a^2t, ..., a^maxi. In addition (not in the original algo but inserted here because 2^8 is a small number), the method computes a^0, a^1, a^2, ..., a^t. Since this is also needed to compute the discrete logarithm. Finally, all the precomputed exponentiations are stored in a dictionnary. ''' limit = 2**self.maxexp Pair = self.PPATSpp.Pair gamma = Pair.gamma Fpk = Pair.Fpk t = int(math.sqrt(limit)) l = int(limit//t) dic = {} dic['t'] = t # storing t for a later use at = oEC.squareAndMultiply(Fpk,a,t,oEC.tmulFp12,oEC.tsqrtFp12,gamma) one = oEC.toTupleFp12(Pair.Fpk1) dic['e1'] = {} dic['e2'] = {} dic['e1'][0] = one dic['e1'][1] = a dic['e2'][one] = 0 dic['e2'][at] = 1 ai = a ait = at # dic['e1'] is a dictionnary containing the a^i for i=0,...,t where the # keys are the indexes for i in range(2,t+1): ai = oEC.tmulFp12(Fpk,ai,a,gamma) dic['e1'][i] = ai # dic['e2'] is a dictionnary containing the a^it for i=0,...,l where the # keys are the a^it and the values are the indexes for i in range(2,l+1): ait = oEC.tmulFp12(Fpk,ait,at,gamma) dic['e2'][ait] = i return dic