ton-blockchain / ton

Main TON monorepo
Other
2.63k stars 727 forks source link

It's impossible to use importKey() via tonlib/json. #22

Open olegvg opened 4 years ago

olegvg commented 4 years ago

Seems to be typo here https://github.com/ton-blockchain/ton/blob/f40822b58a06f8fc9d88a5350b22f43b204ddfc8/tonlib/tonlib/KeyStorage.cpp#L104 which prevents to successfully run tl: importKey local_password:secureBytes mnemonic_password:secureBytes exported_key:exportedKey = Key; Condition !mnemonic.is_basic_seed() must be inverted to mnemonic.is_basic_seed()

ton-blockchain commented 4 years ago

There is no typo in this line.

I could guess it is somehow related to your other changes.

olegvg commented 4 years ago

There are no other changes. I've used vanilla master right now and got the same error with a import_key: inverted condition is_basic_seed() fired again.

ton-blockchain commented 4 years ago

Oh, there seems to be a lot of confusion mostly due to lack of documentation in tonlib.

  1. User can't choose mnemonic words. They are generated by tonlib and are returned by exportKey. In importKey, one must use the mnemonic words which exportKey returned.
  2. mnemonic_password is meant to be 25th word chosen by the user, not by tonlib.
  3. secureBytes and bytes in tl scheme are serialized as base64 in JSON.
  4. secureString and string are serialized as usual strings. So it is wrong to use base64 encoding at least here https://github.com/formony/ton_client/blob/master/ton_client/client.py#L399

The mnemonic.is_basic_seed() checks (with some probability) that menmonic_words were generated by tonlib and are not a random collection of words.

Does this information help?

APshenkin commented 4 years ago

@ton-blockchain As I understand:

createNewKey - creates new KeyPair record in local Keystore. Also you can add mnemonic_password (if user will export key as mnemonic). It returns public key and secret that is not private key, but chiphed presentation of private key in Keystore. You create mnemonic and store it in file. And you get private key from this mnemonic

exportKey - return 24 word mnemonic, chiphed with mnemonic_password. This is not BIP39 mnemonic and mnemonic_password is not BIP39 Passphrase. You create your own algoritm for it, correct? Mnemonic stores origin private_key (and maybe something else?)

importKey - accept exported mnemonic + mnemonic_password + new local_password for this key. So it can't be BIP39 mnemonic

So can you please clarify, why TON use it's own shema for mnemonics?

Why you don't use BIP39 seed as start point to generate private key?

What is an algoritm for TON mnemonic generation? how I can reimplement it?

ton-blockchain commented 4 years ago

This is about right.

mnemonic words and a private key are stored on the disk. And are encrypted with secret and local_password.

We use seed generation which is similar to the one in electrum https://electrum.readthedocs.io/en/latest/seedphrase.html The reasons mostly the same.

  1. We don't want to store all possible lists of words on the client.
  2. There should be a checksum that does not depend on a wordlist.
  3. It should be possible to add a new type of key derivation in future with backward compatibility.

There is no public documentation yet, but the code is pretty straightforward. https://github.com/ton-blockchain/ton/blob/master/tonlib/tonlib/keys/Mnemonic.cpp You are interested in Mnemonic::to_private_key function.

ton-blockchain commented 4 years ago

@APshenkin I should note that it is possible to use externally generated ed25519 private key in tonlib. And it is possible to run tonlib in-memory, without touching the filesystem.

APshenkin commented 4 years ago

@ton-blockchain

Thanks a lot for detailed explanation