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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
|
import json
import pytest
from importlib_resources import files
import test.data.ec
from pyecsca.ec.coordinates import AffineCoordinateModel
from pyecsca.ec.mod import mod
from pyecsca.ec.mult import LTRMultiplier
from pyecsca.ec.params import get_params
from pyecsca.ec.point import Point
from pyecsca.ec.signature import (
Signature,
SignatureResult,
ECDSA_NONE,
ECDSA_SHA1,
ECDSA_SHA224,
ECDSA_SHA256,
ECDSA_SHA384,
ECDSA_SHA512,
)
@pytest.fixture()
def add(secp128r1):
return secp128r1.curve.coordinate_model.formulas["add-2007-bl"]
@pytest.fixture()
def mult(secp128r1, add):
dbl = secp128r1.curve.coordinate_model.formulas["dbl-2007-bl"]
return LTRMultiplier(add, dbl)
@pytest.fixture()
def keypair(secp128r1, mult):
priv = mod(0xDEADBEEF, secp128r1.order)
mult.init(secp128r1, secp128r1.generator)
pub = mult.multiply(int(priv))
return priv, pub
@pytest.fixture()
def msg():
return 0xCAFEBABE.to_bytes(4, byteorder="big")
@pytest.mark.parametrize("algo",
[
ECDSA_SHA1,
ECDSA_SHA224,
ECDSA_SHA256,
ECDSA_SHA384,
ECDSA_SHA512,
])
def test_all(secp128r1, mult, keypair, msg, add, algo):
priv, pub = keypair
signer = algo(mult, secp128r1, privkey=keypair[0])
assert signer.can_sign
sig = signer.sign_data(msg)
verifier = algo(mult, secp128r1, add=add, pubkey=pub)
assert verifier.can_verify
assert verifier.verify_data(sig, msg)
none = ECDSA_NONE(
mult, secp128r1, add=add, pubkey=pub, privkey=priv
)
digest = signer.hash_algo(msg).digest()
sig = none.sign_hash(digest)
assert none.verify_hash(sig, digest)
def test_cannot(secp128r1, add, mult, keypair):
priv, pub = keypair
ok = ECDSA_NONE(
mult, secp128r1, add=add, pubkey=pub, privkey=priv
)
data = b"aaaa"
sig = ok.sign_data(data)
no_priv = ECDSA_NONE(mult, secp128r1, pubkey=pub)
with pytest.raises(RuntimeError):
no_priv.sign_data(data)
with pytest.raises(RuntimeError):
no_priv.sign_hash(data)
no_pubadd = ECDSA_NONE(mult, secp128r1, privkey=priv)
with pytest.raises(RuntimeError):
no_pubadd.verify_data(sig, data)
with pytest.raises(RuntimeError):
no_pubadd.verify_hash(sig, data)
with pytest.raises(ValueError):
Signature(mult, secp128r1)
@pytest.mark.parametrize("algo",
[
ECDSA_SHA1,
ECDSA_SHA224,
ECDSA_SHA256,
ECDSA_SHA384,
ECDSA_SHA512,
])
def test_fixed_nonce(secp128r1, mult, keypair, msg, add, algo):
priv, pub = keypair
signer = algo(mult, secp128r1, privkey=priv)
sig_one = signer.sign_data(msg, nonce=0xABCDEF)
sig_other = signer.sign_data(msg, nonce=0xABCDEF)
verifier = algo(mult, secp128r1, add=add, pubkey=pub)
assert verifier.verify_data(sig_one, msg)
assert verifier.verify_data(sig_other, msg)
assert sig_one == sig_other
def test_der():
sig = SignatureResult(0xAAAAA, 0xBBBBB)
assert sig == SignatureResult.from_DER(sig.to_DER())
assert sig != "abc"
def test_ecdsa_nist():
with files(test.data.ec).joinpath("ecdsa_tv.json").open("r") as f:
nist_data = json.load(f)
P192 = get_params("nist", "P-192", "projective")
affine_model = AffineCoordinateModel(P192.curve.model)
add = P192.curve.coordinate_model.formulas["add-2015-rcb"]
dbl = P192.curve.coordinate_model.formulas["dbl-2015-rcb"]
mult = LTRMultiplier(add, dbl)
priv = mod(int(nist_data["priv"], 16), P192.order)
pub_affine = Point(affine_model,
x=mod(int(nist_data["pub"]["x"], 16), P192.curve.prime),
y=mod(int(nist_data["pub"]["y"], 16), P192.curve.prime))
pub = pub_affine.to_model(P192.curve.coordinate_model, P192.curve)
signer = ECDSA_SHA1(mult, P192, add, pub, priv)
nonce = int(nist_data["k"], 16)
data = bytes.fromhex(nist_data["msg"])
signature = signer.sign_hash(data, nonce=nonce)
assert signature.r == int(nist_data["signature"]["r"], 16)
assert signature.s == int(nist_data["signature"]["s"], 16)
assert signer.verify_hash(signature, data)
|