mirror of
https://github.com/luxfi/crypto.git
synced 2026-10-30 16:59:13 +00:00
Replaces the stub backend (ErrBackendNotWired) with a working byte-
for-byte NIST-compatible HQC implementation. Build tag hqc_pqclean
activates the cgo path; default builds remain stub for portability.
Vendored:
- PQClean HQC-128/192/256 clean reference C (2023-04-30 NIST
submission), public domain
- PQClean shared fips202 (SHA-3 / SHAKE)
- Per-mode/per-source shim TUs (36 total) to keep PQClean's
static helpers isolated and avoid duplicate-symbol collisions
- randombytes_shim.c wiring PQClean's randombytes() to a Go-side
io.Reader callback, mutex-protected for concurrent dispatch
Tests:
- TestKAT_HQC128/192/256 — all three NIST KAT vectors verified
byte-for-byte against META.yml nistkat-sha256
- TestRoundTrip_AllModes — keygen → encap → decap roundtrip,
shared secrets byte-equal in all 3 modes
- TestDeterminism_AllModes — same seed produces identical ct/ss
(load-bearing for the precompile's on-chain determinism)
- -race clean
Correction: ciphertext sizes updated from 4481/9026/14469 (older
HQC round-3 listing) to PQClean's 4433/8978/14421 (2023-04-30 NIST
submission); the prior numbers would have failed round-trip with
a 48-byte mismatch.
39 lines
1.2 KiB
Go
39 lines
1.2 KiB
Go
// Copyright (C) 2026, Lux Industries Inc. All rights reserved.
|
|
// See the file LICENSE for licensing terms.
|
|
|
|
//go:build !hqc_circl && !hqc_pqclean
|
|
|
|
package hqc
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"errors"
|
|
"testing"
|
|
)
|
|
|
|
// TestBackend_StubReturnsErrBackendNotWired confirms the default
|
|
// (no-backend-tag) build cleanly surfaces ErrBackendNotWired rather
|
|
// than silently returning garbage or nil-derefing.
|
|
//
|
|
// Lives in a build-tag-gated test file so it does NOT run when a
|
|
// real backend (hqc_pqclean / hqc_circl) is wired in.
|
|
func TestBackend_StubReturnsErrBackendNotWired(t *testing.T) {
|
|
_, err := KeyGen(HQC128, rand.Reader)
|
|
if !errors.Is(err, ErrBackendNotWired) {
|
|
t.Fatalf("KeyGen with no backend: want ErrBackendNotWired, got %v", err)
|
|
}
|
|
|
|
_, _, err = Encapsulate(&PublicKey{Mode: HQC128, Bytes: make([]byte, 2249)}, rand.Reader)
|
|
if !errors.Is(err, ErrBackendNotWired) {
|
|
t.Fatalf("Encapsulate with no backend: want ErrBackendNotWired, got %v", err)
|
|
}
|
|
|
|
_, err = Decapsulate(
|
|
&PrivateKey{Mode: HQC128, Bytes: make([]byte, 2305)},
|
|
&Ciphertext{Mode: HQC128, Bytes: make([]byte, 4433)},
|
|
)
|
|
if !errors.Is(err, ErrBackendNotWired) {
|
|
t.Fatalf("Decapsulate with no backend: want ErrBackendNotWired, got %v", err)
|
|
}
|
|
}
|