9

Using monero-wallet-cli --restore-deterministic-wallet with the following seeds can restore the same wallet:

First seed: lawsuit artistic jeans lair plus village potato cedar certain sizes ruthless ingested girth films pegs cage exult zombie wade pumpkins candy wetsuit utopia claim potato

Second seed: guarded sake aisle kidneys mayor session vastness wiggle arsenic camp sixteen doing girth films pegs cage exult zombie wade pumpkins candy obnoxious wayside abyss sixteen

Why? Is it safe to keep using the old (first seed) years from today?

More info from this: Using old 0.9.4 wallet

10

TL;DR first is completely random seed, 2nd is the "normalized" seed, and they're both valid and resolve to the same wallet. As long as you know the method to go from mnemonic to the actual private key, you're safe to keep it as it is.

The first is a just some random 256 bits, probably generated by other means and the second is the "normalized" seed, meaning it's a number smaller than l (a parameter specific to the elliptic curve used in monero cryptography scheme). Both seeds resolve to the same private spend key and are equally valid. The private spend key is the important piece of data which is used on the protocol level. You could even use your own, custom, mnemonic scheme to get from mnemonic/seed to private spend key. The protocol doesn't care about the mnemonic/seed, only about the 4 keys (spend keypair and view keypair)

If you restore the wallet with the first seed, and after restoring use the "seed" command, the wallet will print the second seed. This is because it automatically normalizes the seed. Let me elaborate.

First of all, your mnemonic is a representation of a 256 bit integer, ie a very very big number. This number is your seed, and from it the keys are derived and those are actually used in cryptography on the protocol level. There is a function which converts between the number (seed) and the mnemonic. How the conversion works, is explained here.

To get the private spend key, the seed is passed through sc_reduce32 function:

privSpend = sc_reduce32(seed)

if the seed is a random 256bit integer, then it can happen that:

seed != sc_reduce32(seed)

however, if your seed has already been passed through sc_reduce32 function, then it's what we call a "normalized seed" and both the seed and privSpend will be the same, i.e. passing a normalized seed through sc_reduce32 results in the exact same number.

n_seed = privSpend = sc_reduce32(seed)
n_seed == sc_reduce32(n_seed)

Since n_seed != seed, the mnemonic corresponding to each of them will also be different.

You could easily produce the normalized seed yourself, by playing with this page:

  1. Type in your first seed into box 1.
  2. Click "Gen 2." and "Gen 3. & 4.", notice that 2. & 3. are different.
  3. Copy the value from box 3. into box 2.
  4. Click "Gen 1." and "Gen 3. & 4.", you will notice 3. and 4. didn't change and 2. & 3. are now the same.
  • 3
    it's a point on the elliptic curve It's really a scalar < l; public keys are curve points. – Luigi Sep 30 '16 at 22:16
  • 1
    care to elaborate what a "scalar" means in EC context? I'd like to expand it a bit, would also like to understand what sc_reduce32 actually does – JollyMort Oct 1 '16 at 2:49
  • 2
    @JollyMort: Let P be a point on the EC, which is closed under addition. Then if denote 2*P := P+P, that will still be a point on the curve. Similarly, so will 3*P := P+P+P, 4*P := P+P+P+P etc. So that nP just means "add P to itself n times". We call that integer n a scalar. // The point about the order l of the base point G is that lG will be the identity, in other words: nG will be all different points on the curve for n in {1,2,...,l} but beyond that you will just repeat the list of points. – user141 Oct 1 '16 at 16:02
  • I understood that, thanx. So why, in the below example, is the reduced integer "larger" than the original (n=6d32... n_red=938a...) if the requirement is n < l and our n_red > n which implies n_red > l if we started with n > l. – JollyMort Oct 2 '16 at 5:12
  • 1
    Yes that's all sc_reduce32 does. Private keys are indeed little endian. – Luigi Oct 3 '16 at 17:06
6

This answer just reiterates the point Jolly Mort made above with a reference example. The answer to your question concerns the Monero normalization function sc_reduce32() plays when it operates on a seed to create the effective private spend key. Normalized numbers fed to the sc_reduce32() function won't be modified. (Note the example key below is not a secure one.)

% echo "The girl has gone Monero!" | bx base16-encode | bx sha256 6d325642de6bd6aaae6a54ed1d9db564c4081793e3adad171f979058de535627

% ./sc_reduce32 6d325642de6bd6aaae6a54ed1d9db564c4081793e3adad171f979058de535627 938a6a88a9a5b1fa013165a760a9f73ac4081793e3adad171f979058de535607

Experiment with https://xmr.llcoins.net/addresstests.html.

  1. Insert the first hexadecimal number above into the Hexadecimal Seed field, and click on the Gen 1. button.

    The following words result:

    dating buying hover rudely suitcase lemon younger addicted vigilant anvil bovine lyrics simplest copy rugged eldest locker nylon roles rover avoid yellow oncoming semifinal younger

    After clicking Gen 3 & 4., Gen 5., Gen 6., and Gen 7. the following should be the stealth address:

    49Dw3cqJycuEtQvAr3kPiYjX1yiHMDrwr5fqiMr5hCf3MvDGgFjwdXSNCDRpb7N195C81V9wXLZgHWsuEYVwtaNGN9JERGc

  2. Insert the second hexadecimal number into the Hexadecimal Seed field and repeat the process above. Notice how the the Hexadecimal Seed and Private Spend Key fields are the same and the stealth address is the same, but the 25 Electrum words are now:

    mesh deepest rhino tadpoles picked oyster river wept optical fictional lectures remedy simplest copy rugged eldest locker nylon roles rover avoid august paddles pizza simplest

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.