Return-Path: Received: from fraxinus.osuosl.org (smtp4.osuosl.org [140.211.166.137]) by lists.linuxfoundation.org (Postfix) with ESMTP id BE52AC0177 for ; Thu, 27 Feb 2020 03:00:28 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by fraxinus.osuosl.org (Postfix) with ESMTP id A4EF486C19 for ; Thu, 27 Feb 2020 03:00:28 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from fraxinus.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id vmhUcUVfe_QX for ; Thu, 27 Feb 2020 03:00:27 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mail-ot1-f41.google.com (mail-ot1-f41.google.com [209.85.210.41]) by fraxinus.osuosl.org (Postfix) with ESMTPS id 6899286511 for ; Thu, 27 Feb 2020 03:00:27 +0000 (UTC) Received: by mail-ot1-f41.google.com with SMTP id v19so1547054ote.8 for ; Wed, 26 Feb 2020 19:00:27 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:from:date:message-id:subject:to; bh=iVPUDCQpBCGg+jpioWKwBlxQLwfQLLWmi9eImnua8KE=; b=u+P+/dEktAfsUVwHM+Quu5AaYKpjGuk27cczSZQ/fodD4KGfm4h9nHpAa1iq99eIzy D3eUtsrsiMb6g+/KKOpNFfl2MrTOkbXFcIje+yArYiV8Nq48vu1+VxDd6NMwm20yVlKS aSJiP2qFZc2Y9ZXrMBBxOiBbH9P91n3pzN3KEyx1Vr74nsLQc27rX2G5vyoZb3R91oY0 4Tbcz9hHVObDdFoCI5c3d+61GivRwF/H1KfQYsviBQMxXuawt9M66dC2zAEEh24aEfhl g4BfUVXQC5lIdz/jZYIju/bK25Tpw9/y8RjUZ2ZCIFwUGghYsvEAAMb+k6+swEtsmNGW pbRA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:from:date:message-id:subject:to; bh=iVPUDCQpBCGg+jpioWKwBlxQLwfQLLWmi9eImnua8KE=; b=QjV4tbhO4JL8F6xh/2VKLnMeYAfj/XFBO2cSAgWr1jksP2zAWW4h2km6PPjKHS4dsr YeeEj4mWD2HGNHv+butqIvreuv/SWPbIDhF115X6Tzm9lEzOp9Z1xInidS+kR4tIagVl WzZro7hZzMsvJpe4paOWLU3Kyl9oS4wlnenWAuL8Qf0QkR78C22JEES1utV5BBx8itSi YcYWd/u3GxR0etW5+BkwcJX333hZzH8+N8hL/iH3k/2OdSfDgpR8jippQ6HIR65e9Us9 XHJWqGVWCsdYApsdjG4VnCH3xVodW6LGmp7Fa9n/ugA0pknkl+UFvpmJ5zRUv90EtBnC x/cA== X-Gm-Message-State: APjAAAWPyzE8fTo2PqEQjqhDzrayn/ERLI7B2ExfTSTtnoRaZfIIryTF A7ZnQ83Cf2Avj0+qULtPxpIKrEznxUuyuLgzvlBP2e4Hsjo= X-Google-Smtp-Source: APXvYqzUnxAjOGGU0jnJszUkXpONMpjlkuNjfLPbjVPCO3rIVkQ7Yya88l2OW4uAzwKA9EiAG/SMq9k7KeOC9oTbz1c= X-Received: by 2002:a05:6830:10c6:: with SMTP id z6mr1681363oto.203.1582772426100; Wed, 26 Feb 2020 19:00:26 -0800 (PST) MIME-Version: 1.0 From: Stepan Snigirev Date: Thu, 27 Feb 2020 03:59:46 +0100 Message-ID: To: bitcoin-dev@lists.linuxfoundation.org Content-Type: multipart/alternative; boundary="00000000000037d627059f85ecb6" X-Mailman-Approved-At: Thu, 27 Feb 2020 03:13:17 +0000 Subject: [bitcoin-dev] Nonce blinding protocol for hardware wallets and airgapped signers X-BeenThere: bitcoin-dev@lists.linuxfoundation.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: Bitcoin Protocol Discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 27 Feb 2020 03:00:28 -0000 --00000000000037d627059f85ecb6 Content-Type: text/plain; charset="UTF-8" This topic appeared in the list a few times so I would like to discuss it in more detail and maybe push forward to standardization. We have to accept that any hardware wallet or an air-gapped computer we use to sign transactions can be compromised. It may happen via a supply chain attack or malicious firmware update. If the signer is isolated (faraday cage, airgap and so on), it still can leak private keys to the outside world by choosing nonces for signatures in a funny way such that the attacker can calculate our private keys. Back in the days, I wrote a small post [1] and a proof-of-concept demo [2] of this attack. Deterministic nonce generation can be verified only if we have private keys somewhere else. It doubles the attack surface - now we need to maintain two independent signers from different vendors that use the same private key and the same deterministic algorithm for a nonce generation. In addition to that, as Pieter mentioned in the Schnorr-BIP, deterministic nonces are vulnerable to glitch attacks [3]. A simple way to fix it is by forcing the signer to use additional entropy from the host. This protocol takes away the privilege of picking nonce from the signer and doesn't require any secret material outside the signer. I suggest the following implementation of the protocol for signing a message `m`: 1. Host picks a random number `n` and sends its hash together with the message `m` to the signer. 2. Signer computes a nonce `k` it wants to use for signing. It can be either a deterministic scheme or using RNG. Signer commits to the chosen nonce by sending the corresponding point `R=kG` to the host. 3. Host sends the preimage `n` to the signer 4. Signer tweaks the nonce by this number `k'=k+n`, signs the message and sends back the signature (R',s) 5. Host verifies that the public point in the signature is tweaked by n: `R'==R+nG` ASCII-art: Host Untrusted signer 1. Pick random n --- sha256(n),m --> calculate nonce k 2. <------ R=kG ------ commit to k 3. Send preimage -------- n -------> sign with nonce k'=k+n 4. Verify R'==R+nG <------- sig ------ I believe this protocol solves the problem. A drawback of this scheme is that the number of communication rounds doubles, so it might be pretty inconvenient for air-gapped remotely located signers. I also suggest the following extensions that might be helpful for certain use-cases # Extensions ## Multiple hosts There are some use-cases where multiple hosts are involved in the setup and all hosts don't trust each other and the signer. So all of them want to give extra entropy to the signer and verify that it was included. At the moment I have exactly this scenario - our main MCU doesn't trust the proprietary closed-source secure element, and the computer doesn't trust the whole hardware wallet. We need a way to convince both of them that their entropy was used in the nonce. It can be solved by concatenating hashes and preimages: Host1 ------- h(n1) --> Host 2 -- h(n1) h(n2) --> Signer <--- R+n2 G ----- <------- R ------- ------- n1 -----> ------ n1 n2 ----> sign with k''=k+n1+n2 Ver: R''==R'+n1 G Ver: R''==R+n2 G + n1 G In this case, the first host doesn't even notice that the second host was also using this protocol and mixing in the entropy. And the signer only needs to add one extra number to the nonce. ## Stateless random signer If the signer wants to generate a nonce non-deterministically but doesn't have an ability to store a generated nonce it may send back to the host some meta-information that would help it to re-generate the same nonce later. It can be for example additional random data used in a deterministic scheme, either encrypted and authenticated or just as a plain text (I am more a fan of encrypted though). Generally, the host shouldn't care what this data is about - he just stores the data between rounds and sends it back to the signer with the next round. # Implementation for PSBT We can either use proprietary fields [4] or define key-value pairs and add them to the BIP-174. Depends if anyone else is interested in using this protocol or not. I would suggest the following key-value per-input pairs assuming multiple hosts want to mix in external entropy: 1. Key: {PSBT_IN_EXT_NONCE_HASH}|{pubkey}, Value: {sha256(n1)}|{sha256(n2)}|... 2. Key: {PSBT_IN_NONCE_COMMITMENT}|{pubkey}, Value: {33-byte R point} 3. Key: {PSBT_IN_NONCE_SIGNER_METADATA}|{pubkey}, Value: {anything} 4. Key: {PSBT_IN_EXT_NONCE_PREIMAGE}|{pubkey}, Value: {n1}|{n2}|... Then the signature from the signer is placed into existing PSBT_IN_PARTIAL_SIG. Combiner and Finaliser should verify that nonce in the signature includes external entropy and may remove their own entropy from the set. They should also verify that the values of the fields did not change between rounds. So, list, what do you think? Am I missing something? Would it be interesting to have this protocol standardized and deployed? # References [1] https://medium.com/cryptoadvance/hardware-wallets-can-be-hacked-but-this-is-fine-a6156bbd199 [2] https://github.com/stepansnigirev/chosen_nonce_demo/blob/master/HD_key.ipynb [3] https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki#alternative-signing [4] https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki#proprietary-use-type --00000000000037d627059f85ecb6 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
This topic appeared in the list a few times so I would lik= e to discuss it in more detail and maybe push forward to standardization.
We have to accept that any hardware wallet or an air-gapped computer = we use to sign transactions can be compromised. It may happen via a supply = chain attack or malicious firmware update.

If the signer is isolated= (faraday cage, airgap and so on), it still can leak private keys to the ou= tside world by choosing nonces for signatures in a funny way such that the = attacker can calculate our private keys. Back in the days, I wrote a small = post [1] and a proof-of-concept demo [2] of this attack.

Determinist= ic nonce generation can be verified only if we have private keys somewhere = else. It doubles the attack surface - now we need to maintain two independe= nt signers from different vendors that use the same private key and the sam= e deterministic algorithm for a nonce generation. In addition to that, as P= ieter mentioned in the Schnorr-BIP, deterministic nonces are vulnerable to = glitch attacks [3].

A simple way to fix it is by forcing the signer = to use additional entropy from the host. This protocol takes away the privi= lege of picking nonce from the signer and doesn't require any secret ma= terial outside the signer.

I suggest the following implementation of= the protocol for signing a message `m`:

1. Host picks a random numb= er `n` and sends its hash together with the message `m` to the signer.
2= . Signer computes a nonce `k` it wants to use for signing. It can be either= a deterministic scheme or using RNG. Signer commits to the chosen nonce by= sending the corresponding point `R=3DkG` to the host.
3. Host sends the= preimage `n` to the signer
4. Signer tweaks the nonce by this number `k= '=3Dk+n`, signs the message and sends back the signature (R',s)
= 5. Host verifies that the public point in the signature is tweaked by n: `R= '=3D=3DR+nG`

ASCII-art:

=C2=A0 =C2=A0Host =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0Untrusted signer
1. Pick random n =C2=A0 --- sha= 256(n),m --> =C2=A0calculate nonce k
2. =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 <------ R=3DkG ------ =C2=A0commit to k
3= . Send preimage =C2=A0 -------- n -------> =C2=A0sign with nonce k'= =3Dk+n
4. Verify R'=3D=3DR+nG <------- sig ------

I believ= e this protocol solves the problem. A drawback of this scheme is that the n= umber of communication rounds doubles, so it might be pretty inconvenient f= or air-gapped remotely located signers.

I also suggest the following= extensions that might be helpful for certain use-cases

# Extensions=

## Multiple hosts

There are some use-cases where multiple ho= sts are involved in the setup and all hosts don't trust each other and = the signer. So all of them want to give extra entropy to the signer and ver= ify that it was included. At the moment I have exactly this scenario - our = main MCU doesn't trust the proprietary closed-source secure element, an= d the computer doesn't trust the whole hardware wallet. We need a way t= o convince both of them that their entropy was used in the nonce.

It= can be solved by concatenating hashes and preimages:

Host1 ------- = h(n1) --> Host 2 -- h(n1) h(n2) --> Signer
=C2=A0 =C2=A0 =C2=A0 &l= t;--- R+n2 G ----- =C2=A0 =C2=A0 =C2=A0 =C2=A0<------- R -------
=C2= =A0 =C2=A0 =C2=A0 ------- n1 -----> =C2=A0 =C2=A0 =C2=A0 =C2=A0------ n1= n2 ----> sign with k''=3Dk+n1+n2
Ver: R''=3D=3DR'= ;+n1 G =C2=A0 =C2=A0 =C2=A0 Ver: R''=3D=3DR+n2 G + n1 G

In t= his case, the first host doesn't even notice that the second host was a= lso using this protocol and mixing in the entropy. And the signer only need= s to add one extra number to the nonce.

## Stateless random signer
If the signer wants to generate a nonce non-deterministically but doe= sn't have an ability to store a generated nonce it may send back to the= host some meta-information that would help it to re-generate the same nonc= e later. It can be for example additional random data used in a determinist= ic scheme, either encrypted and authenticated or just as a plain text (I am= more a fan of encrypted though).

Generally, the host shouldn't= care what this data is about - he just stores the data between rounds and = sends it back to the signer with the next round.

# Implementation fo= r PSBT

We can either use proprietary fields [4] or define key-value = pairs and add them to the BIP-174. Depends if anyone else is interested in = using this protocol or not.

I would suggest the following key-value = per-input pairs assuming multiple hosts want to mix in external entropy:
1. Key: {PSBT_IN_EXT_NONCE_HASH}|{pubkey}, Value: {sha256(n1)}|{sha256= (n2)}|...
2. Key: {PSBT_IN_NONCE_COMMITMENT}|{pubkey}, Value: {33-byte R= point}
3. Key: {PSBT_IN_NONCE_SIGNER_METADATA}|{pubkey}, Value: {anythi= ng}
4. Key: {PSBT_IN_EXT_NONCE_PREIMAGE}|{pubkey}, Value: {n1}|{n2}|...<= br>
Then the signature from the signer is placed into existing PSBT_IN_P= ARTIAL_SIG. Combiner and Finaliser should verify that nonce in the signatur= e includes external entropy and may remove their own entropy from the set. = They should also verify that the values of the fields did not change betwee= n rounds.

So, list, what do you think? Am I missing something? Would= it be interesting to have this protocol standardized and deployed?

= # References

[1] https://medium.com/cr= yptoadvance/hardware-wallets-can-be-hacked-but-this-is-fine-a6156bbd199=
[2] https://github.com/stepansnigirev/chosen_nonce_demo/b= lob/master/HD_key.ipynb
[3] https://github.com/b= itcoin/bips/blob/master/bip-0340.mediawiki#alternative-signing
[4] <= a href=3D"https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki#pr= oprietary-use-type">https://github.com/bitcoin/bips/blob/master/bip-0174.me= diawiki#proprietary-use-type
--00000000000037d627059f85ecb6--