micro-bitcoin / uBitcoin

Bitcoin library for microcontrollers. Supports Arduino, mbed, bare metal.
https://micro-bitcoin.github.io/
MIT License
163 stars 34 forks source link

Mild wallet(New addition to wallets not hot not cold :)) #6

Closed he3117 closed 4 years ago

he3117 commented 4 years ago

I have an idea about a new type of hardware wallet that I call a mild wallet. The idea is to do signing on the hardware to prevent online hacking and store sensitive data like wallet seed on any location we want like online or on a computer or SD card to prevent hardware hacking. Creating online backups is easier than physical backups and in case of major events it's easier to restore your wallet backup if you store it in different servers.

Basic idea: Instead of storing seed in the hardware create it run time. in this way nothing stored on the hardware and it should be safe against hardware attacks. How to implement it?

1-we need a true random number generator.I'm thinking about this circuit

2-In wallet creation step create a new seed randomly or restore it from mnemonic words.

3-Create a 64-byte random number for salt.

4-Ask user to input a password.

5-Calculate sha512(sha512(password+salt)) and store it as unsigned char lookUpTable[64].

6-store result in a file with this structure: char magicNumber[4]; int version; unsigned char salt[64]; unsigned char buckets[64][256];

7-initially each bucket contains an array of 256 bytes from 0 to 255. we need to shuffle each bucket randomly and use lookup value from step 5 and change that location with the seed value. at the end each bucket contains a random array of bytes [0 -255] without any duplicate entry.

for(int bucket=0;bucket<64;++bucket) { for(int B=0;B<256;++B) { if(B==lookUpTable[bucket]) { WriteToFile(seed[bucket]); } else { WriteToFile(ARandomShuffledValue); } } } to restore seed value when user entere a password: 1-read salt value from the wallet file and calculate lookUpTable from step 5 2-Load seed value using lookUpTable and stored buckets in the file. for(int bucket=0;bucket<64;++bucket) { seed[bucket]=bucketsFromFile[bucket][lookupTable[bucket]]; }

3-Create private key from the restored seed.

Since we do not use any kind of encryption and only using shuffle technique, brute-forcing this file is the same as brute-forcing the seed and it's not practical so it should be safe to store the wallet file online or unencrypted on the SD card. Selecting a passphrase may have the same effect but I think this method is safer than using a passphrase. In case the user forgets the password he/she can restore the wallet from mnemonic words but if you forget your passphrase you can't restore your wallet. And if passphrase implementation changes in the future stored wallet should be compatible with all wallet software.

The user should select a strong password for this method to be safe enough. So any hardware implementation of this method should allow user to use all ASCII chars as input and number only pin codes are not safe. HW wallet should use a touch screen or another method to be easy enough to enter a long password. For the simpler design, I want to use 2 rotary encoders as inputs. one rotary will change the cursor position and another rotary encoder will loop in the char list to allow the user to quickly select char to input.

Please let me know what you think about this method.

stepansnigirev commented 4 years ago

Interesting approach. So the backup would be the salt and the password?

I think resistance against password brute force will be similar to bip39 - if I find out the salt and I know the algorithm I can try to perform a dictionary attack. Brute forcing passwords with a lookup table might be even easier than brute-forcing 2048 rounds of pbkdf2 used in bip39.

Sidenote: you can use rng module from esp32, it is not TRNG, but it takes noise from antennas and converts it to random numbers, so pretty decent rng for free. You can add your circuit as well.

he3117 commented 4 years ago

So the backup would be the salt and the password?

The backup file only contains salt and a shuffled seed table. Not storing any information about the password is the core security model of this method .

Salt used to prevent rainbow attacks and for the shuffle algorithm is used as RNG seed to change the shuffled table every time we create a new wallet even if we use the same password as before. a dictionary attack is possible but since we do not store any other data to check the integrity of the entered password, the result of entering any password is valid. The algorithm uses the result to create a new private key, there is no way an attacker knows which private key is the target. The downside of this approach is we can't warn the user if he/she entered an invalid password. We can only validate the password when we want to sign a TX. I thought more about this method and it seems we can simply use the AES algorithm to encrypt the 64byte seed since AES does not check the integrity of the decrypted message the result will be the same and any entered password will be valid. brute forcing 64-byte seed is not practical attacker should check 256^64 combination, if 2048 rounds of pbkdf2 are harder to break we can store the index of entered mnemonics instead of 64-byte seed but it seems checking the integrity of mnemonic words or words indexes are possible and it will be easier for an attacker to find the private key.

stepansnigirev commented 4 years ago

a dictionary attack is possible but since we do not store any other data to check the integrity of the entered password, the result of entering any password is valid.

For every key you can derive first address with common derivation path and check the transaction count on the blockchain - it gives you a feedback what key is correct.

but since we do not store any other data to check the integrity of the entered password, the result of entering any password is valid

For bip39 it is also the case - any password is correct

brute forcing 64-byte seed is not practical

Yes, that's true, but I thought the idea is to store the seed backup on an untrusted device (sd card, computer, cloud). From your first post:

The idea is to do signing on the hardware to prevent online hacking and store sensitive data like wallet seed on any location we want like online or on a computer or SD card to prevent hardware hacking.

I think your approach is clever, but I don't see security benefits compared to a widely adapted bip39.

he3117 commented 4 years ago

but I don't see security benefits compared to a widely adapted bip39.

I edited my post after you posted your comment but this is exactly the security benefit I'm looking for. I mean the hardware wallet does not contain any information to help the attacker to find the private key. If an attacker can brut-force a wallet by testing all seeds then he/she does not need the hardware wallet to hack your wallet in the first place. Another difference with bip39 is to store mnemonic seeds in bip39 you need to store or remember at least 12 words but in this method you need to remember only one password. To see the benefit of this method you can see how the trezor hardware hacked in this video. Trezor stores mnemonic words and the pin code of the device in the hardware and when an attacker finds a glitch in the system he can export all sensitive data he wants but if the information stored on the device is not usable then this kind of attacks are not possible to find the private key.

stepansnigirev commented 4 years ago

So you are replacing a mnemonic phrase with a seed and lookup table? BIP-39 supports passphrases with arbitrary characters of any length.

How is it different from storing a mnemonic phrase wherever you are planning to store the seed and lookup table?

he3117 commented 4 years ago

mnemonic words are known by all bitcoin hackers and when they find or brut force the password they can check the integrity of the result but when you store a lookup table or 64-byte seed checking the integrity of the result is not possible. As I said in the first post selecting a passphrases can have the same effect the only difference is to store this data if we use AES algorithm we only needs a few bytes and the result can even store in QR codes or we can use Steganography to store the seed in an arbitrary image or file to increase the security. If we use a passphrases the wallet file should store mnemonic words and this may raise a red alert for hackers.

ps:If we store the encrypt file as QR code then we can write a simple program on a mobile phone and send the QR code as a wallet to use and the user can easily print and store the wallet file. This can be intersting use case.

stepansnigirev commented 4 years ago

Ah, got it. Makes sense!

Please keep me updated on the progress - I definitely want to add this project to the list. And if you have any questions about the library - feel free to ask!