def sign(self, pk, sk, message, s=0): if debug: print("Sign...") L, K, c, keyLength, u, h, N = pk['L'], pk['K'], pk['c'], pk['length'], pk['u'], pk['h'], pk['N'] p, q = sk['p'], sk['q'] # Use internal state counter if none was provided if (s == 0): s = self.state self.state += 1 s += 1 # Hash the message using the chameleon hash under params L to obtain (x, r) (x, r) = self.ChameleonHash.hash(L, message); # Compute e = H_k(s) and check whether it's prime. If not, increment s and repeat. phi_N = (p-1)*(q-1) e = self.HW_hash(K, c, s, keyLength) e1 = e % phi_N e2 = e % N while (not (isPrime(e2))) or (not gcd(e1, phi_N) == 1): s += 1 e = self.HW_hash(K, c, s, keyLength) e1 = e % phi_N e2 = e % N e = e1 # Compute B = SQRT(u^x * h)^ceil(log_2(s)) mod N # Note that SQRT requires the factorization p, q temp = ((u ** x) * h) % N power = ((((p-1)*(q-1))+4)/8) ** int(math.ceil(log[2](s))) B = temp ** power sigma1 = (B ** (e ** -1)) % N # Update internal state counter and return sig = (sigma1, r, s) self.state = s return { 'sigma1':sigma1, 'r': r, 's': s, 'e':e }
def paramgen(self, secparam): while True: p, q = randomPrime(secparam), randomPrime(secparam) if isPrime(p) and isPrime(q) and gcd(p * q, (p - 1) * (q - 1)) == 1: break self.p = p self.q = q return (p, q, p * q)
def encrypt(self, pk, m): (n, x) = pk y = self.group.random() while gcd(n, y) != 1: y = self.group.random() if m == 0: return y**2 % n else: return y**2 * x % n
def keygen(self, secparam=1024, params=None): if params: (N, e, d, p, q) = self.convert(params) phi_N = (p - 1) * (q - 1) pk = {'N': N, 'e': e} sk = {'phi_N': phi_N, 'd': d, 'N': N} return (pk, sk) (p, q, N, phi_N) = self.paramgen(secparam) while True: e = random(phi_N) if not gcd(e, phi_N) == 1: continue d = e**-1 break pk = {'N': N, 'e': toInt(e)} # strip off \phi sk = {'phi_N': phi_N, 'd': d, 'N': N} return (pk, sk)
def keygen(self, secparam=1024, params=None): if params: (N, e, d, p, q) = self.convert(params) phi_N = (p - 1) * (q - 1) pk = { 'N':N, 'e':e } sk = { 'phi_N':phi_N, 'd':d , 'N':N} return (pk, sk) (p, q, N, phi_N) = self.paramgen(secparam) while True: e = random(phi_N) if not gcd(e, phi_N) == 1: continue d = e ** -1 break pk = { 'N':N, 'e':toInt(e) } # strip off \phi sk = { 'phi_N':phi_N, 'd':d , 'N':N} return (pk, sk)
def __init__(self, secparam): # generate p,q while True: p, q = randomPrime(secparam), randomPrime(secparam) if isPrime(p) and isPrime(q) and p != q: N = p * q phi = (p - 1) * (q - 1) break # calculate private key and public key while True: e = random(phi) if not gcd(e, phi) == 1: continue d = e**-1 break # prepare public key self.pk = {'N': N, 'e': toInt(e)} # prepare private key self.sk = {'phi': phi, 'd': d, 'N': N}
def sign(self, pk, sk, message, s=0): if debug: print("Sign...") L, K, c, keyLength, u, h, N = pk['L'], pk['K'], pk['c'], pk[ 'length'], pk['u'], pk['h'], pk['N'] p, q = sk['p'], sk['q'] # Use internal state counter if none was provided if (s == 0): s = self.state self.state += 1 s += 1 # Hash the message using the chameleon hash under params L to obtain (x, r) (x, r) = self.ChameleonHash.hash(L, message) # Compute e = H_k(s) and check whether it's prime. If not, increment s and repeat. phi_N = (p - 1) * (q - 1) e = self.HW_hash(K, c, s, keyLength) e1 = e % phi_N e2 = e % N while (not (isPrime(e2))) or (not gcd(e1, phi_N) == 1): s += 1 e = self.HW_hash(K, c, s, keyLength) e1 = e % phi_N e2 = e % N e = e1 # Compute B = SQRT(u^x * h)^ceil(log_2(s)) mod N # Note that SQRT requires the factorization p, q temp = ((u**x) * h) % N power = ((((p - 1) * (q - 1)) + 4) / 8)**(math.ceil(log[2](s))) B = temp**power sigma1 = (B**(e**-1)) % N # Update internal state counter and return sig = (sigma1, r, s) self.state = s return {'sigma1': sigma1, 'r': r, 's': s, 'e': e}
def is_cyclic(a, n): one = integer(1, n) return gcd(a + one, n) == 1 or gcd(a - one, n) == 1
while True: q = randomPrime(prime_bits, 1) q_prime = (q - 1) / 2 if (isPrime(q) and isPrime(q_prime)): break N = p * q group_order = 2 * p_prime * q_prime # order of L_DCR N_square = N * N print('p = ', p) print('q = ', q) # search the generator for L_DCR tmp = 0 while True: tmp = random(N_square) if (gcd(tmp, N_square) == 1): break val1 = (tmp**(2 * N)) % N_square print('val1 = ', val1) print('toInt(val1) = ', toInt(val1)) g = N_square - toInt(val1) g = g % N_square print('g = ', g) alpha_value = random(N_square / 2) # of length bits beta_value = random(N_square / 2) hp_1_value = (g**alpha_value) % N_square hp_2_value = (g**beta_value) % N_square # t_1(k) and u(k) are calculated from the length of r and x