aboutsummaryrefslogtreecommitdiff
path: root/test/ec/test_key_agreement.py
blob: 60e48f83cb75a636a15f0db23e46c8e3ffc824cf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
from copy import copy

import pytest
import json
from importlib_resources import files

from pyecsca.ec.coordinates import AffineCoordinateModel
from pyecsca.ec.key_agreement import (
    ECDH_NONE,
    ECDH_SHA1,
    ECDH_SHA224,
    ECDH_SHA256,
    ECDH_SHA384,
    ECDH_SHA512,
)
from pyecsca.ec.mod import Mod, mod
from pyecsca.ec.mult import LTRMultiplier
import test.data.ec
from pyecsca.ec.params import get_params
from pyecsca.ec.point import Point


@pytest.fixture()
def mult(secp128r1):
    add = secp128r1.curve.coordinate_model.formulas["add-2007-bl"]
    dbl = secp128r1.curve.coordinate_model.formulas["dbl-2007-bl"]
    return LTRMultiplier(add, dbl)


@pytest.fixture()
def keypair_a(secp128r1, mult):
    priv_a = mod(0xDEADBEEF, secp128r1.order)
    mult.init(secp128r1, secp128r1.generator)
    pub_a = mult.multiply(int(priv_a))
    return priv_a, pub_a


@pytest.fixture()
def keypair_b(secp128r1, mult):
    priv_b = mod(0xCAFEBABE, secp128r1.order)
    mult.init(secp128r1, secp128r1.generator)
    pub_b = mult.multiply(int(priv_b))
    return priv_b, pub_b


@pytest.mark.parametrize("algo", [ECDH_NONE, ECDH_SHA1, ECDH_SHA224, ECDH_SHA256, ECDH_SHA384, ECDH_SHA512])
def test_ka(algo, mult, secp128r1, keypair_a, keypair_b):
    result_ab = algo(mult, secp128r1, keypair_a[1], keypair_b[0]).perform()
    result_ba = algo(mult, secp128r1, keypair_b[1], keypair_a[0]).perform()
    assert result_ab == result_ba


def test_ka_secg():
    with files(test.data.ec).joinpath("ecdh_tv.json").open("r") as f:
        secg_data = json.load(f)
    secp160r1 = get_params("secg", "secp160r1", "projective")
    affine_model = AffineCoordinateModel(secp160r1.curve.model)
    add = secp160r1.curve.coordinate_model.formulas["add-2015-rcb"]
    dbl = secp160r1.curve.coordinate_model.formulas["dbl-2015-rcb"]
    mult = LTRMultiplier(add, dbl)
    privA = mod(int(secg_data["keyA"]["priv"], 16), secp160r1.order)
    pubA_affine = Point(affine_model,
                        x=mod(int(secg_data["keyA"]["pub"]["x"], 16), secp160r1.curve.prime),
                        y=mod(int(secg_data["keyA"]["pub"]["y"], 16), secp160r1.curve.prime))
    pubA = pubA_affine.to_model(secp160r1.curve.coordinate_model, secp160r1.curve)
    privB = mod(int(secg_data["keyB"]["priv"], 16), secp160r1.order)
    pubB_affine = Point(affine_model,
                        x=mod(int(secg_data["keyB"]["pub"]["x"], 16), secp160r1.curve.prime),
                        y=mod(int(secg_data["keyB"]["pub"]["y"], 16), secp160r1.curve.prime))
    pubB = pubB_affine.to_model(secp160r1.curve.coordinate_model, secp160r1.curve)

    algoAB = ECDH_SHA1(copy(mult), secp160r1, pubA, privB)
    resAB = algoAB.perform()
    algoBA = ECDH_SHA1(copy(mult), secp160r1, pubB, privA)
    resBA = algoBA.perform()

    assert resAB == resBA
    assert resAB == bytes.fromhex(secg_data["sha1"])

    resAB_raw = algoAB.perform_raw()
    x = int(resAB_raw.x)
    p = secp160r1.curve.prime
    n = (p.bit_length() + 7) // 8
    result = x.to_bytes(n, byteorder="big")
    assert result == bytes.fromhex(secg_data["raw"])