feat: aliro-bench-profile CLI + per-APDU latency probes

New `aliro-bench-profile` entry point drives the applet's INS_DIAG_*
commands over PC/SC at two iteration counts (N=4 / N=16 by default) and
computes per-op cost as the slope, factoring out APDU round-trip + any
one-time Signature.init setup. Reports HMAC, ECDH, ECDSA sign, and
AES-GCM 137B costs side by side, then reconstructs an AUTH1 budget
using the per-primitive counts from the applet's processAuth1 flow so
we can compare the reconstructed estimate against bench-test wall-clock
and see how much of AUTH1 is crypto vs TLV parsing / I/O.

Also extends `aliro-bench-test` to time SELECT / AUTH0 / AUTH1 / total
via time.perf_counter() bracketing each transmit() call. The TransactionResult
now carries a latencies_ms dict, threaded through all return sites so both
success and failure paths print the new "APDU latencies (ms):" block.
Made the 1.78x AUTH1 wall-clock speedup from the 4-bit GHASH commit
quantifiable on real hardware (5,795 -> 3,244 ms).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
michael
2026-06-06 15:53:56 -07:00
parent b03c781b92
commit efac7ce6e6
5 changed files with 275 additions and 6 deletions

View File

@@ -95,6 +95,7 @@ def main(trust_dir: Path | None, reader_index: int, list_readers: bool) -> None:
f"RESULT: FAIL \u2014 {result.error}", err=True
)
_echo_tlv_breakdown(result)
_echo_latencies(result)
click.echo(
"Hint: the AUTH1 response decrypted, so session keys are "
"correct. The signature verification failed — check that the "
@@ -103,10 +104,16 @@ def main(trust_dir: Path | None, reader_index: int, list_readers: bool) -> None:
err=True,
)
raise click.exceptions.Exit(1)
raise click.ClickException(result.error or "Aliro transaction failed.")
# Early failure (e.g. non-9000 SW on SELECT/AUTH0/AUTH1) — print
# whatever per-APDU latencies we collected before bailing so the
# operator can see how long the failing step actually took.
click.echo(f"RESULT: FAIL — {result.error}", err=True)
_echo_latencies(result)
raise click.exceptions.Exit(1)
click.echo("RESULT: OK \u2014 applet round-trip on real hardware.")
_echo_tlv_breakdown(result)
_echo_latencies(result)
def _echo_tlv_breakdown(result) -> None:
@@ -116,3 +123,16 @@ def _echo_tlv_breakdown(result) -> None:
click.echo(f" 0x5A credential_PubK: {cred_pub_len}B")
click.echo(f" 0x9E UD signature: {ud_sig_len}B")
click.echo(f" 0x5E signaling_bitmap: 0x{bitmap_hex}")
def _echo_latencies(result) -> None:
"""Per-APDU wall-clock latencies. Surfaces card-side processing time \u2014
the AUTH1 number is what matters for the RFAL WTX-cap analysis."""
if not result.latencies_ms:
return
click.echo(" APDU latencies (ms):")
for step in ("select", "auth0", "auth1"):
if step in result.latencies_ms:
click.echo(f" {step:<6} {result.latencies_ms[step]:7.1f}")
total = sum(result.latencies_ms.values())
click.echo(f" {'total':<6} {total:7.1f}")