Merge branch 'master' of git://factorcode.org/git/factor
commit
cfd22bdc36
|
@ -0,0 +1 @@
|
||||||
|
Diego Martinelli
|
|
@ -0,0 +1,60 @@
|
||||||
|
USING: help.markup help.syntax kernel math ;
|
||||||
|
IN: hashcash
|
||||||
|
|
||||||
|
ARTICLE: "hashcash" "Hashcash"
|
||||||
|
"Hashcash is a denial-of-service counter measure tool."
|
||||||
|
$nl
|
||||||
|
"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 hashcash stamps efficiently."
|
||||||
|
$nl
|
||||||
|
"More info on hashcash:"
|
||||||
|
$nl
|
||||||
|
{ $url "http://www.hashcash.org/" } $nl
|
||||||
|
{ $url "http://en.wikipedia.org/wiki/Hashcash" } $nl
|
||||||
|
{ $url "http://www.ibm.com/developerworks/linux/library/l-hashcash.html?ca=dgr-lnxw01HashCash" } $nl
|
||||||
|
"This library provide basic utilities for hashcash creation and validation."
|
||||||
|
$nl
|
||||||
|
"Creating stamps:"
|
||||||
|
{ $subsection mint }
|
||||||
|
{ $subsection mint* }
|
||||||
|
"Validation:"
|
||||||
|
{ $subsection check-stamp }
|
||||||
|
"Hashcash tuple and constructor:"
|
||||||
|
{ $subsection hashcash }
|
||||||
|
{ $subsection <hashcash> }
|
||||||
|
"Utilities:"
|
||||||
|
{ $subsection salt } ;
|
||||||
|
|
||||||
|
{ mint mint* <hashcash> check-stamp salt } related-words
|
||||||
|
|
||||||
|
HELP: mint
|
||||||
|
{ $values { "resource" "a string" } { "stamp" "generated stamp" } }
|
||||||
|
{ $description "This word generate a valid stamp with default parameters and the specified resource." } ;
|
||||||
|
|
||||||
|
HELP: mint*
|
||||||
|
{ $values { "tuple" "a tuple" } { "stamp" "generated stamp" } }
|
||||||
|
{ $description "As " { $snippet "mint" } " but it takes an hashcash tuple as a parameter." } ;
|
||||||
|
|
||||||
|
HELP: check-stamp
|
||||||
|
{ $values { "stamp" "a string" } { "?" boolean } }
|
||||||
|
{ $description "Check for stamp's validity. Only supports hashcash version 1." } ;
|
||||||
|
|
||||||
|
HELP: salt
|
||||||
|
{ $values { "length" integer } { "salted" "a string" } }
|
||||||
|
{ $description "It generates a random string of " { $snippet "length" } " characters." } ;
|
||||||
|
|
||||||
|
HELP: <hashcash>
|
||||||
|
{ $values { "tuple" object } }
|
||||||
|
{ $description "It fill an hashcash tuple with the default values: 1 as hashcash version, 20 as bits, today's date as date and a random 8 character long salt" } ;
|
||||||
|
|
||||||
|
HELP: hashcash
|
||||||
|
{ $class-description "An hashcash object. An hashcash have the following slots:"
|
||||||
|
{ $table
|
||||||
|
{ { $slot "version" } "The version number. Only version 1 is supported." }
|
||||||
|
{ { $slot "bits" } "The claimed bit value." }
|
||||||
|
{ { $slot "date" } "The date a stamp was minted." }
|
||||||
|
{ { $slot "resource" } "The resource for which a stamp is minted." }
|
||||||
|
{ { $slot "ext" } "Extensions that a specialized application may want." }
|
||||||
|
{ { $slot "salt" } "A random salt." }
|
||||||
|
{ { $slot "suffix" } "The computed suffix. This is supposed to be manipulated by the library." }
|
||||||
|
}
|
||||||
|
} ;
|
|
@ -0,0 +1,15 @@
|
||||||
|
USING: accessors sequences tools.test hashcash ;
|
||||||
|
|
||||||
|
[ t ] [ "foo@bar.com" mint check-stamp ] unit-test
|
||||||
|
|
||||||
|
[ t ] [
|
||||||
|
<hashcash>
|
||||||
|
"foo@bar.com" >>resource
|
||||||
|
16 >>bits
|
||||||
|
mint* check-stamp ] unit-test
|
||||||
|
|
||||||
|
[ t ] [
|
||||||
|
"1:20:040927:mertz@gnosis.cx::odVZhQMP:7ca28" check-stamp
|
||||||
|
] unit-test
|
||||||
|
|
||||||
|
[ 8 ] [ 8 salt length ] unit-test
|
|
@ -0,0 +1,90 @@
|
||||||
|
! Copyright (C) 2009 Diego Martinelli.
|
||||||
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
|
USING: accessors byte-arrays calendar calendar.format
|
||||||
|
checksums checksums.openssl classes.tuple
|
||||||
|
fry kernel make math math.functions math.parser math.ranges
|
||||||
|
present random sequences splitting strings syntax ;
|
||||||
|
IN: hashcash
|
||||||
|
|
||||||
|
! Hashcash implementation
|
||||||
|
! Reference materials listed below:
|
||||||
|
!
|
||||||
|
! http://hashcash.org
|
||||||
|
! http://en.wikipedia.org/wiki/Hashcash
|
||||||
|
! http://www.ibm.com/developerworks/linux/library/l-hashcash.html?ca=dgr-lnxw01HashCash
|
||||||
|
!
|
||||||
|
! And the reference implementation (in python):
|
||||||
|
! http://www.gnosis.cx/download/gnosis/util/hashcash.py
|
||||||
|
|
||||||
|
<PRIVATE
|
||||||
|
|
||||||
|
! Return a string with today's date in the form YYMMDD
|
||||||
|
: get-date ( -- str )
|
||||||
|
now [ year>> 100 mod pad-00 ]
|
||||||
|
[ month>> pad-00 ]
|
||||||
|
[ day>> pad-00 ] tri 3append ;
|
||||||
|
|
||||||
|
! Random salt is formed by ascii characters
|
||||||
|
! between 33 and 126
|
||||||
|
: available-chars ( -- seq )
|
||||||
|
33 126 [a,b] [ CHAR: : = not ] filter ;
|
||||||
|
|
||||||
|
PRIVATE>
|
||||||
|
|
||||||
|
! Generate a 'length' long random salt
|
||||||
|
: salt ( length -- salted )
|
||||||
|
available-chars '[ _ random ] "" replicate-as ;
|
||||||
|
|
||||||
|
TUPLE: hashcash version bits date resource ext salt suffix ;
|
||||||
|
|
||||||
|
: <hashcash> ( -- tuple )
|
||||||
|
hashcash new
|
||||||
|
1 >>version
|
||||||
|
20 >>bits
|
||||||
|
get-date >>date
|
||||||
|
8 salt >>salt ;
|
||||||
|
|
||||||
|
M: hashcash string>>
|
||||||
|
tuple-slots [ present ] map ":" join ;
|
||||||
|
|
||||||
|
<PRIVATE
|
||||||
|
|
||||||
|
: sha1-checksum ( str -- bytes )
|
||||||
|
openssl-sha1 checksum-bytes ; inline
|
||||||
|
|
||||||
|
: set-suffix ( tuple guess -- tuple )
|
||||||
|
>hex >>suffix ;
|
||||||
|
|
||||||
|
: get-bits ( bytes -- str )
|
||||||
|
[ >bin 8 CHAR: 0 pad-head ] { } map-as concat ;
|
||||||
|
|
||||||
|
: checksummed-bits ( tuple -- relevant-bits )
|
||||||
|
dup string>> sha1-checksum
|
||||||
|
swap bits>> 8 / ceiling head get-bits ;
|
||||||
|
|
||||||
|
: all-char-zero? ( seq -- ? )
|
||||||
|
[ CHAR: 0 = ] all? ; inline
|
||||||
|
|
||||||
|
: valid-guess? ( checksum tuple -- ? )
|
||||||
|
bits>> head all-char-zero? ;
|
||||||
|
|
||||||
|
: (mint) ( tuple counter -- tuple )
|
||||||
|
2dup set-suffix checksummed-bits pick
|
||||||
|
valid-guess? [ drop ] [ 1+ (mint) ] if ;
|
||||||
|
|
||||||
|
PRIVATE>
|
||||||
|
|
||||||
|
: mint* ( tuple -- stamp )
|
||||||
|
0 (mint) string>> ;
|
||||||
|
|
||||||
|
: mint ( resource -- stamp )
|
||||||
|
<hashcash>
|
||||||
|
swap >>resource
|
||||||
|
mint* ;
|
||||||
|
|
||||||
|
! One might wanna add check based on the date,
|
||||||
|
! passing a 'good-until' duration param
|
||||||
|
: check-stamp ( stamp -- ? )
|
||||||
|
dup ":" split [ sha1-checksum get-bits ] dip
|
||||||
|
second string>number head all-char-zero? ;
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Hashcash implementation
|
Loading…
Reference in New Issue