Exemplo n.º 1
0
def mult_sliding_window(m: int,
                        Q: JacPoint,
                        ec: CurveGroup,
                        w: int = 4) -> JacPoint:
    """Scalar multiplication using "sliding window".

    It has the benefit that the pre-computation stage
    is roughly half as complex as the normal windowed method.
    It is not constant time.
    For 256-bit scalars choose w=4 or w=5.

    The input point is assumed to be on curve and
    the m coefficient is assumed to have been reduced mod n
    if appropriate (e.g. cyclic groups of order n).
    """

    if m < 0:
        raise BTClibValueError(f"negative m: {hex(m)}")

    # a number cannot be written in basis 1 (ie w=0)
    if w <= 0:
        raise BTClibValueError(f"non positive w: {w}")

    k = w - 1
    p = pow(2, k)

    # at each step one of the points in T will be added
    P = Q
    for _ in range(k):
        P = ec.double_jac(P)
    T = [P]
    for i in range(1, p):
        T.append(ec.add_jac(T[i - 1], Q))

    digits = convert_number_to_base(m, 2)

    R = INFJ
    i = 0
    while i < len(digits):
        if digits[i] == 0:
            R = ec.double_jac(R)
            i += 1
        else:
            j = len(digits) - i if (len(digits) - i) < w else w
            t = digits[i]
            for a in range(1, j):
                t = 2 * t + digits[i + a]

            if j < w:
                for b in range(i, (i + j)):
                    R = ec.double_jac(R)
                    if digits[b] == 1:
                        R = ec.add_jac(R, Q)
                return R
            for _ in range(w):
                R = ec.double_jac(R)
            R = ec.add_jac(R, T[t - p])
            i += j

    return R
def test_ecf_exceptions() -> None:
    ec = CurveGroup(10007, 497, 1768)

    err_msg = "p is too big to count all group points: "
    with pytest.raises(BTClibValueError, match=err_msg):
        find_all_points(ec)

    err_msg = "p is too big to count all subgroup points: "
    with pytest.raises(BTClibValueError, match=err_msg):
        # p (10007) is too big to count all subgroup points
        G = (2, 3265)
        find_subgroup_points(ec, G)
Exemplo n.º 3
0
def mult_w_NAF(m: int, Q: JacPoint, ec: CurveGroup, w: int = 4) -> JacPoint:
    """Scalar multiplication in Jacobian coordinates using wNAF.

    This implementation uses the same method called "w-ary non-adjacent form" (wNAF)
    we make use of the fact that point subtraction is as easy as point addition to perform fewer operations compared to sliding-window
    In fact, on Weierstrass curves, known P, -P can be computed on the fly.

    The input point is assumed to be on curve and
    the m coefficient is assumed to have been reduced mod n
    if appropriate (e.g. cyclic groups of order n).
    'right-to-left' method.

    FIXME:
    - Make it constant time (if necessary)
    - Try to avoid exception in negation for w=1
    """

    if m < 0:
        raise BTClibValueError(f"negative m: {hex(m)}")

    # a number cannot be written in basis 1 (ie w=0)
    if w <= 0:
        raise BTClibValueError(f"non positive w: {w}")

    M = wNAF_of_m(m, w)

    p = len(M)

    b = pow(2, w)

    Q2 = ec.double_jac(Q)
    T = [Q]
    for i in range(1, (b // 4)):
        T.append(ec.add_jac(T[i - 1], Q2))
    for i in range((b // 4), (b // 2)):
        T.append(ec.negate_jac(T[i - (b // 4)]))

    R = INFJ
    for j in range(p - 1, -1, -1):
        R = ec.double_jac(R)
        if M[j] != 0:
            if M[j] > 0:
                # It adds the element jQ
                R = ec.add_jac(R, T[(M[j] - 1) // 2])
            else:
                # In this case it adds the opposite, ie -jQ
                if w != 1:
                    R = ec.add_jac(R, T[(b // 4) - ((M[j] + 1) // 2)])
                else:
                    # Case w=1 must be studied on its own for now
                    R = R = ec.add_jac(R, T[1])
    return R
def test_ecf() -> None:
    ec = CurveGroup(9739, 497, 1768)

    # challenge = 'Point Negation'
    P = (8045, 6936)
    S = ec.negate(P)
    S_exp = (8045, 2803)
    assert S == S_exp

    # challenge = 'Point Addition'
    X = (5274, 2841)
    Y = (8669, 740)
    assert ec.add(X, Y) == (1024, 4440)
    assert ec.add(X, X) == (7284, 2107)
    P = (493, 5564)
    Q = (1539, 4742)
    R = (4403, 5202)
    S = ec.add(ec.add(ec.add(P, P), Q), R)
    ec.require_on_curve(S)
    S_exp = (4215, 2162)
    assert S == S_exp

    # challenge = 'Scalar Multiplication'
    X = (5323, 5438)
    assert mult_aff(1337, X, ec) == (1089, 6931)
    P = (2339, 2213)
    S = mult_aff(7863, P, ec)
    ec.require_on_curve(S)
    S_exp = (9467, 2742)
    assert S == S_exp

    # challenge = 'Curves and Logs'
    all_points = find_all_points(ec)
    assert len(all_points) == 9735
    G = (1804, 5368)
    points = find_subgroup_points(ec, G)
    assert len(points) == 9735