def reduce(self, a, N): r""" Return an approximation of ``a`` which is reduced modulo `p^N`. INPUT: - ``a`` -- an element of the underlying number field `K` - ``N`` -- a positive Integer OUTPUT: an element `\tilde{a}` of `K` which is congruent to `a` modulo `p^N`, and whose representation in terms of the canonical integral basis of `K` has coefficents of the form `c/p^m`, with `0\leq c < p^N` and `m\geq 0`. """ v_p = self.base_valuation() p = self.p() if self.is_Qp(): # a should be a rational number m = max(-v_p(a), 0) b = a*p**m q = p**(N+m) return QQ(mod(b, q).lift()*p**(-m)) v = self.vector(a) vt = [] for i in range(len(v)): a = v[i] m = max(-v_p(a), 0) b = a*p**m q = p**(N+m) at = mod(b, q).lift()*p**(-m) vt.append(at) return self.element_from_vector(vector(vt))
def id_dirichlet(fun, N, n): N = Integer(N) if N == 1: return (1, 1) p2 = valuation(N, 2) N2 = 2**p2 Nodd = N // N2 Nfact = list(factor(Nodd)) #print "n = "+str(n) #for j in range(20): # print "chi(%d) = e(%d/%d)"%(j+2, fun(j+2,n), n) plist = [z[0] for z in Nfact] ppows = [z[0]**z[1] for z in Nfact] ppows2 = list(ppows) idems = [1 for z in Nfact] proots = [primitive_root(z) for z in ppows] # Get CRT idempotents if p2 > 0: ppows2.append(N2) for j in range(len(plist)): exps = [1 for z in idems] if p2 > 0: exps.append(1) exps[j] = proots[j] idems[j] = crt(exps, ppows2) idemvals = [fun(z, n) for z in idems] # now normalize to right root of unity base idemvals = [ idemvals[j] * euler_phi(ppows[j]) / n for j in range(len(idemvals)) ] ans = [ Integer(mod(proots[j], ppows[j])**idemvals[j]) for j in range(len(proots)) ] ans = crt(ans, ppows) # There are cases depending on 2-part of N if p2 == 0: return (N, ans) if p2 == 1: return (N, crt([1, ans], [2, Nodd])) if p2 == 2: my3 = crt([3, 1], [N2, Nodd]) if fun(my3, n) == 0: return (N, crt([1, ans], [4, Nodd])) else: return (N, crt([3, ans], [4, Nodd])) # Final case 2^3 | N my5 = crt([5, 1], [N2, Nodd]) test1 = fun(my5, n) * N2 / 4 / n test1 = Integer(mod(5, N2)**test1) minusone = crt([-1, 1], [N2, Nodd]) test2 = (fun(minusone, n) * N2 / 4 / n) % (N2 / 4) if test2 > 0: test1 = Integer(mod(-test1, N2)) return (N, crt([test1, ans], [N2, Nodd]))
def id_dirichlet(fun, N, n): N = Integer(N) if N == 1: return (1, 1) p2 = valuation(N, 2) N2 = 2 ** p2 Nodd = N / N2 Nfact = list(factor(Nodd)) # print "n = "+str(n) # for j in range(20): # print "chi(%d) = e(%d/%d)"%(j+2, fun(j+2,n), n) plist = [z[0] for z in Nfact] ppows = [z[0] ** z[1] for z in Nfact] ppows2 = list(ppows) idems = [1 for z in Nfact] proots = [primitive_root(z) for z in ppows] # Get CRT idempotents if p2 > 0: ppows2.append(N2) for j in range(len(plist)): exps = [1 for z in idems] if p2 > 0: exps.append(1) exps[j] = proots[j] idems[j] = crt(exps, ppows2) idemvals = [fun(z, n) for z in idems] # now normalize to right root of unity base idemvals = [idemvals[j] * euler_phi(ppows[j]) / n for j in range(len(idemvals))] ans = [Integer(mod(proots[j], ppows[j]) ** idemvals[j]) for j in range(len(proots))] ans = crt(ans, ppows) # There are cases depending on 2-part of N if p2 == 0: return (N, ans) if p2 == 1: return (N, crt([1, ans], [2, Nodd])) if p2 == 2: my3 = crt([3, 1], [N2, Nodd]) if fun(my3, n) == 0: return (N, crt([1, ans], [4, Nodd])) else: return (N, crt([3, ans], [4, Nodd])) # Final case 2^3 | N my5 = crt([5, 1], [N2, Nodd]) test1 = fun(my5, n) * N2 / 4 / n test1 = Integer(mod(5, N2) ** test1) minusone = crt([-1, 1], [N2, Nodd]) test2 = (fun(minusone, n) * N2 / 4 / n) % (N2 / 4) if test2 > 0: test1 = Integer(mod(-test1, N2)) return (N, crt([test1, ans], [N2, Nodd]))
def modulo(x, p, K): d = K.degree() a = K.gens()[0] a_s = [a ** i for i in range(d)] xl = x.list() xl_p = [mod(b, p).lift() for b in xl] return sum(list(imap(operator.mul, a_s, xl_p)))
def reduced_form_with_sign(tpl): ''' Assuming the 2-by-2 matrix correspoding to tpl is positive definite, returns ((n, r, m), sgn) where (n, r, m) is unmimodular equivalent to tpl s.t. n <= m and 0 <= r <= n. sgn is the determinant of an element GL2(ZZ) that gives the unimodular equivalence. ''' n, r, m = [ZZ(x) for x in tpl] if 4 * n * m - r ** 2 == 0: raise RuntimeError("tpl must be definite.") sign = 1 while True: if n <= m and 0 <= r and r <= n: return ((n, r, m), sign) if n > m: sign *= -1 n, m = m, n rem = mod(r, 2 * n) if rem > n: u = r // (2 * n) + 1 else: u = r // (2 * n) m = n * u ** 2 - r * u + m r = r - 2 * n * u if r < 0: sign *= -1 r *= -1
def generate_W(self, K): result = {} assert len(K) == self.key_length for i in xrange(self.key_amount * 4): # each 128-subkey consists of 4*32bit words if i < self.key_length: result[i] = K[i] elif i >= self.key_length and mod(i, self.key_length) == 0: result[i] = result[i - self.key_length] + self.RotWord( self.SubWord(result[i - 1])) + self.rcon( i / self.key_length) elif i >= self.key_length and self.key_length > 6 and mod( i, self.key_length) == 4: result[i] = result[i - self.key_length] + self.SubWord( result[i - 1]) else: result[i] = result[i - self.key_length] + result[i - 1] return result
def Cn_symmetric_k_points(n,k, alpha=Integer(1) ): n = Integer(n) k = Integer(k) if not mod(k,n) in [Integer(0) ,Integer(1) ]: raise ValueError('Only possible if k mod n in {{0,1}}, here {} mod {} = {}.'.format(k,n,mod(k,n))) res = { i : vector([RR(cos(RR(Integer(2) *pi*i)/n)),RR(sin(RR(Integer(2) *pi*i)/n))]) for i in range(Integer(0) ,n) } N = k if mod(k,n)==Integer(1) : res[N-Integer(1) ] = vector([Integer(0) ,Integer(0) ]) N = N-Integer(1) for i in range(n,N): r = (i-i%n)/n +Integer(1) res[i] = r*res[i%n] for i in res: res[i] = alpha*vector([res[i][Integer(0) ], res[i][Integer(1) ]]) return [res[i] for i in sorted(res.keys())]
def test_key(k): if (k * self.ecdsa.GG).xy()[0] == self.r_list[0]: d = Integer( mod(inverse_mod(self.r_list[0], self.ecdsa.n) * (k * self.s_list[0] - self.h_list[0]), self.ecdsa.n) ) pubkey = self.ecdsa.GG * d if ( itob(pubkey.xy()[0], self.ecdsa.baselen) + itob(pubkey.xy()[1], self.ecdsa.baselen) == self.vk.to_string() ): return True, d return False, None
def key_words(polyList): """ Returns chunks of 4 polynomials in a dictionary with integer keys starting from 0 :param polyList: list of polynomials :return: dictionary of vectors of 4 polynomials for each key """ result = {} assert mod(len(polyList), 4) == 0 index = 0 for i in xrange(0, len(polyList), 4): result[index] = vector(polyList[i:i + 4]) index += 1 return result
def sign(self, h, sk, klen=256, return_k=False): """ Sign ``h`` and signing key ``sk`` :param h: "hash" :param sk: signing key :param klen: number of bits in the nonce. :param return_k: """ d = btoi(sk.to_string()) hi = btoi(h) k = ZZ.random_element(2 ** klen) r = Integer((self.GG * k).xy()[0]) s = lift(inverse_mod(k, self.n) * mod(hi + d * r, self.n)) sig = itob(r, self.baselen) + itob(s, self.baselen) if return_k: return k, sig return sig
def reduced_form_with_sign_test(tpl): mat = matrix([[1, 0], [0, 1]]) sign = 1 (n, r, m) = tpl if n > m: sign *= -1 mat = mat * matrix([[0, 1], [1, 0]]) (n, m) = m, n rem = mod(r, 2 * n) if rem > n: u = r // (2 * n) + 1 else: u = r // (2 * n) m = n * u ** 2 - r * u + m r = r - 2 * n * u mat = mat * matrix([[1, -u], [0, 1]]) if r < 0: sign *= -1 mat = mat * matrix([[1, 0], [0, -1]]) r *= -1 return ((n, r, m), sign, mat)
def reduce_rational_number(self, a, N): r""" Return an approximation of ``a`` which is reduced modulo `p^N`. INPUT: - ``a`` -- a rational number - ``N`` -- a positive Integer OUTPUT: an element `\tilde{a}` of `\mathbb{Q}` which is congruent to `a` modulo `p^N`, of the form `c/p^m`, with `0\leq c < p^N` and `m\geq 0`. """ v_p = self.base_valuation() p = self.p() assert a in QQ # a should be a rational number m = max(-v_p(a), 0) b = a*p**m q = p**(N+m) return QQ(mod(b, q).lift()*p**(-m))
def check_hecke_ring_character_values_and_an(self, rec, verbose=False): """ check that hecke_ring_character_values has the correct format, depending on whether hecke_ring_cyclotomic_generator is set or not check that an has length 100 and that each entry is either a list of integers of length hecke_ring_rank (if hecke_ring_cyclotomic_generator=0) or a list of pairs check that ap has length pi(maxp) and that each entry is formatted correctly (as for an) """ # TIME about 4000s for full table an = rec['an'] if len(an) != 100: if verbose: print("Length an", len(an)) return False ap = rec['ap'] maxp = rec['maxp'] if len(ap) != prime_pi(maxp): if verbose: print("Length ap", len(ap), prime_pi(maxp)) return False if maxp < 997: if verbose: print("Maxp", maxp) return False m = rec['hecke_ring_cyclotomic_generator'] d = rec['hecke_ring_rank'] def check_val(val): if not isinstance(val, list): return False if m == 0: return len(val) == d and all(isinstance(c, integer_types) for c in val) else: for pair in val: if len(pair) != 2: return False if not isinstance(pair[0], integer_types): return False e = pair[1] if not (isinstance(e, integer_types) and 0 <= 2*e < m): return False return True if not all(check_val(a) for a in an): if verbose: for n, a in enumerate(an, 1): if not check_val(a): print("Check an failure (m=%s, d=%s)"%(m, d), n, a) return False if not all(check_val(a) for a in ap): if verbose: for p, a in zip(prime_range(maxp), ap): if not check_val(a): print("Check ap failure (m=%s, d=%s)"%(m, d), p, a) return False for p, a in zip(prime_range(100), ap): if a != an[p-1]: if verbose: print("Match failure", p, a, an[p-1]) return False if rec['char_orbit_index'] != 1: if rec.get('hecke_ring_character_values') is None: if verbose: print("No hecke_ring_character_values") return False N = rec['level'] total_order = 1 for g, val in rec['hecke_ring_character_values']: total_order *= mod(g, N).multiplicative_order() if not check_val(val): if verbose: print("Bad character val (m=%s, d=%s)"%(m, d), g, val) return False success = (total_order == euler_phi(N)) if not success and verbose: print("Generators failed", total_order, euler_phi(N)) return success return True
def check_hecke_ring_character_values_and_an(self, rec, verbose=False): """ check that hecke_ring_character_values has the correct format, depending on whether hecke_ring_cyclotomic_generator is set or not check that an has length 100 and that each entry is either a list of integers of length hecke_ring_rank (if hecke_ring_cyclotomic_generator=0) or a list of pairs check that ap has length pi(maxp) and that each entry is formatted correctly (as for an) """ # TIME about 4000s for full table an = rec['an'] if len(an) != 100: if verbose: print "Length an", len(an) return False ap = rec['ap'] maxp = rec['maxp'] if len(ap) != prime_pi(maxp): if verbose: print "Length ap", len(ap), prime_pi(maxp) return False if maxp < 997: if verbose: print "Maxp", maxp return False m = rec['hecke_ring_cyclotomic_generator'] d = rec['hecke_ring_rank'] def check_val(val): if not isinstance(val, list): return False if m == 0: return len(val) == d and all(isinstance(c, integer_types) for c in val) else: for pair in val: if len(pair) != 2: return False if not isinstance(pair[0], integer_types): return False e = pair[1] if not (isinstance(e, integer_types) and 0 <= 2*e < m): return False return True if not all(check_val(a) for a in an): if verbose: for n, a in enumerate(an, 1): if not check_val(a): print "Check an failure (m=%s, d=%s)"%(m, d), n, a return False if not all(check_val(a) for a in ap): if verbose: for p, a in zip(prime_range(maxp), ap): if not check_val(a): print "Check ap failure (m=%s, d=%s)"%(m, d), p, a return False for p, a in zip(prime_range(100), ap): if a != an[p-1]: if verbose: print "Match failure", p, a, an[p-1] return False if rec['char_orbit_index'] != 1: if rec.get('hecke_ring_character_values') is None: if verbose: print "No hecke_ring_character_values" return False N = rec['level'] total_order = 1 for g, val in rec['hecke_ring_character_values']: total_order *= mod(g, N).multiplicative_order() if not check_val(val): if verbose: print "Bad character val (m=%s, d=%s)"%(m, d), g, val return False success = (total_order == euler_phi(N)) if not success and verbose: print "Generators failed", total_order, euler_phi(N) return success return True
def gen_lattice(self, d=None): """FIXME! briefly describe function :param d: """ try: I = self.indices[self.nbases] # noqa self.nbases += 1 except ValueError: raise StopIteration("No more bases to sample.") p = self.ecdsa.n # w = 2 ** (self.klen - 1) w_list = [2 ** (klen - 1) for klen in self.klen_list] r_list = [self.r_list[i] for i in I] s_list = [self.s_list[i] for i in I] h_list = [self.h_list[i] for i in I] rm = r_list[-1] sm = s_list[-1] hm = h_list[-1] wm = w_list[-1] a_list = [ lift( wi - mod(r, p) * inverse_mod(s, p) * inverse_mod(rm, p) * mod(sm, p) * wm - inverse_mod(s, p) * mod(h, p) + mod(r, p) * inverse_mod(s, p) * mod(hm, p) * inverse_mod(rm, p) ) for wi, h, r, s in zip(w_list[:-1], h_list[:-1], r_list[:-1], s_list[:-1]) ] t_list = [ -lift(mod(r, p) * inverse_mod(s, p) * inverse_mod(rm, p) * sm) for r, s in zip(r_list[:-1], s_list[:-1]) ] d = self.d A = IntegerMatrix(d, d) f_list = [Integer(max(w_list) / w) for w in w_list] for i in range(d - 2): A[i, i] = p * f_list[i] for i in range(d - 2): A[d - 2, i] = t_list[i] * f_list[i] A[d - 2, d - 2] = f_list[-1] for i in range(d - 2): A[d - 1, i] = a_list[i] * f_list[i] A[d - 1, d - 1] = max(w_list) if self.ecdsa.nbits > 384: M = GSO.Mat( A, U=IntegerMatrix.identity(A.nrows, int_type=A.int_type), UinvT=IntegerMatrix.identity(A.nrows, int_type=A.int_type), float_type="ld", flags=GSO.ROW_EXPO, ) else: M = GSO.Mat( A, U=IntegerMatrix.identity(A.nrows, int_type=A.int_type), UinvT=IntegerMatrix.identity(A.nrows, int_type=A.int_type), flags=GSO.ROW_EXPO, ) M.update_gso() return M