NAME
    hashcash - hashcash anti-spam / denial of service counter-measure tool

SYNOPSIS
  Mint (create) token:
    hashcash [ *options* ] [ *-b bits* ] [ *resource* ]>

  Check token:
    hashcash *-c* [ *options* ] *-b bits* *-r resource* [ *token* ]

  Speed estimates:
    hashcash *-s* [ *options* ] [ *-b bits* ]

  Purge database:
    hashcash *-p now* [ *-j resource* ] [ *-k* ] [ *-t time* ] [ *-u* ]

  Count collision bits:
    hashcash *-w* [ *options* ] [ *token* ]

  Get resource name:
    hashcash *-n* [ *options* ] [ *token* ]

  Get time remaining until expiry
    hashcash *-l* [ *options* ] *-e period* [ *token* ]

DESCRIPTION
    Hashcash is a denial-of-service counter measure tool. It's 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 tokens to attach to
    emails you send, and to verify hashcash tokens attached to emails you
    receive. Email senders attach hashcash tokens 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 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. This package also includes a
    sha1 implementation which behaves somewhat like md5sum, but with SHA1.

    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/

USAGE NOTES
    In this man page a resource name is the name of the service or address
    the token is created for. In the case of email, the resource name is the
    recipient's email address in the form user@domain.com.

  Minting tokens
    If neither the *-c* or *-s* option are given, it is assumed that you
    want to mint a token.

    The resource name (recipient's email address) 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.

  Checking tokens
    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 (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 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 (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; exit code unchecked (exit code 2)
    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 (exit code 2) 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 (exit code 2) 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 fully check the
    validty of a token. If these criteria are not met, the program will
    return exit code unchecked (exit code 2) on exit. (See also the *-y*
    flag.)

  Double Spending Protection
    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.

  Purging Periodically vs on Next Access
    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* option 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.

  Speed Estimates
    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 with this option, instead an estimate of how
    many seconds it would take to mint a token of the given size in bits is
    computed.

  Notes
    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, or when quiet mode
    is in effect the output is printed without description (ie just bits,
    just seconds, just resource).

OPTIONS
    *-c*
        Check the token given as an argument or on stdin for validity.

    *-m*
        Mint a token. If none of *-c*, *-p*, *-s*, *-l*, *-n*, *-w* are
        given it is anyway assumed that the user wishes to mint a token.

    *-b bits*
        When minting a token, request a collision of this many bits. When
        verifying a token require that it have a collision of at minimum
        this many bits, otherwise reject it.

    *-r resource*
        When minting tokens, the resource name (recipient's email address)
        to mint the token against can be given either with *-r resource* or
        as an argument to "hashcash".

        When checking tokens, the resource name (your own email address) 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 (exit code 2) on exit.

    *-e time*
        Expiry period for spent tokens. While checking tokens (using the
        *-c* flag), if the token was minted more than the specified amount
        of time ago, it is considered expired. If this option is not used,
        by default tokens do not expire (they have an expiry period of
        forever). The expiry period is given in seconds by default (an
        argument of 0 means forever). 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 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, 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:

        * period >= 2 years then time format YY is used rounded down to the
        nearest year start;
        * 2 years < period <= 2 months then time format YYMM is used rounded
        down to the nearest month start;
        * 2 months < period <= 2 days then time format YYMMDD is used
        rounded down to the begining of the nearest day;
        * 2 days < period <= 2 hours then time format YYMMDDhh is used
        rounded down to the begining of the nearest hour;
        * 2 hours < period <= 2 minutes then time format YYMMDDhhmm is used
        rounded down to the begining of the nearest minute;
        * period < 2 minutes then time format YYMMDDhhmmss is used in
        seconds.

        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.

    *-d*
        Store tokens in a double spend database. If token has been seen
        before it will be rejected even if it is otherwise valid. The
        default database file is database.db in the current directory.

        It is recommended that 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.

    *-f dbname*
        Use dbname instead of default filename for double spend database.

    *-p period*
        Purges the database of expired tokens if the given time period has
        passed since the last time it was purged. As a convenience *-p now*
        is equivalent to *-p 0* both of which mean purge now, regardless of
        when the database was last purged.

        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.

    *-k*
        Use with option *-p* to request all tokens are purged rather than
        just expired ones.

    *-j resource*
        Use with option *-p* to request that just tokens matching the given
        resource name are to be purged, rather than the default which is to
        purge all expired tokens. If the resource name is the empty string,
        all tokens are matched (this is equivalent to omitting the *-j*
        option).

    *-s*
        Print timing information only, and don't proceed to create a token.
        If combined with *-b* flag print estimate of how long the requested
        collision size would take to compute, if *-s* given by itself, just
        prints speed of the collision finder.

    *-h*
        Print short usage information.

    *-v*
        Print more verbose informational output about the token minting or
        verification. (If -v is the only argument, prints the tool version
        number.)

    *-q*
        Batch mode. Prints no information other than output. This option
        overrides the *-v* option.

    *-X*
        When minting, prints the hashcash email X-header 'X-Hashcash: '
        before the token. Without this option just the bare token is
        printed.

        When checking, if no token is given as an argument, scans stdin for
        a line starting with the string 'X-Hashcash:', and uses the rest of
        the matching line 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.

    *-x string*
        Similar effect to *-X* for minting and checking except you get to
        choose your own header string. For example *-x 'X-Hashcash: '* has
        the same effect as *-X*.

    *-i*
        When checking and using the *-X* or *-x* flag, ignore the blank line
        boundary between headers and body of the message, and check for
        collision in the body too if one is not found in the headers.

    *-t time*
        Pretend the current time is the time given for purposes of minting
        tokens, verifying tokens and purging old tokens from the database.
        Time is given in a format based on UTCTIME format
        YYMMDD[hh[mm[ss]]].

        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).

    *-u*
        Input and output absolute times in UTC (GMT) instead of local time.

    *-a period*
        Add (or subtract if number is negative) a random value from the
        current time before minting the token. This hides the time the token
        was created, which may be useful for anonymous users. Note adding
        (rather than subtracting) a random time may be risky if the token
        takes less than the added time to arrive as the recipient will
        reject tokens with time stamps in the future.

    *-n*
        Print resource name parsed from token being verified. Returns exit
        code unchecked on exit.

    *-l*
        Print number of seconds left before token expires. Returns exit code
        unchecked on exit.

    *-w*
        Print number of bits of collision of token. Returns exit code
        unchecked on exit.

    *-y*
        Returns success if the token is valid even if it is not fully
        checked. Use with *-c* where not all of *-b*, *-d*, *-r* are
        specified to get success exit code on valid but partially checked
        token. Similarly can use with *-n*, *-l*, *-w* with same effect.

EXAMPLES
  Creating tokens
    "hashcash -s"
        Print timing information about how many collisions the machine can
        try per second.

    "hashcash -s -b 32"
        Print how long it would take the machine to compute a 32 bit
        collision (but don't actually compute a collision).

    "hashcash"
        Mint a token. Will prompt for resource name and desired value
        (number of collision bits).

    "hashcash foo"
        Compute collision on resource foo. Will prompt desired value (number
        of collision bits).

    "hashcash foo -b 10"
        Compute 10 bit collision on resource foo.

    "hashcash -a -3d"
        Subtract a random time of between 0 days and 3 days to to the
        token's creation time. This is the same fuzz factor used by
        mixmaster to reduce risk of timing-correlations.

  Examining Tokens
    "hashcash -w 0:020814:foo:4333957e84db47f6"
        Report the value of the token (how many bits of collision) there
        are. The example is a 33 bit collision, which would take on average
        13 hours to create on a 400 Mhz Pentium-II.

    "hashcash -q -b 10 foo | hashcash -w"
        Create a token in batch mode, pass to hashcash on stdin to verify,
        have it print how many bits there were. Note: half of the time you
        get a token 1 bit larger; similarly with decreasing probability you
        can get even larger tokens.

    "hashcash -n 0:020814:foo:21c8cf3099cbf467"
        Report the resource name from the token. The resource name in the
        example is foo.

    "hashcash -l -e 30y 0:020814:foo:21c8cf3099cbf467"
        Report how long until the token expires if it expires in 30 years
        from it's creation date. (Note dates too far into the future run
        into the 2038 end of Epoch, which is the unix time analog of the y2k
        bug).

  Verifying Tokens
    "hashcash -c 0:020814:foo:21c8cf3099cbf467"
        Check if the token is valid. Note as we are not checking the token
        in a double spend database, and did not specify a resource name or
        required number of bits of collision and hashcash will consider the
        token not fully checked, and it will report it as valid but not
        fully unchecked, or as invalid if there is any problem with the
        token.

    "hashcash -c -b24 0:020814:foo:21c8cf3099cbf467"
        Check that the value of the token is greater or equal to 24 bits.
        This example has 24 bit value. If you increase the requested number
        of bits or replace the token with one with less than 24 bit
        collision the token will be rejected.

    "hashcash -c -b24 -r foo 0:020814:foo:21c8cf3099cbf467"
        As above check if the token has sufficient value, but in addition
        check that the resource name given matches the resource name in the
        token.

  Double Spending Prevention
    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"
        Check the token and add to double spent database if it's valid (has
        correct resource name and sufficient value).

    "hashcash -cd -b 10 -r foo 0:020814:foo:21c8cf3099cbf467"
        Try to double spend the token. It will be rejected as double spent.

  Token Expiry
    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"
        Try verifying an old token, the above token was created 11 Aug 2002.

        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"
        Test whether the token is otherwise valid, apart from having
        expired. Omitting the *-e* tells hashcash that the token will never
        expire. An expiry period of forever can also be given explitly like
        this: *-e 0*, where an expiry period of 0 means forever.

  Purging old tokens
    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"
        Note: we specified an expiry on minting in this example, to ensure
        that the token creation time is given in high enough resolution in
        the token that the token will not be considered expired at time of
        creation. (Recall the default resolution is in days, a token created
        with a creation time rounded down to the beginging of the day is
        unlikely to be considered valid 1 minute later unless you mint it at
        midnight UTC time.)

    "hashcash -cd -e 1m -b 10 -r foo < token"
        The token expires in 1 minute. Wait 1 minute and then explicitly
        request that expired tokens be purged:

    "hashcash -p now"
        Then try resubmitting the same token:

    "hashcash -cd -e 1m -b 10 -r foo < token"
        and the token will be rejected anyway as it has expired,
        illustrating why it was not necessary to keep this token in the
        database.

        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"
        to see that the token really is added and then after puring
        subsequently purged due to expiry.

  Purging old tokens on Demand
    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"
        It may be inefficient to purge tokens on every use as the entire
        database has to be scanned for expired tokens. By giving a time
        period to the *-p* option, you can tell "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"
        tells "hashcash" to purge any expired tokens no more than once per
        day.

    "hashcash -p 1M -j foo"
        tells "hashcash" to purge only expired tokens matching resource foo
        once per month.

    "hashcash -p now -k"
        tells "hashcash" to purge all tokens (expired and unexpired) now.

token format
    *ver*:*date*:*resource*:*collision*

    where

    *ver* = 0, this version of hashcash only supports version 0
    *date* = YYMMDD[hh[mm[ss]]]
    *resource* = resource string (eg IP address, email address)
    *collision* = printable string of random alpha-numeric chars

FILES
    hashcash.db
        default double spend database

    hashcash.dbt
        default temporary double spend database used when purging tokens.

EXIT STATUS
    "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.

AUTHOR
    Written by Adam Back <adam@cypherspace.org>

SEE ALSO
    sha1(1), http://www.hashcash.org/

