aboutsummaryrefslogtreecommitdiff
path: root/epare/countermeasures/utils.py
blob: 0f9f441ac901eae667753cecb454e979216047d4 (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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
from pyecsca.ec.mult import DoubleAndAddMultiplier
from pyecsca.ec.signature import ECDSA_SHA1,SignatureResult
from pyecsca.ec.model import ShortWeierstrassModel
from pyecsca.ec.mod import Mod, mod
from pyecsca.ec.error import NonInvertibleError
import os

def get_point_bytes(path):
    with open(path, "r") as f:
        line = f.read()
        sx, sy = line.split(",")
        bx = bytes.fromhex(sx[2:])
        by = bytes.fromhex(sy[2:])
        point = bytes([0x04]) + bx + by
        return point


def read_curve_params(path):
    with open(path) as f:
        return f.read().strip()

def serialize_ecdh_response(ecdhresponse,curve,point,key):
    error = str(int(ecdhresponse.error))
    params = ",".join(map(lambda x: x.hex(),ecdhresponse.params))
    apdu = ecdhresponse.resp.data.hex()
    secret = ecdhresponse.secret.hex()
    success = str(int(ecdhresponse.success))
    sws = ",".join(map(str,ecdhresponse.sws))
    point = point.hex()
    key = hex(key)
    return ";".join([success,error,secret,key,point,curve,params,apdu,sws])

def recover_nonce(params,data,key,point_bytes,signature_result):
    point = params.curve.decode_point(point_bytes)
    model = ShortWeierstrassModel().coordinates["projective"]
    sig = ECDSA_SHA1(DoubleAndAddMultiplier(model.formulas["add-2007-bl"],model.formulas["dbl-2007-bl"]),params.to_coords(model),pubkey=point.to_model(model, params.curve.to_coords(model)),privkey=key)
    digest = sig.hash_algo(data).digest()
    z = int.from_bytes(digest, byteorder="big")
    if len(digest) * 8 > sig.params.order.bit_length():
        z >>= len(digest) * 8 - sig.params.order.bit_length()
    r,s = signature_result.r, signature_result.s
    s = mod(int(s),sig.params.order)
    r = mod(int(r), sig.params.order)
    try:
        nonce = s.inverse() * (mod(z, sig.params.order) + r * sig.privkey)
    except NonInvertibleError:
        return 0
    sig.mult.init(sig.params, sig.params.generator)
    point = sig.mult.multiply(int(nonce))
    affine_point = point.to_affine()
    #assert r == mod(int(affine_point.x), sig.params.order)
    return nonce


def serialize_ecdsa_response(response,data,domainparams,key,curve_csv,point_bytes,valid = None):
    error = str(int(response.error))
    params = ",".join(map(lambda x: x.hex(),response.params))
    apdu = response.resp.data.hex()
    signature = response.signature.hex()
    success = str(int(response.success))
    sws = ",".join(map(str,response.sws))
    point_bytes_hex = point_bytes.hex()
    key_hex = hex(key)
    data_hex = data.hex()
    nonce = recover_nonce(domainparams,data,key,point_bytes,SignatureResult.from_DER(response.signature))
    nonce_hex = hex(int(nonce))
    valid_str = "" if valid is None else str(valid)
    return ";".join([success,error,signature,valid_str,data_hex,nonce_hex,key_hex,point_bytes_hex,curve_csv,params,apdu,sws])

def serialize_keygen_response(response,key,curve_csv,point_bytes):
    error = str(int(response.error))
    params = ",".join(map(lambda x: x.hex(),response.params))
    apdu = response.resp.data.hex()
    success = str(int(response.success))
    sws = ",".join(map(str,response.sws))
    point_bytes_hex = point_bytes.hex()
    key_hex = hex(key)
    return ";".join([success,error,key_hex,point_bytes_hex,curve_csv,params,apdu,sws])


def save_ecdh(card,test):
    header = "success;error;secret[SHA1];priv;pub;curve;params;apdu;sws"
    filename = f"results/{card}/{test}/ecdh.csv"
    if os.path.isfile(filename):
        print("Measurement already exists")
    with open(filename,"w") as f:
        f.write(f"{header}\n")
        for line in result_lines:
            f.write(f"{line}\n")

def save_ecdsa(card,test):
    header = "success;error;signature;valid;data;nonce;priv;pub;curve;params;apdu;sws"
    filename = f"results/{card}/{test}/ecdsa.csv"
    if os.path.isfile(filename):
        print("Measurement already exists")
    with open(filename,"w") as f:
        f.write(f"{header}\n")
        for line in result_lines:
            f.write(f"{line}\n")

def save_keygen(card,test):
    header = "success;error;priv;pub;curve;params;apdu;sws"
    filename = f"results/{card}/{test}/keygen.csv"
    if os.path.isfile(filename):
        print("Measurement already exists")
    with open(filename,"w") as f:
        f.write(f"{header}\n")
        for line in result_lines:
            f.write(f"{line}\n")