rmurray2 / arduino-coldwallet-sss

An arduino cold wallet implementing Shamir Secret Sharing

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

arduino-coldwallet-sss

An arduino cold ethereum wallet implementing Shamir Secret Sharing (SSS), intended for use on a Gnosis safe. This project basically glues various libraries together resulting in a do-it-yourself Arduino cold wallet that splits the private key using SSS. One out of the three SSS shares (the zero-index share) is continuously stored on EEPROM until a new wallet is created, and the private key is only written to EEPROM after wallet creation and private key recovery. After splitting and transaction hash signing, the private key is overwritten in EEPROM. By default, at least 2/3 shares are required to recover the private key

Workflow:

  1. A new cold wallet is created with create_wallet_mode.ino
  2. A Gnosis safe contract is created with a "hot" Metamask-generated wallet and the "cold" Arduino wallet as owners, where confirmations from both wallets are required to execute transactions. Native or non-native tokens are sent to the safe contract for storage
  3. The private key is split into three SSS shares with shamir_split_key_mode.ino. The user saves the "primary" share and the "backup" share. There is by default a two share minimum required to recover the secret.
  4. If tokens need to be sent out of the contract, the private key is recovered with shamir_recover_key_mode.ino by passing the "primary" SSS share via Serial communication. This writes the private key "above" the zeroth SSS share in EEPROM.
  5. The intended transaction hash is generated by either calling getTransactionHash on the safe contract or by using the helper script transact.py to get a hash of the transaction. To run the helper script, streamlit is required. It can be used by doing python3.8 -m streamlit run transact.py --server.headless true. Using the helper script makes the process much easier
  6. sign_signature_mode.ino is loaded onto the Arduino and the transaction hash is passed to it via Serial. The Arduino reveals the signed transaction hash.
  7. Now the goal is to call execTransaction on the safe contract with the "hot" Metamask wallet, providing the signature from the "cold" wallet. This can be accomplished by:
    1. Going to the safe contract's page on the appropriate blockchain explorer website (e.g. etherscan, etc) and connecting the hot Metamask wallet OR
    2. Submitting a regular send transaction to the safe contract with a value of zero and passing unique Hex data to call execTransaction
    3. Again, the helper script transact.py makes both of these options much easier, as additional data is added around the transaction hash signature that is required for execTransaction.

Arduino Dependencies:

https://github.com/BlockchainCommons/bc-crypto-base
https://github.com/BlockchainCommons/bc-shamir
https://github.com/firefly/wallet/tree/master/source/libs/ethers
https://github.com/gonzalobellino/ephemeralwallet/tree/master/arduino/libraries/entropy

Python Dependency:

https://pypi.org/project/streamlit/

Arduino modes

Due to memory limitations, the "cold" wallet part of this project has four Arduino sketch files, which put the microcontroller in a particular "mode". The four modes are:

  1. Private key generation: create_wallet_mode.ino

    The public wallet address is displayed. The private key is written to EEPROM. The private key can be displayed by uncommenting in the sketch, in case a separate encrypted backup is needed.

  2. Private key splitting into three Shamir Secret Sharing (SSS) shares: shamir_split_key_mode.ino

    The SSS share with index zero is written to EEPROM, overwriting the private key. The zero-index key isn't revealed to the user, and is always sitting in EEPROM for subsequent modes (until a new wallet is generated). The two remaining SSS shares are shown the user. One is the "primary" share, and one is a "backup". The cold wallet would be in this mode most of the time, only being called for private key recovery and transaction hash signing.

  3. Private key recovery: shamir_recover_key_mode.ino

    The user provides the primary SSS share, (e.g. <237b...f9fe>) and the private key is recovered and written to EEPROM. To use the backup share instead, line 179 would be changed to uint8_t recovery_share_indexes[2] = {0,2};

  4. Transaction hash signing: sign_signature_mode.ino

    The user provides a transaction hash to be signed (e.g. <3327...ac9fe>). Once the hash is signed the signature is displayed and the private key is cleared from EEPROM.

Notes

The cold wallet transaction hash signature needs to have 1b or 1c appended to the end, and I haven't figured out when to use which, so the helper script reports both. If the signature with 1b doesn't work, try the one with 1c.

The sketches and helper script come with no guarantees. I made this to help me understand how Gnosis safes and SSS and cold wallets work.

TODO

Add a pin number to encode SSS shares and temporary private key writing.

Figure out when to use 1b or 1c at the end of transactin hash signatures

About

An arduino cold wallet implementing Shamir Secret Sharing

License:The Unlicense


Languages

Language:C++ 63.0%Language:Python 37.0%