def tonelli_shanks(p, n): Q = p - 1 S = 0 while Q % 2 == 0: Q //= 2 S += 1 for z in range(3, p - 1): # Assume p = +-1 (mod 8), so 2 is a quad residue if powmod(z, (p - 1) // 2, p) == p - 1: break M = S c = powmod(z, Q, p) t = powmod(n, Q, p) R = powmod(n, (Q + 1) // 2, p) while t != 1: # Assume t != 0 i = 0 tsq = t while tsq != 1: i += 1 tsq = (tsq * tsq) % p b = powmod(c, 2**(M - i - 1), p) M = i c = (b * b) % p t = (t * c) % p R = (R * b) % p return min(R, p - R)
def S(n): primes = get_primes_up_to_n(n) # Get prime factorisation of 1, 2, ..., n prime_factors = get_prime_factors(n, primes) # Numba doesn't support axis argument for np.cumsum()... prime_factor_sums = cumsum_axis0(prime_factors) # Calculate modular inverse of p - 1 for all primes p inverses = inv(primes - 1, MOD) # Iteratively get prime factorisation of B(1), B(2), ..., B(n), then use # this to compute and sum D(1), D(2), ..., D(n) total = 0 bn_prime_factors = np.zeros_like(primes, dtype=np.int32) for m in range(n): bn_prime_factors += m * prime_factors[m] if m > 0: bn_prime_factors -= prime_factor_sums[m - 1] div_sum = 1 for i in range(len(primes)): if bn_prime_factors[i] > 0: div_sum *= powmod(primes[i], bn_prime_factors[i] + 1, MOD) - 1 div_sum %= MOD div_sum *= inverses[i] div_sum %= MOD total += div_sum total %= MOD return total
def gen_params(bits): while True: ptildprim = utils.randomnumber(pow(2, bits >> 1)) qtildprim = utils.randomnumber(pow(2, bits >> 1)) ptild = (2 * ptildprim + 1) qtild = (qtildprim + 1) if utils.is_prime(ptild) and utils.is_prime(qtild): break ntild = ptild * qtild pq = ptildprim * qtildprim while True: h2 = utils.randomnumber(ntild) if utils.nonrec_gcd(h2, ntild) == 1 and utils.powmod(h2, pq, ntild) == 1: break x = utils.randomnumber(pq) h1 = utils.powmod(h2, x, ntild) return ntild, h1, h2
def pi2_verify(pi2, c, d, w1, w2, m1, m2, m3, m4, zkpparam, ka_pub, kb_pub): (z1, u1, u2, u3, z2, z3, y, v1, v2, v3, v4, v5, s1, s2, s3, s4, t1, t2, t3, t4, t5, t6, e) = pi2 pkn, g = ka_pub pkn2 = pkn * pkn pknprim, gprim = kb_pub pknprim2 = pknprim * pknprim ntild, h1, h2 = zkpparam q3 = pow(dsa.Q, 3) q7 = pow(dsa.Q, 7) if s1 > q3 or t1 > q3: return False if t5 > q7: return False if not pow(c, s1, dsa.P) == (pow(w1, e, dsa.P) * u1) % dsa.P: return False verif1 = (pow(gprim, s4, pknprim2) * pow(s2, pknprim, pknprim2)) % pknprim2 verif2 = (pow(m1, e, pknprim2) * u2) % pknprim2 if not verif1 == verif2: return False if (not (pow(h1, s1, ntild) * pow(h2, s3, ntild)) % ntild == (pow(z1, e, ntild) * u3) % ntild): return False if not (pow(d, t1 + t2, dsa.P)) == (pow(y, e, dsa.P) * v1) % dsa.P: return False verif1 = (pow(m3, s4, pkn2) * pow(m4, t1, pkn2) * (utils.powmod(g, dsa.Q * t5, pkn2) * utils.powmod(t3, pkn, pkn2)) % pkn2) % pkn2 verif2 = (pow(m2, e, pkn2) * v3) % pkn2 if not verif1 == verif2: return False verif1 = (pow(h1, t1, ntild) * pow(h2, t4, ntild)) % ntild verif2 = (pow(z2, e, ntild) * v4) % ntild if not verif1 == verif2: return False verif1 = (pow(h1, t5, ntild) * pow(h2, t6, ntild)) % ntild verif2 = (pow(z3, e, ntild) * v5) % ntild if not verif1 == verif2: return False return True
def sign(m, p, q, g, x): k = utils.randomnumber(q - 1, inf=2) while True: r = utils.powmod(g, k, p) % q if r == 0: k = utils.randomnumber(q, inf=2) continue break inv = utils.invert(k, q) h = m + x * r s = inv * h % q return r, s
def count_primes(n_max): tn_is_prime = np.ones(n_max + 1, dtype=np.bool) primes = [ p for p in get_primes_up_to_n(int(2**0.5 * n_max)) if p % 8 in (1, 7) ] for p in primes: if p % 8 == 7: # In this case, square root is easy to find r = powmod((p - 1) // 2, (p + 1) // 4, p) r = min(r, p - r) else: r = tonelli_shanks(p, (p + 1) // 2) tn_is_prime[p - r::p] = False tn_is_prime[p + r::p] = False return np.sum(tn_is_prime[2:])
def checking_p(b, lmd, B_h): p3_next_list = [] ###Случай подбора r = powmod(b, -1, lmd) p = r if primes[-1] < B_h / b: bound = primes[-1] else: bound = B_h / b while p < bound: if numth.is_prime(int(p)): p3_next_list.append(p) p += lmd return p3_next_list
def alice_round_2(alpha, zeta, r2, k1, y1, z1, x1, zkpa, ka_pub, rr1, rr2): N, h1, h2 = zkpa eta1 = z1 eta2 = (x1 * z1) % dsa.Q r = utils.powmod(r2, k1, dsa.P) c = r d = dsa.G w1 = r2 w2 = y1 m1 = alpha m2 = zeta x1 = eta1 x2 = eta2 r1 = rr1 r2 = rr2 pi = zkp.pi(c, d, w1, w2, m1, m2, r1, r2, x1, x2, N, h1, h2, ka_pub) return r, pi
def evalcurve(x): a = 5472060717959818805561601436314318772174077789324455915672259473661306552146 beta = addmodp(mulmodp(mulmodp(x, x), x), 3) y = powmod(beta, a, field_modulus) return (beta, y)
def mult(cipher, scalar, n2): return utils.powmod(cipher, scalar, n2)
def decrypt(c, priv): n, p, q, g, lmdba, mu = priv n2 = n * n return L(utils.powmod(c, lmdba, n2), n) * mu % n
def bob_round_1(alpha, zeta): k2 = utils.randomnumber(dsa.Q - 1, inf=2) r2 = utils.powmod(dsa.G, k2, dsa.P) return k2, r2
if __name__ == "__main__": print("S-DSA") # Aclice x1 = utils.randomnumber(dsa.Q, inf=2) y1 = dsa.gen_pub(x1, dsa.G, dsa.P, dsa.Q) ka_pub, ka_priv = paillier.gen_key() zkpa = zkp.gen_params(1024) # Bob x2 = utils.randomnumber(dsa.Q, inf=2) y2 = dsa.gen_pub(x2, dsa.G, dsa.P, dsa.Q) kb_pub, kb_priv = paillier.gen_key() y_x = dsa.gen_pub(x1 * x2 % dsa.Q, dsa.G, dsa.P, dsa.Q) y_a = utils.powmod(y2, x1, dsa.P) y_b = utils.powmod(y1, x2, dsa.P) # Message hash message = "hello" h = hashlib.sha256() h.update(message.encode("utf-8")) m = long(h.hexdigest(), 16) # ALICE ROUND 1 k1, z1, alpha, zeta, rr1, rr2 = alice_round_1(m, x1, y1, ka_pub, ka_priv) # BOB ROUND 1 k2, r2 = bob_round_1(alpha, zeta) # ALICE ROUND 2 r, pi = alice_round_2(alpha, zeta, r2, k1, y1, z1, x1, zkpa, ka_pub, rr1, rr2)
def check_for_psp(a, n): mod = powmod(a, n - 1, n) if mod == 1: return True else: return False
def gen_pub(x, g, p, q): if 0 < x and x < q: return utils.powmod(g, x, p)
def gen_key(p, q, g): # 0 < x < q x = utils.randomnumber(q, inf=0) if 0 < x and x < q: y = utils.powmod(g, x, p) return x, y
def S(p): inv_2 = powmod(2, p - 2, p) inv_6 = powmod(6, p - 2, p) inv_24 = (inv_2 * inv_2 * inv_6) % p inv_24 = (((inv_2 * inv_2) % p) * inv_6) % p return (-inv_2 + inv_6 - inv_24) % p
# print(pub, priv) s1 = 180 s2 = 10 print(s1) print(s2) c1, r1 = encrypt(s1, pub) c2, r2 = encrypt(s2, pub) # print(c1) # print(c2) # Homomorphic properties cadd = c1 * c2 % n2 # print(cadd) cmult = utils.powmod(c1, 20, n2) # print(cmult) # (180 + 10) * 10 + 180 = 2'080 test = add(mult(add(c1, c2, n2), 10, n2), c1, n2) # 180 * 100 + 180 * 100 = 36'000 test2 = add(mult(c1, 100, n2), mult(c1, 100, n2), n2) madd = decrypt(cadd, priv) mmult = decrypt(cmult, priv) mtest = decrypt(test, priv) mtest2 = decrypt(test2, priv) m1 = decrypt(c1, priv) m2 = decrypt(c2, priv) print("add c1 + c2:", madd)
def encrypt(m, pub): n, g = pub n2 = n * n r = R(n) return (utils.powmod(g, m, n2) * utils.powmod(r, n, n2)) % n2, r
def inv(x, mod): return powmod(x, mod - 2, mod)
def test_powmod(): for x in range(1, 5): for y in range(1, 5): for mod in range(1, 5): assert utils.powmod(x, y, mod) == pow(x, y, mod)