From 53a40020f7787ae794f3ba880bed9f7fa8d3d2ef Mon Sep 17 00:00:00 2001 From: Chris Conlon Date: Tue, 25 Feb 2025 17:48:57 -0700 Subject: [PATCH] JNI: wrap native SHA-3 support in com.wolfssl.wolfcrypt.Hmac class --- jni/include/com_wolfssl_wolfcrypt_Hmac.h | 32 +++ jni/jni_hmac.c | 135 ++++++++--- src/main/java/com/wolfssl/wolfcrypt/Hmac.java | 35 ++- .../com/wolfssl/wolfcrypt/test/HmacTest.java | 229 ++++++++++++++++++ 4 files changed, 390 insertions(+), 41 deletions(-) diff --git a/jni/include/com_wolfssl_wolfcrypt_Hmac.h b/jni/include/com_wolfssl_wolfcrypt_Hmac.h index a992d9f..34db274 100644 --- a/jni/include/com_wolfssl_wolfcrypt_Hmac.h +++ b/jni/include/com_wolfssl_wolfcrypt_Hmac.h @@ -113,6 +113,38 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_Hmac_getCodeSha512 JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_Hmac_getCodeBlake2b (JNIEnv *, jclass); +/* + * Class: com_wolfssl_wolfcrypt_Hmac + * Method: getCodeSha3_224 + * Signature: ()I + */ +JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_Hmac_getCodeSha3_1224 + (JNIEnv *, jclass); + +/* + * Class: com_wolfssl_wolfcrypt_Hmac + * Method: getCodeSha3_256 + * Signature: ()I + */ +JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_Hmac_getCodeSha3_1256 + (JNIEnv *, jclass); + +/* + * Class: com_wolfssl_wolfcrypt_Hmac + * Method: getCodeSha3_384 + * Signature: ()I + */ +JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_Hmac_getCodeSha3_1384 + (JNIEnv *, jclass); + +/* + * Class: com_wolfssl_wolfcrypt_Hmac + * Method: getCodeSha3_512 + * Signature: ()I + */ +JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_Hmac_getCodeSha3_1512 + (JNIEnv *, jclass); + /* * Class: com_wolfssl_wolfcrypt_Hmac * Method: mallocNativeStruct diff --git a/jni/jni_hmac.c b/jni/jni_hmac.c index edc66bf..dba7d6c 100644 --- a/jni/jni_hmac.c +++ b/jni/jni_hmac.c @@ -65,7 +65,9 @@ static WC_INLINE int GetHashSizeByType(int type) { if (!(type == WC_MD5 || type == WC_SHA || type == WC_SHA224 - || type == WC_SHA256 || type == WC_SHA384 || type == WC_SHA512)) { + || type == WC_SHA256 || type == WC_SHA384 || type == WC_SHA512 + || type == WC_SHA3_224 || type == WC_SHA3_256 || type == WC_SHA3_384 + || type == WC_SHA3_512)) { return BAD_FUNC_ARG; } @@ -100,14 +102,27 @@ static WC_INLINE int GetHashSizeByType(int type) return SHA512_DIGEST_SIZE; #endif + #if defined(WOLFSSL_SHA3) + case WC_SHA3_224: + return WC_SHA3_224_DIGEST_SIZE; + + case WC_SHA3_256: + return WC_SHA3_256_DIGEST_SIZE; + + case WC_SHA3_384: + return WC_SHA3_384_DIGEST_SIZE; + + case WC_SHA3_512: + return WC_SHA3_512_DIGEST_SIZE; + #endif + default: return BAD_FUNC_ARG; } } -JNIEXPORT jlong JNICALL -Java_com_wolfssl_wolfcrypt_Hmac_mallocNativeStruct( - JNIEnv* env, jobject this) +JNIEXPORT jlong JNICALL Java_com_wolfssl_wolfcrypt_Hmac_mallocNativeStruct + (JNIEnv* env, jobject this) { #ifndef NO_HMAC Hmac* hmac = NULL; @@ -131,9 +146,8 @@ Java_com_wolfssl_wolfcrypt_Hmac_mallocNativeStruct( #endif } -JNIEXPORT void JNICALL -Java_com_wolfssl_wolfcrypt_Hmac_wc_1HmacSetKey( - JNIEnv* env, jobject this, jint type, jbyteArray key_object) +JNIEXPORT void JNICALL Java_com_wolfssl_wolfcrypt_Hmac_wc_1HmacSetKey + (JNIEnv* env, jobject this, jint type, jbyteArray key_object) { #ifndef NO_HMAC int ret = 0; @@ -165,9 +179,8 @@ Java_com_wolfssl_wolfcrypt_Hmac_wc_1HmacSetKey( #endif } -JNIEXPORT void JNICALL -Java_com_wolfssl_wolfcrypt_Hmac_wc_1HmacUpdate__B( - JNIEnv* env, jobject this, jbyte data) +JNIEXPORT void JNICALL Java_com_wolfssl_wolfcrypt_Hmac_wc_1HmacUpdate__B + (JNIEnv* env, jobject this, jbyte data) { #ifndef NO_HMAC int ret = 0; @@ -191,9 +204,8 @@ Java_com_wolfssl_wolfcrypt_Hmac_wc_1HmacUpdate__B( #endif } -JNIEXPORT void JNICALL -Java_com_wolfssl_wolfcrypt_Hmac_wc_1HmacUpdate___3BII( - JNIEnv* env, jobject this, jbyteArray data_object, jint offset, jint length) +JNIEXPORT void JNICALL Java_com_wolfssl_wolfcrypt_Hmac_wc_1HmacUpdate___3BII + (JNIEnv* env, jobject this, jbyteArray data_object, jint offset, jint length) { #ifndef NO_HMAC int ret = 0; @@ -225,9 +237,8 @@ Java_com_wolfssl_wolfcrypt_Hmac_wc_1HmacUpdate___3BII( #endif } -JNIEXPORT void JNICALL -Java_com_wolfssl_wolfcrypt_Hmac_wc_1HmacUpdate__Ljava_nio_ByteBuffer_2II( - JNIEnv* env, jobject this, jobject data_object, jint offset, jint length) +JNIEXPORT void JNICALL Java_com_wolfssl_wolfcrypt_Hmac_wc_1HmacUpdate__Ljava_nio_ByteBuffer_2II + (JNIEnv* env, jobject this, jobject data_object, jint offset, jint length) { #ifndef NO_HMAC int ret = 0; @@ -257,9 +268,8 @@ Java_com_wolfssl_wolfcrypt_Hmac_wc_1HmacUpdate__Ljava_nio_ByteBuffer_2II( #endif } -JNIEXPORT jbyteArray JNICALL -Java_com_wolfssl_wolfcrypt_Hmac_wc_1HmacFinal( - JNIEnv* env, jobject this) +JNIEXPORT jbyteArray JNICALL Java_com_wolfssl_wolfcrypt_Hmac_wc_1HmacFinal + (JNIEnv* env, jobject this) { jbyteArray result = NULL; @@ -308,9 +318,8 @@ Java_com_wolfssl_wolfcrypt_Hmac_wc_1HmacFinal( return result; } -JNIEXPORT jint JNICALL -Java_com_wolfssl_wolfcrypt_Hmac_wc_1HmacSizeByType( - JNIEnv* env, jobject this, jint type) +JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_Hmac_wc_1HmacSizeByType + (JNIEnv* env, jobject this, jint type) { jint result = 0; @@ -330,9 +339,8 @@ Java_com_wolfssl_wolfcrypt_Hmac_wc_1HmacSizeByType( return result; } -JNIEXPORT jint JNICALL -Java_com_wolfssl_wolfcrypt_Hmac_getCodeMd5( - JNIEnv* env, jobject this) +JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_Hmac_getCodeMd5 + (JNIEnv* env, jobject this) { #ifndef NO_MD5 jint result = WC_MD5; @@ -344,9 +352,8 @@ Java_com_wolfssl_wolfcrypt_Hmac_getCodeMd5( #endif } -JNIEXPORT jint JNICALL -Java_com_wolfssl_wolfcrypt_Hmac_getCodeSha( - JNIEnv* env, jobject this) +JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_Hmac_getCodeSha + (JNIEnv* env, jobject this) { #ifndef NO_SHA jint result = WC_SHA; @@ -358,9 +365,8 @@ Java_com_wolfssl_wolfcrypt_Hmac_getCodeSha( #endif } -JNIEXPORT jint JNICALL -Java_com_wolfssl_wolfcrypt_Hmac_getCodeSha224( - JNIEnv* env, jobject this) +JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_Hmac_getCodeSha224 + (JNIEnv* env, jobject this) { #ifdef WOLFSSL_SHA224 jint result = WC_SHA224; @@ -372,9 +378,8 @@ Java_com_wolfssl_wolfcrypt_Hmac_getCodeSha224( #endif } -JNIEXPORT jint JNICALL -Java_com_wolfssl_wolfcrypt_Hmac_getCodeSha256( - JNIEnv* env, jobject this) +JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_Hmac_getCodeSha256 + (JNIEnv* env, jobject this) { #ifndef NO_SHA256 jint result = WC_SHA256; @@ -386,9 +391,8 @@ Java_com_wolfssl_wolfcrypt_Hmac_getCodeSha256( #endif } -JNIEXPORT jint JNICALL -Java_com_wolfssl_wolfcrypt_Hmac_getCodeSha384( - JNIEnv* env, jobject this) +JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_Hmac_getCodeSha384 + (JNIEnv* env, jobject this) { #ifdef WOLFSSL_SHA384 jint result = WC_SHA384; @@ -400,9 +404,8 @@ Java_com_wolfssl_wolfcrypt_Hmac_getCodeSha384( #endif } -JNIEXPORT jint JNICALL -Java_com_wolfssl_wolfcrypt_Hmac_getCodeSha512( - JNIEnv* env, jobject this) +JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_Hmac_getCodeSha512 + (JNIEnv* env, jobject this) { #ifdef WOLFSSL_SHA512 jint result = WC_SHA512; @@ -414,3 +417,55 @@ Java_com_wolfssl_wolfcrypt_Hmac_getCodeSha512( #endif } +JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_Hmac_getCodeSha3_1224 + (JNIEnv* env, jclass this) +{ +#ifdef WOLFSSL_SHA3 + jint result = WC_SHA3_224; + LogStr("WC_SHA3_224 = %d\n", result); + return result; +#else + /* not compiled in */ + return (jint) -1; +#endif +} + +JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_Hmac_getCodeSha3_1256 + (JNIEnv* env, jclass this) +{ +#ifdef WOLFSSL_SHA3 + jint result = WC_SHA3_256; + LogStr("WC_SHA3_256 = %d\n", result); + return result; +#else + /* not compiled in */ + return (jint) -1; +#endif +} + +JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_Hmac_getCodeSha3_1384 + (JNIEnv* env, jclass this) +{ +#ifdef WOLFSSL_SHA3 + jint result = WC_SHA3_384; + LogStr("WC_SHA3_384 = %d\n", result); + return result; +#else + /* not compiled in */ + return (jint) -1; +#endif +} + +JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_Hmac_getCodeSha3_1512 + (JNIEnv* env, jclass this) +{ +#ifdef WOLFSSL_SHA3 + jint result = WC_SHA3_512; + LogStr("WC_SHA3_512 = %d\n", result); + return result; +#else + /* not compiled in */ + return (jint) -1; +#endif +} + diff --git a/src/main/java/com/wolfssl/wolfcrypt/Hmac.java b/src/main/java/com/wolfssl/wolfcrypt/Hmac.java index e5b2abf..846d084 100644 --- a/src/main/java/com/wolfssl/wolfcrypt/Hmac.java +++ b/src/main/java/com/wolfssl/wolfcrypt/Hmac.java @@ -29,7 +29,8 @@ import java.nio.ByteBuffer; public class Hmac extends NativeStruct { private enum hashType { - typeMD5, typeSHA, typeSHA224, typeSHA256, typeSHA384, typeSHA512; + typeMD5, typeSHA, typeSHA224, typeSHA256, typeSHA384, typeSHA512, + typeSHA3_224, typeSHA3_256, typeSHA3_384, typeSHA3_512; } /* types may be -1 if not compiled in at native level */ @@ -45,6 +46,14 @@ public class Hmac extends NativeStruct { public static final int SHA384 = getHashCode(hashType.typeSHA384); /** HMAC-SHA2-512 type */ public static final int SHA512 = getHashCode(hashType.typeSHA512); + /** HMAC-SHA3-224 type */ + public static final int SHA3_224 = getHashCode(hashType.typeSHA3_224); + /** HMAC-SHA3-256 type */ + public static final int SHA3_256 = getHashCode(hashType.typeSHA3_256); + /** HMAC-SHA3-384 type */ + public static final int SHA3_384 = getHashCode(hashType.typeSHA3_384); + /** HMAC-SHA3-512 type */ + public static final int SHA3_512 = getHashCode(hashType.typeSHA3_512); private WolfCryptState state = WolfCryptState.UNINITIALIZED; private int type = -1; @@ -102,6 +111,10 @@ public class Hmac extends NativeStruct { private native static int getCodeSha384(); private native static int getCodeSha512(); private native static int getCodeBlake2b(); + private native static int getCodeSha3_224(); + private native static int getCodeSha3_256(); + private native static int getCodeSha3_384(); + private native static int getCodeSha3_512(); /** * Malloc native JNI Hmac structure @@ -333,6 +346,18 @@ public class Hmac extends NativeStruct { else if (type == SHA512) { return "HmacSHA512"; } + else if (type == SHA3_224) { + return "HmacSHA3-224"; + } + else if (type == SHA3_256) { + return "HmacSHA3-256"; + } + else if (type == SHA3_384) { + return "HmacSHA3-384"; + } + else if (type == SHA3_512) { + return "HmacSHA3-512"; + } else { return ""; } @@ -373,6 +398,14 @@ public class Hmac extends NativeStruct { return getCodeSha384(); case typeSHA512: return getCodeSha512(); + case typeSHA3_224: + return getCodeSha3_224(); + case typeSHA3_256: + return getCodeSha3_256(); + case typeSHA3_384: + return getCodeSha3_384(); + case typeSHA3_512: + return getCodeSha3_512(); default: return WolfCrypt.FAILURE; } diff --git a/src/test/java/com/wolfssl/wolfcrypt/test/HmacTest.java b/src/test/java/com/wolfssl/wolfcrypt/test/HmacTest.java index 695fe3c..f89603e 100644 --- a/src/test/java/com/wolfssl/wolfcrypt/test/HmacTest.java +++ b/src/test/java/com/wolfssl/wolfcrypt/test/HmacTest.java @@ -40,6 +40,7 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.CountDownLatch; import java.util.concurrent.LinkedBlockingQueue; +import com.wolfssl.wolfcrypt.Fips; import com.wolfssl.wolfcrypt.Hmac; import com.wolfssl.wolfcrypt.NativeStruct; import com.wolfssl.wolfcrypt.WolfCryptError; @@ -274,6 +275,197 @@ public class HmacTest { } } + static final String[] sha3KeyVector = new String[] { + "4A656665", /* Jefe */ + "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b", + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "0102030405060708010203040506070801020304050607080102030405060708" + + "0102030405060708010203040506070801020304050607080102030405060708" + + "0102030405060708010203040506070801020304050607080102030405060708" + + "0102030405060708010203040506070801020304050607080102030405060708" + + "0102030405060708010203040506070801020304050607080102030405060708" + }; + static final String[] sha3DataVector = new String[] { + /* what do ya want for nothing? */ + "7768617420646f2079612077616e7420666f72206e6f7468696e673f", + /* Hi There */ + "4869205468657265", + "dddddddddddddddddddd" + + "dddddddddddddddddddd" + + "dddddddddddddddddddd" + + "dddddddddddddddddddd" + + "dddddddddddddddddddd", + /* Big Key Input */ + "426967204b657920496e707574" + }; + + @Test + public void sha3_224HmacShouldMatch() { + String[] hashVector = new String[] { + "7fdb8dd88bd2f60d1b798634ad386811c2cfc85bfaf5d52bbace5e66", + "3b16546bbc7be2706a031dcafd56373d9884367641d8c59af3c860f7", + "676cfc7d16153638780390692be142d2df7ce924b909c0c08dbfdc1a", + "29e05e46c4a45e4674bfd72d1ad866db2d0d104e2bfaad537d15698b" + }; + + for (int i = 0; i < sha3DataVector.length; i++) { + + if ((i == 0) && Fips.enabled) { + /* FIPS doesn't allow short key lengths */ + continue; + } + + try { + Hmac hmac = new Hmac(); + + byte[] key = Util.h2b(sha3KeyVector[i]); + byte[] data = Util.h2b(sha3DataVector[i]); + byte[] expected = Util.h2b(hashVector[i]); + + hmac.setKey(Hmac.SHA3_224, key); + hmac.update(data); + + assertArrayEquals(expected, hmac.doFinal()); + + hmac.reset(); + assertArrayEquals(expected, hmac.doFinal(data)); + + } catch (WolfCryptException e) { + if (e.getError() == WolfCryptError.NOT_COMPILED_IN) { + System.out.println("Hmac SHA3-224 test skipped: " + + e.getError()); + } else { + throw e; + } + } + } + } + + @Test + public void sha3_256HmacShouldMatch() { + String[] hashVector = new String[] { + "c7d4072e788877ae3596bbb0da73b887c9171f93095b294ae857fbe2645e1ba5", + "ba85192310dffa96e2a3a40e69774351140bb7185e1202cdcc917589f95e16bb", + "84ec79124a27107865cedd8bd82da9965e5ed8c37b0ac98005a7f39ed58a4207", + "b55b8d64b69c21d0bf205ca2f7b9b14e8821612c66c391ae6c95168583e6f49b" + }; + + for (int i = 0; i < sha3DataVector.length; i++) { + + if ((i == 0) && Fips.enabled) { + /* FIPS doesn't allow short key lengths */ + continue; + } + + try { + Hmac hmac = new Hmac(); + + byte[] key = Util.h2b(sha3KeyVector[i]); + byte[] expected = Util.h2b(hashVector[i]); + byte[] data = Util.h2b(sha3DataVector[i]); + + hmac.setKey(Hmac.SHA3_256, key); + hmac.update(data); + + assertArrayEquals(expected, hmac.doFinal()); + + hmac.reset(); + assertArrayEquals(expected, hmac.doFinal(data)); + + } catch (WolfCryptException e) { + if (e.getError() == WolfCryptError.NOT_COMPILED_IN) { + System.out.println("Hmac SHA3-256 test skipped: " + + e.getError()); + } else { + throw e; + } + } + } + } + + @Test + public void sha3_384HmacShouldMatch() { + String[] hashVector = new String[] { + "f1101f8cbf9766fd6764d2ed61903f21ca9b18f57cf3e1a23ca13508a93243ce48c045dc007f26a21b3f5e0e9df4c20a", + "68d2dcf7fd4ddd0a2240c8a437305f61fb7334cfb5d0226e1bc27dc10a2e723a20d370b47743130e26ac7e3d532886bd", + "275cd0e661bb8b151c64d288f1f782fb91a8abd56858d72babb2d476f0458373b41b6ab5bf174bec422e53fc3135ac6e", + "aa91b3a62f56a1be8c3e7438db58d9d334dea0606d8d46e0eca9f6063514e6ed83e67c77246c11b59082b575da7b832d" + }; + + for (int i = 0; i < sha3DataVector.length; i++) { + + if ((i == 0) && Fips.enabled) { + /* FIPS doesn't allow short key lengths */ + continue; + } + + try { + Hmac hmac = new Hmac(); + + byte[] key = Util.h2b(sha3KeyVector[i]); + byte[] data = Util.h2b(sha3DataVector[i]); + byte[] expected = Util.h2b(hashVector[i]); + + hmac.setKey(Hmac.SHA3_384, key); + hmac.update(data); + + assertArrayEquals(expected, hmac.doFinal()); + + hmac.reset(); + assertArrayEquals(expected, hmac.doFinal(data)); + + } catch (WolfCryptException e) { + if (e.getError() == WolfCryptError.NOT_COMPILED_IN) { + System.out.println("Hmac SHA3-384 test skipped: " + + e.getError()); + } else { + throw e; + } + } + } + } + + @Test + public void sha3_512HmacShouldMatch() { + String[] hashVector = new String[] { + "5a4bfeab6166427c7a3647b747292b8384537cdb89afb3bf5665e4c5e709350b287baec921fd7ca0ee7a0c31d022a95e1fc92ba9d77df883960275beb4e62024", + "eb3fbd4b2eaab8f5c504bd3a41465aacec15770a7cabac531e482f860b5ec7ba47ccb2c6f2afce8f88d22b6dc61380f23a668fd3888bb80537c0a0b86407689e", + "309e99f9ec075ec6c6d475eda1180687fcf1531195802a99b5677449a8625182851cb332afb6a89c411325fbcbcd42afcb7b6e5aab7ea42c660f97fd8584bf03", + "1cc3a9244a4a3fbdc72000169b79470378752cb5f12e627cbeef4e8f0b112b32a0eec9d04d64640b37f4dd66f78bb3ad52526b6512de0d7cc08b60016c37d7a8" + }; + + for (int i = 0; i < sha3DataVector.length; i++) { + + if ((i == 0) && Fips.enabled) { + /* FIPS doesn't allow short key lengths */ + continue; + } + + try { + Hmac hmac = new Hmac(); + + byte[] expected = Util.h2b(hashVector[i]); + byte[] data = Util.h2b(sha3DataVector[i]); + + hmac.setKey(Hmac.SHA3_512, Util.h2b(sha3KeyVector[i])); + hmac.update(data); + + assertArrayEquals(expected, hmac.doFinal()); + + hmac.reset(); + assertArrayEquals(expected, hmac.doFinal(data)); + + } catch (WolfCryptException e) { + if (e.getError() == WolfCryptError.NOT_COMPILED_IN) { + System.out.println("Hmac SHA3-512 test skipped: " + + e.getError()); + } else { + throw e; + } + } + } + } + private void threadRunnerHmacTest(int hmacType, byte[] inKey, byte[] inData, byte[] inExpected) throws InterruptedException { @@ -421,5 +613,42 @@ public class HmacTest { "952ac4b7da7131f0") ); } + + if (Hmac.SHA3_224 != -1) { + threadRunnerHmacTest(Hmac.SHA3_224, + Util.h2b("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"), /* key */ + Util.h2b("4869205468657265"), /* data */ + Util.h2b("3b16546bbc7be2706a031dcafd56373d" + + "9884367641d8c59af3c860f7") + ); + } + if (Hmac.SHA3_256 != -1) { + threadRunnerHmacTest(Hmac.SHA3_256, + Util.h2b("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"), /* key */ + Util.h2b("4869205468657265"), /* data */ + Util.h2b("ba85192310dffa96e2a3a40e697743" + + "51140bb7185e1202cdcc917589f95e" + + "16bb") + ); + } + if (Hmac.SHA3_384 != -1) { + threadRunnerHmacTest(Hmac.SHA3_384, + Util.h2b("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"), /* key */ + Util.h2b("4869205468657265"), /* data */ + Util.h2b("68d2dcf7fd4ddd0a2240c8a437305f61" + + "fb7334cfb5d0226e1bc27dc10a2e723a" + + "20d370b47743130e26ac7e3d532886bd") + ); + } + if (Hmac.SHA3_512 != -1) { + threadRunnerHmacTest(Hmac.SHA3_512, + Util.h2b("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"), /* key */ + Util.h2b("4869205468657265"), /* data */ + Util.h2b("eb3fbd4b2eaab8f5c504bd3a41465aac" + + "ec15770a7cabac531e482f860b5ec7ba" + + "47ccb2c6f2afce8f88d22b6dc61380f2" + + "3a668fd3888bb80537c0a0b86407689e") + ); + } } }