From f1f3a8adffb9ef4597fea9de8479ee9f84f0a795 Mon Sep 17 00:00:00 2001 From: Rob Austein Date: Tue, 25 Aug 2015 19:21:49 -0400 Subject: More test code. --- tests/test-ecdsa.py | 123 ++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 109 insertions(+), 14 deletions(-) (limited to 'tests/test-ecdsa.py') diff --git a/tests/test-ecdsa.py b/tests/test-ecdsa.py index 8fb33f1..a52f85b 100644 --- a/tests/test-ecdsa.py +++ b/tests/test-ecdsa.py @@ -2,9 +2,6 @@ # # e is given in decimal, all other values are hex, because that's how # these were given in the paper -# -# This script will probably become a bit more elaborate at some later date, eg, -# to add ASN.1 encoding. p256_d = 0x70a12c2db16845ed56ff68cfc21a472b3f04d7d6851bf6349f2d7d5b3452b38a p256_Qx = 0x8101ece47464a6ead70cf69a6e2bd3d88691a3262d22cba4f7635eaff26680a8 @@ -40,22 +37,120 @@ p384_u1 = 0x6ce25649d42d223e020c11140fe772326612bb11b686d35ee98ed4550e0635d9dd p384_u2 = 0xf3b240751d5d8ed394a4b5bf8e2a4c0e1e21aa51f2620a08b8c55a2bc334c9689923162648f06e5f4659fc526d9c1fd6 p384_v = 0xa0c27ec893092dea1e1bd2ccfed3cf945c8134ed0c9f81311a0f4a05942db8dbed8dd59f267471d5462aa14fe72de856 -from textwrap import TextWrapper -from os.path import basename -from sys import argv +from textwrap import TextWrapper +from os.path import basename +from sys import argv +from pyasn1.type.univ import Sequence, Choice, Integer, OctetString, ObjectIdentifier, BitString +from pyasn1.type.namedtype import NamedTypes, NamedType, OptionalNamedType +from pyasn1.type.namedval import NamedValues +from pyasn1.type.tag import Tag, tagClassContext, tagFormatSimple +from pyasn1.type.constraint import SingleValueConstraint +from pyasn1.codec.der.encoder import encode as DER_Encode +from pyasn1.codec.der.decoder import decode as DER_Decode wrapper = TextWrapper(width = 78, initial_indent = " " * 2, subsequent_indent = " " * 2) +def long_to_bytes(l): + # + # This is just plain nasty. + # + s = "%x" % l + return ("0" + s if len(s) & 1 else s).decode("hex") + +def bytes_to_bits(b): + # + # This, on the other hand, is not just plain nasty, this is fancy nasty. + # This is nasty with rasins in it. + # + bits = bin(long(b.encode("hex"), 16))[2:] + if len(bits) % 8: + bits = ("0" * (8 - len(bits) % 8)) + bits + return tuple(int(i) for i in bits) + +### + +class ECDSA_Sig_Value(Sequence): + componentType = NamedTypes( + NamedType("r", Integer()), + NamedType("s", Integer())) + +def encode_sig(r, s): + sig = ECDSA_Sig_Value() + sig["r"] = r + sig["s"] = s + return DER_Encode(sig) + +p256_sig = encode_sig(p256_r, p256_s) +p384_sig = encode_sig(p384_r, p384_s) + +### + +class ECPrivateKey(Sequence): + componentType = NamedTypes( + NamedType("version", Integer(namedValues = NamedValues(("ecPrivkeyVer1", 1)) + ).subtype(subtypeSpec = Integer.subtypeSpec + SingleValueConstraint(1))), + NamedType("privateKey", OctetString()), + OptionalNamedType("parameters", ObjectIdentifier().subtype(explicitTag = Tag(tagClassContext, tagFormatSimple, 0))), + OptionalNamedType("publicKey", BitString().subtype(explicitTag = Tag(tagClassContext, tagFormatSimple, 1)))) + +def encode_key(d, Qx, Qy, oid): + private_key = long_to_bytes(d) + public_key = bytes_to_bits(chr(0x04) + long_to_bytes(Qx) + long_to_bytes(Qy)) + parameters = oid + key = ECPrivateKey() + key["version"] = 1 + key["privateKey"] = private_key + key["parameters"] = parameters + key["publicKey"] = public_key + return DER_Encode(key) + +p256_key = encode_key(p256_d, p256_Qx, p256_Qy, "1.2.840.10045.3.1.7") +p384_key = encode_key(p384_d, p384_Qx, p384_Qy, "1.3.132.0.34") + +### + print "/*" print " * ECDSA test data." print " * File automatically generated by", basename(argv[0]) print " */" -for name in sorted(dir()): - if name.startswith("p256_") or name.startswith("p384_"): - value = "%x" % globals()[name] - value = ("0" + value if len(value) & 1 else value).decode("hex") - print - print "static const uint8_t %s[] = { /* %d bytes */" % (name, len(value)) - print wrapper.fill(", ".join("0x%02x" % ord(v) for v in value)) - print "};" +curves = ("p256", "p384") +vars = set() + +for name in dir(): + head, sep, tail = name.partition("_") + if head in curves: + vars.add(tail) + +vars = sorted(vars) + +for curve in curves: + for var in vars: + name = curve + "_" + var + value = globals().get(name, None) + if isinstance(value, (int, long)): + value = long_to_bytes(value) + if value is not None: + print + print "static const uint8_t %s[] = { /* %d bytes */" % (name, len(value)) + print wrapper.fill(", ".join("0x%02x" % ord(v) for v in value)) + print "};" + +print +print "typedef struct {" +print " hal_ecdsa_curve_t curve;" +for var in vars: + print " const uint8_t *%8s; size_t %8s_len;" % (var, var) +print "} ecdsa_tc_t;" +print +print "static const ecdsa_tc_t ecdsa_tc[] = {" +for curve in curves: + print " { HAL_ECDSA_CURVE_%s," % curve.upper() + for var in vars: + name = curve + "_" + var + if name in globals(): + print " %-14s sizeof(%s)," % (name + ",", name) + else: + print " %-14s 0," % "NULL," + print " }," +print "};" -- cgit v1.2.3