hashcash - hashcash anti-spam / denial of service counter-measure tool
hashcash -m [ [ options ] [ resource ... ] ... ]
hashcash -c [ [ options ] -r resource ... ] [ stamp ... ]
hashcash -s [ options ] [ -b bits ]
hashcash -p now [ -j resource ] [ -k ] [ -t time ] [ -u ]
hashcash -w [ options ] [ stamp ... ]
hashcash -n [ options ] [ stamp ... ]
hashcash -l [ options ] -e period [ stamp ... ]
Hashcash is a denial-of-service counter measure tool. Its main current use is to help hashcash users avoid losing email due to content based and blacklist based anti-spam systems.
The hashcash tool allows you to create hashcash stamps to attach to emails you send, and to verify hashcash stamps attached to emails you receive. Email senders attach hashcash stamps with the X-Hashcash: header. Vendors and authors of anti-spam tools are encouraged to exempt mail sent with hashcash from their blacklists and content based filtering rules.
A hashcash stamp constitutes a proof-of-work which takes a parameterizable amount of work to compute for the sender. The recipient can verify received stamps efficiently.
The hashcash proof-of-work function is to compute partial hash collisions (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 other applications hashcash has been used for see http://www.hashcash.org/
In this man page a resource name is the name of the service or address the stamp is created for. In the case of email, the resource name is the recipient's email address in the form user@domain.com.
The -m flag must be given to mint a stamp.
The resource name (recipient's email address) to mint the stamp 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. See also the -b default option.
The -c flag must be given to check a stamps expiry. The stamp to
check can be given as an argument to hashcash
. If no stamp is
given the stamp is read from stdin. If stdin is a tty the user will
be prompted, if stdin is a pipe the stamp is just silently read. A
resource name (the recipient's email address) can be given with the
-r option. If a resource name is given the resource name is
compared to the resource name in the stamp, if they do not match, the
stamp is rejected.
Note: if no resource name is given the stamp is anyway checked to see if it is otherwise valid, but it could be minted for a different resource, which would allow stamps to be reused across different resources, so hashcash will return unchecked exit code on exit.
Stamps are by default considered to be valid for 28 days. The validity period can be changed using the -e flag.
If the stamp has expired or has a date in the future the stamp is rejected and the program exits immediately.
If a required collision size is given with the -b flag, the stamps value is computed and compared, if the stamp has insufficent value it is rejected, and the program exits immediately. If the -b flag is not given, the stamp is checked to see if it is otherwise valid, but hashcash will return unchecked exit code on exit.
If the stamp is double spent the stamp is rejected. Double spending protection is discussed in more detail below in Double Spending Protection. If double spending protection is not enabled, the stamp could be double spent, so hashcash will return unchecked exit code (exit code 2) on exit.
The -w flag can be used to request that the number of bits of the collision are counted and displayed. The -n flag can be used to request that the resource name in the stamp is parsed out and displayed. The -l flag can be used to request the number of seconds until expiry of the stamp is output.
The program will only return exit codes valid or invalid if the -c flag is used, the -b flag is used, -d, -r resource are used. These are the minimum set of options necessary to fully check the validty of a stamp. If these criteria are not met, the program will return exit code unchecked (exit code 2) on exit. (See also the -y flag.)
If the -d flag is used when checking stamps, a database of spent stamps is kept.
By default stamps expire after 28 days, without expiry the database would grow indefinately. You can specify an alternate expiry period with the -e flag. The recommended (and default) expiry period for email is 28 days. After the expiry period amount of time, the stamp 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 stamps.)
For efficiency reasons a stamp 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 stamp should be considered valid is up to the verifier. If it is too short it is possible for some applications that the stamp 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 stamps in the same database can have different validity periods, so for example stamps for different resources with different validity periods can be stored in the same database, or the recipient may change the validity period for future stamps without affecting the validity of old stamps.
To purge old stamps periodically while checking stamps 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 option to purge unexpired stamps also, and with the -j resource flag to purge only stamps for the given resource.
There are circumstances where it may be inconvenient to purge stamps
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 stamp is minted, or verified.
If the -b flag is used with this option, instead an estimate of how many seconds it would take to mint a stamp of the given size in bits is computed. To find out how much time it will take to mint a default sized stamp use -s -b default.
All informational output is printed on stderr. Minted stamps, and results of stamp 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, or when quiet mode is in effect the output is printed without description (ie just bits, just seconds, just resource).
When checking stamps, require that the stamps have this many bits.
The default number of bits can be specified with -b default. Bits relative to the default can also be specified with -b +n for n bits more than the default and -b -n for n bits less than the default.
-b default, -b +0 and -b -0 are all equivalent.
When doing the speed test -s, can to measure speed of default token with -s -b default.
hashcash
.
When checking stamps, the resource name (your own email address) is given with the -r option. If the resource name is given it is checked against the resource name in the stamp, and if they do not match the stamp is rejected. Note if the resource name is not given, stamps for other resources would be accepted, and therefore hashcash returns exit code unchecked (exit code 2) on exit.
If used with the -d option, the spent stamp and its expiry period is recorded in the database. See the -p option for description of how to purge stamps from the database.
While minting stamps, the -e flag can have an effect on the resolution of time created in the stamp. Without the -e option, the default resolution is days (time format: YYMMDD). Alternate formats based on range of expiry period are as follows:
While minting you can also given an explicit time width with the -z option instead. (-z overrides -e if both are given. If neither are given the default is 6 chars (time format: YYMMDD)).
The rules for automatically determining appropriate time width from -e if no -z option is given are:
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 (UTC = GMT). It may be clearer to understand if you use the -u option.
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 (UTC = GMT). It may be clearer to understand if you use the -u option.
The default units for grace period 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).
If used in combination with -j resource only the stamps minted for the given resource are purged.
If used in combination with -k all stamps even un-expired stamps are purged. Can be used in combination with -t time to expire as if the current time were the given time.
Note the -E, -M and -S type of match flags also apply to resources given with the -j resource flag.
When checking, after scanning stamps given as arguments, scans stdin for lines starting with the string 'X-Hashcash:', and uses the rest of the matching line as the stamp. Only the lines up to and ending at the first blank line are scanned (see also -i flag which can be used to override this). 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).
Note: when time is expressed in local time, if there is daylight savings in your timezone, there are one or two ambiguous hours per year at the time of change from daylight savings time to normal time.
Note: the calculation includes the grace period, so can be up to 2 times grace period longer than you might otherwise expect (clock fast but system has to presume it could be slow). If you want to exclude the grace period add -g0 to set grace period to 0 for the calculation.
(Note even if compiled with BSD regular expressions, POSIX style syntax is used; also note BSD regular expressions do not support ranges {}.)
hashcash -s
hashcash -sv
hashcash -s -b default
hashcash -s -b 32
hashcash -m
hashcash -m foo
hashcash -m foo -b 10
hashcash -a -3d
hashcash -w 1:24:040806:foo::511801694b4cd6b0:1e7297a
hashcash -mq -b 10 foo | hashcash -w
hashcash -n 1:24:040806:foo::511801694b4cd6b0:1e7297a
hashcash -l -e 30y 1:24:040806:foo::511801694b4cd6b0:1e7297a
hashcash -c 1:24:040806:foo::511801694b4cd6b0:1e7297a
hashcash -c -b24 1:24:040806:foo::511801694b4cd6b0:1e7297a
hashcash -c -b24 -r foo 1:24:040806:foo::511801694b4cd6b0:1e7297a
The examples given in Verifying Stamps can be modified to keep a double spend database so that the same stamp will not be accepted twice. Note a stamp 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 1:24:040806:foo::511801694b4cd6b0:1e7297a
hashcash -cd -b 10 -r foo 1:24:040806:foo::511801694b4cd6b0:1e7297a
To prevent the double spend database growing indefinately, the recipient can request that stamps be no older than a specified period. After expiry old stamps can dropped from the double spend database as they will no longer be needed -- expired stamps can be rejected based purely on their old date, so the space taken by expired stamps in the double spend database can be saved without risk of accepting an expired though otherwise valid stamp.
The third field of the stamp 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 28 days.
You can provide an alternative validity period with the -e option.
hashcash -cd -b 10 -e 2d -r foo 1:24:040806:foo::511801694b4cd6b0:1e7297a
We gave option -e 2d so the stamps expiry date is 2 days after creation, which is now in the past.
Note: if the creation time is expressed in the stamp 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 stamp 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 stamp is expressed in UTC time.
hashcash -cd -b 10 -r foo 1:24:040806:foo::511801694b4cd6b0:1e7297a
If the -c, -d options are used together, each time a stamp is checked, if it is valid and all of the mandatory aspects of the stamp are verified (collision bits check, resource name check) then the stamp and its 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 28 days (ie stamps expire after 4 weeks).
First mint and then add a stamp:
hashcash -m -b 10 foo -e 1m > stamp
hashcash -cd -e 1m -b 10 -r foo < stamp
hashcash -p now
hashcash -cd -e 1m -b 10 -r foo < stamp
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.sdb
As a convenience you can purge at the same time as checking stamps by using the -p option with the -c option.
hashcash -m -b 10 foo > stamp
hashcash -cd -p now -e 1 -b 10 -r foo < stamp
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 < stamp
hashcash
to purge any expired stamps no more than once per
day.
hashcash -p 1M -j foo
hashcash
to purge only expired stamps matching resource foo
once per month.
hashcash -p now -k
hashcash
to purge all stamps (expired and unexpired) now.
The current stamp format is version 1. This tool can verify hashcash version 0 stamps also, but version 0 stamps are no longer created as they are being phased out in favor of the more extensible v1 stamp format.
where
name1=2,3;name2;name3=var1=2,var2=3,2,val
Which would be extension name1 has values 2 and 3; extension name2 has no values; extension name3 has 3 values ``var1=2'', ``var2=3'', ``2'' and ``val''. The hashcash extension may interpret the values as it sees fit eg ``var1=2'' could be the value of an option to the extension name3.
hashcash
returns success (exit code 0) after successfully minting a
stamp, after fully checking a stamp and finding it valid, and after a
timing test.
If when checking a stamp 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 stamp, if the stamp 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>
sha1sum(1), sha1(1), http://www.hashcash.org/