Hashcash (hashcash v1.2.0)

Elixir implementation of the hashcash algorigthm as described in http://hashcash.org and https://en.wikipedia.org/wiki/Hashcash

Generate a stamp for another party to generate:

Hashcash.resource("foobar") |> Hashcash.resource_format
%Hashcash{
  bits: 20,
  counter: 0,
  date: [year: 2022, month: 9, day: 2],
  ext: nil,
  rand: "gAbLlrNJFwsKWincKbOvNP6kNkUHRt1",
  resource: "foobar",
  stamp_base: "1:20:220902:foobar::gAbLlrNJFwsKWincKbOvNP6kNkUHRt1",
  stamp_string: "1:20:220902:foobar::gAbLlrNJFwsKWincKbOvNP6kNkUHRt1:0",
  version: 1
}

The stamp_string can be sent to the other party.

To verify:

iex(4)> Hashcash.stamp("1:20:220902:foobar::GszJUJJC+tcQSkvw+GPg7FBYYi289eL:294524") |> Hashcash.verify("foobar")
{:ok, :verified}

Link to this section Summary

Functions

Count leading zero bits in a bitstring

Generate date string section from date keywords list

Generate date keywords list of now

Generate a full stamp, doing the work

Generate the rand field using a crypto.strong_rand_bytes

Create a new %Hashcash with resource_string and today as the date.

Create a new %Hashcash with the resource_string and specified date Keyword list

Modify the bits required of a %Hashcash

Modify the date of a %Hashcash

Return %Hashcash with stamp_base and stamp_string set.

Generate or return hcash.base from properies This excludes the count field so that the generator can use this base with successive iterations of new counts by appending just the count.

Append the counter to the base to make a full stamp string

Set rand field of %Hashcash to newly generated string

Create a %Hashcash stamp from a stamp string. Use this to turn a string that may be passed between parties to a form that can be used with the rest of the functions here.

Validate the stamp string proof-of-work only. Use verify for full check

Verfiy all attributes and proof of work against a list of acceptable resources or a single resource string

Verify stamp resource is a valid resource

Verify date keyword list is within 2 days

Count leading zero bits in SHA1 hash of stamp.stamp_string

Link to this section Types

@type t() :: %Hashcash{
  bits: term(),
  counter: term(),
  date: term(),
  ext: term(),
  rand: term(),
  resource: term(),
  stamp_base: term(),
  stamp_string: term(),
  version: term()
}

Link to this section Functions

Link to this function

count_lead_zeros_in_bitstring(bs, count \\ 0)

@spec count_lead_zeros_in_bitstring(bs :: String.t(), count :: integer()) :: integer()

Count leading zero bits in a bitstring

Link to this function

date_format(date_keywords)

@spec date_format(date_keywords :: Keyword.t()) :: String.t()

Generate date string section from date keywords list

@spec date_now() :: Keyword.t()

Generate date keywords list of now

Link to this function

generate(hcash)

@spec generate(hcash :: t()) :: t()

Generate a full stamp, doing the work

Link to this function

rand_generate()

@spec rand_generate() :: String.t()

Generate the rand field using a crypto.strong_rand_bytes

Link to this function

resource(resource_string)

@spec resource(resource_string :: String.t()) :: t()

Create a new %Hashcash with resource_string and today as the date.

Link to this function

resource(resource_string, date)

@spec resource(resource_string :: String.t(), date :: Keyword.t()) :: t()

Create a new %Hashcash with the resource_string and specified date Keyword list

Link to this function

resource_bits(hcash, bits)

@spec resource_bits(hcash :: t(), bits :: integer()) :: t()

Modify the bits required of a %Hashcash

Link to this function

resource_date(hcash, y, m, d)

@spec resource_date(hcash :: t(), y :: integer(), m :: integer(), d :: integer()) ::
  t()

Modify the date of a %Hashcash

Link to this function

resource_format(hcash)

@spec resource_format(hcash :: t()) :: t()

Return %Hashcash with stamp_base and stamp_string set.

Link to this function

resource_format_base(hcash)

@spec resource_format_base(hcash :: t()) :: String.t()

Generate or return hcash.base from properies This excludes the count field so that the generator can use this base with successive iterations of new counts by appending just the count.

Link to this function

resource_format_string(base, counter)

@spec resource_format_string(base :: String.t(), counter :: integer()) :: String.t()

Append the counter to the base to make a full stamp string

Link to this function

resource_rand(hcash)

@spec resource_rand(stamp :: t()) :: t()

Set rand field of %Hashcash to newly generated string

Link to this function

stamp(stamp_string)

Create a %Hashcash stamp from a stamp string. Use this to turn a string that may be passed between parties to a form that can be used with the rest of the functions here.

Link to this function

strip_trailing_char(string)

@spec strip_trailing_char(string :: String.t()) :: String.t()
Link to this function

validate(hcash)

@spec validate(hcash :: t()) :: tuple()

Validate the stamp string proof-of-work only. Use verify for full check

Link to this function

verify(hcash, valid_resources)

@spec verify(hcash :: t(), valid_resources :: list()) :: tuple()
@spec verify(hcash :: t(), single_resource :: String.t()) :: tuple()

Verfiy all attributes and proof of work against a list of acceptable resources or a single resource string

Link to this function

verify_resource(resource, valid_resources)

@spec verify_resource(resource :: String.t(), valid_resources :: list()) :: tuple()

Verify stamp resource is a valid resource

Link to this function

verify_time(date)

@spec verify_time(date :: Keyword.t()) :: tuple()

Verify date keyword list is within 2 days

Link to this function

zero_bits_count(hcash)

@spec zero_bits_count(hcash :: t()) :: integer()

Count leading zero bits in SHA1 hash of stamp.stamp_string