! Copyright (C) 2009 Diego Martinelli. ! See http://factorcode.org/license.txt for BSD license. USING: accessors byte-arrays calendar calendar.format checksums checksums.sha1 classes.tuple fry kernel make math math.functions math.parser math.ranges present random sequences 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 date< [ pad-00 dup % ] tri@ ] "" make [ 3drop ] dip 2 8 rot subseq ; ! Random salt is formed by ascii characters ! between 33 and 126 : available-chars ( -- seq ) 33 126 [a,b] [ 1string ] map [ ":" = not ] filter ; PRIVATE> ! Generate a 'length' long random salt : salt ( length -- salted ) '[ _ [ available-chars random % ] times ] "" make ; TUPLE: hashcash version bits date resource ext salt suffix ; : ( -- tuple ) hashcash new 1 >>version 16 >>bits get-date >>date "" >>ext 8 salt >>salt ; M: hashcash string>> tuple-slots [ present ] map ":" join ; hex >>suffix ; : get-checksum ( tuple -- checksum ) string>> sha1 checksum-bytes hex-string ; : extract-bits ( checksum tuple -- bits ) bits>> 4 / ceiling 0 spin subseq ; : is-valid? ( bits -- ? ) [ CHAR: 0 = ] all? ; : (mint) ( tuple counter -- tuple ) 2dup next-suffix get-checksum pick extract-bits is-valid? [ drop ] [ 1+ (mint) ] if ; PRIVATE> : mint* ( tuple -- str ) 0 (mint) string>> ; : mint ( resource -- str ) swap >>resource mint* ;