def signcrypt(self, Reciever, params, m): # R = g ** w mod p, w <-- Zq w, R_value = random_pick(params.p, params.q, params.g) # h1_R = H1(ID_R, X_R, Y_R) <-- Zq h1_R = H1_hash(Reciever.uid, Reciever.X_u, Reciever.Y_u, bit_length(params.q)) # T = (X_R * Y_R * (p_pub**h1_R)) ** w mod p T_value = T_compute(Reciever.X_u, Reciever.Y_u, params.p_pub, h1_R, w, params.p) # C = m * T mod p C_value = [] if bit_length(m) < bit_length(params.p): C_value.append(t_mod(m * T_value, params.p)) else: m_list = m2list(m, bit_length(params.p)) for x in range(len(m_list)): C_value.append(t_mod(m_list[x] * T_value, params.p)) # h2 = H2(ID_S, T, m, C) <-- Zq h2_value = H2_hash(self.uid, T_value, m, C_value[0], bit_length(params.q)) # (x_S + y_S) ** -1 mod q x_y_invert = invert(self.x_u + self.y_u, params.q) # S = h2 * w * (x_S + y_S) ** -1 mod q S_value = t_mod(h2_value * w * x_y_invert, params.q) # signcryption_text = (R, C, S) Signcryption_text = (R_value, C_value, S_value) return Signcryption_text
class RSA: #RSA的应用类 def keygen(self, l=2048, s=True): while True: p = gmpy2.mpz(Crypto.Util.number.getPrime(l)) q = gmpy2.mpz(Crypto.Util.number.getPrime(l)) n = gmpy2.mpz(p * q) et = (p - 1) * (q - 1) if s == True: e = 2**16+1 # << - this is better else: e = 3 # << - this is bad d = gmpy2.invert(e, et) if d != None: break return (e, n), (d, n) def encrypt(self, m, (e,n)): #所有加密的m都是用string m=s2i(m) len_n = (gmpy2.bit_length(n))-1 len_m = gmpy2.bit_length(m)-1 if len_n < len_m: pass#return [i2s(pow(s2i(m), e, n))] else: cs=gmpy2.powmod(m,e,n) return cs
def unsigncrypt(self, Sender, params, Signcryption_text): # get R, C, S R_value = Signcryption_text[0] C_value = Signcryption_text[1] S_value = Signcryption_text[2] # T' = R ** (x_R + y_R) mod p , where "un" represent the symbol ' T_value_un = powmod(R_value, t_mod(self.x_u + self.y_u, params.q), params.p) # T' ** -1 mod p T_value_un_invert = invert(T_value_un, params.p) # m' = (T' ** -1) * C mod p m_un = t_mod(T_value_un_invert * C_value, params.p) # h2' = H2(ID_S, T', m', C) <-- Zq h2_value_un = H2_hash(Sender.uid, T_value_un, m_un, C_value, bit_length(params.q)) # h1_S = H1(ID_S, X_S, Y_S) <-- Zq h1_S = H1_hash(Sender.uid, Sender.X_u, Sender.Y_u, bit_length(params.q)) # verify R ** h2' mod p == (X_S * Y_S * (p_pub ** h1_S)) ** S mod p # if return true, then return m' as the plain-text left_value = powmod(R_value, h2_value_un, params.p) right_value = T_compute(Sender.X_u, Sender.Y_u, params.p_pub, h1_S, S_value, params.p) if left_value == right_value: return m_un
def modulus (self, A): B = np.copy(A) p1 = B.view('uint8') p = p1[::-1] p = self.remove_0(p) Pl = self.Polynomial.view('uint8') Polynomial = Pl[::-1] Polynomial = self.remove_0(Polynomial) pf_bit_pos = gmpy2.bit_length(int(Polynomial[0])) p1 = ( Polynomial >> (pf_bit_pos-1) ) & 0xff p2 = ( Polynomial << (9 - pf_bit_pos) ) & 0xff p1 = np.append(p1, 0) p2 = np.append(0, p2) pr = p1 ^ p2 & 0xff while len(p) >= len(Polynomial): #print p if len(p) > len(Polynomial): red_poly = self.Polly_table[p[0]] for j,k in zip(red_poly, self.Polly_index): if j != 0: p[k] ^= j p = p[1:] while p[0] == 0: if len(p) == 1: break p = p[1:] else: f_bit_pos = gmpy2.bit_length(int(p[0])) if f_bit_pos < pf_bit_pos: break p1 = pr << (f_bit_pos -1) & 0xff p2 = pr >> (9 - f_bit_pos) & 0xff p1 = np.append(0, p1) p2 = np.append(p2, 0) pp = p1 ^ p2 pp = pp[1:] if pp[-1] == 0: pp = pp[:-1] pp = p[:len(pp)] ^ pp p = np.append(pp, p[len(pp):]) p = self.remove_0(p) p = p[::-1] q = np.append( p,np.zeros(4 - len(p)%4, dtype=np.int8)) q = np.array(q, dtype='uint8') q = np.getbuffer(q) q = np.frombuffer(q, dtype='uint32') return q
def __init__(self, g, priv): self.curve = g.curve self.g = g self.privkey = priv self.pubkey = priv * g self.Ln = bit_length(self.curve.n) assert priv < self.curve.n - 1
def Curve_Calculation(self, Polynomial): ##### breaking of curve to give only useful information ####### Curve_Polynomial = np.array([], dtype='uint8') Polynomial = self.str2nparray(Polynomial) Curve_len = (len(Polynomial) - 1) * 32 + gmpy2.bit_length( int(Polynomial[-1])) - 1 D = Polynomial.view('uint8')[::-1] D = self.remove_0(D) position = np.nonzero(D) #print position position = position[0] secnd_chunk = 0x00 secnd_position = 0x00 frst_chunk = D[position[1]] frst_position = (position[1] / 8) * 8 + 7 - (position[1] % 8) if (len(position) == 3): secnd_chunk = D[position[2]] secnd_position = (position[2] / 8) * 8 + 7 - (position[2] % 8) Curve_Polynomial = np.array([ Curve_len, frst_position, frst_chunk, secnd_position, secnd_chunk ], dtype='uint8') Curve_Polynomial = self.nparray2str2(Curve_Polynomial) return Curve_Polynomial
def aks_test(n): """ Implement the AKS primality test. """ get_context().precision = bit_length(n) # Check if n is a perfect power. If so, return composite. if is_power(n): return "composite" # Find the smallest r such that the multiplicative order of n modulo r # is greater than log(n, 2)^2 r = get_r(n) # If 1 < gcd(a, n) < n for some a <= r, return composite for a in range(1, r): if gcd(a, n) > 1 and gcd(a, n) < n: return "composite" # If n <= r, return prime if n <= r: return "prime" # Check if (x + a)^n mod (x^r - 1, n) != (x^n + a) mod (x^r - 1, n) if False in ray.get([ is_congruent.remote(a, n, r) for a in range(1, mpz(floor(sqrt(phi(r)) * log2(n)))) ]): return "composite" return "prime"
def pollard_rho(n, process_id): i = 1 # set the point in which rho starts if gmpy2.bit_length(gmpy2.mpz(n)) < RHO_CONSTANT: # small value modulo so we are better off starting with small value if DEBUG: print("bit size", gmpy2.bit_length(gmpy2.mpz(n)), "less than", RHO_CONSTANT, "so non ran") initial = process_id + 2 re_rand = False else: # small value modulo so we are better off starting with a random value if DEBUG: print("ran") # set a flag so we can re rand rho at a latter point re_rand = True # process_id + 2 # this could also be random.randomint(0, n - 1) initial = random.randint(primes[len(primes) - 1], n // (process_id + 2)) if DEBUG: processLock.acquire() print("CORE", process_id, "checking rho of", initial) processLock.release() y = initial k = 2 previous = initial count = 0 while True: i += 1 count += 1 # alt methods # gmpy2.powmod(pow(previous, 2) - 1, 1, n) # ((pow(previous, 2)) - 1) % n # current = (((previous**2) - 1) % n) d = gmpy2.gcd(y - current, n) # check to see if we've found the terminating conditions for rho and we've found a factor if d != 1 and d != n: return d if i == k: y = current k = 2 * k previous = current # check to see if we are in random mode and if we need to re random if re_rand and count > 100000: # (gmpy2.sqrt(n) // primes[len(primes)-1]): # print("RE-RAN") count = 0 previous = random.randint(primes[len(primes) - 1], int(gmpy2.sqrt(n)))
def digitial_generation(self,message,Curve_Polynomial,X,Y,Order,A,d_A): r=np.array([0x0],dtype='uint32') m=hashlib.sha256(message).hexdigest() Order_np = self.str2nparray(Order) Order_int = int(Order,16) l=(len(Order_np)-1)*32+gmpy2.bit_length(int(Order_np[-1])) m = field.str2nparray(m) size = l/32+1 m=self.remove_1(m) if(l>=256): rem=l-256 chunk_added=(rem/32)+1 m=np.append(np.zeros(chunk_added,dtype='uint32'),m) part=32-(l+chunk_added)%32 else: m = m[len(m)-size:] part = 32-l%32 X1=m>>part Y1=m<<(32-part) Z=np.bitwise_xor(Y1[1:],X1[:-1]) Z=np.append(Z,X1[-1]) Z = self.nparray2str(Z) Z = int(Z,16) Z = gmpy2.f_mod(Z,Order_int) S=0 while(S==0): while(np.all(r[0]==0)): k=random.randint(1,Order_int-1) r=self.bin_public_key_gen(X,Y,A,k) k_inv=gmpy2.invert(k,Order_int) r = self.nparray2str(r[0]) r = int(r,16) r=gmpy2.f_mod(r,Order_int) rd_A = gmpy2.mul(r,d_A) rd_A = gmpy2.f_mod(rd_A,Order_int) Zrd_A = rd_A + Z Zrd_A = int(Zrd_A) k_inv = int(k_inv) S = gmpy2.mul(Zrd_A,k_inv) S = gmpy2.f_mod(S,Order_int) return r,S
def digitial_Verification(self,message,Order,X,Y,A,d_A,r,S): X=self.str2nparray(X) Y=self.str2nparray(Y) A=self.str2nparray(A) m=hashlib.sha256(message).hexdigest() Order_np = self.str2nparray(Order) Order_int = int(Order,16) l=(len(Order_np)-1)*32+gmpy2.bit_length(int(Order_np[-1])) m = field.str2nparray(m) size = l/32+1 m=self.remove_1(m) if(l>=256): rem=l-256 chunk_added=(rem/32)+1 m=np.append(np.zeros(chunk_added,dtype='uint32'),m) part=32-(l+chunk_added)%32 else: m = m[len(m)-size:] part = 32-l%32 X1=m>>part Y1=m<<(32-part) Z=np.bitwise_xor(Y1[1:],X1[:-1]) Z=np.append(Z,X1[-1]) Z = self.nparray2str(Z) Z = int(Z,16) Z = gmpy2.f_mod(Z,Order_int) #####Truncated Message w=gmpy2.invert(S,Order_int) u1 = gmpy2.mul(Z,w) u1 = gmpy2.f_mod(u1,Order_int) u2 = gmpy2.mul(r,w) u2 = gmpy2.f_mod(u2,Order_int) Q_A=self.public_key_gen(X,Y,A,d_A) #Q_A = d_A * G X1=self.public_key_gen(X,Y,A,int(u1)) X2=self.public_key_gen(Q_A[0],Q_A[1],A,int(u2)) #u2*Q_A X3=self.point_add(X1[0],X1[1],X2[0],X2[1],A) X3=self.nparray2str(X3[0]) X3 = gmpy2.f_mod(int(X3,16),Order_int) #print X3[0] return X3
def data_format_bind(x, y, bits): len_y = bit_length(y) x_bin = bin(x << (bits - len_y)) x_bin_str = str(x_bin) y_bin = bin(y) y_bin_str = str(y_bin) x_y_bind_str = x_bin_str[2:] + y_bin_str[2 :] x_y_bind = mpz(x_y_bind_str, 2) return x_y_bind
def signcrypt( self, Reciever, params, m): # R = g ** w mod p, w <-- Zq w, R_value = random_pick(params.p, params.q, params.g) # h1_R = H1(ID_R, X_R, Y_R) <-- Zq h1_R = H1_hash(Reciever.uid, Reciever.X_u, Reciever.Y_u, bit_length(params.q)) # V = (X_R * Y_R * (p_pub**h1_R)) ** w mod p V_value = V_compute(Reciever.X_u, Reciever.Y_u, params.p_pub, h1_R, w, params.p) # h3 = H3(V) <-- Zq h3_value = H3_hash( V_value, bit_length( params.p )) # d = H4(ID_S, m, X_S, R) <-- Zq d_value = H4_hash(self.uid, m, self.X_u, R_value, bit_length(params.q)) # f = H4(ID_S, m, Y_S, R) <-- Zq f_value = H4_hash(self.uid, m, self.Y_u, R_value, bit_length(params.q)) # U = d * (x_a + y_a) + w * f mod q U_value = t_mod((d_value * (self.x_u + self.y_u) + w * f_value), params.q) # m || U m_u_value = data_format_bind(m, U_value, bit_length(params.q)) # C = H3(V) (+) m || U C_value = h3_value ^ m_u_value # h2 = H2(ID_a, R, C) <-- Zq h2_value = H2_hash(self.uid, R_value, C_value, bit_length(params.q)) # S = w * ((x_a + y_a +h2) ** -1) mod q x_y_h_invert = invert(self.x_u + self.y_u + h2_value, params.q) S_value = t_mod(w * x_y_h_invert, params.q) # signcryption_text = (h2, S, C) Signcryption_text = (h2_value, S_value, C_value) return Signcryption_text
def unsigncrypt( self, Sender, params, Signcryption_text): # get h2, S, C h2_value = Signcryption_text[0] S_value = Signcryption_text[1] C_value = Signcryption_text[2] # h1_S = H1(ID_S, X_S, Y_S) <-- Zq h1_S = H1_hash(Sender.uid, Sender.X_u, Sender.Y_u, bit_length(params.q)) # R' = (X_S * Y_S * (p_pub**h1_S) * (g ** h2)) ** w mod p, un represent ' temp = powmod(params.g, h2_value, params.p) temp = t_mod(temp * Sender.Y_u, params.p) R_value_un = V_compute(Sender.X_u, temp, params.p_pub, h1_S, S_value, params.p) # V' = R' ** (x_b + y_b) mod q V_value_un = powmod(R_value_un, t_mod(self.x_u + self.y_u, params.q), params.p) # h3 = H3(V') <-- Zp h3_value = H3_hash(V_value_un, bit_length(params.p)) # m || U = C (+) h3 m_u_value_un = C_value ^ h3_value # get m' m_un = m_u_value_un >> bit_length(params.q) # get U' U_value_un = (m_un << bit_length(params.q)) ^ m_u_value_un # d' = H4(ID_a, m', X_a, R) <-- Zq d_value_un = H4_hash(Sender.uid, m_un, Sender.X_u, R_value_un, bit_length(params.q)) # f' = H4(ID_a, m', Y_a, R) <-- Zq f_value_un = H4_hash(Sender.uid, m_un, Sender.Y_u, R_value_un, bit_length(params.q)) # verify g ** U' == ((X_a * Y_a * (p_pub ** h1_a)) ** d') * (R' ** f') mod p # if return true, then return m'; else return None left_value = powmod(params.g, U_value_un, params.p) temp1 = V_compute(Sender.X_u, Sender.Y_u, params.p_pub, h1_S, d_value_un, params.p) temp2 = powmod(R_value_un, f_value_un, params.p) right_value = t_mod(temp1 * temp2, params.p) if left_value == right_value : return m_un
def m2list(m, bits): m_len = bit_length(m) m_number = m_len // (bits - 2) + 1 m_bin_str = bin(m) m_list = [] for x in range(m_number): if x != m_number - 1: temp_str = '1' + m_bin_str[(2 + x * (bits - 2)):(2 + (x + 1) * (bits - 2))] m_list.append(mpz(temp_str, 2)) else: temp_str = '1' + m_bin_str[(2 + x * (bits - 2)):] m_list.append(mpz(temp_str, 2)) return m_list
def bin_inverse(self,A): p=self.Polynomial.tolist() while p[-1] == 0: if len(p) == 1: break p = p[:-1] length=len(p)*32-32+gmpy2.bit_length(p[-1])-1 A=self.str2nparray(A) array=self.baumer_chain(length) C=self.inverse1(A) return C
def public_key_gen(self,x,y,a,n): sq=[] sq_x=[] public_key=[] bit_len = gmpy2.bit_length(n) ####public key generation #########3 if(n&0x1): sq_x.append(x) sq_x.append(y) for i in range(1,bit_len): if((n>>i)&0x01): sq=self.point_doubl(x,y,a) sq_x.append(sq[0]) sq_x.append(sq[1]) x=sq[0] y=sq[1] else: sq=self.point_doubl(x,y,a) x=sq[0] y=sq[1] j=0 sq=[] if(len(sq_x)==2): return sq_x[-2:] x2=sq_x[2] y2=sq_x[3] for i in range(len(sq_x)/2-1): sq = self.point_add(sq_x[j],sq_x[j+1],x2,y2,a) public_key.append(sq[0]) public_key.append(sq[1]) if(i==0): j=j+4 else: j=j+2 x2=(sq[0]) y2=(sq[1]) return public_key[-2:]
def inverse1(self,A): P=self.remove_1(self.Polynomial) l=((len(P)-1)*32)+gmpy2.bit_length(int(P[-1]))-1 array = self.baumer_chain(l) count=0 inv_array=np.array([A],dtype='uint32') prev=np.copy(A) #print array for i in range(0,len(array)-1,2): #print i x=array[i] y=array[i+1] var=y #how many time squaring #print var,x,y n=prev while(var!=0): var=var-1 sqr=self.modulus(self.square(n)) n=sqr #break if(y==1): f=A else: f=prev #print f,d mul=self.modulus(self.multiplication(f,sqr)) count+=1 prev=mul final=self.modulus(self.square(prev)) #print "number of multiplication",count #print prev #print x,y return final
def generate_strong_strong_prime(seed, min_bitsize, strong_strong_integers, number_of_strong_strong_integers, gamma, PI): """Return a strong strong prime deterministically determined from the input parameters, and what remains of the seed. Depending on the target prime size "min_bitsize", we need to find the appropriate table of first primes [p_0,...,p_{f-2},p_{f-1}] such that PI = p_0 * ... * p_{f-1} is larger than 2**(min_bitsize-2), but such that p_0 * ... * p_{f-2} is not. We'll store the primes in a table called "first_primes", such that first_primes[i] = p_i. The variable "strong_strong_integers" will be a list of lists, such that strong_strong_integers[i] is the list of integers r such that r, 2r+1 and 2(2r+1)+1 are invertible modulo first_primes[i]. Taking the inverse CRT on any [c_0,c_1,...,c_{f-1}] = [strong_strong_integers[0][i],strong_strong_integers[1][j],...,strong_strong_integers[f-1][k]] gives an integer c such that c, 2c+1, and 4c+3 are invertible modulo PI, which makes c a good candidate for being a strong strong prime generator (i.e., 4c+3 a good candidate for being a strong strong prime). The seed allows to determine in initial array [c_0,c_1,...,c_{f-1}] and thus an initial candidate c. Going from one such array to the other is done deterministically. """ # Consume the seed and update it (indexes, seed) = list_of_indexes_from_seed(seed, number_of_strong_strong_integers) candidate_nbr = 0 while True: alpha = [x[i] for x, i in zip(strong_strong_integers, indexes) ] # alpha is in Z2* x Z3* x Z5* x ..... Apply the inverse CRT c = sum([x * y for x, y in zip(alpha, gamma)]) % PI candidate_nbr += 1 if gmpy2.bit_length( c ) >= min_bitsize - 2 and subroutines.is_strong_strong_prime_generator( c): break indexes = next_indexes(indexes, number_of_strong_strong_integers) print("\tThe successful candidate is the number %d" % (candidate_nbr)) return (4 * c + 3, seed)
def Curve_Calculation(self,Polynomial): ##### breaking of curve to give only useful information ####### Curve_Polynomial=np.array([],dtype='uint8') Polynomial=self.str2nparray(Polynomial) Curve_len=(len(Polynomial)-1)*32+gmpy2.bit_length(int(Polynomial[-1]))-1 D=Polynomial.view('uint8')[::-1] D=self.remove_0(D) position=np.nonzero(D) #print position position=position[0] secnd_chunk=0x00 secnd_position=0x00 frst_chunk=D[position[1]] frst_position=(position[1]/8)*8+7-(position[1]%8) if(len(position)==3): secnd_chunk=D[position[2]] secnd_position=(position[2]/8)*8+7-(position[2]%8) Curve_Polynomial=np.array([Curve_len,frst_position,frst_chunk,secnd_position,secnd_chunk],dtype='uint8') Curve_Polynomial=self.nparray2str2(Curve_Polynomial) return Curve_Polynomial
def william_p1(n, process_id): # this algorithm technically works but literally none of the modulos were p+1 so idk # choose a B (work limit) to start with if gmpy2.bit_length(gmpy2.mpz(n)) <= 2044: work_limit = pow(n, (1 / 6)) else: work_limit = gmpy2.div(n, 27) threshold = 3 previous_sub2 = 2 # A needs to be greater than 2 to start with so we therefore start with 3 A = process_id + 3 previous = A counter = 0 # if the counter ever reaches m, terminate while counter != threshold: counter += 1 # current = (a^(current-1) - current-2) % n) current = (((A**previous) - previous_sub2) % n) # move the previous variables forward previous_sub2 = previous previous = current d = gmpy2.gcd(current - 2, n) if d != 1 and d != n: # calculate the factorial of m mult = gmpy2.fac(threshold) if DEBUG: print(d, mult) # check to see if we've found the terminating conditions for p + 1 if gmpy2.f_mod(mult, d): return d else: # increment threshold by 1 if we haven't found anything threshold += 1 if threshold > work_limit: return 1 return 1
def pollard_p1(n, process_id): # choose a B (work limit) to start with if gmpy2.bit_length(gmpy2.mpz(n)) <= 2044: work_limit = pow(n, (1 / 6)) else: work_limit = gmpy2.div(n, 27) a = 2 # break up how many things we have to check so we can split over cores process_range = (math.floor(work_limit) // PROCESS_COUNT) start = process_range * process_id end = process_range * (process_id + 1) - 1 # assign default values here so we are an excellent, coding standard following coder q1, q2, q3 = 0, 0, 0 if DEBUG: # lock processes so we can print cleanly (thanks 421) processLock.acquire() print("CORE", process_id, "checking p1 from", start, "to", end) processLock.release() # calculate the quarter ranges q1 = ((process_range // 4) * 1) + start q2 = ((process_range // 4) * 2) + start q3 = ((process_range // 4) * 3) + start for i in range(start, end): # print informative debug statements if DEBUG: if i == q1: print("CORE", process_id, "p1 25%") elif i == q2: print("CORE", process_id, "p1 50%") elif i == q3: print("CORE", process_id, "p1 75%") # check to see if we've found the terminating conditions for p - 1 a = gmpy2.powmod(a, i, n) d = gmpy2.gcd(a - 1, n) if d != 1 and d != n: return d return 1
def generate_strong_strong_prime(seed, min_bitsize,strong_strong_integers,number_of_strong_strong_integers,gamma,PI): """Return a strong strong prime deterministically determined from the input parameters, and what remains of the seed. Depending on the target prime size "min_bitsize", we need to find the appropriate table of first primes [p_0,...,p_{f-2},p_{f-1}] such that PI = p_0 * ... * p_{f-1} is larger than 2**(min_bitsize-2), but such that p_0 * ... * p_{f-2} is not. We'll store the primes in a table called "first_primes", such that first_primes[i] = p_i. The variable "strong_strong_integers" will be a list of lists, such that strong_strong_integers[i] is the list of integers r such that r, 2r+1 and 2(2r+1)+1 are invertible modulo first_primes[i]. Taking the inverse CRT on any [c_0,c_1,...,c_{f-1}] = [strong_strong_integers[0][i],strong_strong_integers[1][j],...,strong_strong_integers[f-1][k]] gives an integer c such that c, 2c+1, and 4c+3 are invertible modulo PI, which makes c a good candidate for being a strong strong prime generator (i.e., 4c+3 a good candidate for being a strong strong prime). The seed allows to determine in initial array [c_0,c_1,...,c_{f-1}] and thus an initial candidate c. Going from one such array to the other is done deterministically. """ # Consume the seed and update it (indexes, seed) = list_of_indexes_from_seed(seed, number_of_strong_strong_integers) candidate_nbr = 0 while True: alpha = [x[i] for x, i in zip(strong_strong_integers, indexes)] # alpha is in Z2* x Z3* x Z5* x ..... Apply the inverse CRT c = sum([x*y for x, y in zip(alpha, gamma)]) % PI candidate_nbr += 1 if gmpy2.bit_length(c) >= min_bitsize-2 and subroutines.is_strong_strong_prime_generator(c): break indexes = next_indexes(indexes, number_of_strong_strong_integers) print("\tThe successful candidate is the number %d"%(candidate_nbr)) return (4*c + 3,seed)
alice_public_exponent, alice_modulus)) log.info("Bob public key has public exponent {} and modulus {}".format( bob_public_exponent, bob_modulus)) # Get K1 and K2 in multi-precision form res_k1 = iroot(mpz(Converter.bytes_to_int(c1)), alice_public_exponent) res_k2 = iroot(mpz(Converter.bytes_to_int(c2)), bob_public_exponent) if (res_k1[1] and res_k2[1]): # Convert results to bytes k1 = Converter.swap_endianness(to_binary(res_k1[0]))[:-2] k2 = Converter.swap_endianness(to_binary(res_k2[0]))[:-2] # Log log.success("Finded K1, with effective length of {} bits, is {}".format( bit_length(res_k1[0]), Converter.bytes_to_hex(k1))) log.success("Finded k2, with effective length of {} bits, is: {}".format( bit_length(res_k2[0]), Converter.bytes_to_hex(k2))) else: # Force exitW log.failure("Failed to obtain K1 and K2") exit(0) # Compute key used in AES xor = bytes([_k1_char ^ _k2_char for _k1_char, _k2_char in zip(k1, k2)]) log.info("XOR between K1 and K2 is: {}".format(Converter.bytes_to_hex(xor))) k = SHA256.new(xor).digest() log.info("Key used for AES encryption is: {}".format( Converter.bytes_to_hex(k)))
def gen_mod_table(self): index = 0 p = self.Polynomial.view('uint8') p = p[::-1] while (p[0] == 0): if (len(p) == 1): break p = p[1:] f_bit_pos = gmpy2.bit_length(int(p[0])) self.Polly_byte_len = len(p) self.Polly_bit_len = f_bit_pos p = np.array(p) p1 = p >> (f_bit_pos-1) p2 = p << (9 - f_bit_pos) p1 = np.append(p1, 0) p2 = np.append(0, p2) pr = p1 ^ p2 & 0xff p1 = pr >> 1 p2 = pr << 7 p1 = np.append(p1, 0) p2 = np.append(0, p2) pl = (p1 ^ p2) & 0xff pl = pl[1:] pl[0] = pl[0] & 0x7F self.pr = pr poly_7 = [] p3 = np.append(0, pr[1:]) poly_7.append(p3) for i in range(7): p1 = p3 << (1) p2 = p3 >> (7) p2 = np.append(p2[1:], 0) p3 = (p1 ^ p2) & 0xff if not p3[0] == 0: p3 = p3 ^ pr poly_7.append(p3) index = [] for i in range(len(poly_7[0])): for j in poly_7: if j[i] != 0: index.append(i) break Polly_table = [] for i in range(256): val = np.zeros(len(poly_7[0]), dtype='uint8') for j in range(8): if ((i >> j) & 0x1): val = val ^ poly_7[j] indexed_val = [] for k in index: indexed_val.append(val[k]) Polly_table.append(np.array(indexed_val)) self.Polly_table = Polly_table self.Polly_index = index return 0
bits = 512 # 1024/2 e = 0x3 while True: p,q = gmpy2.mpz(getPrime(bits)), gmpy2.mpz(getPrime(bits)) N = gmpy2.mpz(p * q) phi = (p - 1) * (q - 1) if gcd(e, phi) == 1: break #print e, phi d = gmpy2.invert(e, phi) return (e, N), (d, N) def rsa_enc(m, (e, N)): m = a2i(m) len_m = gmpy2.bit_length(m) - 1 len_n = gmpy2.bit_length(N) - 1 if len_n < len_m: # if message is bigger than N pass else: c = gmpy2.powmod(m, e, N) return c def rsa_dec(c, (d, N)): m = gmpy2.powmod(c, d, N) return i2a(m) def a2i(m): # transform ASCII to int. return int(m.encode('hex'), 16) def i2a(i):
def main(): # Test local versions of libraries utils.test_python_version() utils.test_gmpy2_version() utils.test_pari_version() utils.test_pari_seadata() now = datetime.now() # Parse command line arguments parser = argparse.ArgumentParser(description="Generate an Edwards curve over a given prime field, suited for cryptographic purposes.") parser.add_argument("input_file", help="""JSON file containing the BBS parameters and the prime of the underlying field (typically, the output of 03_generate_prime_field_using_bbs.py. """) parser.add_argument("output_file", help="Output file where this script will write the parameter d of the curve and the current BBS parameters.") parser.add_argument("--start", type=int, help="Number of the candidate to start with (default is 1).", default=1) parser.add_argument("--max_nbr_of_tests", type=int, help="Number of candidates to test before stopping the script (default is to continue until success).") parser.add_argument("--fast", help=""" While computing a the curve cardinality with SAE, early exit when the cardinality will obviously be divisible by a small integer > 4. This reduces the time required to find the final curve, but the cardinalities of previous candidates are not fully computed. """, default=False, action="store_true") args = parser.parse_args() # Check arguments print("Checking inputs...") output_file = args.output_file if os.path.exists(output_file): utils.exit_error("The output file '%s' already exists. Exiting."%(output_file)) input_file = args.input_file with open(input_file, "r") as f: data = json.load(f) # Declare a few important variables bbs_p = int(data["bbs_p"]) bbs_q = int(data["bbs_q"]) bbs_n = bbs_p * bbs_q bbs_s = int(data["bbs_s"]) % bbs_n p = int(data["p"]) start = max(int(args.start),1) max_nbr_of_tests = None if args.max_nbr_of_tests: max_nbr_of_tests = int(args.max_nbr_of_tests) if not subroutines.is_strong_strong_prime(bbs_p): utils.exit_error("bbs_p is not a strong strong prime.") if not subroutines.is_strong_strong_prime(bbs_q): utils.exit_error("bbs_q is not a strong strong prime.") if not (subroutines.deterministic_is_pseudo_prime(p) and p%4 == 3): utils.exit_error("p is not a prime congruent to 3 modulo 4.") # Initialize BBS print("Initializing BBS...") bbs = bbsengine.BBS(bbs_p, bbs_q, bbs_s) # Info about the prime field utils.colprint("Prime of the underlying prime field:", "%d (size: %d)"%(p, gmpy2.bit_length(p))) size = gmpy2.bit_length(p) # total number of bits queried to bbs for each test # Skip the first "start" candidates candidate_nbr = start-1 bbs.skipbits(size * (start-1)) # Start looking for "d" while True: if max_nbr_of_tests and candidate_nbr >= start + max_nbr_of_tests - 1: print("Did not find an adequate parameter, starting at candidate %d (included), limiting to %d candidates."%(start, max_nbr_of_tests)) utils.exit_error("Last candidate checked was number %d."%(candidate_nbr)) candidate_nbr += 1 bits = bbs.genbits(size) d = 0 for bit in bits: d = (d << 1) | bit print("The candidate number %d is d = %d (ellapsed time: %s)"%(candidate_nbr, d, str(datetime.now()-now))) # Test 1 if not utils.check(d != 0 and d < p, "d != 0 and d < p", 1): continue # Test 2 if not utils.check(gmpy2.legendre(d, p) == -1, "d is not a square modulo p", 2): continue # Test 3 if args.fast: cardinality = subroutines.sea_edwards(1, d, p, 4) else: cardinality = subroutines.sea_edwards(1, d, p) assert(cardinality % 4 == 0) q = cardinality>>2 if not utils.check(subroutines.deterministic_is_pseudo_prime(q), "The curve cardinality / 4 is prime", 3): continue # Test 4 trace = p+1-cardinality cardinality_twist = p+1+trace assert(cardinality_twist % 4 == 0) q_twist = cardinality_twist>>2 if not utils.check(subroutines.deterministic_is_pseudo_prime(q_twist), "The twist cardinality / 4 is prime", 4): continue # Test 5 if not utils.check(q != p and q_twist != p, "Curve and twist are safe against additive transfer", 5): continue # Test 6 embedding_degree = subroutines.embedding_degree(p, q) if not utils.check(embedding_degree > (q-1) // 100, "Curve is safe against multiplicative transfer", 6): continue # Test 7 embedding_degree_twist = subroutines.embedding_degree(p, q_twist) if not utils.check(embedding_degree_twist > (q_twist-1) // 100, "Twist is safe against multiplicative transfer", 7): continue # Test 8 D = subroutines.cm_field_discriminant(p, trace) if not utils.check(abs(D) >= 2**100, "Absolute value of the discriminant is larger than 2^100", 8): continue break # Find a base point while True: bits = bbs.genbits(size) y = 0 for bit in bits: y = (y<<1) | bit u = int((1 - y**2) * gmpy2.invert(1 - d*y**2, p)) % p if gmpy2.legendre(u, p) == -1: continue x = gmpy2.powmod(u, (p+1) // 4, p) (x,y) = subroutines.add_on_edwards(x, y, x, y, d, p) (x,y) = subroutines.add_on_edwards(x, y, x, y, d, p) if (x, y) == (0, 1): continue assert((x**2 + y**2) % p == (1 + d*x**2*y**2) % p) break # Print some informations utils.colprint("Number of the successful candidate:", str(candidate_nbr)) utils.colprint("Edwards elliptic curve parameter d is:", str(d)) utils.colprint("Number of points:", str(cardinality)) utils.colprint("Number of points on the twist:", str(cardinality_twist)) utils.colprint("Embedding degree of the curve:", "%d"%embedding_degree) utils.colprint("Embedding degree of the twist:", "%d"%embedding_degree_twist) utils.colprint("Discriminant:", "%d"%D) utils.colprint("Trace:", "%d"%trace) utils.colprint("Base point coordinates:", "(%d, %d)"%(x, y)) # Save p, d, x, y, etc. to the output_file print("Saving the parameters to %s"%output_file) bbs_s = bbs.s with open(output_file, "w") as f: json.dump({"p": int(p), "bbs_p": int(bbs_p), "bbs_q": int(bbs_q), "bbs_s": int(bbs_s), "candidate_nbr": int(candidate_nbr), "d": int(d), "cardinality": cardinality, "cardinality_twist": cardinality_twist, "embedding_degree": embedding_degree, "embedding_degree_twist": embedding_degree_twist, "discriminant": D, "trace": trace, "base_point_x": x, "base_point_y": y}, f, sort_keys=True)
def partialkey_compute(self, User): r_u, User.Y_u = random_pick(self.p, self.q, self.g) User.y_u = t_mod((r_u + t_mod( self.s * H1_hash(User.uid, User.X_u, User.Y_u, bit_length(self.q)), self.q)), self.q)
def main(): # Test local versions of libraries utils.test_python_version() utils.test_gmpy2_version() # Parse command line arguments parser = argparse.ArgumentParser(description="Generate a prime field, suited for being the underlying field of a twist-secure Edwards curve.") parser.add_argument("input_file", help="JSON file containing the BBS parameters (typically, the output of 02_generate_bbs_parameters.py).") parser.add_argument("output_file", help="Output file where this script will write the prime of the field and the current BBS parameters.") parser.add_argument("prime_size", type=int, help="Size of the prime (e.g. 256 bits)") args = parser.parse_args() # Check arguments output_file = args.output_file if os.path.exists(output_file): utils.exit_error("The output file '%s' already exists. Exiting."%(output_file)) size = int(args.prime_size) input_file = args.input_file with open(input_file, "r") as f: data = json.load(f) bbs_p = int(data["bbs_p"]) bbs_q = int(data["bbs_q"]) bbs_n = bbs_p * bbs_q bbs_s = int(data["bbs_s"]) % bbs_n # Check inputs print("Checking inputs...") if not subroutines.is_strong_strong_prime(bbs_p): utils.exit_error("bbs_p is not a strong strong prime.") if not subroutines.is_strong_strong_prime(bbs_q): utils.exit_error("bbs_q is not a strong strong prime.") # Initialize BBS bbs = bbsengine.BBS(bbs_p, bbs_q, bbs_s) # generate a "size"-bit prime "p" candidate_nbr = 0 print("Generating a prime field Fp (where p is congruent to 3 mod 4)...") while True: candidate_nbr += 1 bits = [1] + bbs.genbits(size-3) + [1,1] assert(len(bits) == size) p = 0 for bit in bits: p = (p << 1) | bit assert(p % 4 == 3) assert(gmpy2.bit_length(p) == size) if subroutines.deterministic_is_pseudo_prime(p): break utils.colprint("%d-bit prime found:"%size, str(p)) utils.colprint("The good candidate was number: ", str(candidate_nbr)) # Save p and the current bbs parameters to the output_file print("Saving p and the BBS parameters to %s"%(output_file)) bbs_s = bbs.s with open(output_file, "w") as f: json.dump({"p": int(p), "bbs_p": int(bbs_p), "bbs_q": int(bbs_q), "bbs_s": int(bbs_s)}, f, sort_keys=True)
def modulus1 (self, A): B = np.copy(A) p1 = B.view('uint8') p = p1[::-1] byte_len = self.Polly_byte_len bit_len = self.Polly_bit_len while p[0] == 0: if len(p) == 1: break p = p[1:] '''Reduction based on lookup tables''' while len(p) > byte_len: red_poly = self.Polly_table[p[0]] for j,k in zip(red_poly, self.Polly_index): if j != 0: p[k] ^= j p = p[1:] while p[0] == 0: if len(p) == 1: break p = p[1:] print p while p[0] == 0: if len(p) == 1: break p = p[1:] if (len(p)+1 < self.Polly_index[-1]): return p r = p[0] & (gmpy2.bit_mask(bit_len-1) ^ 0xFF) if r != 0: '''Last byte reduction when polynomial is equal to primitive''' if (len(p) == self.Polly_index[-1]): red_poly = self.Polly_table[r] for j,k in zip(red_poly, self.Polly_index): if (k < len(p)): p[k] ^= j p[-1] ^= r else: '''Reduction by hand''' while r != 0: f_bit_pos = gmpy2.bit_length(r) p1 = self.pr << (f_bit_pos -1) p2 = self.pr >> (9 - f_bit_pos) p1 = p1[:-1] p2 = p2[1:] p = p ^ p1 ^ p2 r = p[-1] & (gmpy2.bit_mask(bit_len-1) ^ 0xFF) while p[0] == 0: if len(p) == 1: break p = p[1:] p = p[::-1] q = np.append(np.zeros(4 - len(p)%4, dtype=np.int8), p) q = np.array(q, dtype='uint8') q = np.getbuffer(q) q = np.frombuffer(q, dtype='uint32') return q
def main(): print("##### Part 2 #####") # get the modulo we want to factor from the command line n = int(sys.argv[1]) gmpy2.get_context().precision = 4096 # variable to monitor when any process finishes sync = multiprocessing.Event() # Queue to hold the return value of the function so we can use it again in the main process output_q = multiprocessing.Queue() # check the factors of all numbers in batch modulo = n print("Attempting to find factors of", modulo) bit_size = gmpy2.bit_length(gmpy2.mpz(modulo)) print("Modulo size:", bit_size) curr_time = datetime.now().time() print("Start Time:", curr_time) # check if n is prime if gmpy2.is_prime(modulo): print("This probably shouldn't happen but n is prime", modulo) return 0 # start PROCESS_COUNT amount of processes for i in range(0, PROCESS_COUNT): process = multiprocessing.Process(target=break_primes, args=(modulo, i, sync, output_q)) PROCESSES.append(process) process.start() # wait until any of the processes find something then kill the others sync.wait() # kill the remaining processes once the factor has been found for i in PROCESSES: if DEBUG: print("Killing processes") i.terminate() # join processes back to spawning process for i in PROCESSES: i.join() # manage the queue so we can get returns from the processes output_q.put('extra value to make the queue happy') if DEBUG: print("Queue Size", output_q.qsize()) # get the value back from the process result = output_q.get() if DEBUG: print("Queue Size", output_q.qsize()) # clean up the queue while not output_q.empty(): if DEBUG: print("Cleaning") output_q.get_nowait() sync.clear() # print ending time curr_time = datetime.now().time() print("End Time:", curr_time) if DEBUG: print("Factor of n is:", result)