sha2

There is no such thing as sha2. The title is intended to cover the family of hashing algorithms beyond sha1.

The sha1 secure hash algorithm produces a digest of 160 bits. This provides 80 bits of security against collisions given the birthday attack (ref). An updated document from NIST [L1 ] specifies a new family of secure hashing algorithms with longer digest lengths, specifically SHA-256, SHA-384, and SHA-512. An additional update also specifies SHA-224 [L2 ].

tcllib now includes a pure-tcl implementation of SHA-224 and SHA-256. For comparison, here are some timing data for the pure-Tcl implementation of all the digests in tcllib

 md4    time: 248 microseconds per iteration using tcl
 md5    time: 275 microseconds per iteration using tcl
 sha1   time: 409 microseconds per iteration using tcl
 rmd128 time: 410 microseconds per iteration using tcl
 rmd160 time: 679 microseconds per iteration using tcl
 sha224 time: 880 microseconds per iteration using tcl
 sha256 time: 894 microseconds per iteration using tcl

bll 2018-8-20: I have an implementation (in C) available that does SHA-512, SHA-384, SHA-512/256 and SHA-512/224. It can also be compiled to SHA-256, SHA-224 (already available in Tcllib). Pre-built libraries (for the 512 bit versions) are available at: https://sourceforge.net/projects/tcl-sha/files/

bll 2020-5-6: Updated the tcl-sha package to version 1.0 and reworked the API. Repackaged so that it easier for people to install: https://sourceforge.net/projects/tcl-sha/files/


RLH - I have the latest ActiveTcl 8.4.9 and I do not see anything about SHA-256/384/512 in the docs. Were those added after the 8.4.9 release? addendum: I installed 8.5 and no sign in the docs about the other SHA stuff.

PT 22-Feb-2005: When I say 'now' above I actually mean today - 22 Feb 2005. You can grab the CVS sources from

  cvs -d:pserver:[email protected]:/cvsroot/tcllib co tcllib/modules/sha1

until we create a new release.


LV 2007 Jan 31 In the latest tcllib, I see a file called tcllib/modules/sha2/sha256.tcl . The top of the page talks about sha1, and the code appears to implement the 224 and 256 bit algorithms. The longer codes don't appear to be there yet. I also don't see anything in the doc pages. Of course, right now, a competition for sha3 is in the works, so perhaps someone stopped because the older stuff have been challenged.

AMG: 2018-9-19: SHA-3 is complete and resulted in FIPS 202 [L3 ]. Is anyone working on a Tcl implementation?

bll: 2018-9-19: I just finished the SHA-2 implementation [L4 ]. SHA-3 looked rather more complicated, and is it even necessary? SHA-2 is pretty good. See also: [L5 ].

AMG: SHA-3 is intended to be different in structure than SHA-1/2. As for wanting SHA-3, the point is being interoperable with other systems using SHA-3, in my case Fossil.


See http://code.wikia.com/wiki/SHA_checksum for a place where a Tcl enthusist might consider adding an example of the use of the tcllib module to calculate a sha checksum.

Documentation: https://core.tcl-lang.org/tcllib/doc/trunk/embedded/md/tcllib/files/modules/sha1/sha256.md


EL - 2017-08-08 18:53:04

Missing parts of sha and crypto in general can easily be added in with ffidl and openssl (or any other C based crypto library). I did this for HMAC-SHA512, with the following lines:

file: openssl_hmac-0.1.tm

#
# ffidl wrapper for openssl hmac512 algorithm
#
package require Tcl 8.6
package require Ffidl 0.7
package require Ffidlrt 0.2

namespace eval openssl {

#
# library hooks and definitions
#
namespace eval dll {

variable CRYPTODLL [if {$::tcl_platform(platform) eq "windows"} {
    subst libeay32.dll
} else {
    subst libcrypto[info sharedlibext]
}]

ffidl::callout evp_sha512 {} pointer [ffidl::symbol $CRYPTODLL EVP_sha512]
ffidl::callout hmac \
    {pointer pointer-byte int pointer-byte int pointer-var pointer-var} {unsigned char} \
        [ffidl::symbol $CRYPTODLL HMAC]

} ;# namespace openssl::dll

#
# procedures
#

## computes the hmac512 of given data with given key
proc hmac512 {key data args} {
    set mdPtr [binary format x64]
    set mdlenPtr [binary format x[ffidl::info sizeof int]]
    
    set key [binary format a* $key]
    set data [binary format a* $data]
    set r [dll::hmac [dll::evp_sha512] $key [string len $key] $data [string len $data] mdPtr mdlenPtr]
    binary scan $r [ffidl::info format {unsigned char}] ret
    if {$ret == 0} {
        throw {OPENSSL HMAC} "hmac512 returned NULL"
    }
    binary scan $mdlenPtr [ffidl::info format unsigned] mdlen
    binary scan $mdPtr a[set mdlen] md
    if {[lsearch $args -b64] < 0} {
        return $md
    }
    binary encode base64 $md
}

} ;# namespace openssl

Usage:

package require openssl_hmac 0.1
set base64_encoded_hmac_hash [openssl::hmac512 key data -b64]

Of course there is much more that can be done, i.e. other sha algorithms, certificates, ...

See also