Skip to content

Wrong Ethereum address derivation for seed-phrase-imported vaults #572

@Ehsan-saradar

Description

@Ehsan-saradar

Root Cause

The verifier derives Ethereum addresses using TSS-style additive derivation (tss.GetDerivedPubKey / address.GetAddress). This works correctly for MPC-generated vaults where the root public key comes from the TSS protocol.

However, for seed-phrase-imported vaults, the root public key is a standard BIP32 master key derived from a mnemonic. Chain-specific keys were derived using standard BIP44/BIP32 during import — not TSS derivation. TSS derivation on these keys produces different (incorrect) addresses.

Affected Endpoints

1. Auth endpoint — Marketplace API (internal/api/server.go)

Auth() calls address.GetAddress(req.PublicKey, req.ChainCodeHex, common.Ethereum) to derive the Ethereum address used for signature verification. For seed-phrase vaults this produces the wrong address, causing authentication to fail.

Suggested fix: The client already includes the Ethereum address in the signed auth message payload. Extract the address from the parsed message (authData.Address) instead of deriving it. Since VerifyEthAddressSignature recovers the signer from the ECDSA signature and checks it matches the claimed address, a user cannot spoof a false address — the signature verification guarantees authenticity.

2. Auth endpoint — Portal API (internal/portal/server.go)

Same issue and same fix as above — replace address.GetAddress(...) with the address from msgData.Address in the signed message.

3. Policy signature verification (internal/api/policy.go and plugin/server/server.go)

verifyPolicySignature calls address.GetAddress / tss.GetDerivedPubKey to derive the Ethereum address (or public key) for verifying policy signatures. For seed-phrase vaults, the derived key is wrong, so valid policy signatures are rejected.

Suggested fix: Store the Ethereum address in the JWT token during authentication (since the auth fix above already resolves the address correctly). Then in verifyPolicySignature, extract the eth address from the JWT token instead of re-deriving it. This avoids the TSS derivation entirely and ensures consistency with the authenticated session.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions