I am using bip39 specifications for 24-word mnemonic, Whenever user registers with his/her password, A Scrypt key is generated from this password and used to encrypt this mnemonic, The admin of the database in this way, can't decrypt it.
Let's say a user forgot his/her password, there is no way to recover his/her mnemonic. One way is to design a mechanism in which he/she can share their mnemonic with other users on the blockchain.
The mnemonic is broken down into let's say, 5 Shamir secrets out of which, three are necessary to recover the original mnemonic.
Since all the other accounts are already present on the blockchain, their account has a "public" key which has the actual public key from which this account address was generated. The brief outline of accounts on blockchain is like this
public: hex encoded secp256k1 key from which this address was generated created_on: timestamp email: sha256 hash of email id phone_number: sha256 of phone_number secret_shared: list of public keys corresponding to random indexes
the length of the list is dependent upon the number of users with whom the mnemonic will be shared
The user at the time of registration creates five random indexes out of 2^32 and gets his public/private key pairs corresponding to these indexes. From these public keys it generates a different kind of address, let's say secret_sharing_address, The user then encrypts each Shamir secret with other users accounts public keys.
encrypted_shamir_secret: encrypted_shamir_secret shared_with: other user account address is_live: False new_key: null updated_on: latest timestamp when this contract was changed updated_secret: False
for argument, Let's say these are the only keys present on accounts contract on Blockchain. Five transactions of this kind for five different users will be floated. Let's say the user forgets his/her password one day, he enters his email and a new password. (The ownership of email can be checked with OTP etc) Two things will be calculated from these details
The sha256 hash of the email. A new scrypt key from this new password.
This email hash will then be searched in the blockchain if a matching account with this same email hash can be found, The secret_shared key will be fetched(Which has public keys of corresponding secret_sharing_address). secret_sharing_address addresses will be generated from each of these public keys
Then on each address, the key
"is_live": True "new_key": Encrypted with corresponding public key (scrypt key)
Now since these are directed to different users, as soon as they will see is_live is active, they will decrypt their share of Shamir secret with their private key and also decrypt the scrypt key generated from the new password. They then encrypt this decrypted shamir secret with this decrypted scrypt key.
Each user will now again change the contract state and set these key
updated_on: Latest Timestamp updated_secret: share encypted with scrypt key
as soon as the threshold of three users will be reached, Our user will initiate a recover password process, which is
1.He again enter the new password. 2. Decrypts all the shared secrets present on at least three different secret_sharing_address 3. combine at least three secret shares and recovers original mnemonic 4. Encrypts this recovered Mnemonic with this scrypt key and store into the database.
- No association can be drawn from secret_sharing_addresses, so no user who is participating in this process can identify another user.
- No one user can recover the mnemonic alone.
- The Database administrator couldn't see the original mnemonic on the entire process.
Note: My limited encryption knowledge only took me this far, Please help me to refine this process. If this is totally junk, please let me know bluntly.