The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

SHA - Perl interface to the NIST Secure Hash Algorithm

SYNOPSIS

use SHA;

$version = &SHA::sha_version;

$context = new SHA;
$context->reset();

$context->add(LIST);
$context->addfile(HANDLE);

$digest = $context->digest();
$string = $context->hexdigest();

$digest = $context->hash($string);
$string = $context->hexhash($string);

DESCRIPTION

The SHA module allows you to use the NIST SHA message digest algorithm from within Perl programs.

The sha_version routine returns the version of the algorithm which is being used: either "SHA" for the original algorithm or "SHA-1" for the updated algorithm.

A new SHA context object is created with the new operation. Multiple simultaneous digest contexts can be maintained, if desired. The context is updated with the add operation which adds the strings contained in the LIST parameter. Adding two strings separately is equivalent to adding their concatenation: add('foo', 'bar') produces the same effect as add('foo'), add('bar'), which in turn produces the same effect as add('foobar').

The final message digest value is returned by the digest operation as a 20-byte binary string. This operation delivers the result of operations since the last new or reset operation. Once the operation has been performed, the context must be reset before being used to calculate another digest value.

Several convenience functions are also provided. The addfile operation takes an open file-handle and reads it until end-of file in 8192-byte blocks adding the contents to the context. The hexdigest operation calls digest and returns the result as a printable string of hexadecimal digits in eight-digit groups. The hash operation performs the complete series of steps: reset, add, digest on the supplied scalar value, and returns the result as a 20-byte binary string. The hexhash operation does the same thing, but returns the result in the format of the hexdigest operation.

EXAMPLE AND VALIDATION

    use SHA 1.2;

    $ver = &SHA::sha_version;
    $sha = new SHA;

    if ($ver eq 'SHA') {
	print "EXPECT:   0164b8a9 14cd2a5e 74c4f7ff 082c4d97 f1edf880\n";
    } elsif ($ver eq 'SHA-1') {
	print "EXPECT:   a9993e36 4706816a ba3e2571 7850c26c 9cd0d89d\n";
    } else {
	die "panic! unrecognized output '$ver' from sha_version\n";
    }

    $sha->reset();
    $sha->add("abc");
    print "RESULT 1: " . $sha->hexdigest() . "\n";

    $sha->reset();
    $sha->add("a", "bc");
    print "RESULT 2: " . $sha->hexdigest() . "\n";

    $sha->reset();
    $sha->add("ab", "c");
    print "RESULT 3: " . $sha->hexdigest() . "\n";

    $sha->reset();
    $sha->add("a", "b", "c");
    print "RESULT 4: " . $sha->hexdigest() . "\n";

    $sha->reset();
    $sha->add("ab");
    $sha->add("c");
    print "RESULT 5: " . $sha->hexdigest() . "\n";

    $sha->reset();
    $sha->add("a");
    $sha->add("bc");
    print "RESULT 6: " . $sha->hexdigest() . "\n";

    $sha->reset();
    $sha->add("a");
    $sha->add("b");
    $sha->add("c");
    print "RESULT 7: " . $sha->hexdigest() . "\n";

    print "RESULT 8: " . $sha->hexhash("abc") . "\n";

    $sha->reset();
    $sha->add("ab", "c");
    print "result a: " . unpack("H*", ($sha->digest())) . "\n";

    print "result b: " . unpack("H*", ($sha->hash("abc"))) . "\n";

The above example will produce one of two outputs. If the original SHA algorithm is being used, the output will be:

EXPECT:   0164b8a9 14cd2a5e 74c4f7ff 082c4d97 f1edf880
RESULT 1: 0164b8a9 14cd2a5e 74c4f7ff 082c4d97 f1edf880
RESULT 2: 0164b8a9 14cd2a5e 74c4f7ff 082c4d97 f1edf880
RESULT 3: 0164b8a9 14cd2a5e 74c4f7ff 082c4d97 f1edf880
RESULT 4: 0164b8a9 14cd2a5e 74c4f7ff 082c4d97 f1edf880
RESULT 5: 0164b8a9 14cd2a5e 74c4f7ff 082c4d97 f1edf880
RESULT 6: 0164b8a9 14cd2a5e 74c4f7ff 082c4d97 f1edf880
RESULT 7: 0164b8a9 14cd2a5e 74c4f7ff 082c4d97 f1edf880
RESULT 8: 0164b8a9 14cd2a5e 74c4f7ff 082c4d97 f1edf880
result a: 0164b8a914cd2a5e74c4f7ff082c4d97f1edf880
result b: 0164b8a914cd2a5e74c4f7ff082c4d97f1edf880

If the new SHA-1 algorithm is being used, the output will be

EXPECT:   a9993e36 4706816a ba3e2571 7850c26c 9cd0d89d
RESULT 1: a9993e36 4706816a ba3e2571 7850c26c 9cd0d89d
RESULT 2: a9993e36 4706816a ba3e2571 7850c26c 9cd0d89d
RESULT 3: a9993e36 4706816a ba3e2571 7850c26c 9cd0d89d
RESULT 4: a9993e36 4706816a ba3e2571 7850c26c 9cd0d89d
RESULT 5: a9993e36 4706816a ba3e2571 7850c26c 9cd0d89d
RESULT 6: a9993e36 4706816a ba3e2571 7850c26c 9cd0d89d
RESULT 7: a9993e36 4706816a ba3e2571 7850c26c 9cd0d89d
RESULT 8: a9993e36 4706816a ba3e2571 7850c26c 9cd0d89d
result a: a9993e364706816aba3e25717850c26c9cd0d89d
result b: a9993e364706816aba3e25717850c26c9cd0d89d

provided that the implementation is working correctly.

FURTHER EXAMPLES AND VALIDATION

The file sha_driver.pl contains further validation data and examples of how to use the SHA module. It may be invoked with the -h flag, which gives further usage instructions; the -x flag runs a few more tests.

NOTE

The SHA extension may be redistributed under the same terms as Perl. The SHA code is in the public domain. It was heavily modified by Uwe Hollerbach following the implementation by Peter Gutmann.

AUTHOR

The SHA interface was written by Uwe Hollerbach uh@alumni.caltech.edu, shamelessly stealing from the MD5 interface written by Neil Winton (N.Winton@axion.bt.co.uk).