Revision 817a9de4bbcc87bf5fb57ca85eecf0d566e0c414 authored by Sangyub Lee on 12 August 2024, 08:36:12 UTC, committed by GitHub on 12 August 2024, 08:36:12 UTC
* Remove old implementations * Add AIMer mem_opt C implementations for all NIST security levels * Add AIMer v2.1 reference C implementation --------- Co-authored-by: jhkwon3002 <jhkwon3002@gmail.com>
1 parent d5d4ed3
genskiplist.py
#!/usr/bin/env python3
# SPDX-License-Identifier: Apache-2.0 or CC0-1.0
"""This script is used to generate the skiplist.py files in pqm{4,3}. It
takes the output files from the mps2-an386 target, when run via the make
script, i.e., compile pqm{4,3} with the mps2-an38{6,5} plattform and the
run-stack-tests targets (remember to backup your benchmark results, if
you want to keep them!):
cp -r benchmarks benchmarks.bak
make clean # Because this will delete it
make PLATFORM=mps2-an386 -j4 run-stack-tests
find benchmarks -name frommake -exec python3 mupq/genskiplist.py {} + > skiplist.py
You can also simply update a single scheme:
make PLATFORM=mps2-an386 benchmarks/stack/crypto_kem/mysuperscheme/opt/frommake
python3 mupq/genskiplist.py benchmarks/stack/crypto_kem/mysuperscheme/opt/frommake
"""
import argparse
import pprint
import re
import sys
def parse_arguments():
parser = argparse.ArgumentParser(
description="Generate a skiplist.py",
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog=__doc__
)
parser.add_argument(
"inputs",
help="Stack benchmark output of mps2 platform",
nargs="+",
type=argparse.FileType("r"),
)
parser.add_argument(
"-r",
"--round",
help="Round up the usage to N bytes",
default=1024,
type=int,
metavar="N",
)
parser.add_argument(
"-m",
"--margin",
help="Add N bytes of additional stack margin",
default=32,
type=int,
metavar="M",
)
return parser.parse_args()
def parse_flashsize(contents):
match = re.search(
r"^\s+(?P<text>\d+)"
r"\s+(?P<data>\d+)"
r"\s+(?P<bss>\d+)"
r"\s+(?P<dec>\d+)"
r"\s+(?P<hex>[0-9A-Fa-f]+)"
r"\s+(?P<filename>[a-zA-Z0-9_\-/\.]+)",
contents,
re.MULTILINE,
)
if match is None:
raise Exception("Size output not found!")
text = int(match.group("text"))
data = int(match.group("data"))
bss = int(match.group("bss"))
return match.group("filename"), text + data, data + bss
def parse_stackusage(contents):
match = re.search(
r"^keypair stack usage:\s+(?P<usage>\d+)",
contents,
re.MULTILINE,
)
if match is None:
raise Exception("keypair usage not found")
keypair = int(match.group("usage"))
match = re.search(
r"^(sign|decaps) stack usage:\s+(?P<usage>\d+)",
contents,
re.MULTILINE,
)
if match is None:
raise Exception("private-op usage not found")
private = int(match.group("usage"))
match = re.search(
r"^(verify|decaps) stack usage:\s+(?P<usage>\d+)",
contents,
re.MULTILINE,
)
if match is None:
raise Exception("public-op usage not found")
public = int(match.group("usage"))
return max(keypair, public, private)
def parse_filename(filename):
match = re.match(
r"elf/(?P<project>|mupq|mupq_pqclean)_?"
r"crypto_(?P<type>kem|sign)_"
r"(?P<scheme>[a-zA-Z0-9_\-]+)_"
r"(?P<impl>[a-zA-Z0-9_\-]+)"
r"_stack\.elf",
filename,
)
if match is None:
raise Exception("Can't parse filename!")
project = match.group("project")
scheme = match.group("scheme")
impl = match.group("impl")
return project, scheme, impl
def roundto(x, to):
return x + (to - x % to)
def main():
args = parse_arguments()
schemes = []
for f in args.inputs:
contents = f.read()
# Check for failed test
try:
filename, flashsize, ramsize = parse_flashsize(contents)
project, scheme, impl = parse_filename(filename)
match = re.search("HardFault", contents, re.MULTILINE)
if match is None:
stackusage = parse_stackusage(contents)
else:
stackusage = 4096 * 1024
except Exception as e:
if "usage not found" in str(e):
stackusage = 4096 * 1024
else:
print(f"Error during parsing file {f.name}: {e}", file=sys.stderr)
continue
memoryusage = roundto(stackusage + ramsize + args.margin, args.round)
print(
f"Scheme: {scheme} Context: {project} Implementation: {impl} Flashsize: {flashsize} Memorysize: {memoryusage}",
file=sys.stderr,
)
schemes.append(
{
"scheme": scheme,
"implementation": impl,
# 'project': (project + "/") if len(project) > 0 else "",
"estmemory": memoryusage,
}
)
# if project == "":
# del schemes[-1]['project']
print("skip_list = [")
for it in schemes:
print(
" "
+ pprint.pformat(it, indent=4, compact=False, sort_dicts=False, width=110),
end=",\n",
)
print("]")
if __name__ == "__main__":
main()
Computing file changes ...