both ml-dsa schemes from one phrase, with no scheme choice anywhere #65

Closed
opened 2026-09-16 15:22:24 +00:00 by grenade · 1 comment
Owner

Parent: #4

Why

Create and restore ask the person to pick ML-DSA-65 or ML-DSA-87, and the wallet then derives only that account. The same phrase gives a different account under each scheme, so a person who picks the one they did not use sees an empty balance while their funds sit on the other account. That is the kind of mistake a wallet should make impossible rather than warn about.

Scope

  • Remove the scheme selection from create and restore (and from the commands behind them: wallet_create_begin, wallet_import_phrase).
  • Opening a wallet whose file carries a phrase derives both accounts, each at its conventional path (…/0'/0'/0' for ML-DSA-87, …/0'/0'/1' for ML-DSA-65), plus the file's own stored keypair if it sits at another path, de-duplicated by account id. A file with no phrase (a raw-seed or CLI-generated key) keeps its one account.
  • Every screen that lists accounts (accounts, receive, send's from, history, the other-networks overview) shows both, each with its balance. The scheme stays visible as a label, never as a choice.
  • Whichever scheme Quantus's own docs and tools steer people toward is the default: it is written to the keystore file, listed first, and preselected on receive and send. The other is shown alongside, not hidden.
  • The keystore file format stays quantus-cli's. The file records one keypair (the default scheme's); the second account is derived in memory from the phrase on every open.

Acceptance

Restore the public dev phrase once: both qz… accounts appear with their balances without choosing anything, the default one first. A wallet file written by quantus wallet import under either scheme opens with both accounts. A CLI raw-seed file (crystal_alice) opens with its one account. The secret-leak test still passes with both signers held.

Depends on

#15 (keystore), #17 (session).

Parent: #4 ## Why Create and restore ask the person to pick ML-DSA-65 or ML-DSA-87, and the wallet then derives only that account. The same phrase gives a different account under each scheme, so a person who picks the one they did not use sees an empty balance while their funds sit on the other account. That is the kind of mistake a wallet should make impossible rather than warn about. ## Scope - Remove the scheme selection from create and restore (and from the commands behind them: `wallet_create_begin`, `wallet_import_phrase`). - Opening a wallet whose file carries a phrase derives **both** accounts, each at its conventional path (`…/0'/0'/0'` for ML-DSA-87, `…/0'/0'/1'` for ML-DSA-65), plus the file's own stored keypair if it sits at another path, de-duplicated by account id. A file with no phrase (a raw-seed or CLI-generated key) keeps its one account. - Every screen that lists accounts (accounts, receive, send's from, history, the other-networks overview) shows both, each with its balance. The scheme stays visible as a label, never as a choice. - Whichever scheme Quantus's own docs and tools steer people toward is the default: it is written to the keystore file, listed first, and preselected on receive and send. The other is shown alongside, not hidden. - The keystore file format stays quantus-cli's. The file records one keypair (the default scheme's); the second account is derived in memory from the phrase on every open. ## Acceptance Restore the public dev phrase once: both `qz…` accounts appear with their balances without choosing anything, the default one first. A wallet file written by `quantus wallet import` under either scheme opens with both accounts. A CLI raw-seed file (`crystal_alice`) opens with its one account. The secret-leak test still passes with both signers held. ## Depends on #15 (keystore), #17 (session).
grenade added the child label 2026-09-16 15:22:35 +00:00
Author
Owner

Which scheme is the default, from Quantus's own clients: quantus-cli (--scheme default_value_t = DilithiumScheme::MlDsa65; README "default scheme: ml-dsa-65, HD path …/1'"), the mobile SDK (DilithiumSchemeExtension.current = mlDsa65, legacy = mlDsa87), the cold wallet ("New wallets stay ML-DSA-65 unless the user opts into ML-DSA-87") and the browser extension (DEFAULT_TYPE = 'dilithium65'; ML-DSA-87 "must remain importable but is never offered as a choice", and it shows the ML-DSA-65, ML-DSA-87 and wormhole accounts together). The chain node's own key command still defaults to 87, and docs.quantus.com gives no guidance. So: ML-DSA-65 current and first, ML-DSA-87 shown beside it labelled legacy.

Not done here, noted for later: the mobile wallet's import goes further, running a BIP-44 gap-limit scan over account indices (m/44'/189189'/<i>'/0'/<scheme>') for both schemes against its indexer, so a phrase that was used for account 2 or 3 shows those too. This wallet derives account 0 under each scheme. A child for discovery can follow if it matters.

Which scheme is the default, from Quantus's own clients: quantus-cli (`--scheme` `default_value_t = DilithiumScheme::MlDsa65`; README "default scheme: ml-dsa-65, HD path …/1'"), the mobile SDK (`DilithiumSchemeExtension.current = mlDsa65`, `legacy = mlDsa87`), the cold wallet ("New wallets stay ML-DSA-65 unless the user opts into ML-DSA-87") and the browser extension (`DEFAULT_TYPE = 'dilithium65'`; ML-DSA-87 "must remain importable but is never offered as a choice", and it shows the ML-DSA-65, ML-DSA-87 and wormhole accounts together). The chain node's own `key` command still defaults to 87, and docs.quantus.com gives no guidance. So: ML-DSA-65 current and first, ML-DSA-87 shown beside it labelled legacy. Not done here, noted for later: the mobile wallet's import goes further, running a BIP-44 gap-limit scan over account indices (`m/44'/189189'/<i>'/0'/<scheme>'`) for both schemes against its indexer, so a phrase that was used for account 2 or 3 shows those too. This wallet derives account 0 under each scheme. A child for discovery can follow if it matters.
grenade referenced this issue from a commit 2026-09-16 16:22:42 +00:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: blackbeard/wallet#65