guest-sdk: rework the public interface from external feedback - #57
Merged
Conversation
- rename the raw module to bindings; flatten mint into root per-algorithm modules - strip Key from the algorithm-instance newtypes (Mac, Aead, AeadInternalNonce) per RustCrypto precedent; SigningKey/VerifyingKey keep their names (also RustCrypto precedent) - introduce a crate-owned non_exhaustive Error mirroring the WIT variants plus Read(std::io::Error) for failing local producers - operations take impl Into<DataSource>: slices, owned buffers, StreamReader<u8> pass-through, bytes::Buf (feature bytes), and futures_io::AsyncRead (feature futures-io) - seal/open return the underlying StreamReader<u8>; collect() when you want the bytes - re-export wit_bindgen (wasip3 precedent) and StreamReader - docs: link the WebCrypto algorithm registry from the algorithm-* getters, duplicate security-critical WIT contracts into method docs, use intra-doc links instead of WIT-style refs, and document why constant-time-equal stays a component import
8 tasks
# Conflicts: # conformance/signing-guest/src/lib.rs
Module layout: generated, bindings, and the nine per-algorithm creation modules move to their own files; lib.rs keeps the error, data-source, and newtype layers. Copy discipline, in the same spirit throughout: - DataSource is lifetime-parameterized over Cow<'a, [u8]>: borrowed slices stay borrowed until fed (the ABI's write_all needs an owned buffer, so that single copy is deferred to the feed), and Vec<u8> moves without copying. From<Cow<'a, [u8]>> added. - from_buf/from_reader accept borrowing sources (dyn Buf + 'a / dyn AsyncRead + 'a instead of 'static), and their feed loops reuse one scratch buffer across chunks: write_all returns its argument's allocation, so each chunk costs the one unavoidable copy and no allocation. - The list<u8> parameters (nonce, aad, tag, sig) take impl Into<Cow<'_, [u8]>>: slices still work unchanged, and owned vectors are moved instead of forced through to_vec — aad in particular can be large.
The per-algorithm creation modules keep their own files; the bindgen invocation and its re-export surface are two dozen lines that belong next to the crate docs describing them.
The Cow representation only deferred the borrowed-input copy; it did not eliminate it, since write_all needs an owned buffer. Make it earn its keep: feed Cow::Borrowed data in chunks through the same reusable scratch-buffer pattern as the Buf and Reader sources, so a large borrowed input costs one chunk of extra memory instead of a whole duplicate. Owned data is still written whole with zero copies. The demo's wrapper check now round-trips a payload spanning several feed chunks, covering the incremental path on every target.
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.
Reworks the
lann-webcrypto-guestpublic interface per external review feedback. No WIT changes; the component ABI and all cross-implementation behavior are untouched.Changes
raw→bindings: the generated-bindings escape hatch follows ecosystem convention (wasip3-style).from_raw/as_raw/into_rawkeep their names.mintflattened into the root:lann_webcrypto_guest::hmac_sha2::generate_key(...)etc. — one root module per algorithm interface, mirroring the WIT layout, no more jargon module name.MacKey→Mac,AeadKey→Aead,InternalNonceKey→AeadInternalNonce.SigningKey/VerifyingKeydeliberately keepKey: the RustCrypto precedent for stripping it (hmac::Mac,aead::Aead) applies to algorithm-instance objects, while ed25519-dalek and theecdsacrate keep exactly these signature-key names.#[non_exhaustive] Errormirroring the WIT variants plus an unconditionalRead(std::io::Error)variant for failing local producers (the variant is unconditional — only its producer is feature-gated — to avoid the feature-unification semver trap).From<bindings::types::Error>,Display,Error::source.impl Into<DataSource>—&[u8]/&[u8; N]/Vec<u8>/&Vec<u8>(buffered),StreamReader<u8>(passed through without a local feeder),DataSource::from_buf(featurebytes),DataSource::from_reader(featurefutures-io). Blanket impls overBuf/AsyncReadare impossible (&[u8]implements both), hence explicit adapters. A reader failure wins over the operation's own result, which was computed over a truncated input.seal/openreturnStreamReader<u8>: trivial tocollect().await, and unlocks forwarding without buffering.open's docs carry the contract that the stream is handed back only after the tag verifies.algorithm_*getters link the W3C WebCrypto algorithm registry and name the projected spec fields; security-critical WIT contracts (nonce uniqueness, fail-closed verify, unverified-plaintext-never-observable, truncating producers) are duplicated into the method docs; WIT-style refs replaced with intra-doc links;pub use wit_bindgen;(wasip3 precedent).constant_time_equalstays a component import (considered and rejected switching to an in-guestconstant_time_eqre-export): the import lets the host perform the comparison in native code where constant-time properties actually hold; the ABI transit is negligible. Now documented on the function.Consumers (
examples/crypto-demo,conformance/guest,conformance/signing-guest) updated; crypto-demo'shmac-key-exportcheck now exercises the new wrapper layer.Advances (does not close) the guest-side convenience libraries item of #35.
Verification
just check— pass (fmt, clippy incl. wasm target, validate-wit, tests incl. guest-under-Wasmtime)just test-webcrypto-composed— 22/22 checksjust conformance-wasmtime+just conformance-composed— 6226 cases + 5 signing cases, 0 failedjust transpile— passcargo check/clippy/doconwasm32-wasip2under all four feature combos — clean