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 provides shell functions to streamline full wallet encryption using GPG. Prerequisites ------------- gscm : the Gales Scheme interpreter. Installation ------------ This software ignores some historical Unix conventions in favor of a simplified variant of Bernstein's /package scheme ( http://cr.yp.to/slashpackage.html ). Installation paths and command names are not configurable, which amounts to a global namespace claim, such that people and programs can count on finding components at known paths if they are to be found at all. User commands are symlinked into /usr/bin and will replace prior files in case of conflict; see "package/commands" for the list. You will need root privileges to install. 1. Create the top-level /package directory if necessary and place the tree at its fully version-qualified path: mkdir -p /package cp -r /YOUR/PATH/TO/gbw-signer /package/gbw-signer-2 2. Run the install script from the above directory: cd /package/gbw-signer-2 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. To revert to this version after installing a different one, simply repeat step 2. 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 unintended address. More subtle is that, because Bitcoin transactions do not explicitly specify fee and input values, an incorrect prior output value in the "outputs" table can drain funds in the form of an 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 ) !