mirror of
https://github.com/open-quantum-safe/liboqs.git
synced 2025-10-09 00:04:26 -04:00
* algorithm support table should replace the list of algorithms; minor refactor w.r.t. shebang, imports, and unnecessary global states Signed-off-by: Ganyu (Bruce) Xu <g66xu@uwaterloo.ca> * still need to fill in the content Signed-off-by: Ganyu (Bruce) Xu <g66xu@uwaterloo.ca> * first draft of alg support table Signed-off-by: Ganyu (Bruce) Xu <g66xu@uwaterloo.ca> * some refactoring Signed-off-by: Ganyu (Bruce) Xu <g66xu@uwaterloo.ca> * wrap standardization status with url to spec Signed-off-by: Ganyu (Bruce) Xu <g66xu@uwaterloo.ca> * Use split with no argument to split against any whitespace, not just space Signed-off-by: Ganyu (Bruce) Xu <g66xu@uwaterloo.ca> * documentation; make primary implementation monospaced Signed-off-by: Ganyu (Bruce) Xu <g66xu@uwaterloo.ca> * docs/algorithms/sig/sld_dsa.yml is generated from a Jinja template elsewhere Signed-off-by: Ganyu (Bruce) Xu <g66xu@uwaterloo.ca> * fixed invalid markdown anchors Signed-off-by: Ganyu (Bruce) Xu <g66xu@uwaterloo.ca> * algorithm family names will not link to docs/algorithms markdowns because Doxygen cannot handle them Signed-off-by: Ganyu (Bruce) Xu <g66xu@uwaterloo.ca> * add git diff to basic check for debugging purpose Signed-off-by: Ganyu (Bruce) Xu <g66xu@uwaterloo.ca> * resolved failure to consistently produce the same README.md Signed-off-by: Ganyu (Bruce) Xu <g66xu@uwaterloo.ca> * rephrasing standardization status for PQC third round candidates Signed-off-by: Ganyu (Bruce) Xu <g66xu@uwaterloo.ca> * improved explanation for NTRU's standardization status Signed-off-by: Ganyu (Bruce) Xu <g66xu@uwaterloo.ca> * another try at improving phrasing of standardization status Signed-off-by: Ganyu (Bruce) Xu <g66xu@uwaterloo.ca> * fixed typo Signed-off-by: Ganyu (Bruce) Xu <g66xu@uwaterloo.ca> * removed spec-url from lms.yml Signed-off-by: Ganyu (Bruce) Xu <g66xu@uwaterloo.ca> * revised specification URL to be consistent with spec-version Signed-off-by: Ganyu (Bruce) Xu <g66xu@uwaterloo.ca> * Revised FrodoKEM standardization status to reflect ISO consideration Signed-off-by: Ganyu (Bruce) Xu <g66xu@uwaterloo.ca> --------- Signed-off-by: Ganyu (Bruce) Xu <g66xu@uwaterloo.ca>
131 lines
4.9 KiB
Python
Executable File
131 lines
4.9 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
# SPDX-License-Identifier: MIT
|
|
|
|
"""Helper functions for rendering the Algorithm Support table in README.md
|
|
|
|
This is a separate module to facilitate code formatting and other dev tools,
|
|
but it is not meant to be run by itself. Instead, run the legacy
|
|
scripts/update_docs_from_yaml.py to invoke update_readme in this module.
|
|
"""
|
|
|
|
import os
|
|
|
|
import tabulate
|
|
import yaml
|
|
|
|
YAML_EXTS = [".yaml", ".yml"]
|
|
ALG_SUPPORT_HEADER = [
|
|
"Algorithm family",
|
|
"Standardization status",
|
|
"Primary implementation",
|
|
]
|
|
COMMIT_HASH_LEN = 7
|
|
|
|
|
|
def format_upstream_source(source: str) -> str:
|
|
"""For each YAML data sheet, the primary-upstream.source field contains some
|
|
URL to the implementation. At this moment all URLs are links to GitHub, so
|
|
we can format them as follows:
|
|
|
|
<handle>/<repository>@<commit> if commit is available
|
|
<handle>/<repository> otherwise
|
|
with a link to the repository
|
|
"""
|
|
# TODO: we might get GitLab or other non-GH link in the future but oh well
|
|
prefix = "https://github.com/"
|
|
if not prefix in source:
|
|
raise ValueError(f"Non-GitHub source {source}")
|
|
url_start = source.find(prefix)
|
|
# NOTE: split with no argument will split with all whitespaces
|
|
url = source[url_start:].split()[0]
|
|
# example: ["PQClean", "PQClean", "commit", "1eacfdaf..."]
|
|
tokens = url[len(prefix) :].split("/")
|
|
handle, repo = tokens[0], tokens[1]
|
|
output = f"{handle}/{repo}"
|
|
if "commit/" in url:
|
|
commit = tokens[3][:COMMIT_HASH_LEN]
|
|
output += f"@{commit}"
|
|
return f"[`{output}`]({url})"
|
|
|
|
|
|
def render_alg_support_tbl(doc_dir: str, anchor_alg_name: bool = False) -> str:
|
|
"""Render a markdown table summarizing the algorithms described by YAML data
|
|
sheets stored in the specified doc directory
|
|
|
|
:param anchor_alg_name: if set to True, then "algorithm family" will link to
|
|
the corresponding markdown document under docs/algorithms/<kem|sig|sig_stfl>
|
|
otherwise "algorithm family" will be plain text with no link.
|
|
"""
|
|
# TODO: anchor_alg_name is turned off because Doxygen cannot handle links
|
|
# to markdown files under docs/algorithms/xxx
|
|
yaml_paths = [
|
|
os.path.abspath(os.path.join(doc_dir, filepath))
|
|
for filepath in os.listdir(doc_dir)
|
|
if os.path.splitext(filepath)[1].lower() in YAML_EXTS
|
|
]
|
|
yaml_paths.sort()
|
|
rows = [ALG_SUPPORT_HEADER]
|
|
for yaml_path in yaml_paths:
|
|
with open(yaml_path) as f:
|
|
algdata = yaml.safe_load(f)
|
|
alg_name = algdata["name"]
|
|
dirname = "kem"
|
|
if "sig/" in yaml_path:
|
|
dirname = "sig"
|
|
elif "sig_stfl/" in yaml_path:
|
|
dirname = "sig_stfl"
|
|
md_basename = os.path.splitext(os.path.split(yaml_path)[1])[0]
|
|
md_url = f"docs/algorithms/{dirname}/{md_basename}.md"
|
|
std_status = algdata["standardization-status"]
|
|
spec_url = algdata.get("spec-url", None)
|
|
primary_impl = format_upstream_source(algdata["primary-upstream"]["source"])
|
|
rows.append(
|
|
[
|
|
f"[{alg_name}]({md_url})" if anchor_alg_name else f"{alg_name}",
|
|
f"[{std_status}]({spec_url})" if spec_url else std_status,
|
|
primary_impl,
|
|
]
|
|
)
|
|
tbl = tabulate.tabulate(rows, tablefmt="pipe", headers="firstrow")
|
|
return tbl
|
|
|
|
|
|
def update_readme(liboqs_dir: str):
|
|
"""Per liboqs/issues/2045, update README.md with an algorithm support table
|
|
|
|
The algorithm support table is a summary of individual algorithms currently
|
|
integrated into liboqs. The primary source of information are the various
|
|
YAML files under docs/algorithms/<kem|sig|sig_stfl> directory. The table
|
|
summarizes the following attributes:
|
|
- Algorithm family (e.g. Kyber, ML-KEM)
|
|
- Standardization status, with link to specification
|
|
- Primary source of implementation
|
|
- (WIP) Maintenance status
|
|
"""
|
|
kem_doc_dir = os.path.join(liboqs_dir, "docs", "algorithms", "kem")
|
|
kem_tbl = render_alg_support_tbl(kem_doc_dir)
|
|
sig_doc_dir = os.path.join(liboqs_dir, "docs", "algorithms", "sig")
|
|
sig_tbl = render_alg_support_tbl(sig_doc_dir)
|
|
sig_stfl_doc_dir = os.path.join(liboqs_dir, "docs", "algorithms", "sig_stfl")
|
|
sig_stfl_tbl = render_alg_support_tbl(sig_stfl_doc_dir)
|
|
md_str = f"""#### Key encapsulation mechanisms
|
|
{kem_tbl}
|
|
|
|
#### Signature schemes
|
|
{sig_tbl}
|
|
|
|
#### Stateful signature schemes
|
|
{sig_stfl_tbl}
|
|
"""
|
|
readme_path = os.path.join(liboqs_dir, "README.md")
|
|
fragment_start = "<!-- OQS_TEMPLATE_FRAGMENT_ALG_SUPPORT_START -->\n"
|
|
fragment_end = "<!-- OQS_TEMPLATE_FRAGMENT_ALG_SUPPORT_END -->"
|
|
with open(readme_path, "r") as f:
|
|
readme = f.read()
|
|
fragment_start_loc = readme.find(fragment_start) + len(fragment_start)
|
|
fragment_end_loc = readme.find(fragment_end)
|
|
with open(readme_path, "w") as f:
|
|
f.write(readme[:fragment_start_loc])
|
|
f.write(md_str)
|
|
f.write(readme[fragment_end_loc:])
|