Repository navigation
Conversation
Quest-Claim: 8a77b08afdba1233
Resolves X25519, ChaCha20-Poly1305, AES-256-GCM, SHA-256, SHA-512, and the system random source on rind, and nothing else, so BLAKE2 and Curve448 come from a resolver the caller puts behind it with snow's FallbackResolver. Tested with cacophony's Noise vectors, handshakes and transport against snow's default resolver, per-primitive differential checks, and ctgrind. A transport benchmark compares it with snow's RustCrypto and ring resolvers. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
snow 0.10's default resolver has no Curve448, so the fallback recipe covers BLAKE2 alone. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A caller that seals through the resolver's Cipher before set now gets a message no one can open, rather than a panic. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The maintainer kept the panics behind snow's infallible `Cipher::encrypt` and `Hash::result`; each method now says when it panics. The adapter wipes nothing itself, so the scalar comment no longer promises an unconditional wipe that #461 makes opt-in. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
kixelated
marked this pull request as ready for review
November 7, 2026 18:51
|
Your OpenCode Go account is out of credit. Top it up, then re-trigger Pullfrog. OpenCode Go's response
|
|
Warning Review limit reachedYou've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Next included review available in 48 minutes. View limit details
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. |
github-merge-queue
Bot
removed this pull request from the merge queue due to a conflict with the base branch
Nov 7, 2026
kixelated
added a commit
that referenced
this pull request
Nov 9, 2026
…0m's upstream fixes The maintainer dropped them on 2026-11-09, once the launch post was up: Deno as deprecated, rind-snow by closing #470 on purpose (which takes the snow fix that existed for it), and str0m's upstream fixes as not worth pursuing. Bun is the one outside post that goes ahead. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.

Claims and completes quest/m2/adoption/rind-snow.md, and deletes it.
Summary
A new published crate,
rind-snow0.10.0, implements snow 0.10'sCryptoResolveron rind: X25519, ChaCha20-Poly1305, AES-256-GCM, SHA-256, SHA-512, and the system random source. It returnsNonefor everything else, so BLAKE2 and Curve448 come from a resolver the caller puts behind it with snow'sFallbackResolver. It never falls back on its own.rind_snow::resolver()runsrind::cpu::check()and returns snow's ownBoxedCryptoResolver. That box goes straight intoBuilder::with_resolverorFallbackResolver::new. No primitive runs before the check, since the resolver type is private.Dh::dhits whole remote-key buffer (56 bytes, or 65 with snow'sp256feature), so the adapter takes the first 32 bytes. snow'sDh::setcannot fail, so a wrong-length private key leaves no key, and the first DH fails withError::Dh. Noise uses every static key it sends in a DH, so the handshake fails before it completes. snow's own resolver instead zero-pads a short key and panics on a long one.Error::Dh(rind'sagreerefuses the all-zero output, as aws-lc-rs does). snow's default resolver accepts it.set, so sealing or rekeying beforesetcannot panic, and its output opens under no key anyone holds. Opening beforesetfails withError::Decrypt.PrivateKey, and theScalarkept forDh::privkey), so rind's wipe rule covers them: on drop today, and under rind'swipefeature once moq-dev/rind#461 lands. rind-snow does not forward that feature, like the other adapters. Digest state is not wiped, per AGENTS.md.build.ymlandsh/armv7.shtest lists, the README adapter table, MIGRATING.md (adapter map and the crate survey's snow row, which said an adapter was waiting on static X25519 key loading;PrivateKey::from_scalarnow covers that), and MIGRATE.md's adapter list and CPU-check line.Tests
tests/vectors.rs: cacophony's Noise vectors (Unlicense, at 8ee9d41e, the same file snow ships), cut to rind's four suites and ten patterns that together use every token, a one-way handshake, and PSKs. That makes 40 vectors in 62 KB, instead of 375 KB for every pattern. Each vector checks every message's ciphertext and the handshake hash.tests/resolver.rs: XX, IK, KK, and NNpsk0 handshakes in both directions against snow's default (RustCrypto) resolver for every suite, then transport at 0 to 65519 bytes with rekeys both ways. Also: differential checks of each cipher, hash, HMAC, HKDF, rekey, and X25519 against the default resolver; malformed input (short ciphertext, small output, tampering, wrong nonce or AAD, no key set, short or small-order peer key, wrong-length private key); and BLAKE2s throughFallbackResolver.tests/ctgrind.rs: X25519, both ciphers with rekey, and HKDF on secret chaining keys, run byadmin/ctgrind adapters.rind. snow has no aws-lc-rs resolver, so the adapter's own differential peer is snow's default resolver.Benchmark
rind-bench/benches/snow.rstimes one transport message sealed by one peer and opened by the other, per cipher and size, onrind,ring(snow'sRingResolver), andrustcrypto(snow's default). The nightly native rows pick uprindandringthrough their library filter; CodSpeed runs all three.A local
--quickrun on a loaded i7-8700, for orientation only:The AES-GCM 16KB gap to ring is most likely rind's AES-GCM itself on this AVX2-without-VAES CPU: the adapter adds only the plaintext copy into snow's output buffer, which ring's resolver makes too. The nightly rows will show whether it holds on the runners.
Decisions
Cipher::encryptreturnsusizeandHash::resultreturns()(snow 0.10src/types.rs:64,:111), so an output buffer too short for the sealed message or the digest has no error path. Within snow only the first is reachable, through itsToken::Slength check that leaves out the tag (reproduced on 0.10.0 with a 64-byte buffer for XX message 2; snow's main branch still has it); the second needs a caller using the resolvedHashdirectly with a short buffer. snow's own default and ring resolvers panic at both spots. ✅ Keep both panics, documented on each method: they're loud and match snow's resolvers (rejected: degrade silently by returning a zero length or a truncated digest, which would send a truncated handshake message while reporting success; wait for snow to make the methods fallible, a breaking snow change). Settled by the maintainer on 2026-11-07.Choices made without asking
Builder::new, which uses snow's built-in resolver. So rathole cannot opt in without changing its own code, whichever snow version this crate targets, and a snow 0.9 build would not fix that. The quest's Goal ("any snow user, such as rathole, opts in with no upstream change") holds for snow itself: no snow change is needed, but each user must callBuilder::with_resolver.resolver(), notdefault_provider(): snow calls this a resolver, and it returns snow'sBoxedCryptoResolver. It still has its ownMissingFeatureand re-exports no rind types.Upstream draft (follow-up, not posted)
Posting this is outside the moq-dev and kixelated orgs, so the maintainer decides it separately; it does not block this PR.
snow has no AI or contribution policy beyond its license terms (README, SECURITY.md). This is a local misuse panic, not a remotely reachable one, so it suits a public issue rather than a security advisory. Draft for mcginty/snow:
Public API and wire impact
New crate
rind-snow0.10.0:resolver() -> Result<BoxedCryptoResolver, MissingFeature>andMissingFeature. No change torindor any other crate's API. Noise wire format is unchanged (verified against cacophony's vectors and snow's default resolver).Caused by
None: new adapter.
Validation
just checkon a77595e, and again on 8ee3141 after merging main (00610af): passed (rs, msrv, cross, deny, versions, bench, fixtures, patch, quest, gh, shell, nix), including every rind-snow test and its doctest.sh/adapter-versions.sh: passes with rind-snow 0.10.0 on snow^0.10.ctgrind.ymlrunsadmin/ctgrind adapters.Follow-ups
## Waitingholds the maintainer's approval to post outside the orgs. It's a one-line upstream fix that removes the only snow-reachable panic rind-snow keeps.Models
Size: M
Implementer: Claude Code, claude-opus-5-5, high effort
(Written by Claude Opus 5.5 with high)
🤖 Generated with Claude Code
Review
Rewritten by
quest reviewafter each round.01a1b509-8d4d-7e23-995b-5ba8c5db7a00, round 4No findings remain after honoring the recorded maintainer exceptions; the new changes only document those decisions.rind-snow/src/lib.rs:221:Reject undersized handshake output before encryption;The maintainer decision recorded in .tmp/body.md:46 explicitly accepts this panic, now documented at rind-snow/src/lib.rs:211.rind-snow/src/lib.rs:274:Prevent short hash output buffers from reaching unchecked slicing;The same decision in .tmp/body.md:46 explicitly accepts short hash-output panics, now documented at rind-snow/src/lib.rs:277.Head 8ee3141 adds only a conflict-free merge of main (00610af);
git diff origin/main...8ee3141dprints the same as the diff of the reviewed head a77595e, so this record covers it.