From a2abe1753f763b777a7d5e10d0d65d572442acb4 Mon Sep 17 00:00:00 2001 From: Diego Martinelli <martinelli.diego@gmail.com> Date: Fri, 8 May 2009 10:33:20 +0200 Subject: [PATCH 1/4] Initial commit --- extra/hashcash/authors.txt | 0 extra/hashcash/hashcash.factor | 4 ++++ 2 files changed, 4 insertions(+) create mode 100755 extra/hashcash/authors.txt create mode 100755 extra/hashcash/hashcash.factor diff --git a/extra/hashcash/authors.txt b/extra/hashcash/authors.txt new file mode 100755 index 0000000000..e69de29bb2 diff --git a/extra/hashcash/hashcash.factor b/extra/hashcash/hashcash.factor new file mode 100755 index 0000000000..fe7cf10bd3 --- /dev/null +++ b/extra/hashcash/hashcash.factor @@ -0,0 +1,4 @@ +! Copyright (C) 2009 Your name. +! See http://factorcode.org/license.txt for BSD license. +USING: ; +IN: hashcash From dedb1d753660d719bf9b3924179359b2458765f6 Mon Sep 17 00:00:00 2001 From: Diego Martinelli <martinelli.diego@gmail.com> Date: Sat, 9 May 2009 17:23:41 +0200 Subject: [PATCH 2/4] Main implementation done. Need docs and tests. --- extra/hashcash/authors.txt | 1 + extra/hashcash/hashcash.factor | 90 +++++++++++++++++++++++++++++++++- 2 files changed, 89 insertions(+), 2 deletions(-) diff --git a/extra/hashcash/authors.txt b/extra/hashcash/authors.txt index e69de29bb2..f6e3b59c4c 100755 --- a/extra/hashcash/authors.txt +++ b/extra/hashcash/authors.txt @@ -0,0 +1 @@ +Diego Martinelli diff --git a/extra/hashcash/hashcash.factor b/extra/hashcash/hashcash.factor index fe7cf10bd3..3e75aad94c 100755 --- a/extra/hashcash/hashcash.factor +++ b/extra/hashcash/hashcash.factor @@ -1,4 +1,90 @@ -! Copyright (C) 2009 Your name. +! Copyright (C) 2009 Diego Martinelli. ! See http://factorcode.org/license.txt for BSD license. -USING: ; +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 -- str ) + 0 (mint) string>> ; + +: mint ( resource -- str ) + <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? ; + From ef5c9844e4fe34e207f6795605c44d05746d5e3c Mon Sep 17 00:00:00 2001 From: Diego Martinelli <martinelli.diego@gmail.com> Date: Sun, 10 May 2009 14:20:23 +0200 Subject: [PATCH 3/4] Done with docs and unit tests. --- extra/hashcash/hashcash.factor | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extra/hashcash/hashcash.factor b/extra/hashcash/hashcash.factor index 3e75aad94c..1eb690b20f 100755 --- a/extra/hashcash/hashcash.factor +++ b/extra/hashcash/hashcash.factor @@ -74,10 +74,10 @@ M: hashcash string>> PRIVATE> -: mint* ( tuple -- str ) +: mint* ( tuple -- stamp ) 0 (mint) string>> ; -: mint ( resource -- str ) +: mint ( resource -- stamp ) <hashcash> swap >>resource mint* ; From 85facc27d6c610fabc142cc1476c44d5f59b2ec0 Mon Sep 17 00:00:00 2001 From: Diego Martinelli <martinelli.diego@gmail.com> Date: Sun, 10 May 2009 14:27:35 +0200 Subject: [PATCH 4/4] Ops. --- extra/hashcash/hashcash-docs.factor | 60 ++++++++++++++++++++++++++++ extra/hashcash/hashcash-tests.factor | 15 +++++++ extra/hashcash/summary.txt | 1 + 3 files changed, 76 insertions(+) create mode 100644 extra/hashcash/hashcash-docs.factor create mode 100644 extra/hashcash/hashcash-tests.factor create mode 100644 extra/hashcash/summary.txt diff --git a/extra/hashcash/hashcash-docs.factor b/extra/hashcash/hashcash-docs.factor new file mode 100644 index 0000000000..2cfe0bb68e --- /dev/null +++ b/extra/hashcash/hashcash-docs.factor @@ -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." } + } +} ; diff --git a/extra/hashcash/hashcash-tests.factor b/extra/hashcash/hashcash-tests.factor new file mode 100644 index 0000000000..efef40acfa --- /dev/null +++ b/extra/hashcash/hashcash-tests.factor @@ -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 diff --git a/extra/hashcash/summary.txt b/extra/hashcash/summary.txt new file mode 100644 index 0000000000..e5ec1d4064 --- /dev/null +++ b/extra/hashcash/summary.txt @@ -0,0 +1 @@ +Hashcash implementation