Skip to content

feat: add Ethereum, Bitcoin, Solana, Nostr, and SSH authenticators#17

Merged
olanod merged 7 commits intomainfrom
multi-wallet-authenticators
Apr 3, 2026
Merged

feat: add Ethereum, Bitcoin, Solana, Nostr, and SSH authenticators#17
olanod merged 7 commits intomainfrom
multi-wallet-authenticators

Conversation

@olanod
Copy link
Copy Markdown
Member

@olanod olanod commented Apr 3, 2026

Summary

  • Ethereum: secp256k1 + keccak256 personal_sign verification (MetaMask, WalletConnect)
  • Bitcoin: secp256k1 + SHA256d with BIP-137 message signing format
  • Solana: Ed25519 signature verification (Phantom, Solflare)
  • Nostr: BIP-340 Schnorr signatures over secp256k1 (NIP-07 compatible)
  • SSH: Ed25519 with SSHSIG wire format (developer workflows)

Each authenticator follows the same pattern as substrate-keys: implements Authenticator + UserAuthenticator traits from fc-traits-authn, with full pallet-pass integration tests (registration + authentication).

Test plan

  • 44 new tests across all 5 authenticators
  • Full workspace tests pass (existing substrate-keys + webauthn unaffected)
  • Registration and authentication flows tested for each wallet type
  • Invalid signature / wrong key / tampered challenge rejection tested

Addresses virto-network/kreivo#479

New authenticator implementations for pallet-pass multi-wallet support:

- Ethereum: secp256k1 + keccak256 personal_sign (MetaMask, WalletConnect)
- Bitcoin: secp256k1 + SHA256d BIP-137 message signing
- Solana: Ed25519 signature verification (Phantom, Solflare)
- Nostr: BIP-340 Schnorr over secp256k1 (NIP-07 compatible)
- SSH: Ed25519 with SSHSIG wire format (developer workflows)

Each authenticator implements the Authenticator + UserAuthenticator traits
from fc-traits-authn with full registration and authentication test
coverage (44 new tests).
@olanod olanod force-pushed the multi-wallet-authenticators branch from 6556dfd to 0a0eecb Compare April 3, 2026 08:55
olanod added 6 commits April 3, 2026 12:29
- Add domain separators (ETH/BTC/SOL/NOSTR/SSH) to payload() in all
  authenticators to prevent cross-authenticator signature replay
- Replace fake Bitcoin hash160 with real RIPEMD160(SHA256) using the
  ripemd crate for proper wallet interoperability
- Remove ambiguous raw recovery ID (0-3) fallback in Bitcoin, only
  accept BIP-137 flags (27-34)
- Validate EthAddress padding bytes are zero in registration and
  credential verification
- Use BIP-340 tagged hashing for Nostr (SHA256(SHA256(tag)||SHA256(tag)||msg))
  instead of plain SHA256
- Ethereum: zero signature, malformed padding rejection
- Bitcoin: uncompressed key path, raw recovery ID rejection,
  boundary BIP-137 flags (26/35), zero signature
- Nostr: invalid pubkey (not on curve), zero signature, bit-flipped sig
- Solana: zero pubkey, zero signature, tampered signature
- SSH: zero pubkey, zero signature, tampered signature
Tests a runtime with all 5 authenticators combined via composite_authenticator!:

- Cross-authenticator replay: ETH cred can't auth SOL account and vice versa,
  BTC cred can't auth SSH account (composite enum dispatch rejects mismatched
  variants)
- All authenticators work independently in the composite runtime
- Same Ed25519 key registered as both SOL and SSH produces separate accounts;
  cross-variant auth is still rejected
- Wrong authority_id rejects registration
- Session key isolation test
- Rewrite DeviceId collision test: assert pallet-pass correctly rejects
  duplicate DeviceId registration (DeviceAlreadyExists error)
- Add domain separation tests: verify all 5 authenticators produce
  distinct payloads for identical inputs, check prefix correctness
- Add SCALE length-extension test: verify different (context, challenge)
  pairs always produce different payloads
- Remove weak session key test (replaced with assertive checks)
- Add authority mismatch test
The Sign trait provided no polymorphism — each authenticator had exactly
one signer type. Replace with inherent methods on SignedMessage behind
cfg(full-crypto), matching the simpler API.
@olanod olanod merged commit 0927329 into main Apr 3, 2026
6 checks passed
@olanod olanod deleted the multi-wallet-authenticators branch April 3, 2026 16:28
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.

1 participant