Docs for the Rust version; benchmarks; build.sh fixes

README, CLAUDE.md, man pages, the user guide and its screenshot script
now describe the Rust build and the intentional behaviour changes, which
docs/MIGRATION.md lists. Go and Rust micro-benchmarks for the same
operations, and scripts/bench.sh for end-to-end comparison. build.sh
exports its tree root to the per-target jobs and keeps logs out of the
output directory; riscv64 musl builds use getrandom's raw syscall
backend, since zig's musl getrandom never reaches the kernel there.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Andy Dixon
2026-10-08 11:50:55 +01:00
co-authored by Claude
parent cddde5ca52
commit 53968f8822
18 changed files with 659 additions and 109 deletions
@@ -0,0 +1,57 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Test-only benchmarks for comparing with the Rust port (scripts/bench.sh).
package pqcrypt
import (
"bytes"
"io"
"testing"
)
func BenchmarkOracleDerive(b *testing.B) {
seed := pattern(32, 1)
for b.Loop() {
id, _ := NewPQIdentityFromSeed(0x0001, seed)
id.Close()
}
}
func BenchmarkOracleWrap(b *testing.B) {
id, _ := NewPQIdentityFromSeed(0x0001, pattern(32, 1))
r := id.Recipient()
fk := pattern(32, 2)
for b.Loop() {
r.Wrap(fk)
}
}
func BenchmarkOracleUnwrap(b *testing.B) {
id, _ := NewPQIdentityFromSeed(0x0001, pattern(32, 1))
st, _ := id.Recipient().Wrap(pattern(32, 2))
for b.Loop() {
if _, err := id.Unwrap(st); err != nil {
b.Fatal(err)
}
}
}
// Whole-file encryption and decryption of 4 MiB: one vault object.
func BenchmarkOracleObject4MiB(b *testing.B) {
id, _ := NewPQIdentityFromSeed(0x0001, pattern(32, 1))
pt := pattern(4<<20, 3)
var ct bytes.Buffer
b.SetBytes(int64(len(pt)))
for b.Loop() {
ct.Reset()
w, _ := Encrypt(&ct, id.Recipient())
w.Write(pt)
w.Close()
r, err := Decrypt(bytes.NewReader(ct.Bytes()), id)
if err != nil {
b.Fatal(err)
}
io.Copy(io.Discard, r)
}
}
@@ -0,0 +1,27 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Test-only benchmarks for comparing with the Rust port (scripts/bench.sh).
package stream
import (
"bytes"
"io"
"testing"
)
// STREAM seal and open of 64 MiB, one goroutine (the sequential path).
func BenchmarkOracleStream64MiB(b *testing.B) {
key := make([]byte, 32)
pt := make([]byte, 64<<20)
var ct bytes.Buffer
b.SetBytes(int64(len(pt)))
for b.Loop() {
ct.Reset()
w, _ := NewEncryptWriter(key, &ct)
w.Write(pt)
w.Close()
r, _ := NewDecryptReader(key, bytes.NewReader(ct.Bytes()))
io.Copy(io.Discard, r)
}
}