Example #1
0
def symmetric_block_diagonalize(N1):
    r"""Returns matrices `H` and `Q` such that `N1 = Q*H*Q.T` and `H` is block
    diagonal.

    The algorithm used here is as follows. Whenever a row operation is
    performed (via multiplication on the left by a transformation matrix `q`)
    the corresponding symmetric column operation is also performed via
    multiplication on the right by `q^T`.

    For each column `j` of `N1`:

    1. If column `j` consists only of zeros then swap with the last column with
       non-zero entries.

    2. If there is a `1` in position `j` of the column (i.e. a `1` lies on the
       diagonal in this column) then eliminate further entries below as in
       standard Gaussian elimination.

    3. Otherwise, if there is a `1` in the column, but not in position `j` then
       rows are swapped in a way that it appears in the position `j+1` of the
       column. Eliminate further entries below as in standard Gaussian
       elimination.

    4. After elimination, if `1` lies on the diagonal in column `j` then
       increment `j` by one. If instead the block matrix `[0 1 \\ 1 0]` lies
       along the diagonal then eliminate under the `(j,j+1)` element (the upper
       right element) of this `2 x 2` block and increment `j` by two.

    5. Repeat until `j` passes the final column or until further columns
       consists of all zeros.

    6. Finally, perform the appropriate transformations such that all `2 x 2`
       blocks in `H` appear first in the diagonalization. (Uses the
       `diagonal_locations` helper function.)

    Parameters
    ----------
    N1 : GF(2) matrix

    Returns
    -------
    H : GF(2) matrix
        Symmetric `g x g` matrix where the diagonal elements consist of either
        a "1" or a `2 x 2` block matrix `[0 1 \\ 1 0]`.
    Q : GF(2) matrix
        The corresponding transformation matrix.
    """
    g = N1.nrows()
    H = zero_matrix(GF(2), g)
    Q = identity_matrix(GF(2), g)

    # if N1 is the zero matrix the H is also the zero matrix (and Q is the
    # identity transformation)
    if (N1 % 2) == 0:
        return H,Q

    # perform the "modified gaussian elimination"
    B = Matrix(GF(2),[[0,1],[1,0]])
    H = N1.change_ring(GF(2))
    j = 0
    while (j < g) and (H[:,j:] != 0):
        # if the current column is zero then swap with the last non-zero column
        if H.column(j) == 0:
            last_non_zero_col = max(k for k in range(j,g) if H.column(k) != 0)
            Q.swap_columns(j,last_non_zero_col)
            H = Q.T*N1*Q

        # if the current diagonal element is 1 then gaussian eliminate as
        # usual. otherwise, swap rows so that a "1" appears in H[j+1,j] and
        # then eliminate from H[j+1,j]
        if H[j,j] == 1:
            rows_to_eliminate = (r for r in range(g) if H[r,j] == 1 and r != j)
            for r in rows_to_eliminate:
                Q.add_multiple_of_column(r,j,1)
            H = Q.T*N1*Q
        else:
            # find the first non-zero element in the column after the diagonal
            # element and swap rows with this element
            first_non_zero = min(k for k in range(j,g) if H[k,j] != 0)
            Q.swap_columns(j+1,first_non_zero)
            H = Q.T*N1*Q

            # eliminate *all* other ones in the column, including those above
            # the element (j,j+1)
            rows_to_eliminate = (r for r in range(g) if H[r,j] == 1 and r != j+1)
            for r in rows_to_eliminate:
                Q.add_multiple_of_column(r,j+1,1)
            H = Q.T*N1*Q

        # increment the column based on the diagonal element
        if H[j,j] == 1:
            j += 1
        elif H[j:(j+2),j:(j+2)] == B:
            # in the block diagonal case, need to eliminate below the j+1 term
            rows_to_eliminate = (r for r in range(g) if H[r,j+1] == 1 and r != j)
            for r in rows_to_eliminate:
                Q.add_multiple_of_column(r,j,1)
            H = Q.T*N1*Q
            j += 2

    # finally, check if there are blocks of "special" form. that is, shift all
    # blocks such that they occur first along the diagonal of H
    index_one, index_B = diagonal_locations(H)
    while index_one < index_B:
        j = index_B

        Qtilde = zero_matrix(GF(2), g)
        Qtilde[0,0] = 1
        Qtilde[j,0] = 1; Qtilde[j+1,0] = 1
        Qtilde[0,j] = 1; Qtilde[0,j+1] = 1
        Qtilde[j:(j+2),j:(j+2)] = B

        Q = Q*Qtilde
        H = Q.T*N1*Q

        # continue until none are left
        index_one, index_B = diagonal_locations(H)

    # above, we used Q to store column operations on N1. switch to rows
    # operations on H so that N1 = Q*H*Q.T
    Q = Q.T.inverse()
    return H,Q
Example #2
0
    def t1(self, n=5):
        """
        Return choice of element t1 of the Hecke algebra mod 2,
        computed using the Hecke operator $T_n$, where n is self.n
        
        INPUT:
        
            - `n` -- integer (optional default=5)
            
        OUTPUT:

            - a mod 2 matrix

        EXAMPLES::

            sage: from mdsage import *
            sage: C = KamiennyCriterion(29)
            sage: C.t1(n=3)
            22 x 22 dense matrix over Finite Field of size 2 (use the '.str()' method to see the entries)
            sage: C.t1(n=3) == 1
            True
            sage: C.t1()
            Traceback (most recent call last):
            ...
            ValueError: T_5 needs to be a generator of the hecke algebra
            sage: C = KamiennyCriterion(37)
            sage: C.t1()[0]
            (1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0) 
        """
        T = self.S.hecke_matrix(n)
        f = T.charpoly()
        F = f.factor()
        if prod(i[1] for i in F) != 1:
            raise ValueError("T_%s needs to be a generator of the hecke algebra"%n)

        # Compute the iterators of T acting on the winding element.
        e = self.M([0, oo]).element().dense_vector()
        t = self.M.hecke_matrix(n).dense_matrix()
        g = t.charpoly()
        Z = t.iterates(e, t.nrows(), rows=True)
        # We find all factors F[i][0] for f such that
        # (g/F[i][0])(t) * e = 0.
        # We do this by computing the polynomial
        #       h = g/F[i][0],
        # turning it into a vector v, and computing
        # the matrix product v * Z.  If the product
        # is 0, then e is killed by h(t).
        J = []
        for i in range(len(F)):
            h, r = g.quo_rem(F[i][0] ** F[i][1])
            assert r == 0
            v = vector(QQ, h.padded_list(t.nrows()))
            if v * Z == 0:
                J.append(i)


        if self.verbose: print("J =", J)
        if len(J) == 0:
            # The annihilator of e is the 0 ideal.
            return matrix_modp(identity_matrix(T.nrows()))
            
        # Finally compute t1.  I'm concerned about how
        # long this will take, so we reduce T mod 2 first.

        # It is important to call "self.T(2)" to get the mod-2
        # reduction of T2 with respect to the right basis (e.g., the
        # integral basis in case use_integral_structure is true.
        Tmod2 = self.T(n) 
        g = prod(F[i][0].change_ring(GF(2)) ** F[i][1] for i in J)
        t1 = g(Tmod2)
        return t1
Example #3
0
def dim_error_tradeoff(A,
                       c,
                       u,
                       beta,
                       h,
                       k,
                       alpha=None,
                       tau=None,
                       float_type="mpfr",
                       use_lll=True):
    """

    :param A:    LWE matrix
    :param c:    LWE vector
    :param u:	 Uniform vector
    :param beta: BKW block size
    :param h: 	 Hamming weight of secret
    :param k:    LWE dim after tradeoff
    :param tau:  number of new samples to generate
    :param use_lll: 	If True, run BKZ only once and then run LLL
    					If False, run BKZ iteratively

    * secret vector s is used to see the error term of new LWE(-like) samples.

    """

    from fpylll import BKZ, IntegerMatrix, LLL, GSO
    from fpylll.algorithms.bkz2 import BKZReduction as BKZ2

    n = A.ncols()
    q = A.base_ring().order()
    K = GF(q, proof=False)

    if alpha is None:
        alpha = 8 / q

    if tau is None:
        tau = 30

    m = A.nrows() / n

    scale = round(alpha * q * sqrt(m) / sqrt(2 * pi * h))
    scale = ZZ(scale)

    count = 0

    A_k = matrix(ZZ, 1, k)
    c_k = []
    u_k = []
    length = 0

    while count < tau:

        r = count * m
        T = A.matrix_from_rows([i + r for i in range(m)])
        ct = c[r:r + m]
        ut = u[r:r + m]

        T1 = T.matrix_from_columns([i for i in range(n - k)])

        L = dual_instance1(T1, scale=scale)
        L = IntegerMatrix.from_matrix(L)
        L = LLL.reduction(L)
        M = GSO.Mat(L, float_type=float_type)
        bkz = BKZ2(M)
        param = BKZ.Param(block_size=beta,
                          strategies=BKZ.DEFAULT_STRATEGY,
                          auto_abort=True,
                          max_loops=16,
                          flags=BKZ.AUTO_ABORT | BKZ.MAX_LOOPS)
        bkz(param)

        H = copy(L)

        y = vector(ZZ, tuple(L[0]))
        length += y.norm()

        T2 = T.matrix_from_columns([n - k + i for i in range(k)])

        A_kt, c_kt, u_kt = apply_short1(y, T2, ct, ut, scale=scale)
        if r == 0:
            A_k[0] = A_kt
        else:
            A_k = A_k.stack(A_kt)
        c_k.append(c_kt)
        u_k.append(u_kt)

        count += 1

    length = float(length / tau)
    A_k = A_k.change_ring(K)
    c_k = vector(K, c_k)
    u_k = vector(K, u_k)

    B = float(2 + 1 / sqrt(2 * pi)) * (alpha * q)
    B = B * B * m / (m + n)
    B = sqrt(B) * length / scale

    print '(A_k, c_k) is k-dim LWE samples (with secret s[-k:]) / (A_k, u_k) is uniform samples. '

    return A_k, c_k, u_k, B
Example #4
0
# I don't ask you for the backdoor. I just wonder whether it exists or not.   #
# If you know the backdoor, please go on and get the flag!                    #
###############################################################################

from sage.all import EllipticCurve, GF, Zmod, ZZ
import socketserver
import os
import signal
from Crypto.Util.number import bytes_to_long
from hashlib import sha256

# Dual_EC_Drbg parameters taken from:
# https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-90a.pdf
# Section A.1.1
EC = EllipticCurve(
    GF(0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff),
    [-3, 0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b])
n = 0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551
assert EC.cardinality() == n
Zn = Zmod(n)
G = EC((0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296,
        0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5))
P = G
Q = EC((0xc97445f45cdef9f0d3e05e1e585fc297235b82b5be8ff3efca67c59852018192,
        0xb28ef557ba31dfcbdd21ac46e2a91e3c304f44cb87058ada2cb815151e610046))


class DualEcDrbg(object):
    """
    Dual Elliptic Curve Deterministic Random Bit Generator
    """
Example #5
0
import sys

from random_curve_iterator import RandomCurveIterator
from sage.all import GF, next_prime

if __name__ == "__main__":
    p = next_prime(100)

    F = GF(p)

    count = 0
    for ec in RandomCurveIterator(F):
        if ec.cardinality() == p - 1:
            print(ec)
            sys.exit()
Example #6
0
def make_keys(K, p):
    """Find and sort all primes of K above p, and store their sort keys in
    a dictionary with keys the primes P and values their sort keys
    (n,j,e,i) with n the norm, e the ramificatino index, i the index
    (from 1) in the list of all those primes with the same (n,e), and
    j the index (from 1) in the sorted list of all with the same norm.
    This dict is stored in K in a dict called psort_dict, whose keys
    are rational primes p.
    """
    if not hasattr(K, 'psort_dict'):
        K.psort_dict = {}
        K.primes_dict = {}
    if not p in K.psort_dict:
        #print("creating keys for primes above {}".format(p))
        key_dict = {}
        Fp = GF(p)
        g = K.defining_polynomial()
        QQx = g.parent()
        a = K.gen()
        PP = K.primes_above(p)

        if not p.divides(g.discriminant()):
            # the easier unramified case
            gfact = [h for h, e in g.change_ring(Fp).factor()]
            gfact.sort(key=FpX_key)
            hh = [QQx(h) for h in gfact]
            for P in PP:
                # exactly one mod-p factor h will be such that P|h(a).
                i = 1 + next(
                    (i for i, h in enumerate(hh) if h(a).valuation(P) > 0), -1)
                assert i > 0
                key_dict[P] = (P.norm(), P.ramification_index(), i)
        else:
            # the general ramified case factor g over Z_p to precision
            # p^k0 until the mod p^k1 reductions of the factors are
            # distinct, with k0 >= k1 >= 1
            k0 = 20
            ok = False
            while not ok:
                gfact = [h for h, e in g.factor_padic(p, k0)]
                nfact = len(gfact)
                gf = [h.lift() for h in gfact]
                k1 = 1
                while (k1 < k0) and not ok:
                    hh = [h % p**k1 for h in gf]
                    ok = len(Set(hh)) == nfact
                    if not ok:
                        k1 += 1
                if not ok:
                    k0 += 10
            # now hh holds the factors reduced mod p^k1 and these are
            # distinct so we sort the p-adic factors accordingly (these
            # will be first sorted by degree)
            gfact.sort(key=ZpX_key(k1))
            #print("p-adic factors: {}".format(gfact))
            #print("with keys {}".format([ZpX_key(k1)(h) for h in gfact]))
            hh = [h.lift() % p**k1 for h in gfact]
            #print("p-adic factors mod {}^{}: {}".format(p,k1,hh))
            degs = list(Set([h.degree() for h in gfact]))
            hd = dict([(d, [h for h in hh if h.degree() == d]) for d in degs])

            # Finally we find the index of each prime above p
            for P in PP:
                e = P.ramification_index()
                f = P.residue_class_degree()
                hs = hd[e * f]
                # work out which h in hs matches P
                m = max([h(a).valuation(P) for h in hs])
                i = 1 + next(
                    (i
                     for i, h in enumerate(hs) if h(a).valuation(P) == m), -1)
                assert i > 0
                key_dict[P] = (P.norm(), e, i)

        # Lastly we add a field j to each key (n,e,i) -> (n,j,e,i)
        # which is its index in the sublist withe same n-value.  This
        # will not affect sorting but is used in the label n.j.

        vals = key_dict.values()
        new_key_dict = {}
        for P in key_dict:
            k = key_dict[P]
            j = 1 + sorted([v for v in vals if v[0] == k[0]]).index(k)
            new_key_dict[P] = (k[0], j, k[1], k[2])

        #print("Setting psort_dict and primes_dict for p={} for K={}".format(p,K))
        K.psort_dict[p] = new_key_dict
        K.primes_dict[p] = sorted(PP, key=lambda P: new_key_dict[P])
Example #7
0
def eigenvalues(E, l, s=1):
    t = E.trace_of_frobenius()
    x = PolynomialRing(GF(l**s), 'x').gen()
    q = E.base_field().order()
    f = x**2 - t * x + q
    return f.roots()
def solve(vectors, goal):
  M = MatrixSpace(GF(2), len(vectors), len(vectors[0]))
  V = VectorSpace(GF(2), len(goal))
  A = M(vectors)
  b = V(goal)
  return A.solve_left(b)
    info = do_request(store, make_signed(store, 'info'))
    print(info)
    curve_s, gen_s, pub_s = info.split('\n')
    _, ax, bmp = curve_s.split('+')
    a = int(ax.split('*')[0])
    b = int(bmp.split('(')[0])
    p = int(bmp.split('mod')[1][:-1])
    Gxy = eval(gen_s.split(': ')[1])
    assert isinstance(Gxy, tuple) and len(Gxy) == 2
    Hxy = eval(pub_s.split(': ')[1])
    assert isinstance(Hxy, tuple) and len(Hxy) == 2
    print(f'a: {a}\nb: {b}\np: {p}\ngen: {Gxy}\npub: {Hxy}')

    # done parsing curve, now use pohlig to get a priv key
    print(f'doing pohlig...')
    E = EllipticCurve(GF(p), [a, b])
    H = E(Hxy)
    G = E(Gxy)
    key = pohlig(E, H, G)
    print(f'solved: {key}')

    # now we forge a signed request with the 'flag' command
    print('forging request...')
    request = make_request('flag', name='fbctf')
    message = json.dumps(request, sort_keys=True)
    R, S = sign(message, key, E.order(), G)
    sig = base64.b64encode(bytes(str(R) + '|' + str(S), 'utf-'))
    request['sig'] = sig.decode('utf-8')
    r = do_request(store, request)
    print(r)  # FLAG!
Example #10
0
    total = 0
    for f in ea_classes_in_the_ccz_class_of(kim):
        print(
            str(algebraic_degree(f)) + pretty_spectrum(thickness_spectrum(f)))
        total += 1
    print("total: " + str(total))


# !SECTION! Running tests

if __name__ == '__main__':
    # test_ea_permutations()
    # test_ccz_permutations(number="just one")
    # test_enumerate_ea()
    # test_ea_classes()

    # import sys
    # N = int(sys.argv[1])
    # print("=== Linear Equivalence ===")
    # test_le_equivalence(N, verbose=True)
    # print("\n=== Linear Representative ===")
    # test_le_repr(N, verbose=False)
    # print("\n=== Affine Equivalence ===")
    # test_ae_equivalence(N, verbose=True)

    N = 5
    gf = GF(2**N, name="a")
    cube = [(gf.fetch_int(x)**3) for x in range(0, 2**N)]
    for g in ea_classes_in_the_ccz_class_of(cube):
        print(are_ccz_equivalent(f, g), g)
Example #11
0
from sage.all import GF, PolynomialRing

P = PolynomialRing(GF(2), 'x')
e = 31337
n = P(
    'x^2048 + x^2046 + x^2043 + x^2040 + x^2036 + x^2035 + x^2034 + x^2033 + x^2031 + x^2029 + x^2025 + x^2024 + x^2022 + x^2019 + x^2018 + x^2017 + x^2012 + x^2007 + x^2006 + x^2004 + x^2000 + x^1999 + x^1998 + x^1997 + x^1993 + x^1992 + x^1991 + x^1986 + x^1982 + x^1981 + x^1979 + x^1978 + x^1977 + x^1975 + x^1970 + x^1964 + x^1963 + x^1962 + x^1961 + x^1960 + x^1959 + x^1958 + x^1955 + x^1954 + x^1952 + x^1951 + x^1949 + x^1947 + x^1942 + x^1939 + x^1938 + x^1936 + x^1934 + x^1933 + x^1932 + x^1930 + x^1928 + x^1927 + x^1923 + x^1922 + x^1919 + x^1918 + x^1915 + x^1914 + x^1913 + x^1912 + x^1911 + x^1910 + x^1908 + x^1903 + x^1902 + x^1900 + x^1899 + x^1897 + x^1893 + x^1891 + x^1890 + x^1886 + x^1881 + x^1880 + x^1879 + x^1878 + x^1875 + x^1874 + x^1873 + x^1872 + x^1871 + x^1870 + x^1869 + x^1865 + x^1863 + x^1862 + x^1860 + x^1856 + x^1855 + x^1853 + x^1852 + x^1845 + x^1841 + x^1839 + x^1837 + x^1836 + x^1835 + x^1833 + x^1832 + x^1829 + x^1828 + x^1827 + x^1826 + x^1824 + x^1823 + x^1822 + x^1821 + x^1820 + x^1819 + x^1818 + x^1817 + x^1813 + x^1812 + x^1810 + x^1809 + x^1808 + x^1807 + x^1803 + x^1799 + x^1797 + x^1796 + x^1794 + x^1792 + x^1790 + x^1786 + x^1783 + x^1782 + x^1779 + x^1778 + x^1776 + x^1775 + x^1774 + x^1772 + x^1767 + x^1766 + x^1765 + x^1764 + x^1763 + x^1762 + x^1759 + x^1757 + x^1756 + x^1754 + x^1753 + x^1752 + x^1750 + x^1749 + x^1741 + x^1734 + x^1730 + x^1729 + x^1726 + x^1725 + x^1723 + x^1722 + x^1721 + x^1716 + x^1714 + x^1713 + x^1712 + x^1710 + x^1709 + x^1706 + x^1705 + x^1703 + x^1702 + x^1700 + x^1698 + x^1693 + x^1692 + x^1691 + x^1690 + x^1683 + x^1682 + x^1681 + x^1680 + x^1679 + x^1677 + x^1672 + x^1670 + x^1669 + x^1666 + x^1663 + x^1662 + x^1661 + x^1659 + x^1655 + x^1653 + x^1651 + x^1649 + x^1648 + x^1647 + x^1646 + x^1644 + x^1643 + x^1642 + x^1640 + x^1639 + x^1638 + x^1634 + x^1633 + x^1628 + x^1620 + x^1619 + x^1618 + x^1616 + x^1614 + x^1611 + x^1610 + x^1608 + x^1605 + x^1604 + x^1603 + x^1599 + x^1597 + x^1595 + x^1594 + x^1590 + x^1588 + x^1587 + x^1585 + x^1583 + x^1580 + x^1579 + x^1577 + x^1574 + x^1573 + x^1572 + x^1568 + x^1566 + x^1565 + x^1563 + x^1562 + x^1560 + x^1555 + x^1554 + x^1552 + x^1550 + x^1549 + x^1548 + x^1545 + x^1544 + x^1542 + x^1540 + x^1538 + x^1537 + x^1536 + x^1535 + x^1534 + x^1533 + x^1532 + x^1531 + x^1528 + x^1526 + x^1525 + x^1523 + x^1522 + x^1521 + x^1519 + x^1517 + x^1515 + x^1510 + x^1509 + x^1506 + x^1504 + x^1502 + x^1499 + x^1498 + x^1497 + x^1488 + x^1483 + x^1480 + x^1477 + x^1472 + x^1471 + x^1469 + x^1468 + x^1467 + x^1466 + x^1464 + x^1462 + x^1457 + x^1456 + x^1455 + x^1454 + x^1453 + x^1452 + x^1448 + x^1446 + x^1444 + x^1443 + x^1442 + x^1441 + x^1440 + x^1436 + x^1435 + x^1431 + x^1428 + x^1425 + x^1424 + x^1422 + x^1420 + x^1415 + x^1414 + x^1411 + x^1410 + x^1408 + x^1406 + x^1405 + x^1403 + x^1402 + x^1399 + x^1397 + x^1396 + x^1395 + x^1394 + x^1393 + x^1391 + x^1388 + x^1385 + x^1377 + x^1376 + x^1372 + x^1371 + x^1370 + x^1369 + x^1367 + x^1363 + x^1361 + x^1357 + x^1355 + x^1354 + x^1349 + x^1343 + x^1339 + x^1338 + x^1337 + x^1336 + x^1335 + x^1332 + x^1329 + x^1327 + x^1326 + x^1324 + x^1321 + x^1315 + x^1314 + x^1312 + x^1310 + x^1309 + x^1305 + x^1304 + x^1303 + x^1302 + x^1299 + x^1298 + x^1296 + x^1295 + x^1293 + x^1291 + x^1290 + x^1289 + x^1284 + x^1283 + x^1282 + x^1281 + x^1280 + x^1278 + x^1277 + x^1276 + x^1275 + x^1272 + x^1270 + x^1269 + x^1268 + x^1267 + x^1259 + x^1257 + x^1254 + x^1252 + x^1251 + x^1249 + x^1247 + x^1246 + x^1244 + x^1240 + x^1238 + x^1233 + x^1232 + x^1229 + x^1222 + x^1219 + x^1217 + x^1211 + x^1209 + x^1208 + x^1205 + x^1204 + x^1203 + x^1202 + x^1200 + x^1197 + x^1196 + x^1195 + x^1193 + x^1192 + x^1189 + x^1187 + x^1186 + x^1185 + x^1184 + x^1183 + x^1182 + x^1181 + x^1177 + x^1176 + x^1173 + x^1170 + x^1167 + x^1166 + x^1162 + x^1161 + x^1160 + x^1159 + x^1158 + x^1156 + x^1155 + x^1154 + x^1153 + x^1151 + x^1146 + x^1143 + x^1141 + x^1139 + x^1138 + x^1137 + x^1135 + x^1131 + x^1129 + x^1128 + x^1125 + x^1124 + x^1122 + x^1116 + x^1115 + x^1114 + x^1112 + x^1111 + x^1107 + x^1106 + x^1105 + x^1104 + x^1103 + x^1102 + x^1098 + x^1097 + x^1095 + x^1094 + x^1092 + x^1088 + x^1087 + x^1085 + x^1077 + x^1076 + x^1075 + x^1072 + x^1069 + x^1068 + x^1061 + x^1060 + x^1059 + x^1057 + x^1055 + x^1054 + x^1053 + x^1050 + x^1047 + x^1046 + x^1044 + x^1043 + x^1042 + x^1036 + x^1029 + x^1025 + x^1024 + x^1023 + x^1022 + x^1019 + x^1016 + x^1013 + x^1012 + x^1010 + x^1008 + x^1007 + x^1006 + x^1004 + x^1000 + x^996 + x^995 + x^993 + x^992 + x^989 + x^985 + x^983 + x^978 + x^977 + x^975 + x^972 + x^971 + x^970 + x^969 + x^967 + x^963 + x^957 + x^956 + x^952 + x^950 + x^948 + x^945 + x^942 + x^941 + x^940 + x^938 + x^937 + x^936 + x^935 + x^932 + x^931 + x^930 + x^928 + x^927 + x^926 + x^923 + x^921 + x^918 + x^916 + x^914 + x^913 + x^909 + x^906 + x^905 + x^904 + x^902 + x^897 + x^895 + x^892 + x^889 + x^888 + x^887 + x^886 + x^885 + x^884 + x^882 + x^881 + x^879 + x^876 + x^870 + x^868 + x^867 + x^865 + x^862 + x^861 + x^859 + x^858 + x^856 + x^854 + x^848 + x^847 + x^846 + x^843 + x^839 + x^837 + x^836 + x^832 + x^831 + x^830 + x^829 + x^826 + x^823 + x^821 + x^820 + x^817 + x^815 + x^812 + x^809 + x^808 + x^805 + x^803 + x^802 + x^800 + x^799 + x^797 + x^795 + x^793 + x^792 + x^788 + x^786 + x^784 + x^780 + x^775 + x^774 + x^770 + x^768 + x^766 + x^764 + x^761 + x^760 + x^753 + x^752 + x^751 + x^750 + x^747 + x^744 + x^742 + x^741 + x^737 + x^734 + x^732 + x^728 + x^727 + x^724 + x^722 + x^721 + x^719 + x^717 + x^715 + x^714 + x^713 + x^710 + x^709 + x^705 + x^703 + x^701 + x^698 + x^697 + x^695 + x^690 + x^687 + x^685 + x^684 + x^682 + x^681 + x^680 + x^677 + x^676 + x^674 + x^673 + x^672 + x^671 + x^670 + x^669 + x^665 + x^663 + x^659 + x^652 + x^651 + x^650 + x^649 + x^648 + x^647 + x^646 + x^645 + x^642 + x^640 + x^638 + x^632 + x^631 + x^630 + x^629 + x^627 + x^626 + x^623 + x^622 + x^621 + x^620 + x^616 + x^615 + x^610 + x^605 + x^602 + x^601 + x^600 + x^599 + x^598 + x^596 + x^594 + x^593 + x^591 + x^583 + x^581 + x^579 + x^578 + x^577 + x^576 + x^575 + x^573 + x^572 + x^571 + x^570 + x^569 + x^565 + x^563 + x^562 + x^561 + x^559 + x^557 + x^555 + x^552 + x^551 + x^546 + x^544 + x^542 + x^541 + x^540 + x^539 + x^538 + x^537 + x^535 + x^533 + x^530 + x^527 + x^523 + x^522 + x^520 + x^519 + x^515 + x^513 + x^511 + x^509 + x^507 + x^505 + x^504 + x^503 + x^499 + x^497 + x^496 + x^495 + x^493 + x^492 + x^488 + x^486 + x^481 + x^480 + x^479 + x^478 + x^477 + x^472 + x^470 + x^468 + x^467 + x^464 + x^463 + x^460 + x^459 + x^455 + x^454 + x^453 + x^446 + x^445 + x^444 + x^443 + x^440 + x^438 + x^437 + x^432 + x^431 + x^428 + x^427 + x^426 + x^420 + x^419 + x^416 + x^415 + x^414 + x^413 + x^412 + x^411 + x^405 + x^404 + x^401 + x^396 + x^393 + x^392 + x^391 + x^388 + x^387 + x^383 + x^381 + x^380 + x^377 + x^376 + x^369 + x^364 + x^362 + x^358 + x^357 + x^356 + x^355 + x^353 + x^351 + x^349 + x^340 + x^339 + x^338 + x^337 + x^336 + x^335 + x^334 + x^332 + x^330 + x^328 + x^327 + x^326 + x^324 + x^320 + x^318 + x^316 + x^315 + x^309 + x^302 + x^298 + x^292 + x^291 + x^290 + x^289 + x^287 + x^286 + x^285 + x^284 + x^281 + x^279 + x^278 + x^276 + x^274 + x^273 + x^272 + x^271 + x^267 + x^266 + x^264 + x^263 + x^262 + x^260 + x^259 + x^256 + x^254 + x^253 + x^252 + x^251 + x^249 + x^248 + x^247 + x^245 + x^244 + x^241 + x^239 + x^235 + x^234 + x^233 + x^232 + x^231 + x^230 + x^226 + x^224 + x^221 + x^219 + x^218 + x^216 + x^215 + x^214 + x^209 + x^207 + x^206 + x^202 + x^201 + x^198 + x^197 + x^194 + x^193 + x^192 + x^191 + x^189 + x^188 + x^183 + x^182 + x^181 + x^180 + x^179 + x^178 + x^177 + x^175 + x^172 + x^169 + x^168 + x^166 + x^165 + x^164 + x^163 + x^158 + x^157 + x^153 + x^152 + x^149 + x^147 + x^146 + x^144 + x^140 + x^139 + x^136 + x^128 + x^127 + x^126 + x^124 + x^123 + x^122 + x^121 + x^116 + x^115 + x^113 + x^112 + x^109 + x^108 + x^107 + x^106 + x^104 + x^103 + x^102 + x^101 + x^100 + x^99 + x^97 + x^95 + x^94 + x^93 + x^92 + x^87 + x^84 + x^83 + x^82 + x^80 + x^79 + x^78 + x^76 + x^73 + x^70 + x^69 + x^68 + x^67 + x^66 + x^65 + x^63 + x^60 + x^59 + x^57 + x^55 + x^52 + x^51 + x^47 + x^46 + x^45 + x^43 + x^42 + x^40 + x^36 + x^35 + x^30 + x^29 + x^28 + x^27 + x^23 + x^20 + x^17 + x^14 + x^9 + x^7 + x^3 + 1'
)
Example #12
0
 def verify_gamma0(self,d,t,v):
     ker = matrix(GF(2),[(t * self.T(n) * v).list() for n in range(1,d+1)]).kernel()
     #if ker.dimension()<ker.degree():
     #    print ker
     return ker.dimension()==0,"",[ker]
Example #13
0
    def t1_prime(self, n=5, p=65521):
        """
        Return a multiple of element t1 of the Hecke algebra mod 2,
        computed using the Hecke operator $T_n$, where n is self.n.
        To make computation faster we only check if ...==0 mod p.
        Hence J will contain more elements, hence we get a multiple.
        
        INPUT:
        
            - `n` -- integer (optional default=5)
            - `p` -- prime (optional default=65521)

        OUTPUT:

            - a mod 2 matrix

        EXAMPLES::

            sage: from mdsage import *
            sage: C = KamiennyCriterion(29)
            sage: C.t1_prime()
            22 x 22 dense matrix over Finite Field of size 2 (use the '.str()' method to see the entries)
            sage: C.t1_prime(n=3) == 1
            True
            sage: C = KamiennyCriterion(37)
            sage: C.t1_prime()[0]
            (1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0)
        """
        if self.verbose: tm = cputime(); mem = get_memory_usage(); print("t1 start")
        T = self.S.hecke_matrix(n)
        if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "hecke 1")
        f = self.hecke_polynomial(n) # this is the same as T.charpoly()
        if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "char 1")
        Fint = f.factor()
        if all(i[1]!=1 for i in Fint):
            return matrix_modp(zero_matrix(T.nrows()))
        #    raise ValueError("T_%s needs to be a generator of the hecke algebra"%n)
        if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "factor 1, Fint = %s"%(Fint))
        R = f.parent().change_ring(GF(p))
        F = Fint.base_change(R)
        # Compute the iterators of T acting on the winding element.
        e = self.M([0, oo]).element().dense_vector().change_ring(GF(p))
        if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "wind")
        t = matrix_modp(self.M.hecke_matrix(n).dense_matrix(), p)
        if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "hecke 2")
        g = t.charpoly()
        if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "char 2")
        Z = t.iterates(e, t.nrows(), rows=True)
        if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "iter")
        # We find all factors F[i][0] for f such that
        # (g/F[i][0])(t) * e = 0.
        # We do this by computing the polynomial
        #       h = g/F[i][0],
        # turning it into a vector v, and computing
        # the matrix product v * Z.  If the product
        # is 0, then e is killed by h(t).
        J = []
        for i in range(len(F)):
            if F[i][1]!=1:
                J.append(i)
                continue
            h, r = g.quo_rem(F[i][0] ** F[i][1])
            assert r == 0
            v = vector(GF(p), h.padded_list(t.nrows()))
            if v * Z == 0:
                J.append(i)
        if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "zero check")

        if self.verbose: print("J =", J)
        if len(J) == 0:
            # The annihilator of e is the 0 ideal.
            return matrix_modp(identity_matrix(T.nrows()))

        # Finally compute t1.  I'm concerned about how
        # long this will take, so we reduce T mod 2 first.

        # It is important to call "self.T(2)" to get the mod-2
        # reduction of T2 with respect to the right basis (e.g., the
        # integral basis in case use_integral_structure is true.
        Tmod2 = self.T(n)
        if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "hecke mod") 
        g = prod(Fint[i][0].change_ring(GF(2)) ** Fint[i][1] for i in J)
        if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "g has degree %s"%(g.degree()))
        t1 = g(Tmod2)
        if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "t1 finnished")
        return t1        
#! /usr/bin/env sage

from sage.all import GF, matrix
from six.moves import range
import pickle
import io

F = GF(2)


class Instance(object):
    def __init__(self, n, k, r, L, K, R):
        self.n = n
        self.k = k
        self.r = r
        self.L = L
        self.K = K
        self.R = R


def main(blocksize=256, keysize=256, rounds=19):
    ''' Use the global parameters `blocksize`, `keysize` and `rounds`
        to create the set of matrices and constants for the corresponding
        LowMC instance. Save those in a file named
        `matrices_and_constants.dat`.
    '''
    gen = grain_ssg()
    linlayers = []
    for _ in range(rounds):
        linlayers.append(instantiate_matrix(blocksize, blocksize, gen))
Example #15
0
def extend_field(E, r):
    q = E.base_field().order()
    field = GF(q**r)
    a = field(E.a4())
    b = field(E.a6())
    return EllipticCurve(field, [a, b])
Example #16
0
def get_random_point(E, P=None):
    if P is None:
        P = (
            56294930529307888037266989938554520078909974976727867290405186147804672857970,
            40227799284408618946039395270241596338545732655219360714266457471089156305972,
            1)
    k = random.randint(0, E[0])

    P = point_mult(P, k, E)

    return P


if __name__ == '__main__':
    E = EllipticCurve(GF(p), [A, B])
    P = E(G[0], G[1])

    # in sage every point in standart projective coord, we need to move it to jacobian
    # all comutation in chudnovskiy and jcaoban coord, but input|output in sage-projective

    sage_rand_P = E.random_point()

    # newR = get_random_point(E)

    # print(is_inf(P))
    # print(is_on_curve(P, E))
    print(point_double(P, E))
    print(point_add(P, sage_rand_P, E))
    print(point_mult(P, 11, E))
    # print(F"New random point {newR} is on curve: {is_on_curve(newR, E)}")
Example #17
0
def generic_primes(
    K,
    norm_bound=50,
    ice_filter=False,
    auto_stop_strategy=True,
    repeat_bound=4,
    character_enumeration_bound=1000,
):
    """Generic primes are the finitely many primes outside of which
    the isogeny character is necessarily of signature type 1, 2 or 3"""

    contains_imaginary_quadratic = contains_imaginary_quadratic_field(K)

    # Set up important objects to be used throughout

    C_K = K.class_group()
    h_K = C_K.order()

    # Generate the epsilons

    if K.is_galois():
        G_K = K.galois_group()
        G_K_emb, _, _, Kgal, embeddings = galois_action_on_embeddings(G_K)
        strong_type_3_epsilons = get_strong_type_3_epsilons(K, embeddings)
        epsilons = generic_signatures(
            K.degree(),
            strong_type_3_epsilons=strong_type_3_epsilons,
            galgp=G_K_emb,
            ice_filter=ice_filter,
        )
    else:
        Kgal = K.galois_closure("b")
        embeddings = K.embeddings(Kgal)
        strong_type_3_epsilons = get_strong_type_3_epsilons(K, embeddings)
        epsilons = generic_signatures(
            K.degree(),
            strong_type_3_epsilons=strong_type_3_epsilons,
            ice_filter=ice_filter,
        )

    # Now start with the divisibilities. Do the unit computation first

    U_integers_dict = get_U_integers(K, epsilons, embeddings)
    logger.debug("Computed divisibilities from units")

    # Next do the computation of A,B and C integers

    frob_polys_dict = {}

    bound_dict = U_integers_dict

    if auto_stop_strategy:
        aux_primes_iter = split_primes_iter(K)
        class_group_maps = pre_type_3_class_group_maps(K, embeddings)
        epsilon_repeats = {eps: repeat_bound for eps in epsilons}
    else:
        aux_primes = get_aux_primes(K, norm_bound, C_K, h_K,
                                    contains_imaginary_quadratic)
        aux_primes_iter = aux_primes

    for q in aux_primes_iter:
        epsilons_todo = set(
            epsilon_repeats) if auto_stop_strategy else epsilons
        q_class_group_order = C_K(q).multiplicative_order()
        nm_q = q.absolute_norm()
        frob_polys = get_weil_polys(GF(nm_q))
        frob_polys_dict[q] = frob_polys
        ABC_integers_dict = ABC_integers(
            embeddings,
            q,
            epsilons_todo,
            q_class_group_order,
            frob_polys,
            bound_dict,
            ensure_C_nonzero=False,
        )
        if auto_stop_strategy:
            for eps in epsilons_todo:
                if ABC_integers_dict[eps] == bound_dict[eps]:
                    if eps in class_group_maps:
                        if class_group_maps[eps](q) != 0:
                            epsilon_repeats[eps] -= 1
                    else:
                        epsilon_repeats[eps] -= 1
                else:
                    epsilon_repeats[eps] = repeat_bound
                if epsilon_repeats[eps] == 0:
                    del epsilon_repeats[eps]

        bound_dict = {**bound_dict, **ABC_integers_dict}
        if auto_stop_strategy and not epsilon_repeats:
            break

    logger.debug(f"Computed generic ABC integers.")
    logger.debug(f"bound dict before enumeration filter: \n{bound_dict}")

    # Barinder you probably don't want me to compute this cause of prime_divisor
    # however I really want to log this from time to time
    """
    import json

    bound_dict_factored = {
        str(eps): str(bound.prime_divisors()) for eps, bound in bound_dict.items()
    }
    logger.info(
        "bound dict before enumeration filter:\n"
        f"{json.dumps(bound_dict_factored, indent=2)}"
    )
    """

    # Filtering stage

    if ice_filter:
        if auto_stop_strategy:
            aux_primes = character_enumeration_bound
        else:
            aux_primes = get_aux_primes(K, norm_bound, C_K, h_K,
                                        contains_imaginary_quadratic)
        logger.debug("Using ICE filter")
        output = character_enumeration_filter(
            K,
            C_K,
            Kgal,
            bound_dict,
            epsilons,
            aux_primes,
            embeddings,
            auto_stop_strategy=auto_stop_strategy,
        )

    else:
        final_split_dict = {}
        for eps_type in set(epsilons.values()):
            eps_type_tracking_dict_inv = {
                eps: ZZ(bound_dict[eps])
                for eps in epsilons if epsilons[eps] == eps_type
            }
            eps_type_output = lcm(list(eps_type_tracking_dict_inv.values()))
            if eps_type_output.is_perfect_power():
                eps_type_output = eps_type_output.perfect_power()[0]
            eps_type_output = eps_type_output.prime_divisors()
            eps_type_output = filter_ABC_primes(K, eps_type_output, eps_type)
            final_split_dict[eps_type] = set(eps_type_output)

        # Take union of all primes over all epsilons
        output = set.union(*(val for val in final_split_dict.values()))

    return strong_type_3_epsilons, embeddings, sorted(output)
Example #18
0
        Z = [
            False,
        ] * len(X)
        for i in range(len(X)):
            x = list_to_poly(X[i])
            z = x.is_squarefree()
            Z[i] = bool(z)
    else:
        X = []
        Z = []
    d = {"X": X, "Z": Z}
    save_pickle(d, folder, "is_square_free.pkl")


if __name__ == "__main__":
    field = GF(2, modulus="primitive", repr="int")
    sub_folder = "GF(2)"
    seed = 123456789 + 1000
    make_luts(field, sub_folder, seed)

    field = GF(5, modulus="primitive", repr="int")
    sub_folder = "GF(5)"
    seed = 123456789 + 2000
    make_luts(field, sub_folder, seed)

    field = GF(7, modulus="primitive", repr="int")
    sub_folder = "GF(7)"
    seed = 123456789 + 3000
    make_luts(field, sub_folder, seed)

    field = GF(31, modulus="primitive", repr="int")
Example #19
0
def all_fields_of_dimension(N, p=2, name='a'):
    for poly in all_irreducible_polynomials(N, p):
        yield GF(p**N, name=name, modulus=poly)
Example #20
0
 1568074419444165342,853778925104674827,105031681250262217,1204393036537417656,592755100672600484,
 1509207668054427766,1409630039748867615,433329873945170157,168130078420452894,701434349299435396,
 1736119639406860361,1801042332324036889,82826810621030003,581092394588713697,1513323039712657034,
 2086339870071049553,512802587457892537,1294754943443095033,1486581673100914879,930909063370627411,
 2280060915913643774,219424962331973086,118156503193461485,743557822870685069,1997655344719642813,
 393161419260218815,1086985962035808335,2119375969747368461,1650489163325525904,1967094695603069467,
 916149623124228391,1122737829960120900,144869810337397940,2261458899736343261,1226838560319847571,
 897743852062682980,45750188043851908,1858576614171946931,1568041120172266851,289541060457747472,
 1539585379217609033,866887122666596526,6060188892447452,1707684831658632807,1062812350167057257,
 887626467969935688,1968363468003847982,2169897168216456361,217716763626832970,413611451367326769,
 336255814660537144,1464084696245397914,1902174501258288151,1440415903059217441,302153101507069755,
 1558366710940453537,717776382684618355,1206381076465295510,1308718247292688437,555835170043458452,
 1029518900794643490,1034197980057311552,131258234416495689,260799345029896943]

TH_P = prime_range(2**12,2**13)
TH_F = GF(2**61-1)

def TraceHash_from_ap(aplist):
    r"""Return the trace hash of this list of ap, indexed by the primes in TH_P
    """
    return ZZ(sum([TH_F(a*c) for a,c in zip(aplist,TH_C)]))

TH_P_cache = {}


def TraceHash(E):
    r"""Return the trace hash of this elliptic curve defined over either
    QQ or a number field.

    """
    K = E.base_field() 
Example #21
0
def all_irreducible_polynomials(N, p=2):
    FR = PolynomialRing(GF(p), names=("X",))
    for poly in FR.polynomials(of_degree=N):
        if poly.is_irreducible():
            yield poly
Example #22
0
from sage.all import MatrixSpace, matrix, VectorSpace, vector, \
    is_prime, GF

CHARSET = "abcdefghijklmnopqrstuvwxyz01345678{}_"
p = len(CHARSET)
assert is_prime(p)
Fp = GF(p)


def double_char_to_vector(s):
    assert len(s) == 2
    return vector(Fp, [CHARSET.index(s[0]), CHARSET.index(s[1])])


def vector_to_double_char(v):
    assert len(v) == 2
    return CHARSET[v[0]] + CHARSET[v[1]]


def encrypt(msg, K):
    assert all(c in CHARSET for c in msg)
    assert len(msg) % 2 == 0

    A, v = K
    ciphertext = ""
    for i in range(0, len(msg), 2):
        tmp = A * double_char_to_vector(msg[i:i + 2]) + v
        ciphertext += vector_to_double_char(tmp)

    return ciphertext
def final_filter(
    C_K,
    Kgal,
    OK_star_gens,
    aux_primes,
    my_gens_ideals,
    gens_info,
    p,
    eps,
    eps_type,
    embeddings,
    alpha_cache={},
):
    """The possible isogeny prime p is assumed coprime to the prime ideals in
    my_gens_ideals at this point."""
    frak_p0 = Kgal.prime_above(p)  # choice of p_0
    residue_field = frak_p0.residue_field(names="z")
    prime_field = GF(p)

    logger.debug(f"Starting character enumeration filter for Prime {p} for eps {eps}")

    survived = character_unit_filter(OK_star_gens, residue_field, eps, embeddings)
    if not survived:
        logger.debug(f"Prime {p} for eps {eps} removed using unit filter")
        return False

    # Step 1
    possible_vals_at_gens = get_possible_vals_at_gens(
        gens_info, eps, embeddings, residue_field, prime_field
    )

    if not all(possible_vals_at_gens.values()):
        logger.debug(f"Prime {p} for eps {eps} filtered in Step 1 of Heavy filter")
        logger.debug(f"Possible vals at gens: {possible_vals_at_gens}")
        return False
    logger.debug(f"Possible vals at gens: {possible_vals_at_gens}")
    # Step 2

    # a list of tuples
    possible_vals_cart_prod = list(
        product(*[possible_vals_at_gens[q] for q in my_gens_ideals])
    )

    if eps_type == "type-2":

        vals_at_chi_6 = tuple([q.absolute_norm() ** 6 for q in my_gens_ideals])

        possible_vals_cart_prod = [
            x for x in possible_vals_cart_prod if x is not vals_at_chi_6
        ]

    # Step 3

    # The idea is that we try to filter out each tuple in
    # possible_vals_cart_prod using aux primes; the paper explains how
    # these can be considered as refined epsilon types.

    still_in_the_game = possible_vals_cart_prod.copy()
    for q in aux_primes:
        # same result as q.is_coprime(p) but faster
        not_is_coprime = p.divides(q.absolute_norm())
        if not_is_coprime:
            continue
        if q in alpha_cache:
            alpha, exponents_in_class_group = alpha_cache[q]
        else:
            exponents_in_class_group = C_K(q).exponents()

            # Check that these exponents correspond to the ideals in
            # my_gens_ideals in the correct order
            sanity_check = prod(
                [Q ** a for Q, a in zip(my_gens_ideals, exponents_in_class_group)]
            )
            assert C_K(sanity_check) == C_K(q)

            the_principal_ideal = q * prod(
                [Q ** (-a) for Q, a in zip(my_gens_ideals, exponents_in_class_group)]
            )
            alphas = the_principal_ideal.gens_reduced()
            assert len(alphas) == 1, "the principal ideal isn't principal!!!"
            alpha = alphas[0]
            alpha_cache[q] = (alpha, exponents_in_class_group)
        alpha_to_eps = eps_exp(alpha, eps, embeddings)
        alpha_to_eps_mod_p0 = residue_field(alpha_to_eps)
        try:
            thingy = prime_field(alpha_to_eps_mod_p0)
        except TypeError as err:
            # means alpha_to_eps_mod_p0 is not in GF(p) so can ignore and move on
            logger.debug(f"Prime {p} for eps {eps} filtered in Step 3a of Heavy filter")
            logger.debug(f"{repr(err)}")
            return False
        new_still_in_the_game = []
        for possible_val in still_in_the_game:
            possible_val_with_raised_exp = tuple_exp(
                possible_val, exponents_in_class_group
            )
            my_possible_val = thingy * prod(possible_val_with_raised_exp)
            my_possible_val_roots = my_possible_val.nth_root(12, all=True)
            char = q.smallest_integer()
            e = q.residue_class_degree()
            filtered_values = filter_possible_values(
                my_possible_val_roots, char, e, prime_field
            )
            if filtered_values:
                new_still_in_the_game.append(possible_val)
        still_in_the_game = new_still_in_the_game
        if not still_in_the_game:
            logger.debug(f"Prime {p} for eps {eps} filtered in Step 3b of Heavy filter")
            return False

    logger.debug(f"Prime {p} for eps {eps} survived Heavy filter")
    # If not returned False by now, then no obstruction to p being an isogeny prime
    return True
Example #24
0
def Mitm_on_LWE(A, c, u, bound, ell, check_unif=True):

    # Solve LWE on input (A, c) with error bound 'bound' by Mitm strategy
    # check_unif flag : whether try with input (A,u)

    q = A.base_ring().order()
    K = GF(q, proof=False)

    if ell % 2 == 0:
        half = ell // 2
    else:
        half = ell // 2 + 1

    S = data_gen(A, half)
    T = generate_table(S, q)
    is_LWE = False

    print 'Table size = %d' % len(S)
    print

    print '** Mitm on (A_k, c_k) ** '
    print

    count = 0
    print count
    for v in S:

        v = vector(K, v)
        query = c - v
        query = balanced_lift(query)

        sys.stdout.write("\033[F")
        sys.stdout.write("\033[K")

        count += 1
        print 'Number of noisy searches = %d' % count

        res = noisy_search(q, T, bound, query)

        if res is not None:
            is_LWE = True
            if A.nrows() >= A.ncols():
                #print 'query            :', query
                #print 'collision in S   :', res
                #print
                s = solveLA(A, c, query, res, q)
                s = vector(ZZ, s)
            break

    if is_LWE == True:
        if A.nrows() < A.ncols():
            print ' - Input is LWE'
        else:
            print ' - Input is LWE with secret'
            print s

    else:
        print ' - Input is uniform'

    if check_unif is True:
        print
        print '** Mitm on (A_k, u_k) **'
        print

        is_LWE = False
        count = 0
        print count
        for v in S:

            v = vector(K, v)
            query = u - v
            query = balanced_lift(query)

            sys.stdout.write("\033[F")
            sys.stdout.write("\033[K")

            count += 1
            print 'Number of noisy searches = %d' % count

            res = noisy_search(q, T, bound, query)

            if res is not None:
                is_LWE = True
                break

        if is_LWE == True:
            print ' - Input is LWE'

        else:
            print ' - Input is uniform'
Example #25
0
# https://kel.bz/post/sage-p256/
# Finite field prime
p256 = 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF

# Curve parameters for the curve equation: y^2 = x^3 + a256*x +b256
a256 = p256 - 3
b256 = 0x5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B

qq = 0xFFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551

# Base point (x, y)
gx = 0x6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296
gy = 0x4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5

# Create a finite field of order p256
FF = GF(p256)

Fq = Integers(qq)
# Define a curve over that field with specified Weierstrass a and b parameters
EC = EllipticCurve(FF, [a256, b256])
EC.set_order(qq)

g = EC(FF(gx), FF(gy))


##########################################################
##################### Methode utiles #####################
##########################################################

def pad(point):
    """
Example #26
0
"""Contains many 8-bit APN functions"""

from sage.all import GF, PolynomialRing

# global variables of the module
N = 8
F = GF(2**N, name="a")
g = F.gen()
POLY_RING = PolynomialRing(F, "X")
X = POLY_RING.gen()


def poly_to_lut(p):
    s = []
    for x_i in xrange(0, 2**N):
        y = (p(F.fetch_int(x_i))).integer_representation()
        s.append(y)
    return s


def all_quadratic_polynomials():
    """All the functions in Table 9 of
    http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.215.5432&rep=rep1&type=pdf

    """
    return [
        poly_to_lut(X**3),
        poly_to_lut(X**9),
        poly_to_lut(X**3 + sum(X**(9 * 2**i) for i in xrange(0, N))),
        poly_to_lut(X**9 + sum(X**(3 * 2**i) for i in xrange(0, N))),
        poly_to_lut(X**3 + g**245 * X**33 + g**183 * X**66 + g**21 * X**144),
def reduction_maps(betas, ell, verbose=False):
    """Input: 

    betas: a list of d ZZ-module generators of an order O in a number
    field K of degree d,

    ell: a rational prime ell,

    Output: a (possibly empty) list of maps ZZ^d = GF(ell) encoding all
    possible ring homomorphisms from O to GF(ell).  Each map is
    encoded as a list of d elements of GF(ell) giving the images of
    the order's basis (the betas).

    Method: convert each beta into a dxd integer matrix giving the
    multiplication-by-beta map from O to itself.  Reduce these mod
    ell, and use them to define a FiniteDimensionalAlgebra A over
    GF(ell).  Find the maximal ideals of A whose quotient field is
    GF(ell) (and not some extension of it).  So the ideal has
    dimension d-1 and the required map is the inner product with a
    basis vector for its complement.
    """
    K = betas[0].parent()
    #print("K = {}".format(K))
    #print("betas = {}".format(betas))
    assert betas[0]==1
    Fl = GF(ell)
    if verbose:
        print("creating Hecke order mod {} from betas".format(ell))
    coords = K.gen().coordinates_in_terms_of_powers()
    U = Matrix([coords(b) for b in betas]).inverse()
    structure = [(Matrix([coords(bi*bj) for bj in betas])*U).change_ring(Fl)
                 for bi in betas]
    assert structure[0]==1
    #print("structure = {}".format(structure))
    A = FiniteDimensionalAlgebra(Fl, structure)
    #print("A = {}".format(A))
    MM = A.maximal_ideals()
    d = len(betas)
    # dd = [M.basis_matrix().transpose().nullity() for M in MM]
    # print("Algebra over GF({}) of dimension {}  has {} maximal ideals of residue degrees {}".format(ell,len(betas),len(MM), dd))
    vv = [list(M.basis_matrix().right_kernel().basis()[0])
          for M in MM  if M.basis_matrix().rank()==d-1]

    # Taking the dot product with each of these basis vectors gives a
    # GF(l)-linear map from the Hecke order to GF(l), but we need it
    # to be a ring homomorphism, so we must scale it so 1 maps to 1.
    # In practice Sage will always scale the basis vector so that the
    # first nonzero entry (which here must be the first entry) is 1,
    # but we should not rely on this.

    for v in vv:
        if v[0]!=1:
            if verbose:
                print("Rescaling reduction vector v={}".format(v))
            if v[0]==0:
                raise ValueError("reduction map defined by {} maps 1 to 0".format(v))
            v0inv = 1/v[0]
            v = [vi*v0inv for vi in v]
            if verbose:
                print("Rescaled reduction vector v={}".format(v))
    if verbose:
        print("{} reductions found from Hecke order".format(len(vv)))
        if vv:
            print("Reduction vector(s):")
            for v in vv: print(v)
    #return [lambda w: Fl(sum([vi*Fl(wi) for vi,wi in zip(v,w)])) for v in vv]
    return vv
def make_curve(q, t, r, k, D, debug=False):
    """
    Description:
    
        Finds the curve equation for the elliptic curve (q,t,r,k,D) using the Complex Multiplication method
    
    Input:
    
        q - size of prime field
        t - trace of Frobenius
        r - size of prime order subgroup
        k - embedding degree
        D - (negative) fundamental discriminant
    
    Output:
    
        E - elliptic curve over F_q with trace t,
            a subgroup of order r with embedding degree k,
            and fundamental discriminant D
    
    """
    assert is_valid_curve(q, t, r, k,
                          D), 'Invalid input. No curve exists.'  # check inputs
    if debug:
        print('Tested input')
    poly = hilbert_class_polynomial(D)  # compute hilbert class polynomial
    if debug:
        print('Computed Hilbert class polynomial')
    check = False
    j_inv = poly.any_root(GF(q))  # find j-invariant
    orig_curve = EllipticCurve(GF(q), j=j_inv)  # make a curve
    E = orig_curve
    check = test_curve(q, t, r, k, D, E)  # see if this is the right curve
    twist = False
    if not check:  # not the right curve, use quadratic twist
        E = E.quadratic_twist()
        check = test_curve(q, t, r, k, D, E)
        if check:
            twist = True
        else:  # twist didnt work => j = 0 or 1728
            if j_inv == 0:  # for j = 0, use sextic twists
                prim = primitive_root(q)
                i = 1
                while t != E.trace_of_frobenius() and i < 6:
                    E = orig_curve.sextic_twist(power_mod(prim, i, q))
                    i += 1
            elif j_inv == 1728:  # for j = 1728, use quartic twists
                prim = primitive_root(q)
                i = 1
                while t != E.trace_of_frobenius() and i < 4:
                    E = orig_curve.quartic_twist(power_mod(prim, i, q))
                    i += 1
            else:  # twist didnt work and j != 0, 1728. this should never happen, so write input to a file for debugging
                print(
                    'Error. Quadratic twist failed to find the correct curve with j != 0, 1728. Logging output to debug.txt'
                )  # this line should never be reached'
                f = open('debug.txt', 'w')
                f.write('Twist: ' + str(twist) + '\n')
                f.write('q: ' + str(q) + '\n')
                f.write('t: ' + str(t) + '\n')
                f.write('r: ' + str(r) + '\n')
                f.write('k: ' + str(k) + '\n')
                f.write('D: ' + str(D) + '\n')
                f.write('E: ' + str(E) + '\n')
                f.write('orig_curve: ' + str(orig_curve))
                f.close()
                return False
            check = test_curve(q, t, r, k, D, E)
            twist = True
    if not check:  # didnt find a curve. this should never happen, so write input to a file for debugging
        print('Error. Failed to find curve. Logging output to debug.txt')
        f = open('debug.txt', 'w')
        f.write('Twist: ' + str(twist) + '\n')
        f.write('q: ' + str(q) + '\n')
        f.write('t: ' + str(t) + '\n')
        f.write('r: ' + str(r) + '\n')
        f.write('k: ' + str(k) + '\n')
        f.write('D: ' + str(D) + '\n')
        f.write('E: ' + str(E) + '\n')
        f.write('orig_curve: ' + str(orig_curve))
        f.close()
        return False
    return E
Example #29
0
    def __init__(self, p, congruence_type=1, sign=1, algorithm="custom", verbose=False, dump_dir=None):
        """
        Create a Kamienny criterion object.

        INPUT:

            - `p` -- prime -- verify that there is no order p torsion
              over a degree `d` field
            - `sign` -- 1 (default),-1 or 0 -- the sign of the modular symbols space to use 
            - ``algorithm`` -- "default" or "custom" whether to use a custom (faster)
              integral structure algorithm or to use the sage builtin algortihm
            - ``verbose`` -- bool; whether to print extra stuff while
              running.

        EXAMPLES::

            sage: from mdsage import *
            sage: C = KamiennyCriterion(29, algorithm="custom", verbose=False); C
            Kamienny's Criterion for p=29
            sage: C.use_custom_algorithm
            True
            sage: C.p
            29
            sage: C.verbose
            False        
        """
        self.verbose = verbose
        self.dump_dir = dump_dir
        if self.verbose: tm = cputime(); mem = get_memory_usage(); print("init")
        assert congruence_type == 0 or congruence_type == 1
        self.congruence_type=congruence_type
        try:
            p = ZZ(p)
            if congruence_type==0:
                self.congruence_group = Gamma0(p)
            if congruence_type==1:
                self.congruence_group = GammaH(p,[-1])
        except TypeError:
            self.congruence_group = GammaH(p.level(),[-1]+p._generators_for_H())
            self.congruence_type = ("H",self.congruence_group._list_of_elements_in_H())
            
        self.p = self.congruence_group.level()
  
        self.algorithm=algorithm
        self.sign=sign
        
        self.M = ModularSymbols(self.congruence_group, sign=sign)
        if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "modsym")
        self.S = self.M.cuspidal_submodule()
        if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "cuspsub")
        self.use_custom_algorithm = False
        if algorithm=="custom":
            self.use_custom_algorithm = True
        if self.use_custom_algorithm:
            int_struct = self.integral_cuspidal_subspace()
            if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "custom int_struct")
        else:    
            int_struct = self.S.integral_structure()
            if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "sage int_struct")
        self.S_integral = int_struct
        v = VectorSpace(GF(2), self.S.dimension()).random_element()
        self.v=v
        if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "rand_vect")
        if dump_dir:
            v.dump(dump_dir+"/vector%s_%s" % (p,congruence_type))
        if self.verbose: print("time and mem", cputime(tm), get_memory_usage(mem), "dump")