Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/plb500/picowallet

Code for an HD Wallet implementation on the Raspberry Pico
https://github.com/plb500/picowallet

bip44 bitcoin crypto cryptocurrency embedded hardware pi pico raspberry wallet

Last synced: 17 days ago
JSON representation

Code for an HD Wallet implementation on the Raspberry Pico

Awesome Lists containing this project

README

        

# PicoWallet

A hardware-based BIP44 HD (Hierarchical Deterministic) cold wallet implementation on the Raspberry Pico microcontroller using the Pico C SDK and a handful of other open source crypto libraries.

PicoWallet is capable of generating a full hierarchy of derived keys either from scratch (using the Pico's on board entropy sources to generate a new seed) or by hard-coding a seed.

Wallet recovery is also supported using a 24-word mnemonic seed (a seed is also generated and viewable when creating a new wallet)

Generates QR codes for viewing and importing both public and private keys





### Parts list
- Raspberry Pico microntroller (I have only used the RP2040-based Pico, but the newer RP2350 Pico 2 should also work)
- SD card hardware (I used Adafruit's [SPI SD card breakout](https://www.adafruit.com/product/4682))
- [Waveshare 1.44" SPI LCD](https://www.waveshare.com/wiki/Pico-LCD-1.44)
- Some way of wiring everything together (e.g. soldering directly or a carrier board)

### Wiring
The Waveshare LCD uses 10 pins in total and SPI port 1 on the Raspberry Pico. I am using GP4, GP5, GP6 and GP7 for the SD breakout on SPI 0. Currently card detect is not configured but it shouldn't be too difficult to add later.

Mappings are as follows:
- **`GP4`** -> MISO/SO
- **`GP7`** -> MOSI/SI
- **`GP6`** -> CLK
- **`GP5`** -> CS/SS

![Wiring diagram](/images/wiring.png)

### Building
PicoWallet uses the Raspberry Pico C SDK. Ensure that the SDK is setup and able to build example projects as per the instructions in the [Getting Started](https://datasheets.raspberrypi.com/pico/getting-started-with-pico.pdf) guide.

Once the SDK is configured and **`PICO_SDK`** is added to your environment variables, the project can be built from command line by navigating to the project root and running the following commands:
```
mkdir build
cd build
cmake ..
make
```
This will result in a `PicoWallet.uf2` file being built in the `build` directory. Hold down the BOOTSEL button on the Pico and plug it into your build machine and transfer this file across to flash the Pico.

### How it works
- On boot the PicoWallet looks for a `wallet.dat` file located in a folder called `PicoWallet` at the root of the connected SD card. This is the file generated by PicoWallet when creating a new wallet from scratch and is AES-encrypted using a user-supplied passcode, hashed with a salt (see below) which is randomly generated at compile time.
- If `wallet.dat` is found, the user is prompted to enter the passcode to unlock/decrypt the wallet contents
- If `wallet.dat` is not found, PicoWallet looks for a file called `mnemonic.txt` in the `PicoWallet` folder. This is a plain text file containing the 24-word BIP39 mnemonic recovery phrase.
- If `mnemonic.txt` is found, PicoWallet validates the file contents and recovery phrase checksum and if everything is valid, recovers the wallet contents.
- If `mnemonic.txt` is not found, or is found to contain invalid contents, PicoWallet will create a new wallet from scratch, prompting the user for a new passcode with which to encrypt the `wallet.dat` file containing the newly created wallet keys.
- At this point the loaded/recovered/created wallet is now ready for use. The user can select different values in the hierarchy and display either the public address (P2PKH) or the private key (WIF) for each level in the hierarchy via a QR code.

### How secure is the wallet.dat file?
As mentioned, the wallet.dat file is encrypted using 256-bit AES encryption. The encryption key is based on an 8-character user passcode, which is then passed through PBKDF2-SHA256 using a 128-bit salt. The salt is randomly generated at each build time (see [here](https://github.com/plb500/PicoWallet/blob/6949b9bed690f4b4bf7d65f71c7ce82fd0fe8ebb/pico/CMakeLists.txt#L14)). It is only known to your build machine, at the moment you are compiling the executable. Nothing else has access to the generated salt.

**Things to note**
- CMake will keep a record of the salt used when compiling the source in its cache, so when building make sure to wipe your build folder after programming. The salt will also technically be stored somewhere in the compiled ELFs/binaries, so also make sure to delete those after programming the Pico for maximum security.
- After deleting the uf2/binaries, you will only be able to decrypt the wallet contents using the executable flashed to the Pico. Building the source again and reflashing the Pico will result in a different salt, meaning even the correct passcode will not be able to decrypt the contents. After reflashing the only way to get back your original wallet is by using the recovery phrase.
- For debugging purposes, a hard-coded seed is available when building the firmware. When compiling your own build make sure you set **`USE_DEBUG_ENTROPY`** to **0** in CMakeLists.txt (see [here](https://github.com/plb500/PicoWallet/blob/6949b9bed690f4b4bf7d65f71c7ce82fd0fe8ebb/pico/CMakeLists.txt#L84))