Skip to content

HW wallet design

valdok edited this page Jun 8, 2020 · 6 revisions

Beam vs other blockchains

Beam HW wallet supports the functionality similar to other blockchain protocols, such as keeping all the secret keys within the device, and signing transactions authorized by the users.

Since Beam is based in MW, the design of such a wallet is more complex, because of the following:

  • Transactions are built interactively
  • No addresses

Assumptions

  1. The HW wallet is a minimalistic stateless device. It should not handle blockchain events (blocks, headers, reorgs), handle BBS traffic, fully negotiate transactions, and etc.
  2. The host may be compromised, yet no spend should be possible without user's permission.
  3. Once the user activates the HW wallet (enters the pin-code), the host can view all the user information (balance, UTXOs), but not spend funds.
  4. Every spend (transaction that assumes user spends funds) needs a user authorization. The user sees the following:
    1. The amount being-sent
    2. Asset type (beam or CA).
    3. Recipient identifier.
    4. Transaction kernel ID.
    5. Height range (min/max height) during which the transaction is valid.
    • All this information is cryptographically verified, and there should be no feasible way for the host to tamper with it.

Note: Because in MW transactions are essentially (sort of) Schnorr's multisignatures, the (1) is actually tricky to implement. To create a Schnorr's signature the signer generates a nonce, which must be retained for the duration of the multi-signature ritual.

We solve this by assuming the device has a limited non-volatile memory that can be used to store nonce preimage (source material). We make sure that neither the nonce nor the appropriate secret key can be extracted by malicious host (such as attempt to use the same nonce to sign different things).

The HW wallet device should have several 256-bit slots for nonce preimages. The more slots it has - the more ongoing transactions the HW wallet may handle at the same time.

(There is also an option of using VRFs, but it's too complex for HW wallets.)

Terminology

  • CoinID - full UTXO identifier. Consists of the following:
    1. SubIdx 32-bit child key identifier
    2. Idx 64-bit coin number
    3. Value (64 bits)
    4. AssetID (32-bit number)
    • For each CoinID the HW wallet generates a unique blinding factor using the master secret.
  • OwnerKey - derived from the master secret, used to recognize the owned UTXOs.
  • PublicKeyGen - key generator which for a CoinID generates an appropriate public key (EC point) that corresponds to its blinding factor.

Note: the actual key generation is according to HKDF (rfc-5869). The generated blinding factor depends in a non-transparent way on all the fields of CoinID, thus there's no feasible way to tamper with them and adjust the resulting blinding factor accordingly.

In addition to HKDF, each computed key is multiplied by a fixed secret scalar, so-called co-factor. The PublicKeyGen contains the same seed HKDF data, but the co-factor is replaced by its image (EC point).

Functionality high-level

All the HW wallet functionality comes down to the following methods.

The following is returned without user permission

  • OwnerKey
  • PublicKeyGen for arbitrary child key
  • Rangeproof for arbitrary CoinID
  • signature for receive transaction (i.e. transaction in which no funds are lost).

The following needs user permission

  • signature for send transaction
  • signature for split transaction (i.e. only transaction fee is lost)
Clone this wiki locally