From 87e31affba2906d0529aa5a1af24164bffc30172 Mon Sep 17 00:00:00 2001 From: "David A. Harding" Date: Sat, 7 Jun 2014 19:27:49 -0400 Subject: [PATCH] Add Subsection About Wallet Programs, Incl. Hardware Wallets Describe the essential functions of a wallet program and how multiple programs can work together to fulfill those functions, as in the case of a signing-only wallet. --- _includes/guide_wallets.md | 256 ++++++++++++++++++++++- _includes/references.md | 2 + img/dev/en-wallets-distributing-only.dot | 50 +++++ img/dev/en-wallets-distributing-only.png | Bin 0 -> 5998 bytes img/dev/en-wallets-distributing-only.svg | 131 ++++++++++++ img/dev/en-wallets-full-service.dot | 30 +++ img/dev/en-wallets-full-service.png | Bin 0 -> 3818 bytes img/dev/en-wallets-full-service.svg | 95 +++++++++ img/dev/en-wallets-signing-only.dot | 50 +++++ img/dev/en-wallets-signing-only.png | Bin 0 -> 6382 bytes img/dev/en-wallets-signing-only.svg | 131 ++++++++++++ 11 files changed, 737 insertions(+), 8 deletions(-) create mode 100644 img/dev/en-wallets-distributing-only.dot create mode 100644 img/dev/en-wallets-distributing-only.png create mode 100644 img/dev/en-wallets-distributing-only.svg create mode 100644 img/dev/en-wallets-full-service.dot create mode 100644 img/dev/en-wallets-full-service.png create mode 100644 img/dev/en-wallets-full-service.svg create mode 100644 img/dev/en-wallets-signing-only.dot create mode 100644 img/dev/en-wallets-signing-only.png create mode 100644 img/dev/en-wallets-signing-only.svg diff --git a/_includes/guide_wallets.md b/_includes/guide_wallets.md index de895156..f645443a 100644 --- a/_includes/guide_wallets.md +++ b/_includes/guide_wallets.md @@ -2,11 +2,251 @@ {% autocrossref %} -Bitcoin wallets at their core are a collection of private keys. These collections are stored digitally in a file, or can even be physically stored on pieces of paper. +A Bitcoin wallet can refer to either a wallet program or a wallet file. +Wallet programs create public keys to receive satoshis and use the +corresponding private keys to spend those satoshis. Wallet files +store private keys and (optionally) other information related to +transactions for the wallet program. + +Wallet programs and wallet files are addressed below in separate +subsections, and this document attempts to always make it clear whether +we're talking about wallet programs or wallet files. {% endautocrossref %} -### Private Key Formats +### Wallet Programs + +{% autocrossref %} + +Permitting receiving and spending of satoshis is the only essential +feature of wallet software---but a particular wallet program doesn't +need to do both things. Two wallet programs can work together, one +program distributing public keys in order to receive satoshis and +another program signing transactions spending those satoshis. + +Wallet programs also need to interact with the peer-to-peer network to +get information from the block chain and to broadcast new transactions. +However, the programs which distribute public keys or sign transactions +don't need to interact with the peer-to-peer network themselves. + +This leaves us with three necessary, but separable, parts of a wallet +system: a public key distribution program, a signing program, and a +networked program. In the subsections below, we will describe common +combinations of these parts. + +{% endautocrossref %} + +#### Full-Service Wallets + +{% autocrossref %} + +The simplest wallet is a program which performs all three functions: it +generates private keys, derives the corresponding public keys, helps +distribute those public keys as necessary, monitors for outputs spent to +those public keys, creates and signs transactions spending those +outputs, and broadcasts the signed transactions. + +![Full-Service Wallets](/img/dev/en-wallets-full-service.svg) + +As of this writing, almost all popular wallets can be used as +full-service wallets. + +The main advantage of full-service wallets is that they are easy to use. +A single program does everything the user needs to receive and spend +satoshis. + +The main disadvantage of full-service wallets is that they store the +private keys on a device connected to the Internet. The compromise of +such devices is a common occurrence, and an Internet connection makes it +easy to transmit private keys from a compromised device to an attacker. + +To help protect against theft, many wallet programs offer users the +option of encrypting the wallet files which contain the private keys. +This protects the private keys when they aren't being used, but it +cannot protect against an attack designed to capture the encryption +key or to read the decrypted keys from memory. + +{% endautocrossref %} + + +#### Signing-Only Wallets + +{% autocrossref %} + +To increase security, private keys can be generated and stored by a +separate wallet program operating in a more secure environment. These +signing-only wallets work in conjunction with a networked wallet which +interacts with the peer-to-peer network. + +Signing-only wallets programs typically use deterministic key creation +(described in a later subsection) to create parent private and public +keys which can create child private and public keys. + +![Signing-Only Wallets](/img/dev/en-wallets-signing-only.svg) + +When first run, the signing-only wallet creates a parent private key and +transfers the corresponding parent public key to the networked wallet. + +The networked wallet uses the parent public key to derive child public +keys, optionally helps distribute them, monitors for outputs spent to +those public keys, creates unsigned transactions spending those outputs, +and transfers the unsigned transactions to the signing-only wallet. + +Often, users are given a chance to review the unsigned transactions' details +(particularly the output details) using the signing-only wallet. + +After the optional review step, the offline wallet uses the parent +private key to derive the appropriate child private keys and signs the +transactions, giving the signed transactions back to the networked wallet. + +The networked wallet then broadcasts the signed transactions to the +peer-to-peer network. + +The following subsections describe the two most common variants of +signing-only wallets: offline wallets and hardware wallets. + +{% endautocrossref %} + +##### Offline Wallets + +{% autocrossref %} + +Several full-service wallets programs will also operate as two separate +wallets: one program instance acting as a signing-only wallet (often called an +"offline wallet") and the other program instance acting as the networked +wallet (often called an "online wallet" or "watching-only wallet"). + +The offline wallet is so named because it is intended to be run on a +device which does not connect to any network, greatly reducing the +number of attack vectors. If this is the case, it is usually up to the +user to handle all data transfer using removable media such as USB +drives. The user's workflow is something like: + +1. (Offline) Disable all network connections on a device and install the wallet + software. Start the wallet software in offline mode to create the + parent private and public keys. Copy the parent public key to + removable media. + +2. (Online) Install the wallet software on another device, this one + connected to the Internet, and import the parent public key from the + removable media. As you would with a full-service wallet, distribute + public keys to receive payment. When ready to spend satoshis, fill in + the output details and save the unsigned transaction generated by the + wallet to removable media. + +3. (Offline) Open the unsigned transaction in the offline instance, + review the output details to make sure they spend the correct + amount to the correct address. This prevents malware on the online + wallet from tricking the user into signing a transaction which pays + an attacker. After review, sign the transaction and save it to + removable media. + +4. (Online) Open the signed transaction in the online instance so it can + broadcast it to the peer-to-peer network. + +The primary advantage of offline wallets is their possibility for +greatly improved security over full-service wallets. As long as the +offline wallet is not compromised (or flawed) and the user reviews all outgoing +transactions before signing, the user's satoshis are safe even if the +online wallet is compromised. + +The primary disadvantage of offline wallets is hassle. For maximum +security, they require the user dedicate a device to only offline tasks. +The offline device must be booted up whenever funds are to be spent, and +the user must physically copy data from the online device to the offline +device and back. + +{% endautocrossref %} + + + +##### Hardware Wallets + +{% autocrossref %} + +Hardware wallets are devices dedicated to running a signing-only wallet. +Their dedication lets them eliminate many of the vulnerabilities +present in operating systems designed for general use, allowing them +to safely communicate directly with other devices so users don't need to +transfer data manually. The user's workflow is something like: + +1. (Hardware) Create parent private and public keys. Connect hardware + wallet to a networked device so it can get the parent public key. + +2. (Networked) As you would with a full-service wallet, distribute + public keys to receive payment. When ready to spend satoshis, fill in + the transaction details, connect the hardware wallet, and click + Spend. The networked wallet will automatically send the transaction + details to the hardware wallet. + +3. (Hardware) Review the transaction details on the hardware wallet's + screen. Some hardware wallets may prompt for a passphrase or PIN + number. The hardware wallet signs the transaction and uploads it to + the networked wallet. + +4. (Networked) The networked wallet receives the signed transaction from + the hardware wallet and broadcasts it to the network. + +The primary advantage of hardware wallets is their possibility for +greatly improved security over full-service wallets with much less +hassle than offline wallets. + +The primary disadvantage of hardware wallets is their hassle. Even +though the hassle is less than that of offline wallets, the user must +still purchase a hardware wallet device and carry it with them whenever +they need to make a transaction using the signing-only wallet. + +An additional (hopefully temporary) disadvantage is that, as of this +writing, very few popular wallet programs support hardware +wallets---although almost all popular wallet programs have announced +their intention to support at least one model of hardware wallet. + +{% endautocrossref %} + + + + +#### Distributing-Only Wallets + +{% autocrossref %} + +Wallet programs which run in difficult-to-secure environments, such as +webservers, can be designed to distribute public keys (including P2PKH +or P2SH addresses) and nothing more. There are two common ways to +design these minimalist wallets: + +![Distributing-Only Wallets](/img/dev/en-wallets-distributing-only.svg) + +* Pre-populate a database with a number of public keys or addresses, and + then distribute on request an output script or address using one of + the database entries. + +* Use a parent public key to create child public keys. To [avoid key + reuse][devguide avoiding key reuse], a method must be used to ensure the same public key isn't + distributed twice. This can be a database entry for each key + distributed or an incrementing pointer to the current child key + index number. + +Neither method adds a significant amount of overhead, especially if a +database is used anyway to associate each incoming payment with a +separate public key for payment tracking. See the [Payment +Processing][devguide payment processing] section for details. + +{% endautocrossref %} + + + +### Wallet Files + +{% autocrossref %} + +Bitcoin wallets at their core are a collection of private keys. These +collections are stored digitally in a file, or can even be physically +stored on pieces of paper. + +{% endautocrossref %} + +#### Private Key Formats {% autocrossref %} @@ -16,7 +256,7 @@ Private keys are what are used to unlock satoshis from a particular address. In {% endautocrossref %} -#### Wallet Import Format (WIF) +##### Wallet Import Format (WIF) {% autocrossref %} @@ -40,7 +280,7 @@ The process is easily reversible, using the Base58 decoding function, and removi {% endautocrossref %} -#### Mini Private Key Format +##### Mini Private Key Format {% autocrossref %} @@ -62,7 +302,7 @@ address utility]. {% endautocrossref %} -### Hierarchical Deterministic Key Creation +#### Hierarchical Deterministic Key Creation + + + +wallet_program + +cluster_distributing + +Distributing-Only Wallet + +cluster_networked + +       Other Wallet(s) + + + +distributing_pub + +Derive +Child +Public +Keys + + + +distributing_distribute + +Distribute +Public +Keys + + + +distributing_pub->distributing_distribute + + + + + + +networked_monitor + +Monitor +For +Outputs + + +distributing_distribute->networked_monitor + + + + + + + + + + +networked_priv + +Create +Parent +Private +Key + + +networked_pub + +Derive +Parent +Public +Key + + +networked_priv->networked_pub + + + + + +networked_pub->distributing_pub + + + + + + + +networked_create + +Create +Unsigned +Txes + + +networked_monitor->networked_create + + + + + +networked_sign + +Sign +Txes + + + +networked_create->networked_sign + + + + +networked_broadcast + +Broadcast +Txes + + + +networked_sign->networked_broadcast + + + + + diff --git a/img/dev/en-wallets-full-service.dot b/img/dev/en-wallets-full-service.dot new file mode 100644 index 00000000..bfad5bbd --- /dev/null +++ b/img/dev/en-wallets-full-service.dot @@ -0,0 +1,30 @@ +digraph wallet_program { +size="6.25"; +rankdir=LR; +//ratio=fill; +splines=true; +fontname=Sans +ranksep=0.3; +penwidth=1.75; + +overlap = false; + +edge [ fontname=Sans, penwidth=1.75, style = "invis" ]; +node [ fontname=Sans, shape = box, penwidth=1.75 ]; + +subgraph cluster_networked { + penwidth=0; + networked_priv [ label = "Create\nPrivate\nKeys" ]; + networked_pub [ label = "Derive\nPublic\nKeys" ]; + networked_distribute [ label = "Distribute\nPublic\nKeys" ]; + networked_monitor [ label = "Monitor\nFor\nOutputs" ]; + networked_create [ label = "Create\nUnsigned\nTxes" ]; + networked_sign [ label = "Sign\nTxes" ]; + networked_broadcast [ label = "Broadcast\nTxes" ]; + + networked_priv -> networked_pub -> networked_distribute -> networked_monitor -> networked_create -> networked_sign -> networked_broadcast [ style = "" ]; + label = " \nFull-Service Wallet" +} + +} + diff --git a/img/dev/en-wallets-full-service.png b/img/dev/en-wallets-full-service.png new file mode 100644 index 0000000000000000000000000000000000000000..afa2a6ebb0db0a5799ac2c3613ae1e60cddd6af7 GIT binary patch literal 3818 zcmb7Hc{r4B7q*OT2BA#WDM_}mCS{LkLLtm}v(%f)zAqCQ+lVY>H>40!mPxO&gfJtL zAzP6pD#chL`x?IK>-T+sf8Rgv^PcBA*SXJq&V4=CIdK+d7#_F?oQa8v$M~F~B@+`1 z!1yO{GCoYn&r`S<2aBUA#*k_6PEuzR6BBQtv7x?o(C}Oi!pFK_xXm0zIpUkfGlWh$ zoeVqj2wREd=Qo6*6*y&zuQ>js!i!`maAV~vA)1uc_-V6cT z4`pz2#(|QDZzm^H!WxqN=W}1K&yV`gkDdEW*b`12tzX|=|5>ZorL)~VCB?Ci5gMTc>r3CQD`hQ*enYSYX?6qLCb}I#e8mT^CF%5P1 zE=!MM>7g(m)sOIn-px455l-CG&|Wbvn=c{I#ONihB z7lEF$|H>DQ2SX|du?o#mu?}W()I_MicPYoIb-m#^$HO7am$SHhb`mCYi~6_BR`eZ| z#+X9aR--Q|smvA{btYaq4CD}696ynj=!wizxfvP8s*x_4R7q;g9$QjY2z&Ob&Qw&L z2+^*IBh#Zp=kb@#Pp|kSE^(usBEi7AgW@iIW9$NUx;|u%(?hv~i6?cJS1zn{9lq95 zuur7U>2s*E_vd~0Mx>gw0%rKG;sc&@!^%E1OkGSuebF(3xi8hf=UINv1gMA6+moE{ zKRC&adYyu*a{1{zES8|_GKF2T2}=7-eKk6}O6qn3z}|*tEq-#>T0xl-&w)J?Seaiy z%>wtF_}DbPYYx9F;_n|oiICALUEM9{v0QtU|Mv4)7w#Noujfj$eR~=Rbls;^ZGuhg zKk@+c|0;+fmcI&O=;^P57<$@745YA)tx7-G2|?xH1|OCpH%goy>`|>1ZjF`MT#<%&86MLxT!y#Ot$az~`QslN9sl+apc+7YXc&TVd^8i# zhcr(Cvr1F8OLm)Sbate~P^gnv+6@X1IcvW!B=OZcTb~EL^kR4U!uX(VssIqLlPyI4 z5Fc+agHp6)EtC6w>)M=xZY0~YdL(^kSchU}44j7TO&-y`XIw~1jZLC8AfV@-`}nizHX`v<}dj}cT?1?8*}E#Pm+1PQM+=2=7an|H68kh4XJSWAdo zdI#4;U#sx^Xt7?{Ia}U#eA9yCo5gB!1#9D2dyjftR=rV!u_qte(30o?6T~wPF!dJVz=b_5U z0x@YrYc4mGUY>xx;&;cyVV5P}4D>w)smT%-!&=5Ew67R+e|x=K5}pr=?FO+%18M_f zH2mL)F9+DJpd^I>&#Hvw8oxH^rIEWACvF~8kskdPBQ7n!o%Jj(@p0E-47x z&1P~SHM8v;>DrCe+}fPwiZ0|cMjdMDK&SCdzyT?=n>ds$1egoP%)3;$g$eD0ul0c^ zy5kHd)exYt*Kd5km}wDaf|4rpaE2F2sfa!po(6u)3($01Qatscxn!%vL$*6f+lWjs z6hXUiLwvW-%2qy_Y0sO)wky+7Jt5(7;y~iSss*k3NSD2xN-x%64CCyE-#)oV{oUhJ3~@l~|{o4K}0S;R9(7F-?Sx z^HKfE;pv{C2~g)5V1gQ%fl*yXc#XInsyN#!q` z549 zRqh#5F}k&LI#>IHYtOy7Nx(_e=uZl?sKA5Ec@E$PhZ12hG_kc$Jgn$0C+-`;RAWox zJ~ixvIHiCqO^~fs%DnQ-CBpT!vw9u1cfJwuO~R$&w-W*6Ct)QS=~L5*$Ae{I&@*p- zQZQ$k_N`V@X|Crk{CcWe+vdIsB!fRo^PMpaJNoJ2K-v*+=@570+k(f{tx#yw`)nVZ zL@&*&JF)@pg>e*k>-l=CZtkVJO|Tl@ekaZ0RgCRL3;QKQt@KumllOJIF6NHldm?~? zLIQR2`Q37T%a9mqf!^Rv+Cqo+Z7iy}C^;Dwy#JG~z{xh2c~OtfR)qs({r;}B^=n(3 z@R(!eI~STYNKvwE?iPW4?IBgXIOUtPm}m2u2JS7X_g~Z9a-Am}s%NAICM`p=ffHG? z=a0jWRR4%mD9T?<*|99vpkH2V%NWaiuU%q=?b&Y3rgv||8ihl@(!XW?p?(VT^J_kn zrvv7_W?kn|pBzWRN%zxEMP#H|DSHg**R9EdFqy^_WBdB`yZA z9{lMSFM8Liy^;F%PtR5T1vnrRRB2$6=)?1}KtaiI;EmkOjdAwu`FD{gu6tDtP7bu0 zuoflN_~y8t)o&qb_wwFYyr>P(cMIO;pNyr&uKpbCztBF;-d8S(+%={@Fd559mChJb zHXHBvX7f~NFVfy2kU&#|Fx&cJ3zd}Pm8o$O3|<#cY(+>tB!zVl-k>45~XKbRu&ay+wU zi7PqxKUc1lVQYNp95Lw`rMdICC38oA&pv3y0na@&g#c17n}EhO<^trvH+8&a=eH&w zFdlpj=~Pzt&b$-IW44jejL91N{5d-n6q4%B$JAba_{5seEHOuW?gcQAqoir`mds-H{8?U_G#mtwW=Tk;- z6s?uM$RV#NZSr}%l1=`5C^UYzd#lD^)6M7niR+ZqWlPqMm2{U!2Y|CiS)>Ra@}OMa z;MsX&ZF_j@LmA(M4@h$6_Izxs@TVPJTRe-H6^}6V{q^`6y;eGxbgU%Lsi+V3uCo zI*mY*=Qks(3?`RU!dV%4{TLIZ1(h_)e`J8junkl%)D>oY^JH?Y6{)6S1{rXgfUm~I zapY4KU?H=Iz1qO(Ldq_e*i-8>s%@zYmR%KU=I6#v*NV;F%Xf$=@Au}Ma2u36bX9Ww z=nU98VHjukb5PWIqFAPbpN!JjEv{E;-(K4OZ929;xM(F@&6m~6cr4Ax{ENp@<0jrn z$FXKKpgw#{Ef8u%+0#VOl|I5(+ckN@$^|>qI%&)4})lbC> Q|5;* + + + + + +wallet_program + +cluster_networked + + +Full-Service Wallet + + +networked_priv + +Create +Private +Keys + + +networked_pub + +Derive +Public +Keys + + +networked_priv->networked_pub + + + + +networked_distribute + +Distribute +Public +Keys + + +networked_pub->networked_distribute + + + + +networked_monitor + +Monitor +For +Outputs + + +networked_distribute->networked_monitor + + + + +networked_create + +Create +Unsigned +Txes + + +networked_monitor->networked_create + + + + +networked_sign + +Sign +Txes + + +networked_create->networked_sign + + + + +networked_broadcast + +Broadcast +Txes + + +networked_sign->networked_broadcast + + + + + diff --git a/img/dev/en-wallets-signing-only.dot b/img/dev/en-wallets-signing-only.dot new file mode 100644 index 00000000..166480d1 --- /dev/null +++ b/img/dev/en-wallets-signing-only.dot @@ -0,0 +1,50 @@ +digraph wallet_program { +size="6.25"; +rankdir=LR; +//ratio=fill; +splines=true; +fontname=Sans +ranksep=0.3; +penwidth=1.75; + +overlap = false; + +edge [ fontname=Sans, penwidth=1.75, style = "invis" ]; +node [ fontname=Sans, shape = box, penwidth=1.75 ]; + +subgraph cluster_signing { + penwidth=0; + + signing_priv [ label = "Create\nParent\nPrivate\nKey" ]; + signing_pub [ label = "Derive\nParent\nPublic\nKey" ]; + signing_distribute [ label = "Distribute\nPublic\nKeys", style="invis" ]; + signing_monitor [ label = "Monitor\nFor\nOutputs", style="invis" ]; + signing_create [ label = "Create\nUnsigned\nTxes", style="invis" ]; + signing_sign [ label = "Sign\nTxes" ]; + signing_broadcast [ label = "Broadcast\nTxes", style="invis" ]; + + signing_priv -> signing_pub -> signing_distribute -> signing_monitor -> signing_create -> signing_sign -> signing_broadcast; + label = "Signing-Only Wallet" +} + +subgraph cluster_networked { + penwidth=0; + + networked_priv [ label = "Create\nPrivate\nKeys", style="invis" ]; + networked_pub [ label = "Derive\nChild\nPublic\nKeys" ]; + networked_distribute [ label = "Distribute\nPublic\nKeys" ]; + networked_monitor [ label = "Monitor\nFor\nOutputs" ]; + networked_create [ label = "Create\nUnsigned\nTxes" ]; + networked_sign [ label = "Sign\nTxes", style="invis" ]; + networked_broadcast [ label = "Broadcast\nTxes" ]; + + networked_priv -> networked_pub -> networked_distribute -> networked_monitor -> networked_create -> networked_sign -> networked_broadcast; + label = "Networked Wallet" +} + +signing_priv -> signing_pub [style=""]; +signing_pub -> networked_pub [ constraint = false, style = ""]; +networked_pub -> networked_distribute -> networked_monitor -> networked_create -> signing_sign -> networked_broadcast [style=""]; + +} + diff --git a/img/dev/en-wallets-signing-only.png b/img/dev/en-wallets-signing-only.png new file mode 100644 index 0000000000000000000000000000000000000000..0bbf4246dbf1dff7be7e8f17fd21c22d7dc034bb GIT binary patch literal 6382 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 + + + + + +wallet_program + +cluster_signing + +Signing-Only Wallet + +cluster_networked + +Networked Wallet + + +signing_priv + +Create +Parent +Private +Key + + +signing_pub + +Derive +Parent +Public +Key + + + +signing_priv->signing_pub + + + + + + +networked_pub + +Derive +Child +Public +Keys + + +signing_pub->networked_pub + + + + + + + + +signing_sign + +Sign +Txes + + + + + +networked_broadcast + +Broadcast +Txes + + +signing_sign->networked_broadcast + + + + + + +networked_distribute + +Distribute +Public +Keys + + +networked_pub->networked_distribute + + + + + +networked_monitor + +Monitor +For +Outputs + + +networked_distribute->networked_monitor + + + + + +networked_create + +Create +Unsigned +Txes + + +networked_monitor->networked_create + + + + + +networked_create->signing_sign + + + + + + + +