コード例 #1
0
    def add_points(
        self,
        p1: EllipticCurvePoint,
        p2: EllipticCurvePoint,
    ) -> EllipticCurvePoint:
        if p1 == EllipticCurveIdentity:
            return p2

        if p2 == EllipticCurveIdentity:
            return p1

        if p1 == self.invert_point(p2):
            return EllipticCurveIdentity

        p = self.prime
        x1, y1 = p1
        x2, y2 = p2
        if p1 == p2:
            m = mod_divide(3 * x1 * x1 + self.a, 2 * y1, p)
        else:
            m = mod_divide(y2 - y1, x2 - x1, p)

        x3 = (m * m - x1 - x2) % p
        y3 = (m * (x1 - x3) - y1) % p

        return (x3, y3)
コード例 #2
0
ファイル: ecdsa.py プロジェクト: tildedave/cryptopals-set8
def ecdsa_verify(msg: str, sig: ECDSASignature, keypair: ECDHKeypair):
    curve = keypair.config.curve
    n = keypair.config.n
    u1 = mod_divide(hash_msg(msg), sig.s, n)
    u2 = mod_divide(sig.r, sig.s, n)
    R = curve.add_points(keypair.config.scalar_mult_point(u1),
                         curve.scalar_mult(keypair.public, u2))

    return R[0] == sig.r
コード例 #3
0
    def add_points(
        self,
        p1: EllipticCurvePoint,
        p2: EllipticCurvePoint,
    ) -> EllipticCurvePoint:
        # https://www.hyperelliptic.org/EFD/g1p/auto-montgom.html
        x1, y1 = p1
        x2, y2 = p2
        a, b, p = self.a, self.b, self.prime

        x3 = b * pow(y2 - y1, 2, p) * pow(x2 - x1, p - 1 - 2, p) - a - x1 - x2
        y3_first = mod_divide((2 * x1 + x2 + a) * (y2 - y1), x2 - x1, p)
        y3_second = mod_divide(b * (y2 - y1)**3, (x2 - x1)**3, p)

        return mod_point((x3, y3_first - y3_second - y1), p)
コード例 #4
0
ファイル: ecdsa.py プロジェクト: tildedave/cryptopals-set8
def ecdsa_sign(msg: str, keypair: ECDHKeypair):
    n = keypair.config.n
    k = keypair.config.rand_scalar()
    r = keypair.config.scalar_mult_point(k)[0]
    s = mod_divide(hash_msg(msg) + keypair.secret * r, k, n)

    return ECDSASignature(r, s)
コード例 #5
0
def ecdsa_sign_biased(msg: str, keypair: ECDHKeypair):
    n = keypair.config.n
    k = keypair.config.rand_scalar()
    k = (k >> 8) << 8  # Mask off the last 8 bits as suggested
    r = keypair.config.scalar_mult_point(k)[0]
    s = mod_divide(hash_msg(msg) + keypair.secret * r, k, n)

    return ECDSASignature(r, s)
コード例 #6
0
def montgomery_point_test(curve: MontgomeryCurve, u: int) -> bool:
    p = curve.prime
    a = curve.a
    b = curve.b

    rhs = (u**3 + a * (u**2) + u) % p
    v = mod_divide(rhs, b, p)

    return kronecker_symbol(v, p) == 1
コード例 #7
0
def test_lll_against_biased_nonce_attack():
    dh = create_dh()
    chars = string.ascii_lowercase + string.digits
    alice_keypair = dh.generate_keypair()

    num_signatures = 30
    message_length = 40
    l = 8  # Number of biased bits
    q = dh.config.n

    attacker_pairs: List[Tuple[int, int]] = []
    for _ in range(num_signatures):
        msg = ''.join(random.choices(chars, k=message_length))
        sig = ecdsa_sign_biased(msg, alice_keypair)

        r, s = sig.r, sig.s

        t = mod_divide(r, s * 2**l, q)
        u = mod_divide(hash_msg(msg), (-s * 2**l), q)
        attacker_pairs.append((u, t))

    ct = Fraction(1, 2**l)
    cu = Fraction(q, 2**l)
    dim = len(attacker_pairs) + 2
    basis = []
    for i in range(len(attacker_pairs)):
        vec = [0] * dim
        vec[i] = q
        basis.append(vec)

    basis.append(list(map(itemgetter(1), attacker_pairs)) + [ct, 0])
    basis.append(list(map(itemgetter(0), attacker_pairs)) + [0, cu])

    reduction = lll_reduction(basis)
    candidate_rows = [v for v in reduction if v[dim - 1] == cu]

    candidate_keys = [-1 * v[dim - 2] * 2**l for v in candidate_rows]
    assert alice_keypair.secret in candidate_keys, \
        f'Should have seen {alice_keypair.secret} in {candidate_keys}'
コード例 #8
0
def montgomery_find_points(
    curve: MontgomeryCurve,
    u: int,
) -> List[Tuple[int, int]]:
    p = curve.prime
    a = curve.a
    b = curve.b

    rhs = (u**3 + a * (u**2) + u) % p
    if rhs == 0:
        return [(0, 0)]

    v = mod_sqrt(mod_divide(rhs, b, p), p)

    if p - v < v:
        return [(u, p - v), (u, v)]

    return [(u, v), (u, p - v)]