def classify(res,m,n,omega,lastBit): # Initialise the subsets to empty lists and the counters to 0 # (for each subset) r0 = [0,0] c0 = [0,0] r1 = [0,0] c1 = [0,0] # Classify each message depending if there was a reduction or not for i in range(0,sampleSize): # assuming that the bit is 1 #print lastBit #print i #print len(res[0][i]) temp1 = montMul(res[lastBit][i][-1],m[i],n,omega) #multiplication temp1,red = montMulRed(temp1,temp1,n,omega) #squaring r1[red]+=t[i] c1[red]+=1 #assuming that the bit is 0 temp0,red = montMulRed(res[lastBit][i][-1],res[lastBit][i][-1],n,omega) #squaring r0[red]+=t[i] c0[red]+=1 res[1][i].append(temp1) res[0][i].append(temp0) # Calculate the difference between the average times when we assume that # last bit is 0 and when the last bit is 1 u0 = abs(float(r0[1])/c0[1] - float(r0[0])/c0[0]) u1 = abs(float(r1[1])/c1[1] - float(r1[0])/c1[0]) return u0,u1,res
def getRandomMessages(): messages = [] # save the sample cyphers in Mont form times = [] # time taken to decrypt the cypher x = [] # temporary memory to save the partial result of the partial exponentiation for i in range (0,sampleSize): if i%1500==0: print i r = random.getrandbits(n_length) while r>=n: r = random.getrandbits(n_length) times.append(oracle(r)) messages.append(montMul(r,rho2,n,omega)) #convert the message in Mont form and add it to the list x.append(messages[i]) x[i] = montMul(x[i],x[i],n,omega) print "done generating random messages" return messages,times,x;
def resample (m,t,res,sampleSize): for i in range(0,len(m)): res[0][i] = deque([],history_len) res[1][i] = deque([],history_len) res[1][i].append(montMul(m[i],m[i],n,omega)) res[0][i].append(0) for i in range(len(m),sampleSize): r = random.getrandbits(n_length) while r>=n: r = random.getrandbits(n_length) t.append(oracle(r)) m.append(montMul(r,rho2,n,omega)) #convert the message in Mont form and add it to the list res[0].append(deque([],history_len)) res[1].append(deque([],history_len)) res[1][i].append(montMul(m[i],m[i],n,omega)) res[0][i].append(0) return m,t,res
def getRandomMessages(sampleSize): messages = [] # save the sample ciphers in Mont form times = [] # time taken to decrypt the cipher res = [[],[]] # temporary memory to save the partial result of the partial exponentiation for i in range (0,sampleSize): if i%1500==0: print i r = random.getrandbits(n_length) while r>=n: r = random.getrandbits(n_length) times.append(oracle(r)) messages.append(montMul(r,rho2,n,omega)) #convert the message in Mont form and add it to the list res[0].append(deque([],history_len)) res[1].append(deque([],history_len)) res[1][i].append(montMul(messages[i],messages[i],n,omega)) res[0][i].append(0) return messages,times,res
def test_errorFix(res,k,m,t): r0 = [0,0] c0 = [0,0] r1 = [0,0] c1 = [0,0] lastBit = k&1 confidence = deque([],average_n) temp0 = [0]*sampleSize temp1 = [0]*sampleSize x=[] for i in range(0,sampleSize): x.append(res[lastBit][i][-1]) for j in range(0,test_length): r0 = [0,0] c0 = [0,0] r1 = [0,0] c1 = [0,0] for i in range(0,sampleSize): temp = montMul(x[i],m[i],n,omega) temp1[i],red = montMulRed(temp,temp,n,omega) r1[red]+=t[i] c1[red]+=1 temp0[i],red = montMulRed(x[i],x[i],n,omega) r0[red]+=t[i] c0[red]+=1 u0 = abs(float(r0[1])/c0[1] - float(r0[0])/c0[0]) u1 = abs(float(r1[1])/c1[1] - float(r1[0])/c1[0]) confidence.append(abs(u0-u1)) k<<=1 if u1>u0: k+=1 x,temp1 = temp1,x else: x,temp0 = temp0,x # If the average confidence level for the past "average_n" iterations # is under threshold_difference return false if len(confidence)==average_n: if sum(confidence)/len(confidence)<threshold_difference: return False return True
def main(n,e): m,t,x = getRandomMessages() # get the random ciphers (in Mont form), # corresponding times and partial results of the # partial exponentiation # Temporary memory to save partial results of the exponentiation when # assuming the last bit of the key is 0 or 1 res1 = [0]*sampleSize res0 = [0]*sampleSize key_guess = 1; B = 1 #number of bits in the guessed key H = 1 #hamming weight of the guessed key while B+H < maxLength: print B # Initialise the subsets to empty lists and the counters to 0 # (for each subset) r0 = [0,0] c0 = [0,0] r1 = [0,0] c1 = [0,0] # Classify each message depending if there was a reduction or not for i in range(0,sampleSize): # assuming that the bit is 1 res1[i] = montMul(x[i],m[i],n,omega) #multiplication res1[i],red = montMulRed(res1[i],res1[i],n,omega) #squaring r1[red]+=t[i] c1[red]+=1 #assuming that the bit is 0 res0[i],red = montMulRed(x[i],x[i],n,omega) #squaring r0[red]+=t[i] c0[red]+=1 # Calculate the difference between the average times when we assume that # last bit is 0 and when the last bit is 1 u1 = abs(float(r1[1])/c1[1] - float(r1[0])/c1[0]) u0 = abs(float(r0[1])/c0[1] - float(r0[0])/c0[0]) # some threshold conditions if abs(u0-u1)<threshold_difference: print "The difference between deviation of means is not big enough" return -1 if u1>u0 and u1<threshold_individual: print "The timing difference between M1 and M2 is not big enough" return -1 if u0>u1 and u0<threshold_individual: print "The timing difference between M3 and M4 is not big enough" return -1 # Append the guessed bit to the key and save the partial results of the # exponentiation in x and save the partial results in x key_guess = key_guess<<1 if u1>u0: key_guess +=1 H+=1 x,res1 = res1,x else: x,res0 = res0,x B+=1 # Test the key by appending a '1' to it # The last bit of d is '1' because gcd(d,phi(N)) = 1 key_temp = (key_guess<<1) | 1 if testKey(key_temp): return key_temp print "1011111110001100011110011001001001001010111110011101001010000101" print "{0:b}".format(key_guess) print "B="+str(B)+" H="+str(H) return -1