AtlatestRepositorysigil-crypto
sigil-crypto / tree / test / vectorsgen-ed25519-vectors.sh
1
#!/bin/sh2
# Generate test/test-ed25519-vectors.sgl from test/vectors/ed25519-cases.txt.3
#4
# ed25519-cases.txt lines: "<label> <pk-hex> <sig-hex> <msg-hex|-> <expected>"5
# rfc8032-* RFC 8032 section 7.1 (Ed25519), expected valid6
# wycheproof-* C2SP/wycheproof testvectors_v1/ed25519_test.json7
# (commit 5722833ca004983abd1a91bcb6c24596d50ac0f9)8
# crafted-* crafted by the adversarial review: crafted-mixed-order-r is an9
# honest key (seed 00..1f) and R = rB + T8 (T8 of order 8), which10
# passes the cofactored equation and fails libsodium's cofactorless11
# one: the second shape of the documented divergence.12
# speccheck-* novifinancial/ed25519-speccheck cases.json13
# (commit 5e4bfc4542293286e9ad3cb2b805badee00503de), whose14
# expected column is "?": filled in below.15
#16
# speccheck expectations are libsodium's (what the minisign tool uses):17
# reject 0-2 (small-order A or R), accept 3, reject 6-7 (S >= L) and 8-1118
# (non-canonical R or A). Cases 4 and 5 are the documented divergence:19
# they need a public key with a small-order component and pass the20
# cofactored equation (RFC 8032 section 5.1.7), which sigil-crypto checks,21
# but fail libsodium's cofactorless one. Measured by test/differential/run.sh.22
set -eu23
DIR=$(cd "$(dirname "$0")" && pwd)24
OUT="$DIR/../test-ed25519-vectors.sgl"25
awk '26
BEGIN {27
spec["0"]="invalid"; spec["1"]="invalid"; spec["2"]="invalid"; spec["3"]="valid";28
spec["4"]="valid"; spec["5"]="valid"; spec["6"]="invalid"; spec["7"]="invalid";29
spec["8"]="invalid"; spec["9"]="invalid"; spec["10"]="invalid"; spec["11"]="invalid";30
print ";;; GENERATED by test/vectors/gen-ed25519-vectors.sh from"31
print ";;; test/vectors/ed25519-cases.txt. Do not edit by hand."32
print ";;;"33
print ";;; Every case runs through ed25519-verify. A valid case must return #t;"34
print ";;; an invalid one must return #f, or raise when the key or signature has the"35
print ";;; wrong length (the API raises on wrong lengths; nothing else may raise)."36
print ""37
print "(import (sigil test) (sigil crypto) (sigil math))"38
print ""39
print "(define (hex->bv s)"40
print " (if (string=? s \"-\")"41
print " (make-bytevector 0 0)"42
print " (let* ((n (quotient (string-length s) 2))"43
print " (bv (make-bytevector n 0)))"44
print " (let loop ((i 0))"45
print " (if (< i n)"46
print " (begin"47
print " (bytevector-u8-set! bv i (string->number (substring s (* 2 i) (+ 2 (* 2 i))) 16))"48
print " (loop (+ i 1)))"49
print " bv)))))"50
print ""51
print ";; #t, #f, or the symbol raised when the call raises."52
print ";; Hex is decoded outside the guard: only ed25519-verify may raise."53
print "(define (verdict pk sig msg)"54
print " (let ((pk (hex->bv pk)) (sig (hex->bv sig)) (msg (hex->bv msg)))"55
print " (guard (e (#t (quote raised)))"56
print " (ed25519-verify pk msg sig))))"57
print ""58
print "(test-group \"ed25519 vectors\""59
}60
NF != 5 { printf "REFUSING: line %d has %d fields, not 5: %s\n", NR, NF, $1 > "/dev/stderr"; bad = 1; exit 1 }61
{62
label=$1; pk=$2; sig=$3; msg=$4; want_result=$563
if (label ~ /^speccheck-/) { k=label; sub(/^speccheck-/, "", k); want_result=spec[k] }64
if (want_result == "valid") want="(assert-eq #t (verdict \"" pk "\" \"" sig "\" \"" msg "\"))"65
else if (length(pk) == 64 && length(sig) == 128) want="(assert-eq #f (verdict \"" pk "\" \"" sig "\" \"" msg "\"))"66
else want="(assert-eq (quote raised) (verdict \"" pk "\" \"" sig "\" \"" msg "\"))"67
printf " (test \"%s %s\"\n %s)\n", label, want_result, want68
n++69
}70
END { if (bad) exit 1; print " )"; print ""; printf ";;; %d cases\n", n }71
' "$DIR/ed25519-cases.txt" > "$OUT.tmp"72
mv "$OUT.tmp" "$OUT"73
echo "wrote $OUT"