hashcash

package module
Version: v0.0.0-...-f4a6a1a Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 15, 2018 License: MIT Imports: 14 Imported by: 0

README

Hashcash

Hashcash is a Go library which implements the hashcash algorithm. Hashcash is a proof-of-work algorithm, which has been used as a denial-of-service counter measure technique in a number of systems. To learn more about hashcash, go here.

Installation

go get github.com/umahmood/hashcash

Usage

Computing a hashcash:

package main

import (
    "fmt"
    
    "github.com/umahmood/hashcash"
)

func validateResource(resource string) bool {
    // validate resource. resource could be an email, ip 
    // address, etc... so for an email we could check it 
    // exists in the database.
    return true
}

func main() {
    hc, err := hashcash.New(
        &hashcash.Resource{
            Data:          "someone@gmail.com",
            ValidatorFunc: validateResource,
        },
        nil, // use default config.
    )
    if err != nil {
        // handle error
    }
    
    solution, err := hc.Compute()
    if err != nil {
        if err != hashcash.ErrSolutionFail {
            // did not find a solution, can call compute again.
        }
    } 
    fmt.Println(solution)
}

Output:

1:20:040806:foo::65f460d0726f420d:13a6b8
$ echo -n "1:20:040806:foo::65f460d0726f420d:13a6b8" | shasum
00000f91d51a9c213f9b7420c35c62b5e818c23e

Verifying a hashcash:

valid, err := hc.Verify(solution)
if err != nil {
    // handle error
}
if !valid {
   // hashcash token failed verification.
}

Storage:

In order to detect double spending, hashcash stores verified hashcash tokens in a sqlite3 database. This database is stored in ~/.hashcash/spent.db.

If you would like to change the underlying storage (i.e. to an in memory hash table) or location. You will need to build a type which satisfies the Storage interface.

To Do

  • Allow entries in default storage (sqlite3 database) to be purged.

Documentation

http://godoc.org/github.com/umahmood/hashcash

License

See the LICENSE file for license rights and limitations (MIT).

Documentation

Overview

Package hashcash a library which implements the hashcash proof-of-work algorithm.

Computing a hashcash:

package main

import (
    "fmt"

    "github.com/umahmood/hashcash"
)

func validateResource(resource string) bool {
    // validate resource. resource could be an email, ip
    // address, etc... so for an email we could check it
    // exists in the database.
    return true
}

func main() {
    hc, err := hashcash.New(
        &hashcash.Resource{
            Data:          "someone@gmail.com",
            ValidatorFunc: validateResource,
        },
        nil, // use default config.
    )
    if err != nil {
        // handle error
    }

    solution, err := hc.Compute()
    if err != nil {
        if err != hashcash.ErrSolutionFail {
            // did not find a solution, can call compute again.
        }
    }
    fmt.Println(solution)
}

Verifying a hashcash:

valid, err := hc.Verify(solution)
if err != nil {
    // handle error
}
if !valid {
   // hashcash token failed verification.
}

Index

Constants

View Source
const (
	Major = 1
	Minor = 0
	Patch = 0
)

Semantic versioning - http://semver.org/

Variables

View Source
var (
	// ErrSolutionFail error cannot compute a solution
	ErrSolutionFail = errors.New("exceeded 2^20 iterations failed to find solution")

	// ErrResourceEmpty error empty hashcash resource
	ErrResourceEmpty = errors.New("empty hashcash resource")

	// ErrInvalidHeader error invalid hashcash header format
	ErrInvalidHeader = errors.New("invalid hashcash header format")

	// ErrNoCollision error n 5 most significant hex digits (n most significant
	// bits are not 0.
	ErrNoCollision = errors.New("no collision most significant bits are not zero")

	// ErrTimestamp error futuristic and expired time stamps are rejected
	ErrTimestamp = errors.New("time stamp is too far into the future or expired")

	// ErrResourceFail error hashcash resource data did not pass validation
	ErrResourceFail = errors.New("resource data did not pass validation")

	// ErrSpent error avoid accepting the same stamp twice
	ErrSpent = errors.New("hashcash has already been spent")
)
View Source
var DefaultConfig = &Config{
	Bits:    20,
	Future:  time.Now().AddDate(0, 0, 2),
	Expired: time.Now().AddDate(0, 0, -30),
}

DefaultConfig default hashcash configuration

Functions

func Version

func Version() string

Version returns library version.

Types

type Config

type Config struct {
	// Bits recommended default collision sizes are 20-bits
	Bits int
	// Expiry time before hashcash tokens are considered expired. Recommended
	// expiry time is 28 days
	Expired time.Time
	// Future hashcash in the future that should be rejected. Recommended
	// tolerance for clock skew is 48 hours
	Future time.Time
	// Storage underlying storage where hashcash tokens are stored and retrieved.
	Storage Storage
}

Config for a hashcash instance

type DB

type DB struct {
	// contains filtered or unexported fields
}

DB instance

func (*DB) Add

func (d *DB) Add(hash string) error

Add a new hashcash entry to the database

func (*DB) Spent

func (d *DB) Spent(hash string) bool

Spent checks if a hashcash entry already exists in the database

type Hashcash

type Hashcash struct {
	// contains filtered or unexported fields
}

Hashcash instance

func New

func New(res *Resource, config *Config) (*Hashcash, error)

New creates a new Hashcash instance

func (*Hashcash) Compute

func (h *Hashcash) Compute() (string, error)

Compute a new hashcash header. If no solution can be found 'ErrSolutionFail' error is returned.

func (*Hashcash) Verify

func (h *Hashcash) Verify(header string) (bool, error)

Verify that a hashcash header is valid. If the header is not in a valid format, ErrInvalidHeader error is returned.

type Purger

type Purger interface {
	PurgeExpired(time.Time) error
	PurgeSingle(string) error
	PurgeAll() error
}

Purger purges hashcash entries from the underlying storage

type Resource

type Resource struct {
	// Data email, IP address, etc...
	Data string
	// ValidatorFunc user supplied function which validates Data
	ValidatorFunc func(string) bool
}

Resource represents a hashcash resource

type Spender

type Spender interface {
	Add(string) error
	Spent(string) bool
}

Spender operations which can be performed on storage.

type Storage

type Storage interface {
	Spender
}

Storage store and retrieve hashcash entries

func NewSQLite3DB

func NewSQLite3DB() (Storage, error)

NewSQLite3DB creates a new DB Storage instance.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
t or T : Toggle theme light dark auto
y or Y : Canonical URL