Skip to content

Embed ED25519 public key in signature blob#257

Merged
heifner merged 2 commits intomasterfrom
feature/ed-sig-key
Mar 17, 2026
Merged

Embed ED25519 public key in signature blob#257
heifner merged 2 commits intomasterfrom
feature/ed-sig-key

Conversation

@heifner
Copy link
Copy Markdown
Contributor

@heifner heifner commented Mar 16, 2026

Summary

  • Embed 32-byte ED25519 public key directly in signature blob (96 bytes = 32 pubkey + 64 sig), making ED25519 signatures self-contained and recoverable
  • Remove ed_pubkey_extension and reject all transaction extensions at consensus layer (init_for_input_trx)
  • Simplify get_signature_keys — all non-BLS signature types now use uniform recover() path
  • Add sig_type::ed to WASM recover_key allowed list
  • Unify private_key::generate(key_type) interface, replacing template overloads

Context

ED25519 signatures are non-recoverable — you can't derive the public key from (signature, digest). Previously the system stored the public key as a separate ed_pubkey_extension in transaction.transaction_extensions[], then matched extensions to signatures by index order. This was error-prone (ordering dependency, forgotten extensions) and added client complexity.

With the public key embedded at [0..31] and the signature at [32..95], recover() extracts the key, verifies the signature against it, and returns it — identical to the K1/R1/WebAuthn flow.

Companion CDT PR: Wire-Network/wire-cdt#38

Make ED25519 signatures self-contained by embedding the 32-byte public
key directly in the signature blob (96 bytes = 32 pubkey + 64 sig).
This eliminates ed_pubkey_extension and the ordering dependency between
transaction extensions and signatures.

Core changes:
- signature_shim: 64→96 bytes, is_recoverable=true, recover() verifies
  embedded key and returns it
- sign_sha256/sign_raw: embed pubkey at [0..31], sig at [32..95]
- Remove ed_pubkey_extension, replace with transaction_extension_placeholder
- Reject transaction extensions in transaction_context::init_for_input_trx
- Simplify get_signature_keys: all non-BLS types use uniform recover() path
- Add sig_type::ed to recover_key allowed list in WASM crypto layer
- Unify private_key::generate(key_type) interface, removing template overloads
The signature_shim was expanded to [pubkey 32B][sig 64B] but the
Solana interop test still tried to parse a raw 64-byte fixture
signature via from_base58_string. Construct the blob manually instead.
@heifner heifner merged commit 0986f54 into master Mar 17, 2026
22 checks passed
@heifner heifner deleted the feature/ed-sig-key branch March 17, 2026 14:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants