def test_jac_equality() -> None: ec = ec23_31 assert ec._jac_equality(ec.GJ, _jac_from_aff(ec.G)) # q in [2, n-1], as the difference with ec.GJ is checked below q = 2 + secrets.randbelow(ec.n - 2) Q = _mult_aff(q, ec.G, ec) QJ = _mult(q, ec.GJ, ec) assert ec._jac_equality(QJ, _jac_from_aff(Q)) assert not ec._jac_equality(QJ, ec.negate_jac(QJ)) assert not ec._jac_equality(QJ, ec.GJ)
def test_negate() -> None: for ec in all_curves.values(): # just a random point, not INF q = 1 + secrets.randbelow(ec.n - 1) Q = mult(q, ec.G, ec) minus_Q = ec.negate(Q) assert ec.add(Q, minus_Q) == INF # Jacobian coordinates QJ = _jac_from_aff(Q) minus_QJ = ec.negate_jac(QJ) assert ec._jac_equality(ec._add_jac(QJ, minus_QJ), INFJ) # negate of INF is INF minus_INF = ec.negate(INF) assert minus_INF == INF # negate of INFJ is INFJ minus_INFJ = ec.negate_jac(INFJ) assert ec._jac_equality(minus_INFJ, INFJ) with pytest.raises(TypeError, match="not a point"): ec.negate(ec.GJ) # type: ignore with pytest.raises(TypeError, match="not a Jacobian point"): ec.negate_jac(ec.G) # type: ignore
def test_aff_jac_conversions() -> None: for ec in all_curves.values(): # just a random point, not INF q = 1 + secrets.randbelow(ec.n - 1) Q = mult(q, ec.G, ec) QJ = _jac_from_aff(Q) assert Q == ec._aff_from_jac(QJ) x_Q = ec._x_aff_from_jac(QJ) assert Q[0] == x_Q assert INF == ec._aff_from_jac(_jac_from_aff(INF)) # relevant for BIP340-Schnorr signature verification assert not ec.has_square_y(INF) with pytest.raises(ValueError, match="infinity point has no x-coordinate"): ec._x_aff_from_jac(INFJ) with pytest.raises(TypeError, match="not a point"): ec.has_square_y("notapoint") # type: ignore
def test_aff_jac_conversions() -> None: for ec in all_curves.values(): # just a random point, not INF q = 1 + secrets.randbelow(ec.n - 1) Q = mult(q, ec.G, ec) QJ = _jac_from_aff(Q) assert Q == ec._aff_from_jac(QJ) x_Q = ec._x_aff_from_jac(QJ) assert Q[0] == x_Q y_Q = ec._y_aff_from_jac(QJ) assert Q[1] == y_Q assert INF == ec._aff_from_jac(_jac_from_aff(INF)) with pytest.raises(BTClibValueError, match="INF has no x-coordinate"): ec._x_aff_from_jac(INFJ) with pytest.raises(BTClibValueError, match="INF has no y-coordinate"): ec._y_aff_from_jac(INFJ)
def test_add_double_aff_jac() -> None: "Test consistency between affine and Jacobian add/double methods." for ec in all_curves.values(): # just a random point, not INF q = 1 + secrets.randbelow(ec.n - 1) Q = mult(q, ec.G, ec) QJ = _jac_from_aff(Q) # add Q and G R = ec._add_aff(Q, ec.G) RJ = ec._add_jac(QJ, ec.GJ) assert R == ec._aff_from_jac(RJ) # double Q R = ec._double_aff(Q) RJ = ec._double_jac(QJ) assert R == ec._aff_from_jac(RJ) assert R == ec._add_aff(Q, Q) assert ec._jac_equality(RJ, ec._add_jac(QJ, QJ))
def test_assorted_jac_mult() -> None: ec = ec23_31 H = second_generator(ec) HJ = _jac_from_aff(H) for k1 in range(ec.n): K1J = _mult(k1, ec.GJ, ec) for k2 in range(ec.n): K2J = _mult(k2, HJ, ec) shamir = _double_mult(k1, ec.GJ, k2, ec.GJ, ec) assert ec.is_on_curve(ec._aff_from_jac(shamir)) assert ec._jac_equality(shamir, _mult(k1 + k2, ec.GJ, ec)) shamir = _double_mult(k1, INFJ, k2, HJ, ec) assert ec.is_on_curve(ec._aff_from_jac(shamir)) assert ec._jac_equality(shamir, K2J) shamir = _double_mult(k1, ec.GJ, k2, INFJ, ec) assert ec.is_on_curve(ec._aff_from_jac(shamir)) assert ec._jac_equality(shamir, K1J) shamir = _double_mult(k1, ec.GJ, k2, HJ, ec) assert ec.is_on_curve(ec._aff_from_jac(shamir)) K1JK2J = ec._add_jac(K1J, K2J) assert ec._jac_equality(K1JK2J, shamir) k3 = 1 + secrets.randbelow(ec.n - 1) K3J = _mult(k3, ec.GJ, ec) K1JK2JK3J = ec._add_jac(K1JK2J, K3J) assert ec.is_on_curve(ec._aff_from_jac(K1JK2JK3J)) boscoster = _multi_mult([k1, k2, k3], [ec.GJ, HJ, ec.GJ], ec) assert ec.is_on_curve(ec._aff_from_jac(boscoster)) assert ec._aff_from_jac(K1JK2JK3J) == ec._aff_from_jac( boscoster), k3 assert ec._jac_equality(K1JK2JK3J, boscoster) k4 = 1 + secrets.randbelow(ec.n - 1) K4J = _mult(k4, HJ, ec) K1JK2JK3JK4J = ec._add_jac(K1JK2JK3J, K4J) assert ec.is_on_curve(ec._aff_from_jac(K1JK2JK3JK4J)) points = [ec.GJ, HJ, ec.GJ, HJ] boscoster = _multi_mult([k1, k2, k3, k4], points, ec) assert ec.is_on_curve(ec._aff_from_jac(boscoster)) assert ec._aff_from_jac(K1JK2JK3JK4J) == ec._aff_from_jac( boscoster), k4 assert ec._jac_equality(K1JK2JK3JK4J, boscoster) assert ec._jac_equality(K1JK2JK3J, _multi_mult([k1, k2, k3, 0], points, ec)) assert ec._jac_equality(K1JK2J, _multi_mult([k1, k2, 0, 0], points, ec)) assert ec._jac_equality(K1J, _multi_mult([k1, 0, 0, 0], points, ec)) assert ec._jac_equality(INFJ, _multi_mult([0, 0, 0, 0], points, ec)) err_msg = "mismatch between number of scalars and points: " with pytest.raises(BTClibValueError, match=err_msg): _multi_mult([k1, k2, k3, k4], [ec.GJ, HJ, ec.GJ], ec) err_msg = "negative coefficient: " with pytest.raises(BTClibValueError, match=err_msg): _multi_mult([k1, k2, -k3], [ec.GJ, HJ, ec.GJ], ec) with pytest.raises(BTClibValueError, match="negative first coefficient: "): _double_mult(-5, HJ, 1, ec.GJ, ec) with pytest.raises(BTClibValueError, match="negative second coefficient: "): _double_mult(1, HJ, -5, ec.GJ, ec)