{"id":51254470,"url":"https://github.com/shurlinet/go-hqc","last_synced_at":"2026-06-29T09:01:49.135Z","repository":{"id":358552146,"uuid":"1241635324","full_name":"shurlinet/go-hqc","owner":"shurlinet","description":"Pure Go implementation of HQC (Hamming Quasi-Cyclic) post-quantum KEM. NIST backup to ML-KEM. Zero dependencies.","archived":false,"fork":false,"pushed_at":"2026-05-17T23:05:03.000Z","size":676,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-05-18T00:22:13.183Z","etag":null,"topics":["code-based","cryptography","fips-207","golang","hqc","kem","key-encapsulation","lattice-alternative","nist","post-quantum","pqc","pqclean","pure-go","quantum-resistant","zero-dependencies"],"latest_commit_sha":null,"homepage":"https://pkg.go.dev/github.com/shurlinet/go-hqc","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/shurlinet.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-17T16:24:18.000Z","updated_at":"2026-05-17T23:05:06.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/shurlinet/go-hqc","commit_stats":null,"previous_names":["shurlinet/go-hqc"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/shurlinet/go-hqc","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shurlinet%2Fgo-hqc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shurlinet%2Fgo-hqc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shurlinet%2Fgo-hqc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shurlinet%2Fgo-hqc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/shurlinet","download_url":"https://codeload.github.com/shurlinet/go-hqc/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shurlinet%2Fgo-hqc/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34919884,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-29T02:00:05.398Z","response_time":58,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["code-based","cryptography","fips-207","golang","hqc","kem","key-encapsulation","lattice-alternative","nist","post-quantum","pqc","pqclean","pure-go","quantum-resistant","zero-dependencies"],"created_at":"2026-06-29T09:01:44.275Z","updated_at":"2026-06-29T09:01:49.121Z","avatar_url":"https://github.com/shurlinet.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# go-hqc\n\n[![Go Tests](https://github.com/shurlinet/go-hqc/actions/workflows/ci.yml/badge.svg)](https://github.com/shurlinet/go-hqc/actions/workflows/ci.yml)\n[![Go Reference](https://pkg.go.dev/badge/github.com/shurlinet/go-hqc.svg)](https://pkg.go.dev/github.com/shurlinet/go-hqc)\n[![Go Report Card](https://goreportcard.com/badge/github.com/shurlinet/go-hqc)](https://goreportcard.com/report/github.com/shurlinet/go-hqc)\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)\n\nPure Go implementation of **HQC** (Hamming Quasi-Cyclic), a code-based\nKey Encapsulation Mechanism selected by NIST for standardization as a backup\nto ML-KEM (lattice-based). Different cryptographic foundation: if lattice\nassumptions break, HQC remains secure.\n\nNIST [selected HQC](https://csrc.nist.gov/projects/post-quantum-cryptography)\nfor standardization (March 2025) as\n[FIPS 207](https://csrc.nist.gov/presentations/2025/fips-207-hqc-kem).\nThe formal standard is expected but not yet finalized. The standard adjusts parameter sizes\n(seed 40-\u003e32, shared secret 64-\u003e32) from the submission. The core cryptographic\nconstruction (code-based KEM with Fujisaki-Okamoto transform, Reed-Solomon/\nReed-Muller error correction) is mature (published 2017, 7+ years of\ncryptanalysis). go-hqc tracks the official HQC v5.0.0 reference and will be\nupdated when FIPS 207 is published.\n\n\u003e **Warning**\n\u003e\n\u003e * This library has not received any formal audit\n\u003e * While we use Go's standard library cryptographic primitives (`crypto/sha3`, `crypto/subtle`), it is up to **you** to evaluate whether they meet your security and integrity requirements\n\u003e * **Pre-FIPS:** implements HQC v5.0.0 specification. API may change with FIPS 207. v0.x API is explicitly unstable\n\n## Install\n\n```\ngo get github.com/shurlinet/go-hqc\n```\n\nRequires Go 1.26+ (for `crypto/sha3`).\n\n## Usage\n\n```go\npackage main\n\nimport (\n    \"bytes\"\n    \"fmt\"\n    \"log\"\n\n    \"github.com/shurlinet/go-hqc\"\n)\n\nfunc main() {\n    // Generate a keypair.\n    dk, err := hqc.GenerateKey128()\n    if err != nil {\n        log.Fatal(err)\n    }\n    defer dk.Destroy()\n\n    // Encapsulate: peer gets the public key and produces shared secret + ciphertext.\n    sharedSecret, ciphertext := dk.EncapsulationKey().Encapsulate()\n\n    // Decapsulate: owner recovers the shared secret from ciphertext.\n    recovered, err := dk.Decapsulate(ciphertext)\n    if err != nil {\n        log.Fatal(err)\n    }\n\n    fmt.Printf(\"match: %v, length: %d bytes\\n\",\n        bytes.Equal(sharedSecret, recovered), len(sharedSecret))\n}\n```\n\n## Features\n\n- Pure Go, zero external dependencies (uses `crypto/sha3` from stdlib)\n- Three parameter sets: HQC-128 (Level 1), HQC-192 (Level 3), HQC-256 (Level 5)\n- API follows Go `crypto/mlkem` pattern (typed per-param-set keys)\n- Constant-time FO transform using `crypto/subtle`\n- Secret key zeroing via `Destroy()` (all persistent secret material)\n- Deterministic key generation from seed (`NewDecapsulationKey128(seed)`)\n- Deterministic encapsulation for testing (`EncapsulateWithEntropy` / `hqctest` sub-package, mirrors `crypto/mlkem/mlkemtest`)\n- Key consistency validation on parse (`ParseDecapsulationKey128`)\n- Concurrent-safe: `Decapsulate` is safe for concurrent use\n- Specification version check via `Version()`\n\n## Size Constants\n\n| Parameter Set | Public Key | Secret Key | Ciphertext | Shared Secret | Seed |\n|--------------|-----------|-----------|------------|--------------|------|\n| HQC-128 | 2,241 | 2,321 | 4,433 | 32 | 32 |\n| HQC-192 | 4,514 | 4,602 | 8,978 | 32 | 32 |\n| HQC-256 | 7,237 | 7,333 | 14,421 | 32 | 32 |\n\nAll sizes in bytes.\n\n## Security\n\n- **Implicit rejection**: invalid ciphertexts produce a random-looking shared\n  secret derived from sigma (never an error that reveals decryption success/failure)\n- **Constant-time FO comparison**: uses `crypto/subtle.ConstantTimeSelect`\n- **Key zeroing**: `Destroy()` zeroes seedDK, sigma, seedKem, x, y, sk via\n  `//go:noinline` zero functions\n- **Parse validation**: `ParseDecapsulationKey` verifies the embedded public key\n  matches seed_dk (catches corruption)\n- **WASM caveat**: constant-time guarantees hold for native targets (amd64,\n  arm64). WASM compilation does not provide timing guarantees.\n- **No fault injection countermeasures**: this implementation does not defend\n  against voltage glitch or rowhammer attacks. See the package documentation\n  for details.\n\n## Consumer Responsibilities\n\n* **Call `Destroy()` on decapsulation keys** when they are no longer needed. `Destroy()` zeroes secret material. The Go garbage collector does not guarantee timely zeroing of freed memory. Dropping the key reference without calling `Destroy()` leaves secrets in memory until GC collects them.\n* **Do not reuse ciphertexts.** Each `Encapsulate()` call produces a fresh shared secret and ciphertext. Replaying a ciphertext to a different decapsulation key is not meaningful.\n* **Validate ciphertext source.** The KEM provides implicit rejection (invalid ciphertexts produce random shared secrets), but it does not authenticate the sender. Use the shared secret to key an authenticated channel.\n* **Check `Version()` programmatically** if your application needs to track which HQC specification is in use. The version string will change when FIPS 207 is implemented.\n\n## Testing\n\n```sh\nmake test              # KAT + property + AI threat + accumulated-100 (~30s total)\nmake bench             # benchmarks for all 3 param sets (~15s)\nmake fuzz              # 30s fuzz per target, 2 targets (~1 min total)\nmake fuzz-long         # 5 min fuzz per target, 2 targets (~10 min total)\nmake lint              # go vet + staticcheck (~5s)\n```\n\n### Accumulated verification tiers\n\nVerifies N complete KEM cycles (keygen + encaps + decaps) against SHAKE128\naccumulated hashes generated by v5.0.0 C. One hash proves N cycles byte-correct.\n\n```sh\nmake accumulated-100   # 100 iterations   (~10s total, runs in make test)\nmake accumulated-1k    # 1,000 iterations (~2 min total)\nmake accumulated-10k   # 10,000 iterations (~17 min total)\nmake accumulated-100k  # 100,000 iterations (~2.5 hours total, pre-release)\nmake accumulated-1m    # 1,000,000 iterations (~28 hours total, auditor)\n```\n\nTimings on M3 Max. HQC-256 is ~6x slower than HQC-128 (larger polynomials).\nAll 3 param sets run sequentially.\n\nOr directly: `GOHQC_ACCUMULATED=10000 go test -run=TestAccumulated -v ./...`\n\n### Test inventory\n\n| Category | Count | Description |\n|----------|-------|-------------|\n| KAT keygen | 30 | v5.0.0 vectors, byte-for-byte (10 per param set) |\n| KAT encaps | 30 | v5.0.0 vectors with decaps verification (10 per param set) |\n| Round-trip | 3 | Encaps/Decaps agreement per param set |\n| Key serialization | 1 | Bytes/Parse/Seed round-trip (HQC-128) |\n| Edge cases | 4 | Zero ct, modified salt, wrong lengths |\n| Concurrency | 1 | 8-goroutine parallel Decapsulate |\n| Destroy lifecycle | 1 | Post-Destroy errors, double Destroy safety |\n| Slice isolation | 1 | Returned slices independent of internal state |\n| Constant-time | 1 | Valid vs invalid ct path equivalence |\n| Size constants | 1 | Computed from params, anti-tamper |\n| Property: round-trip | 3 | 5 iterations per param set |\n| Property: key serial | 3 | DK + EK round-trip per param set |\n| Property: seed | 3 | Seed round-trip per param set |\n| AI threat defense | 4 | Domain bytes (G/H/I/J/XOF/PRNG), hashG + hashH independent, nMu/rejThreshold formula |\n| Version | 1 | Version() returns expected spec string |\n| Keygen verification | 1 | Re-derive y,x from seed_dk, verify s = x + y*h |\n| Accumulated | 3 | SHAKE128 accumulated hashes vs v5.0.0 C (100-1M tiers) |\n| Benchmarks | 9 | Keygen/Encaps/Decaps per param set |\n| Fuzz | 2 | FuzzDecapsulate128, FuzzKeyRoundTrip128 |\n| Godoc examples | 3 | Basic, serialization, all param sets |\n| hqctest deterministic | 6 | Deterministic encaps reproducibility + size check (all 3 param sets) |\n| **Component tests** | 50 | GF, seedexpander, gf2x, vector, RM, RS, FFT, code |\n\n## Verification\n\ngo-hqc is verified by:\n\n* [KAT vectors](testdata/) - 60 Known Answer Tests (30 keygen + 30 encaps/decaps) across all 3 parameter sets, byte-for-byte match against the official HQC v5.0.0 C reference. Generated using HQC's custom SHAKE256 DRBG ([tools/gen-vectors/](tools/gen-vectors/)).\n* [Accumulated hash anchors](testdata/accumulated.json) - SHA256 hashes over 1M keygen/encaps iterations per parameter set. Go tests verify up to 100K; 1M hashes are reference data for external verifiers.\n* [Property tests](hqc_property_test.go) - 15 round-trip iterations (5 per param set), 3 key serialization round-trips (Bytes/Parse + Seed/New + EK), 3 seed determinism proofs\n* [Fuzz tests](hqc_fuzz_test.go) - 2 targets: `FuzzDecapsulate128` (random ciphertexts, no panics, always 32-byte implicit rejection) and `FuzzKeyRoundTrip128` (random seeds, generate/serialize/parse/decaps agreement with 5 VP1 length assertions)\n* [AI threat defense](hqc_property_test.go) - 4 independent verifications: domain separation bytes (G/H/I/J/XOF/PRNG uniqueness + pinned values), hashG via independent SHA3-512, hashH via independent SHA3-256, nMu/rejectionThreshold formula recomputation for all 3 param sets\n* [Component tests](gf_test.go) - 50 tests across 8 subsystems: GF(2^m) exhaustive 65,536-multiply oracle, seedexpander direct squeeze + pinned regression, karatsuba polynomial multiply, Reed-Muller RM(1,7) all-256-byte round-trip, Reed-Solomon LFSR encode + Berlekamp decode with varying error counts, Gao-Mateer additive FFT root finding, concatenated code round-trip, sampler1/sampler2 weight + determinism + consecutive calls\n* 9 [benchmarks](hqc_property_test.go) - Keygen/Encapsulate/Decapsulate for all 3 parameter sets\n\n```\nmake test\n```\n\nOr equivalently: `go test -race -count=1 ./...`\n\n## Examples\n\n| Example | Description |\n|---------|-------------|\n| [`examples/basic/`](examples/basic/) | HQC-128 key exchange (generate, encapsulate, decapsulate) |\n| [`examples/serialization/`](examples/serialization/) | Key persistence (Bytes/Parse, Seed/New, EK round-trip) |\n\n## Dependencies\n\nNone. go-hqc uses only the Go standard library (`crypto/sha3`, `crypto/subtle`,\n`crypto/rand`). Zero external module dependencies.\n\n| Dependency | Purpose |\n|-----------|---------|\n| Go 1.26+ | Required for `crypto/sha3` |\n\n## Upstream Tracking\n\nSource: official HQC v5.0.0 (https://gitlab.com/pqc-hqc/hqc/). See [UPSTREAM.md](UPSTREAM.md) for full\ntracking details and FIPS 207 status.\n\n## AI Transparency\n\nThis library was developed with AI assistance ([Claude](https://claude.ai)).\nAll cryptographic decisions were verified against the official v5.0.0 C reference.\nKAT vectors are generated from v5.0.0 harnesses and verified byte-for-byte.\nThe test suite includes AI threat defense tests designed to catch both human and\nAI-introduced errors. The AI generated code; the human made every design\ndecision, reviewed every line, and owns every bug.\n\n## Acknowledgments\n\n- The HQC authors and former PQClean contributors for the clean\n  portable C reference implementations (public domain)\n- Carlos Aguilar Melchor, Nicolas Aragon, Slim Bettaieb, Loic Bidoux, Olivier\n  Blazy, Jurjen Bos, Jean-Christophe Deneuville, Philippe Gaborit, Edoardo\n  Persichetti, Jean-Marc Robert, Pascal Veron, Gilles Zemor, and the HQC\n  design team for creating the algorithm\n\n## Future: Go Standard Library\n\nWhen FIPS 207 is finalized, Go will likely add `crypto/hqc` to the standard\nlibrary (as it did with `crypto/mlkem` for ML-KEM). When that happens:\n\n- `crypto/hqc` becomes the official Go implementation\n- go-hqc continues to work as a separate module (no breakage)\n- Migration is an import path change (API follows the same `crypto/mlkem` pattern)\n- go-hqc may still be useful for pre-FIPS deployment or environments pinned to\n  older Go versions\n\nThis is the same lifecycle as [`filippo.io/mldsa`](https://pkg.go.dev/filippo.io/mldsa)\n(pre-stdlib ML-DSA used by [go-clatter](https://github.com/shurlinet/go-clatter)),\nwhich will migrate to `crypto/mldsa` when Go ships it.\n\n## References\n\n- [HQC specification](https://pqc-hqc.org) - official HQC website with the algorithm specification, design rationale, and parameter selection\n- [NIST Post-Quantum Cryptography](https://csrc.nist.gov/projects/post-quantum-cryptography) - NIST PQC standardization project (HQC selected as backup KEM alongside ML-KEM)\n- [FIPS 207](https://csrc.nist.gov/presentations/2025/fips-207-hqc-kem) - HQC standardization (not yet finalized, expected late 2026 / early 2027)\n- [HQC official](https://gitlab.com/pqc-hqc/hqc/) - official reference implementation (v5.0.0)\n- [PQNoise paper](https://doi.org/10.1145/3548606.3560577) - PQNoise extensions (ACM CCS 2022) that use KEMs like HQC in Noise handshakes (implemented by [go-clatter](https://github.com/shurlinet/go-clatter))\n\n## License\n\nMIT. See [LICENSE](LICENSE).\n\nHQC reference code is public domain (CC0). See\n[THIRD_PARTY_LICENSES](THIRD_PARTY_LICENSES).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshurlinet%2Fgo-hqc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fshurlinet%2Fgo-hqc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshurlinet%2Fgo-hqc/lists"}