Skip to content

Instantly share code, notes, and snippets.

@jeffro256
Last active January 1, 2025 21:06
Show Gist options
  • Save jeffro256/4155401274699e0437ba5b79b93c647f to your computer and use it in GitHub Desktop.
Save jeffro256/4155401274699e0437ba5b79b93c647f to your computer and use it in GitHub Desktop.
Extracting Monero Wallet Seeds From Addresses with a Quantum Computer

Extracting Monero Wallet Seeds From Addresses with a Quantum Computer

Wallet Derivation Assumputions

  1. Not multisig
  2. The private spend key is the seed src
  3. The private view key is a hash of solely the private spend key src
  4. Subaddresses are generated by adding the public spend key to a base point multiplied by a scalar hash of the private view key and a small "index" space src

This is not the exact math, but here is a simplified deriviation scheme which preserves all the relationships that we care about:

  • ks = seed
  • kv = Hn(ks)
  • Ks0 = ks G
  • Kv0 = kv G
  • Ksj = Ks0 + Hn(ks || j)
  • Kvj = kv Ksj

Where ks is the private spend key, kv is the private view key, (Ks0, Kv0) is the main address, (Ksj, Kvj) is a subaddress for some index j, Hn() is a hash-to-scalar function, and G is a generator of the prime order subgroup in ed25519..

Quantum Computer Assumption

Given any P and Q, a quantum computer can efficiently calculate k = dlog(P, Q) such that P = k Q. For the rest of the document, we assume that this problem (the "Discrete Logarithm Problem") is easy.

Finding the Wallet Seed from a Main Address

Given the address (Ks0, Kv0), we can simply find seed = ks = dlog(Ks0, G).

Find the Wallet Seed from a Subaddress

Given the address (Ksj, Kvj), we cannot do a simple deterministic deiscrete log to find the private spend key because an additional hashed component is added to the pubkey. However, we can find the private view key and then guess the subaddress "extensions" until the guessed private spend key derived the known private view key.

kv := dlog(Kvj, Ksj) for j' in {our guesses of the subaddress index}: Ks0' := Ksj - Hn(kv || j') ks' := dlog(Ks0', G) kv' := Hn(ks') if kv' ?== kv: return ks'

This should work in most cases since the subaddress index j should be within a small, easily iterable range for reference wallets.

Potential Applications

RingCT does not have any forward secrecy for the transaction graph whatsoever, so that information would be available to a quantum computer even without any access to off-chain address data. And with the private view key, which can be extracted from addresses, we can already tie adddresses together as beloning to the same wallet (Janus attacks), as well as scan the blockchain to see received enotes and amounts.

If other wallets use a different way to derive addresses and the private keys, then this scheme would let a quantum computer differentiate between "standard" addresses and "non-standard" addresses. The only other unique privacy concern for seed phrase extraction would be if other secrets were derived from the seed/private spend key.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment