def main2(): print("MAIN 2:") print(gauss(Integer(2), Integer(13))) print(legendre_symbol(Integer(2), Integer(13))) print(gauss(Integer(2), Integer(31))) print(legendre_symbol(Integer(2), Integer(31))) print()
def attack(p, h, c1, c2): """ Returns the Legendre symbol of the message encrypted using an unsafe generator. :param p: the prime used in the ElGamal scheme :param h: the public key :param c1: the ciphertext :param c2: the ciphertext :return: the Legendre symbol """ return int( legendre_symbol(c2, p) // max(legendre_symbol(h, p), legendre_symbol(c1, p)))
def split_class(label, p): """given the label of one curve E in a p-irreducible isogeny class, return the list of all labels of curves in that class, partitioned into 2 parts where those in the first part are m-isogenous to E with legendre(m,p)=+1 and those in the second part (which may be empty) are m-isogenous to E with legendre(m,p)=-1. """ C = CDB.isogeny_class(label) isodict = {Elabel(E): E.isogeny_degree(C[0]) for E in C} set1 = [lab for lab in isodict if legendre_symbol(isodict[lab], 7) == +1] set2 = [lab for lab in isodict if legendre_symbol(isodict[lab], 7) == -1] return [set1, set2]
def main4(): print("MAIN 4:") zeta = CDF(exp(Integer(2) * pi * I / Integer(5))) print(zeta) v = [legendre_symbol(n, Integer(5)) * zeta**(Integer(2) * n) for n in range(Integer(1), Integer(5))] S = sum([point(tuple(z), pointsize=Integer(100)) for z in v]) G = point(tuple(sum(v)), pointsize=Integer(100), rgbcolor='red') (S + G).save(filename="gauss_sum.png") print()
def satisfies_condition_CC_uniform(possible_odd_f, p): """Determine whether degrees,p satisfies condition CC. Args: K ([NumberField]): the number field p ([Prime]): the prime p Returns: boolean """ if p % 4 == 1 or p == 2: return False for q in prime_range((p / 4) ^ (1 / max(possible_odd_f)) + 1): if legendre_symbol(q, p) == 1: if all((q**(2 * f) + q**f + 1) % p != 0 for f in possible_odd_f): return False return True
def satisfies_condition_CC(K, p): """Determine whether K,p satisfies condition CC. Args: K ([NumberField]): the number field p ([Prime]): the prime p Returns: boolean """ for q in prime_range(p / 4): if (q ** 2 + q + 1) % p != 0: if not K.ideal(q).is_prime(): if legendre_symbol(q, p) == 1: # i.e. not inert return False return True
def test_unsafe_generator(self): # Safe prime. p = 16902648776703029279 # Unsafe generator, generates the entire group. g = 7 for i in range(100): x = randint(1, p - 1) h = pow(g, x, p) y = randint(1, p - 1) s = pow(h, y, p) c1 = pow(g, y, p) m = randint(1, p - 1) c2 = m * s % p k = self.unsafe_generator.attack(p, h, c1, c2) self.assertIsInstance(k, int) self.assertEqual(legendre_symbol(m, p), k)
def satisfies_condition_CC(K, p): """Determine whether K,p satisfies condition CC. Args: K ([NumberField]): the number field p ([Prime]): the prime p Returns: boolean """ for q in prime_range(p / 4): for frak_q in K.primes_above(q): f = frak_q.residue_class_degree() if f % 2 == 1 and q**f < p / 4: if (q**(2 * f) + q**f + 1) % p != 0: if legendre_symbol(q, p) == 1: # i.e. not inert return False return True
def jordan_blocks_odd(S, p): ''' p: odd prime, S: half integral matrix. Let S ~ sum p**a_i * b_i * x_i^2 be a jordan decomposition. Returns the instance of JordanBlocks attached to a list of (a_i, b_i) sorted so that a_0 >= a_1 >= ... ''' p = Integer(p) res = [] u = least_quadratic_nonresidue(p) for e, ls in groupby(_jordan_decomposition_odd_p(S, p), key=lambda x: valuation(x, p)): ls = [x // p ** e for x in ls] part_res = [(e, ZZ(1)) for _ in ls] if legendre_symbol(mul(ls), p) == -1: part_res[-1] = (e, u) res.extend(part_res) return JordanBlocks(list(reversed(res)), p)
def find_sqrt(a, p): assert (p - Integer(1)) % Integer(4) == Integer(0) assert legendre_symbol(a, p) == Integer(1) S = PolynomialRing(GF(p), names=('x',)) (x,) = S.gens() R = S.quotient(x**Integer(2) - a, names=('alpha',)) (alpha,) = R.gens() while True: z = GF(p).random_element() w = (Integer(1) + z * alpha)**((p - Integer(1)) // Integer(2)) (u, v) = (w[Integer(0)], w[Integer(1)]) if v != Integer(0): break if (-u / v)**Integer(2) == a: return -u / v if ((Integer(1) - u) / v)**Integer(2) == a: return (Integer(1) - u) / v if ((-Integer(1) - u) / v)**Integer(2) == a: return (-Integer(1) - u) / v
def _generate_s(bases, k2, k3): s = [] for b in bases: s_b = set() for p in range(1, 4 * b, 2): if legendre_symbol(b, p) == -1: s_b.add(p) s.append(s_b) for i in range(len(s)): mod = 4 * bases[i] inv2 = inverse_mod(k2, mod) inv3 = inverse_mod(k3, mod) s2 = set() s3 = set() for z in s[i]: s2.add(inv2 * (z + k2 - 1) % mod) s3.add(inv3 * (z + k3 - 1) % mod) s[i] &= s2 & s3 return s
def t(m): if p.divides(m): return 2 + (1 - legendre_symbol(m // p, p)) // 2 else: return (1 - legendre_symbol(m, p)) // 2
def get_type_1_primes(K, aux_prime_count=3, loop_curves=False): """Compute the type 1 primes""" C_K = K.class_group() aux_primes = [Q_2] prime_to_append = Q_2 for _ in range(1, aux_prime_count): prime_to_append = next_prime(prime_to_append) aux_primes.append(prime_to_append) # We need at least one aux prime that splits to have provable termination my_legendre_symbols = set([legendre_symbol(K._D, p) for p in aux_primes]) if 1 not in my_legendre_symbols: prime_to_append = next_prime(prime_to_append) while legendre_symbol(K._D, prime_to_append) != 1: prime_to_append = next_prime(prime_to_append) aux_primes.append(prime_to_append) D_dict = {} for q in aux_primes: frak_q = K.primes_above(q)[0] residue_field = frak_q.residue_field(names="z") residue_field_card = residue_field.cardinality() frak_q_class_group_order = C_K(frak_q).multiplicative_order() exponent = 12 * frak_q_class_group_order running_D = q if loop_curves: weil_polys = get_weil_polys(residue_field) else: weil_polys = R.weil_polynomials(2, residue_field_card) # First add the C((0,0), frak_q) terms for wp in weil_polys: D = get_C00(wp, residue_field_card, exponent) D = Integer(D) # If q splits then we know C((0,0),frak_q) is non-zero # so we can insist on only adding D if it is non-zero if legendre_symbol(K._D, q) == 1: if D != 0: running_D = lcm(running_D, D) else: # Here we do not provably know that the integer is non-zero # so add it directly to the running_D running_D = lcm(running_D, D) # Put the other term in the lcm before adding to dictionary running_D = lcm(residue_field_card ** exponent - 1, running_D) D_dict[q] = running_D output = gcd(list(D_dict.values())) output = set(output.prime_divisors()) # Add the bad formal immersion primes output = output.union(set(prime_range(62)), {71}) # Sort and return output = list(output) output.sort() return output
def gauss_sum(a, p): K = CyclotomicField(p, names=('zeta',)) (zeta,) = K.gens() return sum(legendre_symbol(n, p) * zeta**(a * n) for n in range(Integer(1), p))