Exemplo n.º 1
0
def test_minus_one_quadr_res() -> None:
    "Ensure that if p = 3 (mod 4) then p - 1 is not a quadratic residue"
    for p in primes:
        if (p % 4) == 3:
            with pytest.raises(BTClibValueError, match="no root for "):
                mod_sqrt(p - 1, p)
        else:
            assert p == 2 or p % 4 == 1, "something is badly broken"
            root = mod_sqrt(p - 1, p)
            assert p - 1 == root * root % p
Exemplo n.º 2
0
def test_mod_sqrt() -> None:
    for p in primes[:30]:  # exhaustable only for small p
        has_root = {0, 1}
        for i in range(2, p):
            has_root.add(i * i % p)
        for i in range(p):
            if i in has_root:
                root1 = mod_sqrt(i, p)
                assert i == (root1 * root1) % p
                root2 = p - root1
                assert i == (root2 * root2) % p
                root = mod_sqrt(i + p, p)
                assert i == (root * root) % p
                if p % 4 == 3 or p % 8 == 5:
                    assert tonelli(i, p) in (root1, root2)
            else:
                with pytest.raises(BTClibValueError, match="no root for "):
                    mod_sqrt(i, p)
Exemplo n.º 3
0
 def y(self, x: int) -> int:
     """Return the y coordinate from x, as in (x, y)."""
     if not 0 <= x < self.p:
         err_msg = "x-coordinate not in 0..p-1: "
         err_msg += f"{hex_string(x)}" if x > HEX_THRESHOLD else f"{x}"
         raise BTClibValueError(err_msg)
     y2 = self._y2(x)
     try:
         return mod_sqrt(y2, self.p)
     except BTClibValueError as e:
         err_msg = "invalid x-coordinate: "
         err_msg += f"{hex_string(x)}" if x > HEX_THRESHOLD else f"{x}"
         raise BTClibValueError(err_msg) from e
Exemplo n.º 4
0
def test_symmetry() -> None:
    "Methods to break simmetry: quadratic residue, even/odd, low/high."
    for ec in low_card_curves.values():

        # just a random point, not INF
        q = 1 + secrets.randbelow(ec.n - 1)
        Q = mult(q, ec.G, ec)
        x_Q = Q[0]

        assert not ec.y_even(x_Q) % 2
        assert ec.y_low(x_Q) <= ec.p // 2

        # compute quadratic residues
        hasRoot = {1}
        for i in range(2, ec.p):
            hasRoot.add(i * i % ec.p)

        if ec.p % 4 == 3:
            quad_res = ec.y_quadratic_residue(x_Q)

            # in this case only quad_res is a quadratic residue
            assert quad_res in hasRoot
            root = mod_sqrt(quad_res, ec.p)
            assert quad_res == (root * root) % ec.p
            root = ec.p - root
            assert quad_res == (root * root) % ec.p

            assert ec.p - quad_res not in hasRoot
            with pytest.raises(BTClibValueError, match="no root for "):
                mod_sqrt(ec.p - quad_res, ec.p)
        else:
            assert ec.p % 4 == 1
            # cannot use y_quadratic_residue in this case
            err_msg = "field prime is not equal to 3 mod 4: "
            with pytest.raises(BTClibValueError, match=err_msg):
                ec.y_quadratic_residue(x_Q)

            y_even = ec.y_even(x_Q)
            y_odd = ec.p - y_even
            # in this case neither or both y_Q are quadratic residues
            neither = y_odd not in hasRoot and y_even not in hasRoot
            both = y_odd in hasRoot and y_even in hasRoot
            assert neither or both
            if y_odd in hasRoot:  # both have roots
                root = mod_sqrt(y_odd, ec.p)
                assert y_odd == (root * root) % ec.p
                root = ec.p - root
                assert y_odd == (root * root) % ec.p
                root = mod_sqrt(y_even, ec.p)
                assert y_even == (root * root) % ec.p
                root = ec.p - root
                assert y_even == (root * root) % ec.p
            else:
                err_msg = "no root for "
                with pytest.raises(BTClibValueError, match=err_msg):
                    mod_sqrt(y_odd, ec.p)
                with pytest.raises(BTClibValueError, match=err_msg):
                    mod_sqrt(y_even, ec.p)

    with pytest.raises(BTClibValueError):
        secp256k1.y_even(INF[0])
    with pytest.raises(BTClibValueError):
        secp256k1.y_low(INF[0])
    with pytest.raises(BTClibValueError):
        secp256k1.y_quadratic_residue(INF[0])
Exemplo n.º 5
0
 maxordera = -1
 maxorderb = -1
 maxorderlessthanprime = 0
 maxorderlessthanprimea = -1
 maxorderlessthanprimeb = -1
 for a in range(200):
     for b in range(200):
         order = 0
         for x in range(prime):
             y2 = ((x * x + a) * x + b) % prime
             if y2 == 0:
                 order += 1
                 # print("#", order+1, " ", x, ", ", 0, "  #####", sep="")
                 continue
             try:
                 y = mod_sqrt(y2, prime)
                 assert (y * y) % prime == y2
                 # print("#", order+1, " ", x, ",", y, sep="")
                 # print("#", order+2, " ", x, ",", prime-y, sep="")
                 order += 2
             except Exception:
                 continue
         order += 1
         if isprime(order):
             # print(a, b, prime, "gen", order)
             if order > maxorder:
                 maxorder = order
                 maxordera = a
                 maxorderb = b
             if order > maxorderlessthanprime and order < prime:
                 maxorderlessthanprime = order