SHA3_384Digest

OOP API SHA-3/SHAKE implementation aliases.

alias SHA3_384Digest = WrapperDigest!SHA3_384

Examples

Test OOP wrappers

import std.conv : hexString;

SHA3_224Digest sha3_224 = new SHA3_224Digest();
assert(sha3_224.finish() == cast(ubyte[]) hexString!
    "6b4e03423667dbb73b6e15454f0eb1abd4597f9a1b078e3f5b5a6bc7");

SHA3_256Digest sha3_256 = new SHA3_256Digest();
assert(sha3_256.finish() == cast(ubyte[]) hexString!
    "a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a");

SHA3_384Digest sha3_384 = new SHA3_384Digest();
assert(sha3_384.finish() == cast(ubyte[]) hexString!(
    "0c63a75b845e4f7d01107d852e4c2485c51a50aaaa94fc61995e71bbee983a2a"~
    "c3713831264adb47fb6bd1e058d5f004"));

SHA3_512Digest sha3_512 = new SHA3_512Digest();
assert(sha3_512.finish() == cast(ubyte[]) hexString!(
    "a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a6"~
    "15b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26"));

SHAKE128Digest shake128 = new SHAKE128Digest();
assert(shake128.finish() == cast(ubyte[]) hexString!(
    "7f9c2ba4e88f827d616045507605853e"));

SHAKE256Digest shake256 = new SHAKE256Digest();
assert(shake256.finish() == cast(ubyte[]) hexString!(
    "46b9dd2b0ba88d13233b3feb743eeb243fcd52ea62b81b82b50c27646ed5762f"));

Testing with HMAC

    // NOTE: OpenSSL (even 3.0.1) is incapable of producing a hash with
    //       SHAKE and HMAC, but should work since unittests for
    //       SHAKE-related hashes (including XOFs) are passing.
    
    import std.ascii : LetterCase;
    import std.string : representation;
    import std.digest.hmac : hmac;

    auto secret = "secret".representation;
    
    assert("The quick brown fox jumps over the lazy dog"
        .representation
        .hmac!SHA3_256(secret)
        .toHexString!(LetterCase.lower) ==
	    "93379fab68fae6d0fde0c816ea8a49fbd3c80f136c6af08bc61df5268d01b4d8");
    assert("The quick brown fox jumps over the lazy dog"
        .representation
        .hmac!SHA3_512(secret)
        .toHexString!(LetterCase.lower) ==
	    "394e52da72b28bab49174a0d22cd48eac415de750027e6485ceb945b9948d8ae"~
        "e656e61e217ac1352a41c66454e2a9ae830fddbdf4f8aa6215c586b88e158ee8");

Testing out various SHAKE XOFs.

import std.conv : hexString;

// SHAKE128("", 256)
auto shake128_256empty = hexString!(
    "7f9c2ba4e88f827d616045507605853ed73b8093f6efbc88eb1a6eacfa66ef26");
// SHAKE256("", 512)
auto shake256_512empty = hexString!(
    "46b9dd2b0ba88d13233b3feb743eeb243fcd52ea62b81b82b50c27646ed5762f"~
    "d75dc4ddd8c0f200cb05019d67b592f6fc821c49479ab48640292eacb3b7c4be");

// SHAKE-128/256
alias SHAKE128_256 = KECCAK!(128, 256);
alias SHAKE128_256Digest = WrapperDigest!SHAKE128_256;
auto shake128_256Of(T...)(T data) { return digest!(SHAKE128_256, T)(data); }

// Template API
assert(shake128_256Of("") == shake128_256empty);

// OOP API
Digest shake128_256 = new SHAKE128_256Digest();
assert(shake128_256.finish() == shake128_256empty);

// SHAKE-256/512
alias SHAKE256_512 = KECCAK!(256, 512);
alias SHAKE256_512Digest = WrapperDigest!SHAKE256_512;
auto shake256_512Of(T...)(T data) { return digest!(SHAKE256_512, T)(data); }

// Template API
assert(shake256_512Of("") == shake256_512empty);

// OOP API
Digest shake256_512 = new SHAKE256_512Digest();
assert(shake256_512.finish() == shake256_512empty);

Meta