def primes_of_bounded_norm(B): """ Return the prime ideals of the integers of the field Q(sqrt(5)) of norm at most B, ordered first by norm, then by the image of the golden ratio mod the prime in GF(p)={0,1,...,p-1}. INPUT: - B -- integer OUTPUT: - list of prime ideals EXAMPLES:: sage: import psage sage: psage.modform.hilbert.sqrt5.primes_of_bounded_norm(4) [Fractional ideal (2)] sage: len(psage.modform.hilbert.sqrt5.primes_of_bounded_norm(10^4)) 1233 sage: v = psage.modform.hilbert.sqrt5.primes_of_bounded_norm(11); v [Fractional ideal (2), Fractional ideal (2*a - 1), Fractional ideal (3), Fractional ideal (3*a - 1), Fractional ideal (3*a - 2)] Check that the sort order is as claimed:: sage: P0 = v[-2]; P1 = v[-1] sage: K = P0.number_field(); K Number Field in a with defining polynomial x^2 - x - 1 sage: P0.residue_field()(K.gen()) 4 sage: P1.residue_field()(K.gen()) # yep, 4 < 8 8 """ v = [] g = F.gen() for p in primes(B + 1): if p == 5: v.append((5, F.ideal(2 * g - 1))) elif p % 5 in [2, 3]: Norm = p * p if Norm <= B: v.append((Norm, F.ideal(p))) else: s = pari(5).Mod(p).sqrt() a = int(((1 + s) / 2).lift()) b = int(((1 - s) / 2).lift()) v.append((p, a, F.ideal([p, g - a]))) v.append((p, b, F.ideal([p, g - b]))) v.sort() return [z[-1] for z in v]
def primes_of_degree_iter(K, deg, condition=None, sort_key=prime_label, maxnorm=Infinity): """Iterator through primes of K of degree deg, sorted using the provided sort key, optionally with an upper bound on the norm. If condition is not None it should be a True/False function on rational primes, in which case only primes P dividing p for which condition(p) holds will be returned. For example, condition=lambda:not p.divides(6). """ for p in primes(2,stop=maxnorm): if condition==None or condition(p): make_keys(K,p) for P in K.primes_dict[p]: if P.residue_class_degree()==deg and P.norm()<=maxnorm: yield P
def primes_of_bounded_norm(B): """ Return the prime ideals of the integers of the field Q(sqrt(5)) of norm at most B, ordered first by norm, then by the image of the golden ratio mod the prime in GF(p)={0,1,...,p-1}. INPUT: - B -- integer OUTPUT: - list of prime ideals EXAMPLES:: sage: import psage sage: psage.modform.hilbert.sqrt5.primes_of_bounded_norm(4) [Fractional ideal (2)] sage: len(psage.modform.hilbert.sqrt5.primes_of_bounded_norm(10^4)) 1233 sage: v = psage.modform.hilbert.sqrt5.primes_of_bounded_norm(11); v [Fractional ideal (2), Fractional ideal (2*a - 1), Fractional ideal (3), Fractional ideal (3*a - 1), Fractional ideal (3*a - 2)] Check that the sort order is as claimed:: sage: P0 = v[-2]; P1 = v[-1] sage: K = P0.number_field(); K Number Field in a with defining polynomial x^2 - x - 1 sage: P0.residue_field()(K.gen()) 4 sage: P1.residue_field()(K.gen()) # yep, 4 < 8 8 """ v = [] g = F.gen() for p in primes(B+1): if p == 5: v.append((5, F.ideal(2*g-1))) elif p%5 in [2,3]: Norm = p*p if Norm <= B: v.append((Norm, F.ideal(p))) else: s = pari(5).Mod(p).sqrt() a = int(((1 + s)/2).lift()); b = int(((1 - s)/2).lift()) v.append((p, a, F.ideal([p, g - a]))) v.append((p, b, F.ideal([p, g - b]))) v.sort() return [z[-1] for z in v]
def primes_of_degree_iter(K, deg, condition=None, sort_key=prime_label, maxnorm=Infinity): """Iterator through primes of K of degree deg, sorted using the provided sort key, optionally with an upper bound on the norm. If condition is not None it should be a True/False function on rational primes, in which case only primes P dividing p for which condition(p) holds will be returned. For example, condition=lambda:not p.divides(6). """ for p in primes(2, stop=maxnorm): if condition is None or condition(p): make_keys(K, p) for P in K.primes_dict[p]: if P.residue_class_degree()==deg and P.norm()<=maxnorm: yield P
def deg_one_primes_iter(K, principal_only=False): r""" Return an iterator over degree 1 primes of ``K``. INPUT: - ``K`` -- a number field - ``principal_only`` -- bool; if ``True``, only yield principal primes OUTPUT: An iterator over degree 1 primes of `K` up to the given norm, optionally yielding only principal primes. EXAMPLES:: sage: K.<a> = QuadraticField(-5) sage: from sage.schemes.elliptic_curves.gal_reps_number_field import deg_one_primes_iter sage: it = deg_one_primes_iter(K) sage: [next(it) for _ in range(6)] [Fractional ideal (2, a + 1), Fractional ideal (3, a + 1), Fractional ideal (3, a + 2), Fractional ideal (-a), Fractional ideal (7, a + 3), Fractional ideal (7, a + 4)] sage: it = deg_one_primes_iter(K, True) sage: [next(it) for _ in range(6)] [Fractional ideal (-a), Fractional ideal (-2*a + 3), Fractional ideal (2*a + 3), Fractional ideal (a + 6), Fractional ideal (a - 6), Fractional ideal (-3*a + 4)] """ # imaginary quadratic fields have no principal primes of norm < disc / 4 start = K.discriminant().abs() // 4 if principal_only and K.signature( ) == (0, 1) else 2 K_is_Q = (K == QQ) from sage.arith.misc import primes from sage.rings.infinity import infinity for p in primes(start=start, stop=infinity): if K_is_Q: yield ZZ.ideal(p) else: for P in K.primes_above(p, degree=1): if not principal_only or P.is_principal(): yield P
def deg_one_primes_iter(K, principal_only=False): r""" Return an iterator over degree 1 primes of ``K``. INPUT: - ``K`` -- a number field - ``principal_only`` -- bool; if ``True``, only yield principal primes OUTPUT: An iterator over degree 1 primes of `K` up to the given norm, optionally yielding only principal primes. EXAMPLES:: sage: K.<a> = QuadraticField(-5) sage: from sage.schemes.elliptic_curves.gal_reps_number_field import deg_one_primes_iter sage: it = deg_one_primes_iter(K) sage: [next(it) for _ in range(6)] [Fractional ideal (2, a + 1), Fractional ideal (3, a + 1), Fractional ideal (3, a + 2), Fractional ideal (-a), Fractional ideal (7, a + 3), Fractional ideal (7, a + 4)] sage: it = deg_one_primes_iter(K, True) sage: [next(it) for _ in range(6)] [Fractional ideal (-a), Fractional ideal (-2*a + 3), Fractional ideal (2*a + 3), Fractional ideal (a + 6), Fractional ideal (a - 6), Fractional ideal (-3*a + 4)] """ # imaginary quadratic fields have no principal primes of norm < disc / 4 start = K.discriminant().abs() // 4 if principal_only and K.signature() == (0,1) else 2 K_is_Q = (K==QQ) from sage.arith.misc import primes from sage.rings.infinity import infinity for p in primes(start=start, stop=infinity): if K_is_Q: yield ZZ.ideal(p) else: for P in K.primes_above(p, degree=1): if not principal_only or P.is_principal(): yield P
def primes_of_bounded_norm_iter(self, B): r""" Iterator yielding all primes less than or equal to `B`. INPUT: - ``B`` -- a positive integer; upper bound on the primes generated. OUTPUT: An iterator over all integer primes less than or equal to `B`. .. note:: This function exists for compatibility with the related number field method, though it returns prime integers, not ideals. EXAMPLES:: sage: it = QQ.primes_of_bounded_norm_iter(10) sage: list(it) [2, 3, 5, 7] sage: list(QQ.primes_of_bounded_norm_iter(1)) [] """ try: B = ZZ(B.ceil()) except (TypeError, AttributeError): raise TypeError("%s is not valid bound on prime ideals" % B) if B < 2: return from sage.arith.all import primes for p in primes(B + 1): yield p
def primes_of_bounded_norm_iter(self, B): r""" Iterator yielding all primes less than or equal to `B`. INPUT: - ``B`` -- a positive integer; upper bound on the primes generated. OUTPUT: An iterator over all integer primes less than or equal to `B`. .. note:: This function exists for compatibility with the related number field method, though it returns prime integers, not ideals. EXAMPLES:: sage: it = QQ.primes_of_bounded_norm_iter(10) sage: list(it) [2, 3, 5, 7] sage: list(QQ.primes_of_bounded_norm_iter(1)) [] """ try: B = ZZ(B.ceil()) except (TypeError, AttributeError): raise TypeError("%s is not valid bound on prime ideals" % B) if B<2: raise StopIteration from sage.arith.all import primes for p in primes(B+1): yield p
def has_blum_prime(lbound, ubound): """ Determine whether or not there is a Blum prime within the specified closed interval. INPUT: - ``lbound`` -- positive integer; the lower bound on how small a Blum prime can be. The lower bound must be distinct from the upper bound. - ``ubound`` -- positive integer; the upper bound on how large a Blum prime can be. The lower bound must be distinct from the upper bound. OUTPUT: - ``True`` if there is a Blum prime ``p`` such that ``lbound <= p <= ubound``. ``False`` otherwise. ALGORITHM: Let `L` and `U` be distinct positive integers. Let `P` be the set of all odd primes `p` such that `L \leq p \leq U`. Our main focus is on Blum primes, i.e. odd primes that are congruent to 3 modulo 4, so we assume that the lower bound `L > 2`. The closed interval `[L, U]` has a Blum prime if and only if the set `P` has a Blum prime. EXAMPLES: Testing for the presence of Blum primes within some closed intervals. The interval `[4, 100]` has a Blum prime, the smallest such prime being 7. The interval `[24, 28]` has no primes, hence no Blum primes. :: sage: from sage.crypto.util import has_blum_prime sage: from sage.crypto.util import is_blum_prime sage: has_blum_prime(4, 100) True sage: for n in range(4, 100): ....: if is_blum_prime(n): ....: print(n) ....: break 7 sage: has_blum_prime(24, 28) False TESTS: Both the lower and upper bounds must be greater than 2:: sage: from sage.crypto.util import has_blum_prime sage: has_blum_prime(2, 3) Traceback (most recent call last): ... ValueError: Both the lower and upper bounds must be > 2. sage: has_blum_prime(3, 2) Traceback (most recent call last): ... ValueError: Both the lower and upper bounds must be > 2. sage: has_blum_prime(2, 2) Traceback (most recent call last): ... ValueError: Both the lower and upper bounds must be > 2. The lower and upper bounds must be distinct from each other:: sage: has_blum_prime(3, 3) Traceback (most recent call last): ... ValueError: The lower and upper bounds must be distinct. The lower bound must be less than the upper bound:: sage: has_blum_prime(4, 3) Traceback (most recent call last): ... ValueError: The lower bound must be less than the upper bound. """ # sanity checks if (lbound < 3) or (ubound < 3): raise ValueError("Both the lower and upper bounds must be > 2.") if lbound == ubound: raise ValueError("The lower and upper bounds must be distinct.") if lbound > ubound: raise ValueError("The lower bound must be less than the upper bound.") # now test for presence of a Blum prime for p in primes(lbound, ubound + 1): if mod(p, 4).lift() == 3: return True return False