aboutsummaryrefslogtreecommitdiff
path: root/tests/test-ecdsa.py
diff options
context:
space:
mode:
authorRob Austein <sra@hactrn.net>2015-08-25 19:21:49 -0400
committerRob Austein <sra@hactrn.net>2015-08-25 19:21:49 -0400
commitf1f3a8adffb9ef4597fea9de8479ee9f84f0a795 (patch)
tree362933599bbe929c151db005cd235811b750e4ad /tests/test-ecdsa.py
parenta4930dbbac93b3637a6f99a443dca55319c35d92 (diff)
More test code.
Diffstat (limited to 'tests/test-ecdsa.py')
-rw-r--r--tests/test-ecdsa.py123
1 files changed, 109 insertions, 14 deletions
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 "};"