PBKDF2 (Password-Based Key Derivation Function 2) is, according to Wikipedia [http://en.wikipedia.org/wiki/PBKDF2], a "key derivation function that is part of RSA Laboratories' Public-Key Cryptography Standards (PKCS) series, specifically PKCS #5 v2.0, also published as Internet Engineering Task Force's http://tools.ietf.org/html/rfc2898%|%RFC 2898%|%." Basically, using passwords as cryptographic keys isn't considered good enough, so "Password-Based Key Derivation" is used to turn your password into a cryptographic key that ''is'' good enough. Since Google gave no usable hits regarding this topic.. here we go: pure Tcl PBKDF2 with SHA-256 (with timing capability)! ====== package require sha256 namespace eval ::pbkdf2 { variable version 1.0.5 } proc ::pbkdf2::pbkdf2 {password salt count dklen} { set hlen 32 ;# 256 bits -> 32 bytes if {$dklen > (2**32-1)*$hlen} { error "derived key too long" } set l [expr {int(ceil(double($dklen)/$hlen))}] # set r [expr {$dklen-($l-1)*$hlen}] #set t1 [clock milliseconds] set dkl [list] for {set i 1} {$i <= $l} {incr i} { set xsor [debin [set salty [::sha2::hmac -bin -key $password "$salt[binary format I $i]"]]] for {set j 1} {$j < $count} {incr j} { set xsor [expr {$xsor ^ [debin [set salty [::sha2::hmac -bin -key $password $salty]]]}] } lappend dkl $xsor } #set t2 [clock milliseconds] #puts "[expr {($t2-$t1)/1000.0}] s" set dk [list] foreach dkp $dkl { set dkhl [list] while {$dkp > 0} { lappend dkhl [binary format Iu* [expr {$dkp & 0xFFFFFFFF}]] set dkp [expr {$dkp >> 32}] } lappend dk [join [lreverse $dkhl] ""] } # binary scan [string range [join $dk ""] 0 [incr dklen -1]] H* r # return $r return [string range [join $dk ""] 0 [incr dklen -1]] } proc ::pbkdf2::debin {vat} { binary scan $vat Iu* rl return [expr {([lindex $rl 0] << 224) + ([lindex $rl 1] << 192) + ([lindex $rl 2] << 160) + ([lindex $rl 3] << 128) + ([lindex $rl 4] << 96) + ([lindex $rl 5] << 64) + ([lindex $rl 6] << 32) + [lindex $rl 7]}] # set sh 224 # set rs 0 # foreach r $rl { # incr rs [expr {$r << $sh}] # incr sh -32 # } # return $rs } package provide pbkdf2 $::pbkdf2::version ====== Feel free to find use for it. And anything (excluding Critcl and friends) making it run faster is highly appreciated. http://tools.ietf.org/html/draft-josefsson-scrypt-kdf-00#section-10%|%"Password NaCl 80000 64"%|% took 331 seconds for me. <> Cryptography