About ----- This is gbw-signer, the offline signing component of Gales Bitcoin Wallet as described at http://fixpoint.welshcomputing.com/2019/gales-bitcoin-wallet-spec-and-battle-plan/ , written by Jacob Welsh for JWRD Computing. It is written in Scheme with original implementations of the cryptographic primitives, and shell functions to simplify full wallet encryption using GPG. Prerequisites ------------- gscm : the Gales Scheme interpreter. Installation ------------ This software sheds some historical Unix conventions in favor of Bernstein's /package scheme ( http://cr.yp.to/slashpackage.html ), which I find meshes fairly well with the ideas of V. If this is your first time using it, you may need to create the /package directory and add /command to your shell's PATH variable. 1. Press or otherwise install the tree at the path: /package/gbw-signer-1 The installation path is not configurable. This amounts to a claim on the global namespace, as command names always do. People and programs can count on finding components at known paths if they are to be found at all, as surely as with /bin/sh. This doesn't mean the files must physically exist under /package; for example, a symlink from there could ease working on the code as a non-root user. 2. From the above directory, run (as root): sh package/install ECC cache generation will take a noticeable time, depending on hardware, though hopefully not so much as to suggest preparing a beverage. 3. Run the test suite: sh package/check Ensure there are no failures indicated. It should take about the same time. Operation --------- A wallet is represented as a filesystem tree serving as key-value store, arranged as follows: wallet/ keys/ address : hex-encoded private key ... change : change address fee : transaction fee in BTC/kB outputs : unspent outputs table transactions : linefeed-delimited raw transaction list The outputs table is awk-style, that is, with fields separated by one or more space or tab characters and records separated by linefeeds. It can be constructed by hand or using the companion "gbw-node" tools to collect it from the blockchain. Fields are, in order: Address : address to which the output was sent, in the usual Base58 Value : monetary value of the output, in decimal BTC (see Warnings below) TXID : hash of transaction containing the output, in the "little-endian" hex format used by bitcoind Index : position in the transaction's output vector, as decimal integer Any further text in a line is considered comment. An initial wallet tree must be constructed including empty keys directory, change, fee, and outputs. "gbw-init" described below can assist with all but the outputs part. The main program is "gbw-signer", which provides subcommands for key generation or import and transaction issuance. Run "gbw-signer help" for details. GPG integration: setup ---------------------- Wallet encryption is managed by working with a tree in memory then saving to a GPG encrypted tar file. Tools are included to facilitate this; they operate through the shell environment and thus are configured using it. Presumably you will want to do this in your shell startup (~/.bashrc or equivalent) to make it permanent. 1. Set GBW_RECIPIENT to your desired GPG key ID for wallet encryption. 2. Set GBW_TMPDIR to an absolute path to a writeable temporary directory. To avoid spilling plaintext keys to permanent storage, this must be on a tmpfs and the machine must not have swap enabled. 3. Source the file /package/gbw-signer/library/gbw-shell.sh to load its function definitions. Example: GBW_RECIPIENT=0123456789ABCDEF GBW_TMPDIR=/tmp . /package/gbw-signer/library/gbw-shell.sh GPG integration: operation -------------------------- gbw-init PATH : creates a new wallet tree under GBW_TMPDIR and moves the shell to its root. PATH specifies where the GPG-encrypted archive will be later saved. gbw-save : saves an encrypted copy of the tree, leaving the plaintext open. gbw-close : saves and deletes the plaintext tree. gbw-discard : deletes the plaintext tree without saving. gbw-open PATH : decrypts a saved wallet from PATH into a tree under GBW_TMPDIR and moves the shell to its root. Shell variables prefixed with GBW_ are used to coordinate these commands; see source for details. The save process is believed to be atomic but as always, keep backups, and verify that you can re-open an encrypted wallet before counting on it. Warnings -------- A strong entropy source is required in /dev/urandom. Compromised inputs can drain your funds even without disclosure of private keys. The most obvious case would be sending to a valid but incorrect address. More subtle is that, because Bitcoin transactions do not explicitly specify fee and input values, an incorrect value field in "outputs" can result in excess input consumption and incorrect change computation, causing loss through exhorbitant transaction fee. The cryptographic operations do not use constant-time algorithms, thus side channel attacks (timing, electromagnetic, sonic, power, thermal) are possible. Fixing this is in scope for future revisions; meanwhile, use appropriate precautions. The signer does not include checking for hardware faults, which while rare are not impossible. Fixing this is in scope for future revisions; meanwhile, it may be prudent to decode raw transactions after signing to verify addresses and amounts prior to broadcasting. Enjoy your new nuclear briefcase ( http://trilema.com/2016/how-to-cut-the-wallet/#footnote_1_69751 ) !