Hardware-backed signers for G accounts: some secp256r1 numbers, and CAP-43 #2015
adrianvrj
started this conversation in
Core Advancement Proposals
Replies: 3 comments
|
+1 there. xrpl for reference supports secp256k1 and ed25519. With the state of passkey now it seems that secp256r1 would be a sensible choice if we were to only pick one extra curve for now. I also have some NFC cards that either support secp256k1 or secp256r1 and being able to sign with either would open up the door to a classic account bound to hardware. |
0 replies
|
+1 |
0 replies
|
Would be nice if we could have @leighmcculloch here |
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
I'd like to restart the conversation around CAP-0043, which adds a secp256r1 signer to classic accounts. It was drafted in 2022 and never discussed, so this is partly an attempt to find out whether there's any appetite for it.
Context
A classic account can only be controlled by an Ed25519 key. Secure elements don't implement Ed25519: Android StrongBox supports "ECDSA, ECDH P-256", and Apple's CryptoKit only exposes
SecureEnclave.P256. So a Stellar signing key is always software that can be copied out of the device, which is the part I'd like to be able to fix.To be clear about scope, this isn't about passkeys. A WebAuthn assertion signs
SHA256(authenticatorData || SHA256(clientDataJSON))and needs both of those carried in the transaction, which doesn't fittypedef opaque Signature<64>in Stellar-types.x. A device key signs a digest directly and itsr||sis exactly 64 bytes, so it fits today's envelope. That's the case CAP-43 already specifies, and it matches the HSM motivation it was originally written for.On cost
The obvious objection is verification cost in the classic path, so I measured it. Using the crate versions pinned in stellar-core's
Cargo.lock(p2560.13.2,ed25519-dalek2.2.0), 32-byte prehashed messages, on an M4:The
p256/dalekratio comes out at 7.79–7.86x. As a sanity check on the method, the calibration in budget.rs gives 3,000,906 / 377,551 = 7.95x, so this reproduces the published figure to about 1.3%. On the same machine the same curve through OpenSSL is 1.38x Ed25519, which suggests the 8x is mostly the pure-Rust implementation rather than the curve.I should flag that this is arm64 and pubnet validators are mostly x86_64, so I don't think these numbers should carry much weight on their own. I skipped emulation since the timings wouldn't mean anything. Happy to share the code, or run whatever variant would be more useful.
Two things that might make this cheaper than it looks
stellar-core doesn't link OpenSSL, but
p256is already in the binary viasoroban-env-hostfor CAP-0051'ssecp256r1_verify. Going through the Rust bridge would add no new dependency, andverify_ed25519_signature_dalekinsrc/rust/src/ed25519_verify.rsis already precedent for Rust crypto in the signature path. That does mean the honest number for the cheap implementation is 7.85x, not 1.38x, getting to 1.38x would mean adding a C crypto library to consensus code, which I'm not asking for.There's also already a bounded verification budget in the classic path:
TX_ED25519_VERIFY_BUDGET = 1000in SignatureChecker.h, added in v26.1.0 after theed25519SignedPayloadissue. Making that budget weighted, so a P-256 verify costs ~8 units where an Ed25519 verify costs 1, would bound worst-case validation work with the same constant as today and wouldn't touch fees.What I'm asking
Mostly whether this is worth pursuing at all. Specifically:
I noticed the quantum preparedness plan mentions quantum-safe signer types as first-class signers on classic accounts via
set_options. IfSignerKeyis getting new arms anyway, secp256r1 seems like the cheapest possible one, given the curve is already in consensus and the implementation is already linked.For context on why I care: we build multi-chain smart accounts, and our device-signer flow uses secp256r1 verified on-chain on Starknet and Solana. On Stellar it has to fall back to a software Ed25519 key. Glad to help with implementation or test vectors if there's interest.
All reactions