fingerprintd/packaging/fptrial.sh
Jorijn van der Graaf edb0d8e530 Spend the presses on the open question, and report what learning actually folded
Two changes to the measurement, both about not wasting a finger.

The wrong-finger control is off by default now. Across every run this project
has made the wrong finger has matched zero times out of forty-odd taps; the
question that is still open is the false-negative rate, and each control tap
spends a press that could have measured it. Pass a count to put the control
back, and the summary says plainly when it was not run rather than printing a
zero that reads like a result.

And a trend run now reports how many frames learning folded, out of the daemon's
own transcript, alongside the container size. Without that a run cannot tell
"learning fired and did not help" from "learning never fired" -- which is exactly
the confusion that let the first trend run measure a static template three times
and look like a result.

Default trial length goes to fifteen taps, since dropping the control freed the
presses and ten was too few to separate three-in-ten from five-in-ten.
2026-09-04 23:43:47 +02:00

42 lines
2.1 KiB
Shell

#!/bin/sh
# fptrial.sh -- a labelled verification protocol against fingerprintd.
#
# fptrial.sh [correct_taps] [wrong_taps] defaults 10 and 5
#
# Runs fprintd-verify once per tap and tells you which finger to use before
# each one. The daemon's transcript records every frame; THIS records the label
# and the wall-clock time from "press now" to the client seeing a result, which
# is the latency a user feels. Unlabelled runs cannot be turned into a rate.
C=${1:-10}; W=${2:-5}
OUT=/tmp/fptrial-$(date +%Y%m%d-%H%M%S).log
now() { awk '{gsub(/\./,""); print $1 "0000000"}' /proc/uptime; }
run() { # $1 = label
printf '\n>>> %s -- press and LIFT (quick tap) ... ' "$1"
t0=$(now)
res=$(timeout 20 fprintd-verify user 2>&1 | grep -E 'Verify result' | tail -1)
t1=$(now)
ms=$(( (t1 - t0) / 1000000 ))
verdict=$(printf '%s' "$res" | grep -oE 'verify-(match|no-match|unknown-error)' || echo timeout)
printf '%s (%d ms)\n' "$verdict" "$ms"
printf '%s %s %d\n' "$1" "$verdict" "$ms" >> "$OUT"
sleep 1
}
echo "labelled trial -> $OUT"
i=1; while [ $i -le $C ]; do run "CORRECT $i/$C"; i=$((i+1)); done
# The wrong-finger half is skippable, and skipping it is the right default once
# the question it answers is settled. Across every run this project has made the
# wrong finger has matched ZERO times out of forty-odd taps; the open question
# is the FALSE NEGATIVE rate, and each wrong-finger tap spends a press that
# could have measured that instead. Pass a count to put the control back.
if [ "$W" -gt 0 ]; then
echo; echo "===== now switch to a DIFFERENT finger ====="; sleep 3
i=1; while [ $i -le $W ]; do run "WRONG $i/$W"; i=$((i+1)); done
fi
echo
echo "===== summary ====="
awk '$1=="CORRECT"{c++; if($3=="verify-match")cm++; ct+=$4}
$1=="WRONG" {w++; if($3=="verify-match")wm++; wt+=$4}
END{printf " correct finger: %d/%d matched (false negatives %d) mean %d ms\n", cm,c,c-cm,(c?ct/c:0);
if (w) printf " wrong finger: %d/%d matched (false ACCEPTS %d) mean %d ms\n", wm,w,wm,wt/w;
else printf " wrong finger: not run this trial\n"}' "$OUT"
echo " per-tap log: $OUT"