liboqs 2.0.0
liboqs: ^2.0.0 copied to clipboard
Dart FFI bindings for liboqs — high-performance post-quantum cryptography (PQC) with ML-KEM, ML-DSA, Falcon, SLH-DSA for key encapsulation and signatures.
2.0.0 - 2026-07-20 #
For Users #
✨ Highlights
- Bundled liboqs upgraded 0.15.0 → 0.16.0 (breaking) — includes upstream security fixes (see Security) plus the algorithm removals and renames below.
- Dart API unchanged —
KEM,Signature, andOQSRandomare source-compatible; every breaking change is in algorithm availability or the bundled native library, not the class API. - SPHINCS+ removed (breaking) —
Signature.create('SPHINCS+-…')now throwsLibOQSException; migrate to SLH-DSA (FIPS 205) or ML-DSA (FIPS 204). - HQC renamed and enabled by default (breaking) —
HQC-128/HQC-192/HQC-256→HQC-1/HQC-3/HQC-5, updated to the 2025-08-22 spec. - FrodoKEM is now the salted variant (silent breaking) — keys/ciphertexts are
not interoperable with 0.15.0; the old ephemeral behavior moved to the new
eFrodoKEM-*identifiers. - Now usable from standalone Dart — the package dropped its Flutter SDK
constraint (pure
dart:ffi), so it works outside Flutter and shows both the Dart and Flutter badges on pub.dev.
Changed (Breaking)
- Upgraded bundled liboqs native library from 0.15.0 to 0.16.0.
FrodoKEM-640-AES,FrodoKEM-640-SHAKE,FrodoKEM-976-AES,FrodoKEM-976-SHAKE,FrodoKEM-1344-AES, andFrodoKEM-1344-SHAKEnow select the salted FrodoKEM variant instead of the ephemeral variant used in 0.15.0. The identifiers are unchanged but keys and ciphertexts are not interoperable with 0.15.0. The previous ephemeral behavior is now available under the neweFrodoKEM-*identifiers (see Added). PrefereFrodoKEM-*when each keypair encapsulates only a few shared secrets, andFrodoKEM-*(salted) for high-volume encapsulation.- HQC identifiers were renamed
HQC-128/HQC-192/HQC-256→HQC-1/HQC-3/HQC-5. HQC is now enabled by default and updated to the 2025-08-22 specification.KEM.create('HQC-128')now throwsLibOQSException.
Changed
ML-DSA-44/ML-DSA-65/ML-DSA-87are now backed by the portablemldsa-nativeimplementation (with x86_64/aarch64 optimizations); identifiers and behavior are unchanged.sntrup761(NTRU Prime) now uses the public-domain OpenSSH implementation.- Dropped the
flutter: ">=3.38.0"SDK constraint. The package contains no Flutter imports (puredart:ffi), so it is now usable from standalone Dart as well as Flutter, and pub.dev reports both the Dart and Flutter SDK badges (previously Flutter only). Verified withpana. SECURITY.mdsubstantially expanded: secret lifetime and memory model (what the native/Dart layers guarantee and what garbage-collected memory cannot), timing-attack prevention, key-material handling, randomness, supply-chain integrity of the prebuilt native libraries (including the honest limits of same-release SHA256 verification), and a contributor security checklist.
Added
- Ephemeral FrodoKEM identifiers:
eFrodoKEM-640-AES,eFrodoKEM-640-SHAKE,eFrodoKEM-976-AES,eFrodoKEM-976-SHAKE,eFrodoKEM-1344-AES, andeFrodoKEM-1344-SHAKE. - HQC (
HQC-1,HQC-3,HQC-5) is now enabled by default. - MQOM signature scheme family (12
mqom2_cat{1,3,5}_gf16_{fast,short}_r{3,5}parameter sets) — a candidate in NIST's Additional Digital Signatures process, new upstream in liboqs 0.16.0 and enabled by default. - Upstream runtime-detection API for stateful signature support (
OQS_SIG_STFL_*).
Removed (Breaking)
- SPHINCS+ signature algorithms — all 12
*-simplevariants of both theSPHINCS+-SHA2-*andSPHINCS+-SHAKE-*families — were removed upstream in liboqs 0.16.0.Signature.create('SPHINCS+-…')now throwsLibOQSException. Migrate to SLH-DSA (FIPS 205,SLH_DSA_PURE_*) or ML-DSA (FIPS 204). - Legacy HQC identifiers
HQC-128/HQC-192/HQC-256(renamed; see Changed (Breaking)).
Fixed
- Build hook: the download cache key now includes the full version
(
native_version+native_build) and the full platform variant. Previously it keyed only onos-arch, which (1) let iOS device and simulator builds shareios-arm64on Apple-silicon hosts and poison each other's cache (dyld "incompatible platform" at runtime), and (2) omitted the version, so after a version bump a stale binary from the previous release could be reused instead of downloading the new one. - Build hook: download/cache resilience against partial and transient failures.
A cache entry is now reused only after a
.download-completemarker proves the extraction finished, so an interruptedtarno longer leaves a truncated library that is registered and reused forever; and both the checksums fetch and the binary download now retry on transient HTTP 5xx/429 instead of failing the build on a single network blip.
Security
- Build hook: SHA256 verification of downloaded native libraries is now
fail-closed. Previously a missing or unreachable checksums file (e.g. a
MITM blocking the checksums URL) was downgraded to a warning and the
unverified binary was installed anyway. The build now aborts unless the new
LIBOQS_ALLOW_UNVERIFIED_DOWNLOAD=1escape hatch is explicitly set.
Includes the following upstream liboqs 0.16.0 security fixes:
- Fixed uninitialized
encaps_derandpointer dereference (open-quantum-safe/liboqs#2460). - Fixed out-of-bounds read in XMSS/XMSS^MT signature verification (open-quantum-safe/liboqs#2384).
- Fixed integer underflow in CROSS
crypto_sign_open(). - Fixed incorrect array size when calling
secure_clean. - Added the
OQS_MEM_BLACK_BOXoptimization barrier hardening FrodoKEMct_selectconstant-time protection (open-quantum-safe/liboqs#2431).
See the full liboqs 0.16.0 release notes.
For Contributors #
Added
make check-targets— guard that keeps the iOS/macOS deployment targets in the native build scripts internally consistent (scripts/check_deployment_targets.dart); now also enforced in CI (see Changed).make release— one-command scripted release (scripts/release.dart): checks you are on a clean, up-to-datemain, verifies the nativeliboqs-<fullVersion>GitHub Release exists (fail-closed — the published build hook downloads it), bumpspubspec.yaml, finalizes the CHANGELOG[Unreleased]section including the bottom compare links, validates with a publish dry-run, then creates a signed commit + signedvX.Y.Ztag and pushes to trigger the pub.dev publish. Comes with arelease-packageskill guide and unit tests for the CHANGELOG finalization.make update-changelog— AI-drafted CHANGELOG entry for liboqs version bumps (scripts/update_changelog.dart, GitHub Models): classifies upstream changes by user visibility (algorithm additions/removals/renames and wire-format changes are breaking and user-visible; CI/docs/build-system churn is not). The liboqs update checker now includes such a draft[Unreleased]entry in its automated PRs (requires theAI_MODELS_TOKENrepository secret; non-fatal when absent).make release-native— deliberate, scripted release of the native libraries (scripts/release_native.dart): verifies a cleanmainexactly in sync withorigin/mainand thatliboqs-<fullVersion>(tag and release) doesn't exist yet, then creates a signedliboqs-<fullVersion>tag and pushes it, which triggers the native build.make setup-repo-protections— applies the committed repository rulesets (.github/rulesets/*.json: protected release tags, protectedmain, signed commits, no branch deletion) and configures thenative-buildenvironment with a required reviewer viagh(scripts/setup_repo_protections.dart; runbook in.github/rulesets/README.md).- Build provenance attestation for the native release archives:
build-liboqs.ymlattests every archive with GitHub Artifact Attestations (Sigstore, SLSA Build L2) and attaches the Sigstore bundle (liboqs-<fullVersion>.sigstore.jsonl) to the release, so any downloaded binary can be verified — online or fully offline — withgh attestation verify(see SECURITY.md → Authenticity). This breaks the self-trust of the same-release SHA256 checksums file. - Dependabot for GitHub Actions (
.github/dependabot.yml): weekly grouped update PRs (Monday 06:00 UTC,chore(deps)prefix) bump the pinned actions — commit SHA and its version comment — across the workflows and the composite actions, so the SHA pins from the supply-chain audit don't go stale.
Changed
- Regenerated FFI bindings for liboqs 0.16.0.
- CI hardening & reliability (Phase 4). Workflows now run with a
least-privilege
GITHUB_TOKEN(workflow-levelcontents: read; only the release-publishing jobs opt up to the specific writes they need). The native-library build workflow serializes concurrent runs for the same ref via aconcurrencygroup. Windows runners install GNU Make from a pinned GitHub release (with retry + size check) via asetup-makecomposite action instead of Chocolatey. The deployment-target guard (make check-targets) runs in the CI quality checks alongsideanalyze/format-check. The publish workflow gained a dedicated package-validation (publish-dry-run) job that gates publishing. The liboqs update checker skips when an open update PR for the same version already exists, so scheduled runs no longer force-push over manual commits on that PR. - CI supply-chain hardening (pre-release audit). The upstream version tag
from the liboqs update check is format-validated before it reaches
GITHUB_OUTPUT, and workflowrun:blocks read it (and the other step outputs) viaenv:instead of inline${{ }}interpolation — closing a shell-injection path from upstream release names. Third-party GitHub Actions are pinned to commit SHAs, and the Windows GNU Make helper binary is verified against a hardcoded SHA256 before use. - Tag-triggered native builds.
build-liboqs.ymlnow triggers on aliboqs-<fullVersion>tag push (created bymake release-native) instead of everypubspec.yamlpush tomain: merging a version bump no longer builds or publishes anything by itself, the tag is validated againstpubspec.yamlat the tagged commit, the GitHub Release is created on that same tag (the delete-then-recreate step is gone), and the release-publishing job is gated by thenative-buildenvironment (mirrors the pub.dev publish gate; inert until reviewers are configured). - Release notes hardened against changelog injection.
publish.ymlnow passes the version and changelog throughenv:and writes the release notes withprintfto a--notes-file, so a literalEOFline in the changelog can no longer terminate the inline heredoc early and execute the remaining text as shell under thecontents: writetoken. - Release-exists CI probe fails closed.
check_release.dartnow distinguishes exists / missing / inconclusive and aborts (exit 1) on an API error or network failure instead of reporting the release as absent and letting a build proceed on a wrong assumption. - Release-script robustness.
runInheritfails loud on any non-zero exit (previously swallowed when no failure message was passed),finalizeChangelogvalidates the--date(YYYY-MM-DD) before stamping the immutable released heading, and the commit-failure message now states the version bump is left staged and how to recover.
Removed
- All platform-plugin scaffolding: the
ios/macos/liboqs.podspecfiles, theios/Classes/LiboqsPlugin.swiftstub, theandroid/Gradle project (build.gradle,settings.gradle,AndroidManifest.xml), and thelinux//windows/CMakeLists.txt(plus stale generated app registrants). This is a plain Dart FFI package, not a Flutter plugin, so none of these files were ever consumed — a consuming app'spod installinstalls onlyFlutter/FlutterMacOS, and platform support is declared purely via the top-levelplatforms:key. Verified withpana(all five platform badges unchanged) and by rebuilding/running the iOS and macOS example. Native libraries continue to ship via Build Hooks.
1.2.1 - 2026-05-14 #
Fixed #
- Android: native libraries are now built with LOAD segments aligned to 16 KB, so they load correctly on Android 15+ devices that use 16 KB memory pages (#1). The Android build script now passes
-Wl,-z,max-page-size=16384 -Wl,-z,common-page-size=16384to the linker and verifies alignment on the 64-bit ABIs viallvm-readelf/readelfafter the build.
1.2.0 - 2026-02-07 #
Changed #
- Raised minimum iOS deployment target from 12.0 to 13.0 (matches Flutter 3.38.x minimum)
- Raised minimum macOS deployment target from 10.14 to 10.15 (matches Flutter 3.32+ minimum)
1.1.3 - 2026-02-07 #
Fixed #
- macOS x86_64 build deployment target lowered from 10.15 to 10.14 (matches podspec minimum)
1.1.2 - 2026-01-10 #
Added #
- Pre-commit git hook for format check and static analysis (configured via
make setup) - Multi-platform testing workflow (
test-reusable.yml): Linux x86_64, Linux ARM64, macOS ARM64, Windows x86_64 - GitHub App token support for signed commits in CI workflows
- Skip tests for automated bot PRs (native libraries not yet built)
.claude/skills/folder now included in repository and published package
Changed #
Signature.sign()andSignature.verify()now allow empty messages (valid per FIPS 204 and liboqs)- Simplified
check-liboqs-updates.ymlworkflow: removed AI analysis, now only updatesnative_versionin pubspec.yaml - Removed
--ai,--no-ai,--bump,--no-changelogflags fromcheck_updates.dart(script now focuses on version checking only) - Replaced
softprops/action-gh-releasewith officialghCLI for release creation (build-liboqs.yml, publish.yml) - Updated GitHub Actions:
peter-evans/create-pull-requestv8,actions/create-github-app-tokenv2,ilammy/msvc-dev-cmdv1.13.0 - Improved Windows FVM setup with PUB_CACHE detection and shell wrapper for Git Bash compatibility
- Native library release description simplified: removed "Usage" section, renamed "Archive Format" to "Platforms"
Fixed #
- Fixed version parsing in
build-liboqs.ymlworkflow (use Dart script instead of grep for reliable parsing) - Added checkout step to create-release job (required for gh CLI)
- FVM config changes are now discarded after setup to prevent unwanted modifications
Removed #
scripts/src/ai_analysis.dart- AI-powered changelog generation removed.github/prompts/ai-analysis-prompt.md- AI prompt template removed
1.1.1 - 2026-01-02 #
Added #
analysis_options.yamlwith recommended lints and exclusions for auto-generated bindingsmake doccommand for local API documentation generation
Fixed #
.pubignorenow includesCONTRIBUTING.mdin published package (needed for pub.dev links).pubignorenow excludes generateddoc/directory
Changed #
- Refactored CI update workflow: moved AI analysis from bash to Dart script
- Simplified
check-liboqs-updates.ymlworkflow (~540 → ~190 lines) - Added
--ai,--no-ai,--ciflags tocheck_updates.dartscript - Script now writes directly to
GITHUB_OUTPUTin CI mode (no jq parsing needed) make checkandmake combinenow create.skip_liboqs_hookto prevent build hooks during executionmake coveragenow uses--check-ignoreflag (respectscoverage:ignoreannotations)- CI test workflow now uses
make coverageinstead of direct commands - Removed
print()calls from tests (follow Dart best practices) build-liboqs.ymlworkflow now skips build if release already exists (prevents unnecessary rebuilds when only package version changes)
1.1.0 - 2025-12-28 #
Added #
LibOQSUtils.constantTimeEquals()for timing-safe byte array comparison (prevents timing attacks)LibOQSUtils.zeroMemory()for secure memory zeroing using nativeOQS_MEM_cleanse(compiler-optimization resistant)clearSecrets()method toKEMKeyPair,KEMEncapsulationResult, andSignatureKeyPairfor explicit secret zeroing- Safe getters:
publicKeyBase64,publicKeyHex,ciphertextBase64,ciphertextHex(don't expose secrets) - Export
LibOQSUtilsfrom main library entry point - Security documentation in SECURITY.md, README.md, and CLAUDE.md
- Finalizers for automatic secret zeroing on garbage collection (
KEMKeyPair,KEMEncapsulationResult,SignatureKeyPair) - SHA256 checksum verification for native library downloads in build hooks (supply chain security)
- Comprehensive test coverage (100%):
exception_test.dart,utils_test.dart, extended KEM/Signature/Random tests - Test coverage reporting with GitHub Gist badge
make coveragecommand for local coverage testing- Centralized
get_version.dartscript for version parsing runDart/runDartOrFailhelpers incommon.dartfor consistent FVM usagecryptopackage dependency for SHA256 checksum verification
Changed #
LibOQSUtils.secureFreePointer()now uses nativeOQS_MEM_secure_freeinstead of manual zeroingLibOQSUtils.constantTimeEquals()now performs constant-time length comparison (prevents length oracle attacks)LibOQSUtils.constantTimeEquals()now usessecureFreePointer()for temporary buffersclearSecrets()and Finalizers now useOQS_MEM_cleansevia centralizedzeroMemory()function- Added documentation explaining silent failure behavior in
secureFreePointer()(by design for cryptographic libraries) - Native library version moved from
LIBOQS_VERSION/NATIVE_BUILDfiles topubspec.yaml(centralized version management) - All scripts now read version from
pubspec.yamlviaget_version.dart make regennow creates.skip_liboqs_hookmarker file to prevent Build Hooks during regenerationregenerate_bindings.dartnow uses FVM Dart when available
Fixed #
dispose()operation order in KEM and Signature classes (free → detach → flag) to prevent memory leaks on exceptions- Null pointer checks for native function pointers before calling
asFunction() OQSRandom.generateBytes()now usessecureFreePointerfor sensitive data- Added explicit
nullptrcheck inKEM.generateKeyPairDerand()forkeypair_derandfunction pointer - Added signature length validation in
Signature.verify()(empty check and max length check) OQSRandom.generateInt()now has retry limit to prevent potential infinite loops in rejection sampling- CI workflow now uses
--check-ignoreflag for coverage reporting (respectscoverage:ignoreannotations) - Regex replacement bug in
check_updates.dart(replaceFirst→replaceFirstMapped)
Security #
- Added security warnings to
toStrings()andtoHexStrings()methods that expose secret keys - Examples updated to use
constantTimeEquals()instead of loop-based comparison - Defense-in-depth: Finalizers automatically zero secrets if user forgets to call
clearSecrets() - Build hooks now verify SHA256 checksums of downloaded native libraries (prevents supply chain attacks)
Removed #
LIBOQS_VERSIONfile (version now inpubspec.yaml)NATIVE_BUILDfile (build number now inpubspec.yaml)
1.0.3 - 2025-12-18 #
Added #
- Add support "@Native" annotation instead use library loader class
- Add "NATIVE_BUILD" file to manage build number of native library
- Add settings for code formatter
1.0.2 - 2025-12-14 #
Added #
- Linux ARM64 (aarch64) platform support for native libraries
- Updated README platform support table with architecture details
Fixed #
- Library loading on Linux and Windows Flutter desktop apps (paths relative to executable)
- Library loading for CLI applications in both JIT (
dart run) and AOT (dart build cli) modes - AOT detection logic no longer incorrectly triggers on project paths containing "dart" substring
1.0.1 - 2025-12-14 #
1.0.0 - 2025-12-13 #
Added #
- Pre-built native libraries for all platforms (iOS, Android, macOS, Linux, Windows)
- Key Encapsulation Mechanisms (KEM): ML-KEM, Kyber, Classic McEliece, FrodoKEM, HQC, NTRU
- Digital Signatures: ML-DSA, SLH-DSA, Falcon, SPHINCS+, MAYO, CROSS
- Cryptographically secure random number generation (
OQSRandom) - Automatic native library bundling via FFI plugin configuration
LibOQS.init()for optional library pre-initializationLibOQS.getSupportedKEMAlgorithms()andLibOQS.getSupportedSignatureAlgorithms()for runtime algorithm discoveryLibOQS.isKEMSupported()andLibOQS.isSignatureSupported()for algorithm availability checks- Algorithm name validation in
KEM.create()andSignature.create() LibOQSUtils.secureFreePointer()for secure memory clearing (zeros memory before freeing)- Comprehensive test suite (44 tests)
- GitHub Actions CI/CD pipeline for automated testing and publishing
- Automated liboqs version tracking via
LIBOQS_VERSIONfile - Cross-platform build scripts for native library compilation
- Example Flutter application demonstrating all features
Security #
- Secret keys are automatically zeroed before memory is freed
- Based on liboqs 0.15.0 with NIST-standardized algorithms (FIPS 203, 204, 205)