Repository navigation
feat(picky-crypto): add the RustCrypto backend - #559
Open
Benoît Cortier (CBenoit) wants to merge 5 commits into
Open
Benoît Cortier (CBenoit) wants to merge 5 commits into
Benoît Cortier (CBenoit) wants to merge 5 commits into
Conversation
There was a problem hiding this comment.
🟡 Changes recommended
Contract inconsistencies, ECDSA nonce handling, PBKDF2 error mapping, and the prohibited intent-file addition remain unresolved.
5 open findings
What changed in this PR
Adds a feature-gated RustCrypto implementation of the picky-crypto provider contract and integrates it with conformance testing and CI.
Changes:
- Implements 64 cryptographic provider entries across eight feature families.
- Clarifies contract error handling and malformed RSA-key behavior.
- Adds conformance, feature-powerset, documentation, and dependency-policy checks.
| File | Description |
|---|---|
.github/workflows/ci.yml |
Adds backend conformance and CI checks. |
Cargo.lock |
Locks backend dependencies. |
Cargo.toml |
Registers the backend workspace crate. |
picky/src/signature.rs |
Disambiguates signature encoding. |
picky-crypto/CONTRACT.md |
Revises error and RSA-key rules. |
picky-crypto-conformance/Cargo.toml |
Adds the optional backend feature. |
picky-crypto-conformance/tests/main.rs |
Registers the RustCrypto provider. |
picky-crypto-rustcrypto/AGENTS.md |
Adds backend maintenance guidance. |
picky-crypto-rustcrypto/Cargo.toml |
Defines features and dependencies. |
picky-crypto-rustcrypto/INTENT.md |
Adds backend intent and invariants. |
picky-crypto-rustcrypto/README.md |
Documents features and capabilities. |
picky-crypto-rustcrypto/deny.toml |
Bans weakened Ed25519 compatibility. |
picky-crypto-rustcrypto/src/aead.rs |
Implements AES-GCM. |
picky-crypto-rustcrypto/src/cbc.rs |
Implements CBC ciphers. |
picky-crypto-rustcrypto/src/curve25519.rs |
Implements Ed25519 and X25519. |
picky-crypto-rustcrypto/src/ec.rs |
Implements NIST EC operations. |
picky-crypto-rustcrypto/src/hash.rs |
Implements digest entries. |
picky-crypto-rustcrypto/src/key_wrap.rs |
Implements AES-KW. |
picky-crypto-rustcrypto/src/lib.rs |
Assembles feature-selected entries. |
picky-crypto-rustcrypto/src/mac.rs |
Implements HMAC. |
picky-crypto-rustcrypto/src/pbkdf2.rs |
Implements PBKDF2. |
picky-crypto-rustcrypto/src/random.rs |
Implements secure randomness. |
picky-crypto-rustcrypto/src/rc4.rs |
Implements RC4. |
picky-crypto-rustcrypto/src/rsa.rs |
Implements RSA operations and keys. |
picky-crypto-rustcrypto/src/util.rs |
Adds zeroizing buffer and length helpers. |
🧠 Review effort: Balanced
💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Benoît Cortier (CBenoit)
force-pushed
the
cbenoit-picky-crypto-rustcrypto
branch
5 times, most recently
from
October 13, 2026 07:01
969bab0 to
aed983a
Compare
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Ed25519 signatures gain an inherent to_vec when the ed25519 crate's alloc feature is enabled anywhere in the build, which leaves the trait import unused and fails clippy with warnings denied. Calling the trait method by path compiles the same with and without that feature. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
ECDSA signing now mixes operating-system randomness into the RFC 6979 nonce, as the contract requires for ECDSA nonces. PBKDF2 reports an output allocation failure as unsupported only above the must-support output length. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
The section 4 rule on library validation failures covers key validation only; non-key inputs keep the errors the section 4 table assigns. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Conformance outcome sets for RSA private keys with inconsistent or non-distinct components are exact per test input: a signature verifies under (n, e) or the call returns InvalidKey, and decrypting a ciphertext with valid padding returns the expected plaintext or InvalidKey, never VerificationFailed. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Benoît Cortier (CBenoit)
force-pushed
the
cbenoit-picky-crypto-rustcrypto
branch
from
October 13, 2026 08:14
aed983a to
6482c34
Compare
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


Implementing the picky-crypto contract needs at least one software backend. RustCrypto covers every contract algorithm except the key-based KDFs and FFDH, and it includes the legacy algorithms NTLM, Kerberos and legacy PKCS#12 need.
Add the picky-crypto-rustcrypto crate (
publish = false). It is a thin adapter: each entry maps the contract's arguments to RustCrypto calls, checks algorithm-fixed lengths and constant bytes, and maps library errors to the contract's error set. Library capabilities the adapter relies on are cited at their locked versions in code comments.fips()is always false. Library zeroize features are enabled, and adapter-held secret copies and returned buffers use zeroizing storage. No secret-holding type implementsDebug.Algorithm families are features, with nothing enabled by default. A build without features yields an empty provider, and each feature only adds entries:
digest: SHA-1, SHA-2 and SHA3-384/512 hashes, HMAC and PBKDF2aes: AES-CBCaead: AES-GCMkey-wrap: AES-KWrsa: PKCS#1 v1.5 signature verification (MD5, SHA-1, SHA-2, SHA3-384/512), PKCS#1 v1.5 and OAEP encryption, private-key loading, 2048/3072/4096-bit generationnist-ec: ECDSA and ECDH on P-256, P-384 and P-521, private-key loading and generationcurve25519: Ed25519 verification, loading and generation; X25519 ephemeral and static agreementlegacy: MD4, MD5, RC4, 3DES-EDE3-CBC and RC2-CBCall: every family (64 entries)A secure-random entry comes with
aead,rsa,nist-ecorcurve25519. Key-based KDFs and FFDH are not provided; other providers supply them.Where the library falls short of the contract, the adapter uses library functions only:
Unsupported.RSA signing and decryption are blinded, and ECDSA signing mixes OS randomness into the RFC 6979 nonce.
picky-crypto-rustcrypto/deny.toml bans ed25519-dalek's
legacy_compatibilityfeature over the workspace, because it would weaken the Ed25519Srange check through feature unification.CONTRACT.md clarifications motivated by this backend:
InvalidKey, except when the library only rejects a well-formed key for its size or parameters, which maps toUnsupported.The picky-crypto-conformance runner gains a
rustcryptofeature that registers this provider withall. CI runs it, together with a depth-2 cargo-hack clippy powerset over the backend's features and the cargo-deny feature ban.The separate
fix(picky)commit makes an Ed25519SignatureEncoding::to_veccall explicit, so workspace clippy passes whened25519/allocis unified in. It duplicates a standalone fix against master and drops out when this branch is rebased after that fix lands.Stacked on #556; merge after it.
Size: backend source +1544 (about 180 of it inline adapter tests), manifests and runner +78, documentation +89/−8, CI +29/−2, Cargo.lock +69 (md4 0.11.0, rc4 0.2.0 and this crate), picky +2/−2.
Open question:
rsais the prerelease0.10.0-rc.18, which the workspace already locks.