-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathblockchain_tools.w
7674 lines (6451 loc) · 271 KB
/
blockchain_tools.w
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
\documentclass{report}
% ****** TURN OFF HARDWARE TABS BEFORE EDITING THIS DOCUMENT ******
%
% Should you ignore this admonition, tabs in the program code will
% not be respected in the LaTeX-generated program document.
% If that should occur, simply pass this file through
% expand to replace the tabs with sequences of spaces.
% This document MUST be edited with a utility that understands
% and displays Unicode characters in the UTF-8 encoding.
% This program is written using the Nuweb Literate Programming
% tool:
%
% http://sourceforge.net/projects/nuweb/
%
% For information about Literate Programming, please visit the
% site: http://www.literateprogramming.com/
\setlength{\oddsidemargin}{0cm}
\setlength{\evensidemargin}{0cm}
\setlength{\topmargin}{0cm}
\addtolength{\topmargin}{-\headheight}
\addtolength{\topmargin}{-\headsep}
\setlength{\textheight}{22.5cm}
\setlength{\textwidth}{16.5cm}
\setlength{\marginparwidth}{1.25cm}
\setcounter{tocdepth}{6}
\setcounter{secnumdepth}{6}
\newcommand{\dense}{\setlength{\itemsep}{-1ex}}
\newcommand{\expunge}[2]{}
\newcommand{\impunge}[2]{}
\let\cleardoublepage\clearpage
% Space between paragraphs, don't indent
\usepackage[parfill]{parskip}
% Keep section numbers from colliding with title in TOC
\usepackage{tocloft}
\cftsetindents{subsection}{4em}{4em}
\cftsetindents{subsubsection}{6em}{5em}
% Enable PDF output and hyperlinks within PDF files
\usepackage[unicode=true,pdftitle={Fourmilab @<Project Title@>},pdfauthor={John Walker},colorlinks=true,linkcolor=blue,urlcolor=blue]{hyperref}
% Enable inclusion of graphics files
\usepackage{graphicx}
% Enable proper support for appendices
\usepackage[toc,titletoc,title]{appendix}
% Support text wrapping around figures
\usepackage{wrapfig}
% Add additional math notation, including \floor and \ceil
\usepackage{mathtools}
\expunge{begin}{userguide}
\title{\bf Fourmilab @<Project Title@>}
\expunge{end}{userguide}
\impunge{userguide}{\title{\bf Fourmilab @<Project Title@>\\ User Guide}}
\author{
by \href{http://www.fourmilab.ch/}{John Walker}
}
\date{
Version @<Project Version@> \\
November 2021 \\
\vspace{12ex}
\includegraphics[width=3cm]{figures/fourlogo_640.png} \\
\vspace{2cm}
\includegraphics[width=4cm]{figures/eth_btc.png} \\
\vspace{\fill}
{\small
Build @<Build number@> --- @<Build date and time@> UTC
}
}
\begin{document}
\pagenumbering{roman}
\maketitle
\tableofcontents
\clearpage
\pagenumbering{arabic}
\expunge{begin}{userguide}
\chapter{Introduction}
This collection of programs and utilities provides a set of tools for
advanced users, explorers, and researchers of the Bitcoin and Ethereum
blockchains. Some of the tools are self-contained, while others require
access to a system (either local or remote) which runs a ``full node''
using the \href{https://bitcoin.org/en/bitcoin-core/}{Bitcoin Core}
software and maintains a complete copy of the up-to-date Bitcoin
blockchain. In order to use the \hyperref[UG:AW]{Address Watcher}, the
node must maintain a transaction index, which is enabled by setting
``{\tt txindex=1}'' in its {\tt bitcoin.conf} file.
Some utilities (for example, the Bitcoin and Ethereum address generator
and paper wallet tools) do not require access to a Bitcoin node and
others may be able to be used on nodes which have ``pruned'' the
blockchain to include only more recent blocks.
@d Project Title @{Blockchain Tools@}
@d Project Version @{1.0.5@}
@d Project File Name @{blockchain_tools@}
% The following allows disabling the build number and date and
% time inclusion in programs during periods of active development.
% The build number continues to be incremented as a record, but
% we embed zero values here to avoid having files which are not
% otherwise changed be updated by Nuweb. Such unnecessary updates
% would generate a large number of meaningless Git transactions which
% would only confuse the record of genuine changes to the code.
%
% When it's time to go into production, re-enable the include of
% build.w to restore the build number configuration control
% facility.
%
@i build.w
%d Build number @{0@}
%d Build date and time @{1900-01-01 00:00@}
\section{Configuration}
Include the configuration from {\tt configuration.w}.
@i configuration.w
\section{Host System Properties}
These path names to the Perl and Python interpreters are embedded in
programs in the respective languages so they may be invoked directly
from the command line. If these are incorrect, you can still run
the programs by explicitly calling the correct interpreter. Due to
incompatibilities, many systems have both Python versions 2 and 3
installed. If this is the case, be sure you specify the path to
Python version 3 or greater below.
@d Perl directory @{/usr/bin/perl@}
@d Python directory @{/usr/bin/python3@}
\expunge{end}{userguide}
\chapter{User Guide}
\section{Overview}
Fourmilab @<Project Title@> provide a variety of utilities for users,
experimenters, and researchers working with blockchain-based
cryptocurrencies such as Bitcoin and Ethereum. These are divided
into two main categories.
\subsection{Bitcoin and Ethereum Address Tools}
These programs assist in generating, analysing, archiving,
protecting, and monitoring addresses on the Bitcoin and
Ethereum blockchains. They do not require you to run a local
node or maintain a copy of the blockchain, and all
security-related functions may be performed on an ``air-gapped''
machine with no connection to the Internet or any other computer.
\begin{itemize}
\item \hyperref[UG:BAG]{Blockchain Address Generator} creates
address and private key pairs for both the Bitcoin
and Ethereum blockchains, supporting a variety of
random generators, address types, and output formats.
\item \hyperref[UG:MKM]{Multiple Key Manager} allows you to
split the secret keys associated with addresses into
$n$ multiple parts, from which any $k\leq n$ can be used
to reconstruct the original key, allowing a variety of
secure custodial strategies.
\item \hyperref[UG:PWU]{Paper Wallet Utilities} includes a
\hyperref[UG:PWg]{Paper Wallet Generator} which transforms
a list of addresses and private keys generated by the
Blockchain Address Generator or parts of keys produced by
the Multiple Key Manager into a HTML file which may be
printed for off-line ``cold storage'', and a
\hyperref[UG:PWv]{Cold Storage Wallet Validator} that
provides independent verification of the correctness of
off-line copies of addresses and keys.
\item \hyperref[UG:CSM]{Cold Storage Monitor} connects to free
blockchain query services to allow periodic monitoring of a
list of cold storage addresses to detect unauthorised
transactions which may indicate that they have been
compromised.
\end{itemize}
\subsection{Bitcoin Blockchain Analysis Tools}
This collection of tools allows various kinds of monitoring and
analysis of the Bitcoin blockchain. It does not support Ethereum.
These programs are intended for advanced, technically-oriented users
who run their own full Bitcoin Core node on a local computer. Note
that anybody can run a Bitcoin node as long as they have a computer
with the modest CPU and memory capacity required, plus the very large
(and inexorably growing) file storage capacity to archive the entire
Bitcoin blockchain. You can run a Bitcoin node without being a
``miner'', or exposing your computer to external accesses from
other nodes unless you so wish.
These tools are all read-only monitoring and analysis utilities.
They do not generate transactions of any kind, nor do they require
unlocked access to the node owner's wallet.
\begin{itemize}
\item \hyperref[UG:AW]{Address Watch} monitors the
Bitcoin blockchain and reports any transactions which
reference addresses on a ``watch list'', either deposits to
the address or spending of funds from it. The program
may also be used to watch activity on the blockchain,
reporting statistics on blocks as they are mined and
published.
\item \hyperref[UG:CW]{Confirmation Watch} examines blocks
as they are mined and reports confirmations for a transaction
as they arrive.
\item \hyperref[UG:TFW]{Transaction Fee Watch} analyses the
transaction fees paid to include transactions in blocks
and the reward to miners, producing real-time statistics
and log files which may be used to analyse transaction fees
over time.
\end{itemize}
\section{Blockchain Address Generator}
\label{UG:BAG}
The Blockchain Address Generator, with program name @<BA@>, is a
stand-alone tool for generating addresses and private keys for
both the Bitcoin and Ethereum blockchains. This program does not
require access to a Bitcoin node and may be run on an ``air gapped''
machine without access to the Internet. This permits generating
keys and addresses for offline cold storage of funds (for example,
in paper wallets kept in secure locations) without the risk of
having private keys compromised by spyware installed on the
generating machine.
The Address Generator may be run from the command line (including
being launched by another program) or interactively, where the user
enters commands from the keyboard. The commands used in both modes
of operation are identical.
\subsection{Architecture}
The address generator is not a single-purpose utility, but rather more
of a toolkit which can be used in a variety of ways to meet your
requirements. The program is implemented as a ``stack machine'',
somewhat like the FORTH or PostScript languages. Its stack stores
``seeds'', which are 256-bit integers represented as 64 hexadecimal
digits, ``{\tt 0}'' to ``{\tt F}'' (when specifying seeds in
hexadecimal, upper or lower case letters may be used interchangeably).
Specifications on the command line are not options in the usual sense,
but rather commands that perform operations on the stack. When in
interactive mode, the same commands may be entered from the keyboard,
without the leading ``{\tt -}'', and perform identically.
Here are some sample commands which illustrate operations you can
perform.
\begin{description}
\item[{\tt @<BA@> -urandom -btc}]~\\
Obtain a seed from the system's fast (non-blocking) entropy
source and generate a Bitcoin key/address pair from it,
printing the results on the console.
\item[{\tt @<BA@> -repeat 10 -pseudo -format CSV -eth}]~\\
Generate 10 seeds using the program's built-in Mersenne Twister
pseudorandom generator (seeded with entropy from the system's
fast entropy source), then create Ethereum key/address pairs
for each and write as a Comma-Separated Value (CSV) file
intended, for example, as offline ``paper wallet'' cold
storage.
\item[{\tt @<BA@> -repeat 16 -hbapik MyApiKey -hotbits -shuffle
-repeat 1 -xor -test -btc}]~\\
Request 16 seeds from Fourmilab's
\href{https://www.fourmilab.ch/hotbits/}{HotBits} radioactive
random number generator (requires Internet connection), shuffle
the bytes among the 16 seeds, exclusive-or the two top seeds
together, perform a randomness test on the result using
Fourmilab's
\href{https://www.fourmilab.ch/random/}{random sequence tester},
then use the seed to generate a Bitcoin key/address
pair.
\end{description}
\subsection{Commands}
\begin{description}
\item[{\tt -aes}] ~\\
Encrypt the second item on the stack with the
\href{https://en.wikipedia.org/wiki/Advanced_Encryption_Standard}{Advanced
Encryption Standard}, 256 bit key size version, with the key on
the top of the stack. The stack data are encrypted in two 128
bit AES blocks in cipher-block chaining mode and the encrypted
result is placed on the top of the stack.
\item[{\tt -bindump} {\em filename}] ~\\
Write the entire stack in binary to the named {\tt filename}.
A dump to file may be reloaded onto the stack with the {\tt
-binfile} command.
\item[{\tt -binfile} {\em filename}] ~\\
Read successive 64 byte blocks from the binary file {\em
filename} and place them on the stack, pushing down the stack
with each block.
\item[{\tt -btc}] ~\\
Use the seed on the top of the stack, which is removed after
the command completes, to generate a Bitcoin private key and
public address, which are displayed on the console in all of
the various formats available. If the {\tt -format} command has
been to select CSV output, CSV records are generated using
the specified format options. If a {\tt -repeat} value has
been set, that number of stack items will be used to generate
multiple key/address pairs.
\item[{\tt -clear}] ~\\
Remove all items from the stack.
\item[{\tt -drop}] ~\\
Remove the top item from the stack.
\item[{\tt -dump}] ~\\
Dump the entire stack in hexadecimal to the console or to a
file if {\tt -outfile} has been set. A dump to file may be
reloaded onto the stack with the {\tt -hexfile} command.
\item[{\tt -dup}] ~\\
Duplicate the top item on the stack and push on the stack.
\item[{\tt -eth}] ~\\
Generate an Ethereum private key and public address from the
seed at the top of the stack, which is removed. The key and
address are displayed on the console in human-readable form. If
the {\tt -format} command has been to select CSV output, CSV
records are generated using the specified format options. If a
{\tt -repeat} value has been set, that number of stack items
will be used to generate multiple key/address pairs.
\item[{\tt -format} {\em fmt}] ~\\
Set the format to be used for key/address pairs generated by
the {\tt -btc} and {\tt -eth} commands. If the first three
letters of {\em fmt} are ``{\tt CSV}'' (case-sensitive), a
Comma-Separated Value file is generated. Letters following
``{\tt CSV}'' select options, which vary depending upon the
type of address being generated. For Bitcoin addresses, the
following options are available.
\begin{quote}
\begin{description}
\dense
\item[{\tt q}] Use uncompressed private key
\item[{\tt u}] Use uncompressed public address
\item[{\tt l}] Legacy (``{\tt 1}'') public address
\item[{\tt c}] Compatible (``{\tt 3}'') public address
\item[{\tt s}] Segwit ``{\tt bc1}'' public address
\end{description}
\end{quote}
For Ethereum addresses, options are:
\begin{quote}
\begin{description}
\dense
\item[{\tt n}] No checksum on public address
\item[{\tt p}] Include full public key
\end{description}
\end{quote}
For either kind of address, the letter ``{\tt k}'' indicates
that a subsequent key generation command will not remove
the keys it processes from the stack. This permits generating
the same keys in different formats. The letter ``{\tt b}''
on either address type causes the private key to be omitted
from CSV format output, replaced by a null string. This allows
generation of address lists containing only public addresses
that may be used with utilities such as @<CC@> and @<AW@>
without risking compromise of the private keys.
\item[{\tt -hbapik} {\em APIkey}] ~\\
When requesting true random data from Fourmilab's HotBits
radioactive random number generator, use the
\href{https://www.fourmilab.ch/hotbits/apikey.html}{\em APIkey}
to permit access to the generator. If you don't have an API
key (they are free), you may request pseudorandom data based
upon a radioactively-generated seed by specifying an API key
of ``{\tt Pseudorandom}''.
\item[{\tt -help}] ~\\
Print a summary of these commands.
\item[{\tt -hexfile} {\em filename}] ~\\
Load one or more seeds from the named {\em filename}, which
contains data in hexadecimal format. White space in the file
(including line breaks) is ignored, and each successive
sequence of 64 hexadecimal digits is pushed onto the stack as
a 256 bit seed. The {\tt -hexfile} command can load keys
dumped to a file with the {\tt -outfile} and {\tt -dump}
commands back onto the stack.
\item[{\tt -hotbits}] ~\\
Retrieve one or more 256 bit seeds from Fourmilab's HotBits
radioactive random number generator, using the API key specified
by the {\tt -hbapik} command. If the {\tt -repeat} command has
specified multiple keys, that number of keys will be retrieved
from HotBits and pushed onto the stack.
\item[{\tt -inter}] ~\\
Enter interactive mode. The user is prompted for commands,
which are entered exactly as on the command line, except without
the leading hyphen on the command name. To exit interactive
mode and return to processing commands from the command line,
enter ``{\tt end}'', ``{\tt exit}'', ``{\tt quit}'', or the
end of file character.
\item[{\tt -minigen}] ~\\
Generate a Bitcoin
\href{https://en.bitcoin.it/wiki/Mini_private_key_format}{mini
private key}, display the generated key, and push the full seed
for the key onto the stack. Mini private keys were introduced
to allow encoding a Bitcoin private key on physical coins,
bills, or other objects which lack the space for a full private
key, which can be up to 52 characters long. A mini key is just
30 characters, but can represent only a subset of possible
Bitcoin addresses and is consequently less secure---they should
be used only when absolutely necessary. Due to the nature of
mini keys, the generation process differs from that used by the
{\tt -btc} command. The {\tt -minigen} command internally
generates the seed for the key by mixing the system's fast
entropy generator and this program's internal pseudorandom
generator seeded by the system fast entropy generator. After
finding a suitable key, it pushes the seed onto the stack and
displays the corresponding key. You may then use the {\tt
-btc} command to generate the corresponding public Bitcoin
address in whichever format(s) you wish. If the {\tt -format}
is set to ``{\tt CSV}'', an address file is generated which is
compatible with the {\tt btc} command, but with the addition of
a fifth field in every record containing the mini key. You may
use the {\tt -repeat} command to generate multiple keys and the
``{\tt k}'' option on the {\tt -format} to keep the seeds on
the stack.
\item[{\tt -minikey}] {\em mini\_private\_key} ~\\
Validate and decode the specified mini private key (see above)
and, if it is properly formatted, place the seed it encodes on
the stack. You may then use the {\tt -btc} command to generate
other forms of private keys or public addresses from the seed.
Both legacy 22 character and the present standard 30 character
mini keys may be specified.
\item[{\tt -mnemonic}] ~\\
Generate a
\href{https://en.bitcoin.it/wiki/BIP_0039}{Bitcoin Improvement
Proposal 39} (BIP39) mnemonic phrase from the seed on the top
of the stack. The seed remains on the stack.
\item[{\tt -not}] ~\\
Invert the bits of the seed on the top of the stack.
\item[{\tt -outfile} {\em filename}] ~\\
Output from subsequent {\tt -btc}, {\tt -eth}, and {\tt dump}
commands will be written to {\em filename} instead of standard
output. Specifying a {\em filename} of ``{\tt -}'' restores
output to standard output. Each key generation command
overwrites any previous output in {\em filename}; it is not
concatenated. Note that a file written by {\tt -dump}
may be loaded back on the stack with the {\tt -hexfile}
command.
\item[{\tt -over}] ~\\
Duplicate the second item on the stack and push it onto the top
of the stack.
\item[{\tt -p}] ~\\
Print the top item on the stack on the console.
\item[{\tt -phrase} {\em words\ldots}] ~\\
Push a key defined by a
\href{https://en.bitcoin.it/wiki/BIP_0039}{Bitcoin Improvement
Proposal 39} (BIP39) mnemonic phrase on the stack. On the
command line, the phrase should be enclosed in quotes.
\item[{\tt -pseudo}] ~\\
Push one or more seeds generated by the internal Mersenne
Twister pseudorandom generator onto the stack. If the
{\tt -repeat} command has been set to greater than one, that
number of seeds will be generated and pushed. The pseudorandom
generator is itself seeded by entropy supplied by the system's
fast entropy source ({\tt /dev/urandom} on most Unix-like
systems).
\item[{\tt -pseudoseed}] ~\\
Use the number of stack items set by {\tt -repeat} to seed the
pseudorandom generator. You may specify up to 78 stack items,
representing 624 32-bit seed values. Any more than 78 are not
used will be left on the stack. Any previous generator and
seed are deleted. This is normally used only for regression
testing where repeatable pseudorandom data are required.
\item[{\tt -random}] ~\\
Push one or more seeds read from the system's strong
entropy source ({\tt /dev/random} on most Unix-like
systems) onto the stack. If the {\tt -repeat} command
has been set to greater than one, that number of seeds will be
generated and pushed. Reading data from a strong source
faster than the system can collect hardware entropy may result
in delays: the program will wait as long as necessary to obtain
the requested number of bytes.
\item[{\tt -repeat} {\em n}] ~\\
Commands which generate and consume seeds will create and use
$n$ seeds instead of the default of 1. To restore the default,
specify {\tt repeat 1}.
\item[{\tt -roll} {\em n}] ~\\
Rotate the top $n$ stack items, moving item $n$ to the top of
the stack and pushing other items down.
\item[{\tt -rot}] ~\\
Rotate the top three stack items. Item three becomes the top
of the stack and the other items are pushed down.
\item[{\tt -rrot}] ~\\
Reverse rotate the top three stack items. The seed on the top
of the stack becomes the third item and the two items below it
move up, with the second becoming the top.
\item[{\tt -seed} {\em hex\_data}] ~\\
The 256 bit seed, specified as 64 hexadecimal digits, is pushed
onto the stack. The seed may be preceded by ``{\tt 0x}'', but
this is not required.
\item[{\tt -sha2}] ~\\
The seed on the top of the stack is replaced by the hash
(digest) generated by the
\href{https://en.wikipedia.org/wiki/SHA-2}{Secure Hash
Algorithm 2} (SHA-2), 256 bit version (SHA2-256). If
{\tt -repeat} has been set greater than one, the specified
number of seeds will be removed from the stack and
concatenated, top down, the digest computed, and placed
back on the stack.
\item[{\tt -sha3}] ~\\
The seed on the top of the stack is replaced by the hash
(digest) generated by the
\href{https://en.wikipedia.org/wiki/SHA-3}{Secure Hash
Algorithm 3} (SHA-3), 256 bit version (SHA3-256). If
{\tt -repeat} has been set greater than one, the specified
number of seeds will be removed from the stack and
concatenated, top down, the digest computed, and placed
back on the stack.
\item[{\tt -shuffle}] ~\\
Shuffle bytes of items on the stack using
pseudorandom values generated as for the {\tt -pseudo} command.
Shuffling bytes can mitigate the risk of interception of seeds
generated remotely and transmitted across the Internet.
(Secure {\tt https:} connections are used for all such
requests, but you never know\ldots .) The number of items
shuffled is set by {\tt -repeat}.
\item[{\tt -swap}] ~\\
Exchange the top two items on the stack.
\item[{\tt -test}] ~\\
Use the Fourmilab
\href{https://www.fourmilab.ch/random/}{\tt ent} random
sequence tester to evaluate the apparent randomness of the top
items on the stack. The number of items tested may be set with
{\tt -repeat}. You must have {\tt ent} installed on your system
to use this command. Randomness is evaluated at the bit stream
level.
\item[{\tt -testall}] ~\\
Use the Fourmilab
\href{https://www.fourmilab.ch/random/}{\tt ent} random
sequence tester to evaluate the apparent randomness of the
entire contents of the stack. You must have {\tt ent}
installed on your system to use this command.
Randomness is evaluated at the bit stream level.
\item[{\tt -testmode} {\em n}] ~\\
Set developer test modes to the bit-coded value {\em n}, which
is the sum of the mode bits to enable. These are intended for
development and regression testing and should not be enabled
for production use, leaving the setting at the default of 0.
The 1 bit makes the {\tt -minigen} produce deterministic output
from a fixed {\tt -pseudoseed}. The 2 bit causes @<BA@> to
list all of the Perl library modules it has used during its
execution.
\item[{\tt -type} {\em Any text}] ~\\
Display the text on the console. This is often used in command
files to inform the user of what's going on.
\item[{\tt -urandom}] ~\\
Push one or more seeds read from the system's fast entropy
source ({\tt /dev/urandom} on most Unix-like systems) onto the
stack. If the {\tt -repeat} command has been set to greater
than one, that number of seeds will be generated and pushed.
The fast generator has no limitation on generation rate, so you
may request any amount of data without possibility of delay.
\item[{\tt -wif} {\em private\_key}] ~\\
Push the seed represented by the Bitcoin Wallet Import Format
(WIF) key onto the stack.
\item[{\tt -xor}] ~\\
Perform a bitwise exclusive or of the top two items on the
stack and push the result on the stack.
\item[{\tt -zero}] ~\\
Push an all zero seed on the stack.
\end{description}
\section{Multiple Key Manager}
\label{UG:MKM}
The Multiple Key Manager (@<MK@>) splits the private keys used to
access funds stored in Bitcoin or Ethereum addresses into multiple
independent parts, allowing them to be distributed among a number of
custodians or storage locations. The original keys may subsequently be
reconstructed from a minimum specified number of parts. Each secret
key is split into $n$ parts ($n\geq 2$), of which any $k, 2\leq k\leq n$ are
sufficient to reconstruct the entire original key, but from which the
key cannot be computed from fewer than $k$ parts. In the discussion
below, we refer to $n$ as the number of {\tt parts} and $k$ as the
number {\tt needed}. The splitting and reconstruction of keys is
performed using the
\href{https://en.wikipedia.org/wiki/Shamir%27s_Secret_Sharing}{Shamir
Secret Sharing} technique.
The ability to split secret keys into parts allows implementing
a wide variety of custodial arrangements. For example, a company
treasury's cold storage vault might have secret keys split
five ways, with copies entrusted to the chief executive officer,
chief financial officer, an inside director, an outside director,
and one kept in a safe at the office of the company's legal firm.
If the parts were generated so that any three would re-generate
the secret keys, then at least three people would have to approve
access to the funds stored in the vault, which reduces the
likelihood of their misappropriation. The existence of more
parts than required guards against loss or theft of one of the parts:
should that happen, three of the remaining copies can be used to
withdraw the funds and transfer them to new accounts
protected by new multi-part keys.
To create multiple keys, start with a comma-separated value (CSV)
file in the format created by @<BA@> with ``{\tt format CSV}''
selected. Let's call this file {\tt keyfile.csv}. Now, to split
the keys in this file into five parts, any three of which are
sufficient to reconstruct the original keys, use the command:
{\tt @<MK@> -parts 5 -needed 3 keyfile.csv}
This will generate five split key files named {\tt keyfile-1.csv},
{\tt keyfile-2.csv}, \ldots\ {\tt keyfile-5.csv}. These are the
files which are distributed to the five custodians. After verifying
independently that the parts can be successfully reconstructed (you
can't be too careful!), the original {\tt keyfile.csv} is destroyed,
leaving no copy of the complete keys. (All of this should, of course,
be done on an ``air gapped'' machine not connected to any network or
external device which might compromise the complete keys while they
exist.)
When access to the keys is required, any three of the five parts
should be provided by their holders and combined with a command
like:
{\tt @<MK@> -join keyfile-4.csv keyfile-1.csv keyfile-2.csv}
Again, you can use any three parts and specify them in any order.
This will create a file named {\tt keyfile-merged.csv} containing
the original keys in the same format as was created by @<BA@>. You
can then use this file with any of the other utilities in this
collection or use one or more of the secret keys to ``sweep'' the
funds into a new address. To maximise security, once a set of
keys has been recombined, funds should be removed from all and those
not used transferred to new cold storage addresses, broken into parts
as you wish. In many cases, it makes sense to split individual keys
rather than a collection of many so you need only join the ones
you immediately intend to use.
Once the parts have been generated on the air-gapped machine, they
are usually written to offline paper storage (using the @<PW@>
program, for example, which works with split key files as well as
complete key files) or archival media such as write-once
optical discs, perhaps with several identical redundant copies per
part. Their custodians should store the copies of their parts in
multiple secure, private locations to protect against mishaps that
might destroy all copies of their part.
The ability to create multiple parts allows flexibility in their
distribution. You might, for example, entrust two parts to the
company CEO, who would only need one part from another officer or
director to access the vault, while requiring three people other
than the CEO to access it.
Although primarily intended to split blockchain secret keys into
parts, @<MK@> may be used to protect and control access to any
kind of secret which can be expressed as 1024 or fewer text characters:
for example, passwords on root signing certificates, decryption keys
for private client information, or the formula for fizzy soft drinks.
\subsection{Command line options}
\begin{description}
\item[{\tt -help}] ~\\
Print how to call information.
\item[{\tt -join}] ~\\
Reconstruct the original private keys from the parts included
in the files specified on the command line. You must supply
at least the {\tt -needed} number of parts when they were
created (if you specify more, the extras are ignored). The
output is written to a file with the specified {\tt -name} or,
if none is given, that of the first part with its number
replaced with ``{\tt -merged}''. The file will be in the
comma-separated value (CSV) format in which @<BA@> writes
addresses and keys it generates and is used by other programs
in this collection.
\item[{\tt -name} {\em name}] ~\\
When splitting keys, the individual part files will be named
``{\em name}{\tt -}{\em n}{\tt .csv}'', where {\em n} is
the part number. If no {\tt -name} is specified, the name
of the first key file supplied will be used.
\item[{\tt -needed} {\em k}] ~\\
When reconstructing the original keys, at least {\em k} parts
(default 3) must be specified. This option is ignored when
joining the parts.
\item[{\tt -parts} {\em n}] ~\\
Keys will be split into {\em n} parts (default 3). This option
is ignored when joining parts.
\item[{\tt -prime} {\em p}] ~\\
Use the prime number {\em p} when splitting parts. This should
only be specified if you're a super expert who has read the
code, understands the algorithm, and knows what you're doing,
otherwise you're likely to mess things up. The default is
257.
\end{description}
\section{Paper Wallet Utilities}
\label{UG:PWU}
The safest way to store cryptocurrency assets not needed for
transactions in the near term is in ``cold storage'': kept offline
either on a secure (and redundant) digital medium or, safest of
all, paper (again, replicated and stored in multiple secure
locations). A cold storage wallet consists simply of a list of one
or more pairs of blockchain public addresses and private keys.
Funds are sent to the public address and the corresponding private
key is never used until the funds are needed and they are ``swept''
into an online wallet by entering the private key.
The @<BA@> program makes it easy to generate address and key pairs for
offline cold storage, encoding them as comma-separated value (CSV)
files which can easily be read by programs. For storage on paper,
a more legible human-oriented format is preferable, which the utilities
in this chapter aid in creating and verifying.
\subsection{Paper Wallet Generator}
\label{UG:PWg}
The @<PW@> program reads a list of Bitcoin or Ethereum public address
and private key pairs, generated by the @<BA@> program in
comma-separated value (CSV) format, and creates an HTML file which can
be loaded into a browser and then printed locally to create paper cold
storage wallets. In the interest of security, this process, as with
generation of the CSV file, should be done on a machine with no
connection to the Internet (``air gapped''), and copies of the files
deleted from its storage before the machine is connected to a public
network.
\subsubsection{Creating a paper wallet}
Assume you've created a cold storage wallet with twenty Ethereum
addresses using the @<BA@> program, for example with the command:
{\tt @<BA@> -repeat 20 -urandom -outfile coldstore.csv -format CSV -eth}
This should be done on the same air-gapped machine on which you'll
now create the paper wallet. Be careful to generate the
{\tt coldstore.csv} file in a location you'll erase before connecting
the machine to a public network. If you wish to keep a
machine-readable cold storage wallet, copy the {\tt coldstore.csv} file
to multiple removable media (for example, flash storage devices
[perhaps encrypted], writeable compact discs, etc.) Be aware that no
digital storage medium has unlimited data retention life, and
even if the data are physically present, it may be difficult to
near-impossible to find a drive which can read it in the not-so-distant
future. By contrast, we have millennia of experience with ink on
paper, and if protected from physical damage, a printed cold storage
wallet will remain legible for centuries.
Now let's create a paper wallet. Using the {\tt coldstore.csv} file
we've just generated and the default parameters, this can be done
with:
{\tt @<PW@> coldstore.csv >coldstore.html}
You can now load the {\tt coldstore.html} file into a Web browser with
a {\tt file:coldstore.html} URL, use print preview to verify it is
properly formatted, then print as many copies as you require for safe
storage to a local printer. Even though you're using a Web browser
to load and print the file, security is not compromised as long as the
computer running it is not connected to the Internet. After printing
the paper wallet, be sure to clear the browser's cache, deleting any
copy it may have made of the file.
\subsubsection{Command line options}
\begin{description}
\item[{\tt -date} {\em text}] ~\\
The specified {\em text} will be used as the date in the
printed wallet. Any text may be used: enclose it in quotes if
it contains spaces or special characters interpreted by the
shell. If no {\tt -date} is specified, the current date
is used, in ISO-8601 {\tt YYYY-MM-DD} format.
\item[{\tt -font} {\em fname}] ~\\
Use HTML/CSS font name {\em fname} to display addresses
and keys. The default is {\tt monospace}.
\item[{\tt -help}] ~\\
Print a summary of the command line options.
\item[{\tt -offset} {\em n}] ~\\
The integer {\em n} will be added to the address numbers
(first CSV field) in the input file. If you've generated
a number of cold storage wallets with the same numbers and
wish to distinguish them in the printed versions, this
allows doing so.
\item[{\tt -perpage} {\em n}] ~\\
Addresses will be printed {\em n} per page. The default
is 10 addresses per page. The number which will fit on a
page depends upon your paper size, font selection, and
margins used when printing---experiment with print preview
to choose suitable settings.
\item[{\tt -prefix} {\em text}] ~\\
Use {\em text} as a prefix for address numbers from
the CSV file (optionally adjusted by the {\tt -offset}
option). This allows further distinguishing addresses in
the printed document.
\item[{\tt -separator} {\em text}] ~\\
Display addresses and private keys as groups of four letters
and numbers separated by the sequence {\em text}, which may be
an HTML text entity such as ``\verb+–+''.
\item[{\tt -size} {\em sspec}] ~\\
Use HTML/CSS font size {\em sspec} to display addresses
and keys. The default is {\tt medium}.
\item[{\tt -title} {\em text}] ~\\
Use the specified {\tt text} as the title for the cold
storage wallet. If no title is specified, ``Bitcoin Wallet''
or ``Ethereum Wallet'' will be used, depending upon the
type of address in the CSV file.
\item[{\tt -weight} {\em wgt}] ~\\
Use HTML/CSS font weight {\em wgt} to display addresses
and keys. The default is {\tt normal}.
\end{description}
\subsection{Cold Storage Wallet Validator}
\label{UG:PWv}
When placing funds in offline cold storage wallets, an abundance of
caution is the prudent approach. By their very nature, once funds
are sent to the public address of a cold storage wallet, that address
is never used again, nor is its private key ever used at all until
the time comes, perhaps years or decades later, to ``sweep'' the
funds from cold storage back into an online wallet. Consequently,
if, for whatever reason, there should be an error in which the
private key in the offline wallet does not correspond to the public
address to which the funds were sent, those funds will be
irretrievably lost, with no hope whatsoever of recovery. Entering
the private key into a machine connected to the Internet in order to
verify it would defeat the entire purpose of a cold storage wallet:
that its private keys, once generated on an air-gapped machine, are
never used prior to returning the funds from cold storage.
While the circumstances in which a bad address/key pair might be
generated and stored may seem remote, the consequences of this
happening, whether due to software or hardware errors, incorrect
operation of the utilities used to generate them, or malice, are
so dire that a completely independent way to verify their correctness
is valuable.
The @<VW@> program performs this validation on cold storage wallets,
either in the CSV format generated by @<BA@> or the printable
HTML produced by @<PW@>. Further verification that the printed output
from the HTML corresponds to the file which was printed will require
manual inspection or scanning and subsequent verification. The @<VW@>
program is a ``clean room'' re-implementation of the blockchain address
generation process used by @<BA@> to create cold storage wallets. It
is written in a completely different programming language (Python
version 3 as opposed to Perl), and uses the Python cryptographic
libraries instead of Perl's. While it is possible that errors
in lower-level system libraries shared by both programming languages
might corrupt the results, this is much less likely than an error
in the primary code or the language-specific libraries they use.
\section{Cold Storage Monitor}
\label{UG:CSM}
For safety, cryptocurrency balances which are not needed for active
transactions are often kept in ``cold storage'', either off-line in
redundant digital media not accessible over a network or printed on
paper (for example, produced with the @<PW@> program) kept in multiple
separate locations. Once sent to these cold storage addresses, there
should be no further transactions whatsoever referencing them until
they are ``swept'' back into an active account for use.
But under the principle of
%Доверяй, но проверяй
\href{https://en.wikipedia.org/wiki/Trust,_but_verify}{\em doveryay, no
proveryay} (trust, but verify), a prudent custodian should monitor cold
storage addresses to confirm they remain intact and have not been
plundered by any means. (It's usually an inside job, but you never
know.) One option is to run a ``hot monitor'' that constantly watches
transactions on the blockchain such as the @<AW@> utility included
here, but that requires you to operate a full Bitcoin node and does
not, at present, support monitoring of Ethereum addresses.
The @<CC@> utility provides a less intensive form of monitoring which
works for both Bitcoin and Ethereum cold storage addresses, does not
require access to a local node, but instead uses free query services
that return the current balance for addresses. You can run this
job periodically (once a week is generally sufficient) with a list of
your cold storage addresses, producing a report of any
discrepancies between their expected balances and those returned
by the query.
Multiple query servers are supported for both Bitcoin and Ethereum
addresses, which may be selected by command line options, and
automatic recovery from transient errors while querying servers
is provided.
\subsection{Watching cold storage addresses}
The list of cold storage addresses to be watched is specified in a CSV
file in the same format produced by @<BA@> and read by @<PW@>,
plus an extra field giving the expected balance in the cold storage
address. For example, an Ethereum address in which a balance of 10.25
Ether has been deposited might be specified as:
{\tt 1,"0x1F77Ea4C2d49fB89a72A5F690fc80deFbb712021","",10.25}
The private key field is not used by the @<CC@> program and should, in
the interest of security, be replaced by a blank field as has been done
here. There is no reason to expose the private keys of cold storage
addresses on a machine intended only to monitor them. You can use the
``{\tt b}'' and ``{\tt k}'' options on a {\tt -format~CSV} command to
generate a copy of the addresses without the private keys. To query
all addresses specified in a file named {\tt coldstore.csv} and report
the current and expected balances, noting any discrepancies, use:
{\tt @<CC@> -verbose coldstore.csv}
If you don't specify {\tt -verbose}, only addresses whose balance
differs from that specified in the CSV file will be reported.
\subsection{Command line options}
The @<CC@> program is configured by the following command line options.
\begin{description}
\item[{\tt -btcsource} {\em sitename}] ~\\
Specify the site queried to obtain the balance
of Bitcoin addresses. The sites supported are:
\begin{itemize}
\dense
\tt
\item blockchain.info
\item blockcypher.com
\item btc.com
\end{itemize}
You must specify the site name exactly as given above.
\item[{\tt -dust} {\em n}] ~\\
Some miscreants use the blockchain as a means of ``spamming''
users, generally to promote some shady, scammy scheme. They
do this by sending tiny amounts of currency to a large number
of accounts, whose holders they hope will be curious and
investigate the transaction that sent them, in which the
spam message is embedded, usually as bogus addresses. You
might think getting paid to receive spam is kind of cool, but
the amounts sent are smaller than the transaction cost it would
take to spend or aggregate them with other balances. This is