hashcash - hashcash minting and verification command line tool
hashcash [ options ] [ -b bits ] [ resource ]>
hashcash -c [ options ] -b bits -r resource [ token ]
hashcash -s [ options ] [ -b bits ]
hashcash -p now [ -j resource ] [ -k ] [ -t time ] [ -u ]
hashcash -w [ options ] [ token ]
hashcash -n [ options ] [ token ]
hashcash -l [ options ] -e period [ token ]
Hashcash is a DoS counter-measure tool. This tool allows you to mint (create) and verify hashcash tokens. A hashcash token constitutes a proof-of-work which takes a parameterizable amount of work to compute for the sender. The recipient can verify received tokens efficiently.
The proof-of-work function is to compute partial hash collisions (in this version the SHA1 hash function is used). By choosing the number of bits of collision, the work required to compute a collision can be made arbitrarily expensive -- from fractions of a second to minutes or hours. The verification is efficient requiring the same small cost whatever the collision size.
For more detailed discussion of potential applications for hashcash see http://www.cypherspace.org/hashcash/.
If neither the -c or -s option are given, it is assumed that you want to mint a token.
The resource name to mint the token against can be passed as an argument, or if omitted is read from stdin. If stdin is a tty the user is prompted, if stdin is a pipe the resource name is just silently read. The desired collision size can be specified with the -b option. If no collision size is specified, the default is 20 bits. As a convenience, if stdin is a tty and no collision size is given with the -b flag, the user is prompted for a collision size.
The -c flag must be given to check tokens. The token to check can
be given as an argument to hashcash
. If no token is given the
token is read from stdin. If stdin is a tty the user will be
prompted, if stdin is a pipe the token is just silently read. A
resource name can be given with the -r option. If a resource name
is given the resource name is compared to the name in the token, if
they do not match, the token is rejected.
Note: if no resource name is given the token is anyway checked to see if it is otherwise valid, but it could be minted for a different resource, which would allow tokens to be reused across different resources, so hashcash will return unchecked exit code on exit.
Tokens are by default considered to be valid forever. The validity period can be changed using the -e flag.
If the token has expired or has a date in the future the token is rejected and the program exits immediately.
If a required collision size is given with the -b flag, the tokens value is computed and compared, if the token has insufficent value it is rejected, and the program exits immediately. If the -b flag is not given, the token could be of any size, so hashcash will return unchecked exit code on exit.
If the token is double spent the token is rejected. Double spending protection is discussed in more detail below in Double Spending Protection. If double spending protection is not enabled, the token could be double spent, so hashcash will return unchecked exit code on exit.
The -w flag can be used to request that the number of bits of the collision are counted and displayed; exit code unchecked is returned on exit. The -n flag can be used to request that the resource name in the token is parsed out and displayed; exit code unchecked is returned on exit. The -l flag can be used to request the number of seconds until expiry of the token is output; exit code unchecked is returned on exit.
The program will only return exit codes valid or invalid if the -c flag is used, and all of the options -b bits, -d, -r resource are used. These are the minimum set of options necessary to check the validty of a token. If these criteria are not met, the program will return exit code unchecked on exit.
If the -d flag is used with the -c flag a database of spent tokens is kept.
By default tokens do not expire, and over time the database will grow indefinately. To prevent this, you can specify an expiry period with the -e flag. A recommended expiry period is 28 days. After the expiry period amount of time, the token is anyway considered expired and may be purged from the database to save space. (See Purging Periodically vs on Next Access for how to purge tokens.)
For efficiency reasons a token is verified before it is checked in the database; if it is otherwise invalid no database activity will occur.
Note: The decision about how long the token should be considered valid is up to the verifier. If it is too short it is possible for some applications that the token will expire before arriving at the recipient (eg with email.) The suggested value of 28 days should be safe for normal email delivery delays. The choice is a trade-off between database size and risk of expiry prior to arrival, and depends on the application.
Note: Different tokens in the same database can have different validity periods, so for example tokens for different resources with different validity periods can be stored in the same database, or the recipient may change the validity period for future tokens without affecting the validity of old tokens.
To purge old tokens periodically while checking tokens use the -p period option to purge no sooner than the given time period since the last purge. Purging can be used with the -k to purge unexpired tokens also, and with the -r resource flag to purge only tokens for the given resource.
There are circumstances where it may be inconvenient to purge tokens
on the next access, for example if there is a large double spend
database which takes some time to purge, and the response time of the
hashcash checker is important. To avoid this problem, purging can be
done separately using just the -p now option to request just the
purge operation. On unix for example you could call hashcash -p
now
in a cron job once per day, or on demand when disk was running
low.
The -s flag requests measurement of how many collisions can be tested per second. No token is minted, or verified.
If the -b flag is used this option, instead an estimate of how many seconds it would take to mint a token of that size is computed.
All informational output is printed on stderr. Minted tokens, and results of token verification and timing are printed on stdout. The quiet flag -q suppresses all informational output. The -v flag requests more informational output. The requested output, which is the only information that is output in quiet mode (when -q is specified) is printed on standard output. If stdout is a pipe the output is printed without description (ie just bits, just seconds, just resource).
hashcash
.
When checking tokens, the resource name can be given with the -r option. If the resource name is given it is checked against the resource name in the token, and if they do not match the token is rejected. Note if the resource name is not given, tokens for other resources would be accepted, and therefore hashcash returns exit code unchecked on exit.
If used with the -d option, the spent token and it's expiry period is recorded in the database. See the -p option for description of how to purge tokens from the database.
While minting tokens, if the -e flag can have an effect on the resolution of time created in the token. Without the -e option, the default resolution is days (time format: YYMMDD). Alternate formats based on range of expiry period are as follows:
Note the rounding down is based on UTC time, not local time. This can lead to initially suprising results when rounding down to eg days in time zones other than GMT (GMT = UTC). It may be clearer to understand if you use the -u option.
It is recommended that if you use the -e option with the database option, to prevent the database growing indefinately over time. A suggested value is -e 28d, 28 days.
If used in combination with -j resource only the tokens minted for the given resource are purged.
If used in combination with -k all tokens even un-expired tokens are purged. Can be used in combination with -t time to expire as if the current time were the given time.
When checking, if no token is given as an argument, scans stdin for a line starting with the given string, and use the rest of the matching as the token. Only the lines up to and ending at the first blank line are scanned. A blank line is the separator used to separate the headers from the body of a mail message or USENET article. This is meant to make it convenient to pipe a mail message or USENET article to hashcash on stdin.
Time is expressed in local time by default. Use with -u flag to give time in UTC (GMT).
You can also give time relative to the current time by prefixing the argument with + or -. The default units for relative time are seconds. A single character suffix can be used to specify alternate units (m = minutes, h = hours, d = days, M = months, y = Y = years, and s = seconds).
hashcash -s
hashcash -s -b 32
hashcash
hashcash foo
hashcash foo -b 10
hashcash -a -3d
hashcash -w 0:020814:foo:4333957e84db47f6
hashcash -q -b 10 foo | hashcash -w
hashcash -n 0:020814:foo:21c8cf3099cbf467
hashcash -l -e 30y 0:020814:foo:21c8cf3099cbf467
hashcash -c 0:020814:foo:21c8cf3099cbf467
hashcash -c -b24 0:020814:foo:21c8cf3099cbf467
hashcash -c -b24 -r foo 0:020814:foo:21c8cf3099cbf467
The examples given in Verifying Tokens can be modified to keep a double spend database so that the same token will not be accepted twice. Note a token will only be checked in and added to the database if it is otherwise valid and fully checked (a required number of bits of collision has been specified and a resource has been specified).
hashcash -cd -b 10 -r foo 0:020814:foo:21c8cf3099cbf467
hashcash -cd -b 10 -r foo 0:020814:foo:21c8cf3099cbf467
To prevent the double spend database growing indefinately, the recipient can request that tokens be no older than a specified period. After expiry old tokens can dropped from the double spend database as they will no longer be needed -- expired tokens can be rejected based purely on their old date, so the space taken by expired tokens in the double spend database can be saved without risk of accepting an expired though otherwise valid token.
The first field of the token is the UTC time since 1st January 1970. The default time format is YYMMDD, time rounded down to the nearest day. The default validity period is forever.
You can provide an alternative validity period with the -e option.
hashcash -cd -b 10 -e 2d -r foo 0:020811:foo:21dd87d4c9f5aae1
We gave option -e 2d so the tokens expiry date is 2 days after creation, which is now in the past.
Note: if the creation time is expressed in the token in days, the precise creation date is the begining of the specified day in UTC time (similarly for alternate units the creation time is rounded down to the begining of the unit it is expressed in). For units in days, for example, this may mean depending on your time zone that the token appears to be considered invalid in under the specified expiry period in days relative to your relative view of what day it is, as the calculation is based on current time in UTC, and the creation time of the token is expressed in UTC time.
hashcash -cd -b 10 -r foo 0:020811:foo:21dd87d4c9f5aae1
If the -c, -d options are used together, each time a token is checked, if it is valid and all of the mandatory aspects of the token are verified (collision bits check, resource name check) then the token and it's expiry period is written to the database file. The default expiry period if an expiry period is not given explicitly with the -e option is forever (ie tokens do not expire).
First mint and then add a token:
hashcash -b 10 foo -e 1m > token
hashcash -cd -e 1m -b 10 -r foo < token
hashcash -p now
hashcash -cd -e 1m -b 10 -r foo < token
With the default database (the sdb format) the database contents are human readable, so you can view their contents by cating them to the terminal:
cat hashcash.db
As a convenience you can purge at the same time as checking tokens by using the -p option with the -c option.
hashcash -b 10 foo > token
=item hashcash -cd -p now -e 1 -b 10 -r foo < token
hashcash
to purge no more
frequently than that time period since the previous purge.
For example:
hashcash -cd -p 1d -e 1 -b 10 -r foo < token
hashcash
to purge any expired tokens no more than once per
day.
hashcash -p 1M -j foo
hashcash
to purge only expired tokens matching resource foo
once per month.
hashcash -p now -k
hashcash
to purge all tokens (expired and unexpired) now.
where
hashcash
returns success (exit code 0) after successfully minting a
token, after fully checking a token and finding it valid, and after a
timing test.
If when checking a token it is found to be invalid (due to being
malformed, being expired, having insufficient value, having a date in
the future, or being double spent), hashcash
returns failure (exit
code 1).
If insufficient options are given to fully check a token, or if using the -n, -l, or -w options, if the token is otherwise valid return unchecked (exit code 2). If the -y flag is given and hashcash would normally return unchecked, exit code success is returned instead.
If any exception occurs (file read failure for database checking or corrupted database contents) an exit status of 3 is returned.
Written by Adam Back <adam@cypherspace.org>
sha1(1), http://www.cypherspace.org/hashcash/