PBKDF2 (Password-Based Key Derivation Function 2) is, according to Wikipedia [1 ], 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 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)!

JJM 2016-02-25: It seems like an implementation of this algorithm should be included in tcllib?

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. "Password NaCl 80000 64" took 331 seconds for me.

APN TWAPI includes an implementation for Windows.