Merge branch 'hashcash' of git://github.com/martind/factor
						commit
						f07707fb72
					
				|  | @ -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