예제 #1
0
def _pubkey_recovery(ec: Curve, c: int, sig: ECDS) -> Sequence[Point]:
    """Private function provided for testing purposes only."""
    # ECDSA public key recovery operation according to SEC 1
    # http://www.secg.org/sec1-v2.pdf
    # See SEC 1 v.2 section 4.1.6

    r, s = _to_sig(ec, sig)

    # precomputations
    r1 = mod_inv(r, ec.n)
    r1s = r1 * s
    r1e = -r1 * c
    keys: Sequence[Point] = list()
    for j in range(ec.h):  # 1
        x = r + j * ec.n  # 1.1
        try:  #TODO: check test reporting 1, 2, 3, or 4 keys
            x %= ec._p
            R = x, ec.y_odd(x, 1)  # 1.2, 1.3, and 1.4
            # skip 1.5: in this function, c is an input
            Q = double_mult(ec, r1s, R, r1e, ec.G)  # 1.6.1
            if Q[1] != 0 and _verhlp(ec, c, Q, sig):  # 1.6.2
                keys.append(Q)
            R = ec.opposite(R)  # 1.6.3
            Q = double_mult(ec, r1s, R, r1e, ec.G)
            if Q[1] != 0 and _verhlp(ec, c, Q, sig):  # 1.6.2
                keys.append(Q)  # 1.6.2
        except Exception:  # R is not a curve point
            pass
    return keys
예제 #2
0
def point_from_octets(ec: Curve, o: octets) -> Point:
    """Return a tuple (Px, Py) that belongs to the curve

       SEC 1 v.2, section 2.3.4
    """
    if isinstance(o, str):
        o = bytes.fromhex(o)

    bsize = len(o)  # bytes
    if bsize == 1 and o[0] == 0x00:  # infinity point
        return Point()

    if bsize == ec.psize + 1:  # compressed point
        if o[0] not in (0x02, 0x03):
            m = f"{ec.psize+1} bytes, but not a compressed point"
            raise ValueError(m)
        Px = int.from_bytes(o[1:], 'big')
        try:
            Py = ec.y_odd(Px, o[0] % 2)  # also check Px validity
            return Point(Px, Py)
        except:
            raise ValueError("point not on curve")
    else:  # uncompressed point
        if bsize != 2 * ec.psize + 1:
            m = f"wrong byte-size ({bsize}) for a point: it "
            m += f"should have be {ec.psize+1} or {2*ec.psize+1}"
            raise ValueError(m)
        if o[0] != 0x04:
            raise ValueError("not an uncompressed point")
        Px = int.from_bytes(o[1:ec.psize + 1], 'big')
        P = Point(Px, int.from_bytes(o[ec.psize + 1:], 'big'))
        if ec.is_on_curve(P):
            return P
        else:
            raise ValueError("point not on curve")
def _batch_verify(ec: Curve, hf, ms: List[bytes], P: List[Point],
                  sig: List[ECSS]) -> bool:
    t = 0
    scalars: List(int) = list()
    points: List[Point] = list()
    for i in range(len(P)):
        _ensure_msg_size(hf, ms[i])
        ec.require_on_curve(P[i])
        r, s = _to_sig(ec, sig[i])
        e = _e(ec, hf, r, P[i], ms[i])
        y = ec.y(r)  # raises an error if y does not exist

        # deterministically generated using a CSPRNG seeded by a cryptographic
        # hash (e.g., SHA256) of all inputs of the algorithm, or randomly
        # generated independently for each run of the batch verification
        # algorithm  FIXME
        a = (1 if i == 0 else random.getrandbits(ec.nlen) % ec.n)
        scalars.append(a)
        points.append(_jac_from_aff((r, y)))
        scalars.append(a * e % ec.n)
        points.append(_jac_from_aff(P[i]))
        t += a * s % ec.n

    TJ = _mult_jac(ec, t, ec.GJ)
    RHSJ = _multi_mult(ec, scalars, points)

    # return T == RHS, checked in Jacobian coordinates
    RHSZ2 = RHSJ[2] * RHSJ[2]
    TZ2 = TJ[2] * TJ[2]
    if (TJ[0] * RHSZ2) % ec._p != (RHSJ[0] * TZ2) % ec._p:
        return False

    return (TJ[1] * RHSZ2 * RHSJ[2]) % ec._p == (RHSJ[1] * TZ2 * TJ[2]) % ec._p
예제 #4
0
def _verhlp(ec: Curve, c: int, P: Point, sig: ECDS) -> bool:
    # Private function for test/dev purposes

    # Fail if r is not [1, n-1]
    # Fail if s is not [1, n-1]
    r, s = _to_sig(ec, sig)  # 1

    # Let P = point(pk); fail if point(pk) fails.
    ec.require_on_curve(P)
    if P[1] == 0:
        raise ValueError("public key is infinite")

    w = mod_inv(s, ec.n)
    u = c * w
    v = r * w  # 4
    # Let R = u*G + v*P.
    RJ = _double_mult(ec, u, ec.GJ, v, (P[0], P[1], 1))  # 5

    # Fail if infinite(R).
    assert RJ[2] != 0, "how did you do that?!?"  # 5

    Rx = (RJ[0] * mod_inv(RJ[2] * RJ[2], ec._p)) % ec._p
    x = Rx % ec.n  # 6, 7
    # Fail if r ≠ x(R) %n.
    return r == x  # 8
예제 #5
0
def _batch_verify(ec: Curve, hf: Callable[[Any], Any], ms: Sequence[bytes],
                  P: Sequence[Point], sig: Sequence[ECSS]) -> bool:

    # the bitcoin proposed standard is only valid for curves
    # whose prime p = 3 % 4
    if not ec.pIsThreeModFour:
        errmsg = 'curve prime p must be equal to 3 (mod 4)'
        raise ValueError(errmsg)

    batch_size = len(P)
    if len(ms) != batch_size:
        errMsg = f"mismatch between number of pubkeys ({batch_size}) "
        errMsg += f"and number of messages ({len(ms)})"
        raise ValueError(errMsg)
    if len(sig) != batch_size:
        errMsg = f"mismatch between number of pubkeys ({batch_size}) "
        errMsg += f"and number of signatures ({len(sig)})"
        raise ValueError(errMsg)

    if batch_size == 1:
        return _verify(ec, hf, ms[0], P[0], sig[0])

    t = 0
    scalars: Sequence(int) = list()
    points: Sequence[Point] = list()
    for i in range(batch_size):
        r, s = _to_sig(ec, sig[i])
        _ensure_msg_size(hf, ms[i])
        ec.require_on_curve(P[i])
        e = _e(ec, hf, r, P[i], ms[i])
        # raises an error if y does not exist
        # no need to check for quadratic residue
        y = ec.y(r)

        # a in [1, n-1]
        # deterministically generated using a CSPRNG seeded by a
        # cryptographic hash (e.g., SHA256) of all inputs of the
        # algorithm, or randomly generated independently for each
        # run of the batch verification algorithm
        a = (1 if i == 0 else (1 + random.getrandbits(ec.nlen)) % ec.n)
        scalars.append(a)
        points.append(_jac_from_aff((r, y)))
        scalars.append(a * e % ec.n)
        points.append(_jac_from_aff(P[i]))
        t += a * s

    TJ = _mult_jac(ec, t, ec.GJ)
    RHSJ = _multi_mult(ec, scalars, points)

    # return T == RHS, checked in Jacobian coordinates
    RHSZ2 = RHSJ[2] * RHSJ[2]
    TZ2 = TJ[2] * TJ[2]
    if (TJ[0] * RHSZ2) % ec._p != (RHSJ[0] * TZ2) % ec._p:
        return False

    return (TJ[1] * RHSZ2 * RHSJ[2]) % ec._p == (RHSJ[1] * TZ2 * TJ[2]) % ec._p
예제 #6
0
def octets_from_point(ec: Curve, Q: Point, compressed: bool) -> bytes:
    """Return a compressed (0x02, 0x03) or uncompressed (0x04) point as octets

       SEC 1 v.2, section 2.3.3
    """
    # check that Q is a point and that is on curve
    ec.require_on_curve(Q)

    if Q[1] == 0:  # infinity point in affine coordinates
        return b'\x00'

    bPx = Q[0].to_bytes(ec.psize, byteorder='big')
    if compressed:
        return (b'\x03' if (Q[1] & 1) else b'\x02') + bPx

    return b'\x04' + bPx + Q[1].to_bytes(ec.psize, byteorder='big')
예제 #7
0
def _verify(ec: Curve, hf: Callable[[Any], Any], mhd: bytes, P: Point,
            sig: ECSS) -> bool:
    # This raises Exceptions, while verify should always return True or False

    # the bitcoin proposed standard is only valid for curves
    # whose prime p = 3 % 4
    if not ec.pIsThreeModFour:
        errmsg = 'curve prime p must be equal to 3 (mod 4)'
        raise ValueError(errmsg)

    # Let r = int(sig[ 0:32]).
    # Let s = int(sig[32:64]); fail if s is not [0, n-1].
    r, s = _to_sig(ec, sig)

    # The message mhd: a 32-byte array
    _ensure_msg_size(hf, mhd)

    # Let P = point(pk); fail if point(pk) fails.
    ec.require_on_curve(P)
    if P[1] == 0:
        raise ValueError("public key is infinite")

    # Let e = int(hf(bytes(r) || bytes(P) || mhd)) mod n.
    e = _e(ec, hf, r, P, mhd)

    # Let R = sG - eP.
    # in Jacobian coordinates
    R = _double_mult(ec, s, ec.GJ, -e, (P[0], P[1], 1))

    # Fail if infinite(R).
    if R[2] == 0:
        raise ValueError("sG - eP is infinite")

    # Fail if jacobi(R.y) ≠ 1.
    if legendre_symbol(R[1] * R[2] % ec._p, ec._p) != 1:
        raise ValueError("(sG - eP).y is not a quadratic residue")

    # Fail if R.x ≠ r.
    return R[0] == (R[2] * R[2] * r % ec._p)
예제 #8
0
    def test_exceptions(self):
        # good
        Curve(11, 2, 7, (6, 9), 7, 2, False)

        # p not odd
        self.assertRaises(ValueError, Curve, 10, 2, 7, (6, 9), 7, 1, False)

        # p not prime
        self.assertRaises(ValueError, Curve, 15, 2, 7, (6, 9), 7, 1, False)

        # a > p
        self.assertRaises(ValueError, Curve, 11, 12, 7, (6, 9), 13, 1, False)

        # b > p
        self.assertRaises(ValueError, Curve, 11, 2, 12, (6, 9), 13, 1, False)

        # zero discriminant
        self.assertRaises(ValueError, Curve, 11, 7, 7, (6, 9), 7, 1, False)

        # G not Tuple (int, int)
        self.assertRaises(ValueError, Curve, 11, 2, 7, (6, 9, 1), 7, 1, False)

        # G not on curve
        self.assertRaises(ValueError, Curve, 11, 2, 7, (7, 9), 7, 1, False)

        # n not prime
        self.assertRaises(ValueError, Curve, 11, 2, 7, (6, 9), 8, 1, False)

        # n not Hesse
        self.assertRaises(ValueError, Curve, 11, 2, 7, (6, 9), 71, 1, True)

        # h not as expected
        self.assertRaises(ValueError, Curve, 11, 2, 7, (6, 9), 7, 1, True)
        # Curve(11, 2, 7, (6, 9), 7, 1, 0, True)

        # n not group order
        self.assertRaises(ValueError, Curve, 11, 2, 7, (6, 9), 13, 1, False)

        # n=p -> weak curve
        # missing

        # weak curve
        self.assertRaises(UserWarning, Curve, 11, 2, 7, (6, 9), 7, 2, True)

        # x-coordinate not in [0, p-1]
        ec = CURVES['secp256k1']
        self.assertRaises(ValueError, ec.y, ec.p)
        # secp256k1.y(secp256k1.p)

        # INF point does not generate a prime order subgroup
        self.assertRaises(ValueError, Curve, 11, 2, 7, INF, 7, 2, False)
예제 #9
0
def test_jac():

    ec = Curve(13, 0, 2, (1, 9), 19, 1, False)
    assert ec._jac_equality(ec.GJ, _jac_from_aff(ec.G))

    # q in [2, n-1]
    q = 2 + secrets.randbelow(ec.n - 2)
    Q = _mult_aff(q, ec.G, ec)
    QJ = _mult_jac(q, ec.GJ, ec)
    assert ec._jac_equality(QJ, _jac_from_aff(Q))
    assert not ec._jac_equality(QJ, ec.negate(QJ))
    assert not ec._jac_equality(QJ, ec.GJ)
예제 #10
0
def test_jac_equality() -> None:

    ec = Curve(13, 0, 2, (1, 9), 19, 1, False)
    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 _pubkey_recovery(ec: Curve, hf, e: int, sig: ECSS) -> Point:
    # Private function provided for testing purposes only.

    r, s = _to_sig(ec, sig)

    K = r, ec.y_quadratic_residue(r, True)
    # FIXME y_quadratic_residue in Jacobian coordinates?

    if e == 0:
        raise ValueError("invalid (zero) challenge e")
    e1 = mod_inv(e, ec.n)
    P = double_mult(ec, e1 * s, ec.G, -e1, K)
    assert P[1] != 0, "how did you do that?!?"
    return P
예제 #12
0
def verify_commit(c: bytes, ec: Curve, hf, receipt: Receipt) -> bool:
    w, R = receipt
    # w in [1..n-1] dsa
    # w in [1..p-1] ssa
    # different verify functions?

    # verify R is a good point?

    ch = hf(c).digest()
    e = hf(octets_from_point(ec, R, True) + ch).digest()
    e = int_from_bits(ec, e)
    W = ec.add(R, mult(ec, e, ec.G))
    # different verify functions?
    # return w == W[0] # ECSS
    return w == W[0] % ec.n  # ECDS, FIXME: ECSSA
예제 #13
0
def _verhlp(ec: Curve, e: int, P: Point, sig: ECDS) -> bool:
    """Private function provided for testing purposes only."""
    # Fail if r is not [1, n-1]
    # Fail if s is not [1, n-1]
    r, s = _to_sig(ec, sig)                                # 1

    # Let P = point(pk); fail if point(pk) fails.
    ec.require_on_curve(P)
    if P[1] == 0:
        raise ValueError("public key is infinite")

    s1 = mod_inv(s, ec.n)
    u1 = e*s1
    u2 = r*s1                                              # 4
    # Let R = u*G + v*P.
    RJ = _double_mult(ec, u1, ec.GJ, u2, (P[0], P[1], 1))  # 5

    # Fail if infinite(R).
    assert RJ[2] != 0, "how did you do that?!?"            # 5

    Rx = (RJ[0]*mod_inv(RJ[2]*RJ[2], ec._p)) % ec._p
    v = Rx % ec.n                                          # 6, 7
    # Fail if r ≠ x(R) %n.
    return r == v                                          # 8
예제 #14
0
def second_generator(ec: Curve, hf) -> Point:
    """Nothing-Up-My-Sleeve (NUMS) second generator H wrt ec.G 

       source: https://github.com/ElementsProject/secp256k1-zkp/blob/secp256k1-zkp/src/modules/rangeproof/main_impl.h
       idea: https://crypto.stackexchange.com/questions/25581/second-generator-for-secp256k1-curve
       Get the hash of G, then coerce it to a point (hx, hy).
       The resulting point could not be a curvepoint: in this case keep on
       incrementing hx until a valid curve point (hx, hy) is obtained.
    """
    G_bytes = octets_from_point(ec, ec.G, False)
    hd = hf(G_bytes).digest()
    hx = int_from_bits(ec, hd)
    isCurvePoint = False
    while not isCurvePoint:
        try:
            hy = ec.y_odd(hx, False)
            isCurvePoint = True
        except:
            hx += 1
    return Point(hx, hy)
예제 #15
0
def test_exceptions():

    # good curve
    Curve(13, 0, 2, (1, 9), 19, 1, False)

    with pytest.raises(ValueError, match="p is not prime: "):
        Curve(15, 0, 2, (1, 9), 19, 1, False)

    with pytest.raises(ValueError, match="negative a: "):
        Curve(13, -1, 2, (1, 9), 19, 1, False)

    with pytest.raises(ValueError, match="p <= a: "):
        Curve(13, 13, 2, (1, 9), 19, 1, False)

    with pytest.raises(ValueError, match="negative b: "):
        Curve(13, 0, -2, (1, 9), 19, 1, False)

    with pytest.raises(ValueError, match="p <= b: "):
        Curve(13, 0, 13, (1, 9), 19, 1, False)

    with pytest.raises(ValueError, match="zero discriminant"):
        Curve(11, 7, 7, (1, 9), 19, 1, False)

    err_msg = "Generator must a be a sequence\\[int, int\\]"
    with pytest.raises(ValueError, match=err_msg):
        Curve(13, 0, 2, (1, 9, 1), 19, 1, False)

    with pytest.raises(ValueError, match="Generator is not on the curve"):
        Curve(13, 0, 2, (2, 9), 19, 1, False)

    with pytest.raises(ValueError, match="n is not prime: "):
        Curve(13, 0, 2, (1, 9), 20, 1, False)

    with pytest.raises(ValueError, match="n not in "):
        Curve(13, 0, 2, (1, 9), 71, 1, False)

    with pytest.raises(ValueError, match="INF point cannot be a generator"):
        Curve(13, 0, 2, INF, 19, 1, False)

    with pytest.raises(ValueError, match="n is not the group order: "):
        Curve(13, 0, 2, (1, 9), 17, 1, False)

    with pytest.raises(ValueError, match="invalid h: "):
        Curve(13, 0, 2, (1, 9), 19, 2, False)

    # n=p -> weak curve
    # missing

    with pytest.raises(UserWarning, match="weak curve"):
        Curve(11, 2, 7, (6, 9), 7, 2, True)
예제 #16
0
from btclib.curve import Curve

# low cardinality curves p<100
ec11_7  = Curve(11, 2, 7, (6,   9),   7, 2, 0, False)
ec11_17 = Curve(11, 2, 4, (0,   9),  17, 1, 0, False)
ec13_11 = Curve(13, 7, 6, (1,   1),  11, 1, 0, False)
ec13_19 = Curve(13, 0, 2, (1,   9),  19, 1, 0, False)
ec17_13 = Curve(17, 6, 8, (0,  12),  13, 2, 0, False)
ec17_23 = Curve(17, 3, 5, (1,  14),  23, 1, 0, False)
ec19_13 = Curve(19, 0, 2, (4,  16),  13, 2, 0, False)
ec19_23 = Curve(19, 2, 9, (0,  16),  23, 1, 0, False)
ec23_19 = Curve(23, 9, 7, (5,   4),  19, 1, 0, False)
ec23_31 = Curve(23, 5, 1, (0,   1),  31, 1, 0, False)
ec29_37 = Curve(29, 4, 9, (0,  26),  37, 1, 0, False)
ec31_23 = Curve(31, 4, 7, (0,  10),  23, 1, 0, False)
ec31_43 = Curve(31, 0, 3, (1,   2),  43, 1, 0, False)
ec37_31 = Curve(37, 2, 8, (1,  23),  31, 1, 0, False)
ec37_43 = Curve(37, 2, 9, (0,  34),  43, 1, 0, False)
ec41_37 = Curve(41, 2, 6, (1,  38),  37, 1, 0, False)
ec41_53 = Curve(41, 4, 4, (0,   2),  53, 1, 0, False)
ec43_37 = Curve(43, 1, 5, (2,  31),  37, 1, 0, False)
ec43_47 = Curve(43, 1, 3, (2,  23),  47, 1, 0, False)
ec47_41 = Curve(47, 3, 9, (0,   3),  41, 1, 0, False)
ec47_61 = Curve(47, 3, 5, (1,   3),  61, 1, 0, False)
ec53_47 = Curve(53, 9, 4, (0,  51),  47, 1, 0, False)
ec53_61 = Curve(53, 1, 8, (1,  13),  61, 1, 0, False)
ec59_53 = Curve(59, 9, 3, (0,  48),  53, 1, 0, False)
ec59_73 = Curve(59, 3, 3, (0,  48),  73, 1, 0, False)
ec61_59 = Curve(61, 2, 5, (0,  35),  59, 1, 0, False)
ec61_73 = Curve(61, 1, 9, (0,  58),  73, 1, 0, False)
ec67_61 = Curve(67, 3, 8, (2,  25),  61, 1, 0, False)
예제 #17
0
"Tests for `btclib.secpoint` module."

import secrets
from typing import Dict

import pytest

from btclib.curve import Curve, _mult_aff
from btclib.curves import CURVES
from btclib.secpoint import bytes_from_point, point_from_octets

# test curves: very low cardinality
low_card_curves: Dict[str, Curve] = {}
# 13 % 4 = 1; 13 % 8 = 5
low_card_curves["ec13_11"] = Curve(13, 7, 6, (1, 1), 11, 1, False)
low_card_curves["ec13_19"] = Curve(13, 0, 2, (1, 9), 19, 1, False)
# 17 % 4 = 1; 17 % 8 = 1
low_card_curves["ec17_13"] = Curve(17, 6, 8, (0, 12), 13, 2, False)
low_card_curves["ec17_23"] = Curve(17, 3, 5, (1, 14), 23, 1, False)
# 19 % 4 = 3; 19 % 8 = 3
low_card_curves["ec19_13"] = Curve(19, 0, 2, (4, 16), 13, 2, False)
low_card_curves["ec19_23"] = Curve(19, 2, 9, (0, 16), 23, 1, False)
# 23 % 4 = 3; 23 % 8 = 7
low_card_curves["ec23_19"] = Curve(23, 9, 7, (5, 4), 19, 1, False)
low_card_curves["ec23_31"] = Curve(23, 5, 1, (0, 1), 31, 1, False)

all_curves: Dict[str, Curve] = {}
all_curves.update(low_card_curves)
all_curves.update(CURVES)
예제 #18
0
    def test_exceptions(self):
        # good
        Curve(11, 2, 7, (6, 9), 7, 2, 0, False)

        # p not odd
        self.assertRaises(ValueError, Curve, 10, 2, 7, (6, 9),    7, 1, 0, False)

        # p not prime
        self.assertRaises(ValueError, Curve, 15, 2, 7, (6, 9),    7, 1, 0, False)

        # required security level not in the allowed range
        ec = secp112r1
        p = ec._p
        a = ec._a
        b = ec._b
        G = ec.G
        n = ec.n
        t = ec.t
        h = ec.h
        self.assertRaises(UserWarning, Curve, p, a, b, G, n, h, 273)
        #Curve(p, a, b, G, n, h, 273)

        # not enough bits for required security level
        ec = secp160r1
        p = ec._p
        a = ec._a
        b = ec._b
        G = ec.G
        n = ec.n
        t = ec.t
        h = ec.h
        self.assertRaises(UserWarning, Curve, p, a, b, G, n, h, 2*t)
        #Curve(p, a, b, G, n, h, 2*t)

        # a > p
        self.assertRaises(ValueError, Curve, 11, 12, 7, (6, 9),   13, 1, 0, False)

        # b > p
        self.assertRaises(ValueError, Curve, 11, 2, 12, (6, 9),   13, 1, 0, False)

        # zero discriminant
        self.assertRaises(ValueError, Curve, 11, 7, 7, (6, 9),    7, 1, 0, False)

        # G not Tuple (int, int)
        self.assertRaises(ValueError, Curve, 11, 2, 7, (6, 9, 1), 7, 1, 0, False)

        # G not on curve
        self.assertRaises(ValueError, Curve, 11, 2, 7, (7, 9),    7, 1, 0, False)

        # n not prime
        self.assertRaises(ValueError, Curve, 11, 2, 7, (6, 9),    8, 1, 0, False)

        # n not Hesse
        self.assertRaises(ValueError, Curve, 11, 2, 7, (6, 9),   71, 1, 0, True)

        # h not as expected
        self.assertRaises(ValueError, Curve, 11, 2, 7, (6, 9),   7, 1, 0, True)
        #Curve(11, 2, 7, (6, 9), 7, 1, 0, True)

        # n not group order
        self.assertRaises(ValueError, Curve, 11, 2, 7, (6, 9),   13, 1, 0, False)

        # n=p -> weak curve
        # missing

        # weak curve
        self.assertRaises(UserWarning, Curve, 11, 2, 7, (6, 9), 7, 2, 0, True)

        # x-coordinate not in [0, p-1]
        self.assertRaises(ValueError, secp256k1.y, secp256k1._p)
# scroll down at the end of the file for 'relevant' code

from btclib.curve import Curve

# SEC 2 v.1 curves, removed from SEC 2 v.2 as insecure ones
# http://www.secg.org/SEC2-Ver-1.0.pdf

__p = (2**128 - 3) // 76439
__a = 0xDB7C2ABF62E35E668076BEAD2088
__b = 0x659EF8BA043916EEDE8911702B22
__Gx = 0x09487239995A5EE76B55F9C2F098
__Gy = 0xA89CE5AF8724C0A23E0E0FF77500
__n = 0xDB7C2ABF62E35E7628DFAC6561C5
__h = 1
secp112r1 = Curve(__p, __a, __b, (__Gx, __Gy), __n, __h, 56, True)

__p = (2**128 - 3) // 76439
__a = 0x6127C24C05F38A0AAAF65C0EF02C
__b = 0x51DEF1815DB5ED74FCC34C85D709
__Gx = 0x4BA30AB5E892B4E1649DD0928643
__Gy = 0xADCD46F5882E3747DEF36E956E97
__n = 0x36DF0AAFD8B8D7597CA10520D04B
__h = 4
secp112r2 = Curve(__p, __a, __b, (__Gx, __Gy), __n, __h, 56, False)

__p = 2**128 - 2**97 - 1
__a = 0xFFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC
__b = 0xE87579C11079F43DD824993C2CEE5ED3
__Gx = 0x161FF7528B899B2D0C28607CA52C5B86
__Gy = 0xCF5AC8395BAFEB13C02DA292DDED7A83