Skip to content

mid-signer: the DeviceSigner seam as a no_std leaf - #3

Open
Ttimmahlax wants to merge 2 commits into
no-std-typesfrom
device-signer-leaf
Open

mid-signer: the DeviceSigner seam as a no_std leaf#3
Ttimmahlax wants to merge 2 commits into
no-std-typesfrom
device-signer-leaf

Conversation

@Ttimmahlax

Copy link
Copy Markdown

Stacked on #1 (no-std-types), the other half of the same seam.

What

  • mid-signer (new): DeviceSignerdevice_id(&self) -> &str, sign_prehash(&self, &[u8; 32]) -> [u8; 64] (low-s) — and InMemoryDeviceSigner, moved verbatim out of kms-client, plus canonical_bytes(Signature) -> [u8; 64] (the low-s rule, public so a hardware part that returns raw (r, s) applies the same one) and a blanket impl DeviceSigner for &T. no_std + alloc without the default std feature; std adds p256's std types and the generate helper's OS randomness.
  • kms-client depends on the leaf and re-exports DeviceSigner / InMemoryDeviceSigner at the old paths, so mata-sign, mid-issuer and every downstream keep compiling. Its own rand_core dependency goes with the helper.

Why

Every signer implementation and every consumer of the trait currently has to depend on kms-client, which brings reqwest and a runtime. The Janus ESP32 family carries a copy of the trait for that reason (rusty_esp_mid-core::signer, byte-for-byte this one, with a comment saying "when mid extracts it into a leaf crate, this module becomes a re-export"). This is that leaf.

Gates

gate result
cargo test -p mid-signer -p kms-client 4 + 3 + 5 end-to-end + doctests green
cargo check -p mid-signer --no-default-features --target riscv32imac-unknown-none-elf clean
cargo check --workspace clean
cargo clippy -p mid-signer --all-targets -- -D warnings clean (kms-verifier has a pre-existing len_without_is_empty, untouched)

🤖 Generated with Claude Code

tim-almond-house and others added 2 commits September 2, 2026 17:59
`DeviceSigner` (a stable device id and a low-s ECDSA P-256 signature over
a 32-byte prehash) and `InMemoryDeviceSigner` move out of `kms-client`
into `mid-signer`, `no_std` + `alloc` without the `std` feature, so a
hardware implementation (secure element, eFuse key, an ESP32's DS
peripheral) depends on the trait and `p256` alone and no consumer has to
pull an HTTP client to name it. `canonical_bytes` is the shared low-s
rule, public so a part that returns raw (r, s) applies the same one.
`kms-client` depends on the leaf and re-exports both names at their old
paths; `mata-sign` and `mid-issuer` compile unchanged. A blanket impl for
`&T` lets `&dyn DeviceSigner` and `impl DeviceSigner` callers coexist.

Gates: mid-signer 4 tests (every signature low-s, deterministic and
verifying; the canonical rule on a flipped twin; the reference impl; the
SEC1 pubkey), kms-client 3 + 5 end-to-end + doctests, riscv32imac no_std
check of mid-signer, workspace check. `kms-verifier` fails clippy on its
own `len_without_is_empty`, untouched here.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
`InMemoryDeviceSigner` moves behind an `alloc` feature (implied by `std`,
on by default); without it the crate is `DeviceSigner` and
`canonical_bytes` over `core` and `p256` alone, which is what a
microcontroller with its key in hardware links. riscv32imac checks with
and without `alloc`; kms-client and the workspace unchanged.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants