Add SHA-512-256.
(Not wired up into all the signature verifiers because we don't need or
recommend that.)
Change-Id: Ia212a1f0e1c389a31d303e00a6fafb0ec3db7c71
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/40704
Commit-Queue: Adam Langley <agl@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
diff --git a/crypto/digest_extra/digest_test.cc b/crypto/digest_extra/digest_test.cc
index 5cfe1c8..ba0884a 100644
--- a/crypto/digest_extra/digest_test.cc
+++ b/crypto/digest_extra/digest_test.cc
@@ -53,6 +53,7 @@
static const MD sha256 = { "SHA256", &EVP_sha256, &SHA256 };
static const MD sha384 = { "SHA384", &EVP_sha384, &SHA384 };
static const MD sha512 = { "SHA512", &EVP_sha512, &SHA512 };
+static const MD sha512_256 = { "SHA512-256", &EVP_sha512_256, &SHA512_256 };
static const MD md5_sha1 = { "MD5-SHA1", &EVP_md5_sha1, nullptr };
struct DigestTestVector {
@@ -69,79 +70,81 @@
static const DigestTestVector kTestVectors[] = {
// MD4 tests, from RFC 1320. (crypto/md4 does not provide a
// one-shot MD4 function.)
- { md4, "", 1, "31d6cfe0d16ae931b73c59d7e0c089c0" },
- { md4, "a", 1, "bde52cb31de33e46245e05fbdbd6fb24" },
- { md4, "abc", 1, "a448017aaf21d8525fc10ae87aa6729d" },
- { md4, "message digest", 1, "d9130a8164549fe818874806e1c7014b" },
- { md4, "abcdefghijklmnopqrstuvwxyz", 1,
- "d79e1c308aa5bbcdeea8ed63df412da9" },
- { md4,
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", 1,
- "043f8582f241db351ce627e153e7f0e4" },
- { md4, "1234567890", 8, "e33b4ddc9c38f2199c3e7b164fcc0536" },
+ {md4, "", 1, "31d6cfe0d16ae931b73c59d7e0c089c0"},
+ {md4, "a", 1, "bde52cb31de33e46245e05fbdbd6fb24"},
+ {md4, "abc", 1, "a448017aaf21d8525fc10ae87aa6729d"},
+ {md4, "message digest", 1, "d9130a8164549fe818874806e1c7014b"},
+ {md4, "abcdefghijklmnopqrstuvwxyz", 1, "d79e1c308aa5bbcdeea8ed63df412da9"},
+ {md4, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", 1,
+ "043f8582f241db351ce627e153e7f0e4"},
+ {md4, "1234567890", 8, "e33b4ddc9c38f2199c3e7b164fcc0536"},
// MD5 tests, from RFC 1321.
- { md5, "", 1, "d41d8cd98f00b204e9800998ecf8427e" },
- { md5, "a", 1, "0cc175b9c0f1b6a831c399e269772661" },
- { md5, "abc", 1, "900150983cd24fb0d6963f7d28e17f72" },
- { md5, "message digest", 1, "f96b697d7cb7938d525a2f31aaf161d0" },
- { md5, "abcdefghijklmnopqrstuvwxyz", 1,
- "c3fcd3d76192e4007dfb496cca67e13b" },
- { md5,
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", 1,
- "d174ab98d277d9f5a5611c2c9f419d9f" },
- { md5, "1234567890", 8, "57edf4a22be3c955ac49da2e2107b67a" },
+ {md5, "", 1, "d41d8cd98f00b204e9800998ecf8427e"},
+ {md5, "a", 1, "0cc175b9c0f1b6a831c399e269772661"},
+ {md5, "abc", 1, "900150983cd24fb0d6963f7d28e17f72"},
+ {md5, "message digest", 1, "f96b697d7cb7938d525a2f31aaf161d0"},
+ {md5, "abcdefghijklmnopqrstuvwxyz", 1, "c3fcd3d76192e4007dfb496cca67e13b"},
+ {md5, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", 1,
+ "d174ab98d277d9f5a5611c2c9f419d9f"},
+ {md5, "1234567890", 8, "57edf4a22be3c955ac49da2e2107b67a"},
// SHA-1 tests, from RFC 3174.
- { sha1, "abc", 1, "a9993e364706816aba3e25717850c26c9cd0d89d" },
- { sha1,
- "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 1,
- "84983e441c3bd26ebaae4aa1f95129e5e54670f1" },
- { sha1, "a", 1000000, "34aa973cd4c4daa4f61eeb2bdbad27316534016f" },
- { sha1,
- "0123456701234567012345670123456701234567012345670123456701234567", 10,
- "dea356a2cddd90c7a7ecedc5ebb563934f460452" },
+ {sha1, "abc", 1, "a9993e364706816aba3e25717850c26c9cd0d89d"},
+ {sha1, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 1,
+ "84983e441c3bd26ebaae4aa1f95129e5e54670f1"},
+ {sha1, "a", 1000000, "34aa973cd4c4daa4f61eeb2bdbad27316534016f"},
+ {sha1, "0123456701234567012345670123456701234567012345670123456701234567",
+ 10, "dea356a2cddd90c7a7ecedc5ebb563934f460452"},
// SHA-224 tests, from RFC 3874.
- { sha224, "abc", 1,
- "23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7" },
- { sha224,
- "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 1,
- "75388b16512776cc5dba5da1fd890150b0c6455cb4f58b1952522525" },
- { sha224,
- "a", 1000000,
- "20794655980c91d8bbb4c1ea97618a4bf03f42581948b2ee4ee7ad67" },
+ {sha224, "abc", 1,
+ "23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7"},
+ {sha224, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 1,
+ "75388b16512776cc5dba5da1fd890150b0c6455cb4f58b1952522525"},
+ {sha224, "a", 1000000,
+ "20794655980c91d8bbb4c1ea97618a4bf03f42581948b2ee4ee7ad67"},
// SHA-256 tests, from NIST.
- { sha256, "abc", 1,
- "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad" },
- { sha256,
- "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 1,
- "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1" },
+ {sha256, "abc", 1,
+ "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"},
+ {sha256, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 1,
+ "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1"},
// SHA-384 tests, from NIST.
- { sha384, "abc", 1,
- "cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed"
- "8086072ba1e7cc2358baeca134c825a7" },
- { sha384,
- "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
- "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", 1,
- "09330c33f71147e83d192fc782cd1b4753111b173b3b05d22fa08086e3b0f712"
- "fcc7c71a557e2db966c3e9fa91746039" },
+ {sha384, "abc", 1,
+ "cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed"
+ "8086072ba1e7cc2358baeca134c825a7"},
+ {sha384,
+ "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
+ "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
+ 1,
+ "09330c33f71147e83d192fc782cd1b4753111b173b3b05d22fa08086e3b0f712"
+ "fcc7c71a557e2db966c3e9fa91746039"},
// SHA-512 tests, from NIST.
- { sha512, "abc", 1,
- "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a"
- "2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f" },
- { sha512,
- "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
- "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", 1,
- "8e959b75dae313da8cf4f72814fc143f8f7779c6eb9f7fa17299aeadb6889018"
- "501d289e4900f7e4331b99dec4b5433ac7d329eeb6dd26545e96e55b874be909" },
+ {sha512, "abc", 1,
+ "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a"
+ "2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f"},
+ {sha512,
+ "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
+ "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
+ 1,
+ "8e959b75dae313da8cf4f72814fc143f8f7779c6eb9f7fa17299aeadb6889018"
+ "501d289e4900f7e4331b99dec4b5433ac7d329eeb6dd26545e96e55b874be909"},
+
+ // SHA-512-256 tests, from
+ // https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/examples/sha512_256.pdf
+ {sha512_256, "abc", 1,
+ "53048e2681941ef99b2e29b76b4c7dabe4c2d0c634fc6d46e0e2f13107e7af23"},
+ {sha512_256,
+ "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopj"
+ "klmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
+ 1, "3928e184fb8690f840da3988121d31be65cb9d3ef83ee6146feac861e19b563a"},
// MD5-SHA1 tests.
- { md5_sha1, "abc", 1,
- "900150983cd24fb0d6963f7d28e17f72a9993e364706816aba3e25717850c26c9cd0d89d" },
+ {md5_sha1, "abc", 1,
+ "900150983cd24fb0d6963f7d28e17f72a9993e364706816aba3e25717850c26c9cd0d89d"},
};
static void CompareDigest(const DigestTestVector *test,
diff --git a/crypto/fipsmodule/digest/digests.c b/crypto/fipsmodule/digest/digests.c
index f2fa349..16daeba 100644
--- a/crypto/fipsmodule/digest/digests.c
+++ b/crypto/fipsmodule/digest/digests.c
@@ -243,6 +243,22 @@
}
+static void sha512_256_init(EVP_MD_CTX *ctx) {
+ CHECK(SHA512_256_Init(ctx->md_data));
+}
+
+DEFINE_METHOD_FUNCTION(EVP_MD, EVP_sha512_256) {
+ out->type = NID_sha512_256;
+ out->md_size = SHA512_256_DIGEST_LENGTH;
+ out->flags = 0;
+ out->init = sha512_256_init;
+ out->update = sha512_update;
+ out->final = sha512_final;
+ out->block_size = 128;
+ out->ctx_size = sizeof(SHA512_CTX);
+}
+
+
typedef struct {
MD5_CTX md5;
SHA_CTX sha1;
diff --git a/crypto/fipsmodule/sha/sha512.c b/crypto/fipsmodule/sha/sha512.c
index 848f3b6..fd02574 100644
--- a/crypto/fipsmodule/sha/sha512.c
+++ b/crypto/fipsmodule/sha/sha512.c
@@ -105,6 +105,23 @@
return 1;
}
+int SHA512_256_Init(SHA512_CTX *sha) {
+ sha->h[0] = UINT64_C(0x22312194fc2bf72c);
+ sha->h[1] = UINT64_C(0x9f555fa3c84c64c2);
+ sha->h[2] = UINT64_C(0x2393b86b6f53b151);
+ sha->h[3] = UINT64_C(0x963877195940eabd);
+ sha->h[4] = UINT64_C(0x96283ee2a88effe3);
+ sha->h[5] = UINT64_C(0xbe5e1e2553863992);
+ sha->h[6] = UINT64_C(0x2b0199fc2c85b8aa);
+ sha->h[7] = UINT64_C(0x0eb72ddc81c52ca2);
+
+ sha->Nl = 0;
+ sha->Nh = 0;
+ sha->num = 0;
+ sha->md_len = SHA512_256_DIGEST_LENGTH;
+ return 1;
+}
+
uint8_t *SHA384(const uint8_t *data, size_t len,
uint8_t out[SHA384_DIGEST_LENGTH]) {
SHA512_CTX ctx;
@@ -125,6 +142,16 @@
return out;
}
+uint8_t *SHA512_256(const uint8_t *data, size_t len,
+ uint8_t out[SHA512_256_DIGEST_LENGTH]) {
+ SHA512_CTX ctx;
+ SHA512_256_Init(&ctx);
+ SHA512_Update(&ctx, data, len);
+ SHA512_Final(out, &ctx);
+ OPENSSL_cleanse(&ctx, sizeof(ctx));
+ return out;
+}
+
#if !defined(SHA512_ASM)
static void sha512_block_data_order(uint64_t *state, const uint8_t *in,
size_t num_blocks);
@@ -141,6 +168,17 @@
return SHA512_Update(sha, data, len);
}
+int SHA512_256_Update(SHA512_CTX *sha, const void *data, size_t len) {
+ return SHA512_Update(sha, data, len);
+}
+
+int SHA512_256_Final(uint8_t out[SHA512_256_DIGEST_LENGTH],
+ SHA512_CTX *sha) {
+ // |SHA512_256_Init| sets |sha->md_len| to |SHA512_256_DIGEST_LENGTH|, so this
+ // has a |smaller output.
+ return SHA512_Final(out, sha);
+}
+
void SHA512_Transform(SHA512_CTX *c, const uint8_t block[SHA512_CBLOCK]) {
sha512_block_data_order(c->h, block, 1);
}
@@ -231,41 +269,12 @@
return 0;
}
- switch (sha->md_len) {
- // Let compiler decide if it's appropriate to unroll...
- case SHA384_DIGEST_LENGTH:
- for (n = 0; n < SHA384_DIGEST_LENGTH / 8; n++) {
- uint64_t t = sha->h[n];
-
- *(out++) = (uint8_t)(t >> 56);
- *(out++) = (uint8_t)(t >> 48);
- *(out++) = (uint8_t)(t >> 40);
- *(out++) = (uint8_t)(t >> 32);
- *(out++) = (uint8_t)(t >> 24);
- *(out++) = (uint8_t)(t >> 16);
- *(out++) = (uint8_t)(t >> 8);
- *(out++) = (uint8_t)(t);
- }
- break;
- case SHA512_DIGEST_LENGTH:
- for (n = 0; n < SHA512_DIGEST_LENGTH / 8; n++) {
- uint64_t t = sha->h[n];
-
- *(out++) = (uint8_t)(t >> 56);
- *(out++) = (uint8_t)(t >> 48);
- *(out++) = (uint8_t)(t >> 40);
- *(out++) = (uint8_t)(t >> 32);
- *(out++) = (uint8_t)(t >> 24);
- *(out++) = (uint8_t)(t >> 16);
- *(out++) = (uint8_t)(t >> 8);
- *(out++) = (uint8_t)(t);
- }
- break;
- // ... as well as make sure md_len is not abused.
- default:
- // TODO(davidben): This bad |md_len| case is one of the few places a
- // low-level hash 'final' function can fail. This should never happen.
- return 0;
+ assert(sha->md_len % 8 == 0);
+ const size_t out_words = sha->md_len / 8;
+ for (size_t i = 0; i < out_words; i++) {
+ const uint64_t t = CRYPTO_bswap8(sha->h[i]);
+ memcpy(out, &t, sizeof(t));
+ out += sizeof(t);
}
return 1;
diff --git a/crypto/obj/obj_dat.h b/crypto/obj/obj_dat.h
index 888ea67..778d8e3 100644
--- a/crypto/obj/obj_dat.h
+++ b/crypto/obj/obj_dat.h
@@ -57,7 +57,7 @@
/* This file is generated by crypto/obj/objects.go. */
-#define NUM_NID 962
+#define NUM_NID 963
static const uint8_t kObjectData[] = {
/* NID_rsadsi */
@@ -7127,6 +7127,16 @@
0x2b,
0x65,
0x6f,
+ /* NID_sha512_256 */
+ 0x60,
+ 0x86,
+ 0x48,
+ 0x01,
+ 0x65,
+ 0x03,
+ 0x04,
+ 0x02,
+ 0x06,
};
static const ASN1_OBJECT kObjects[NUM_NID] = {
@@ -8770,6 +8780,7 @@
{"CECPQ2", "CECPQ2", NID_CECPQ2, 0, NULL, 0},
{"ED448", "ED448", NID_ED448, 3, &kObjectData[6181], 0},
{"X448", "X448", NID_X448, 3, &kObjectData[6184], 0},
+ {"SHA512-256", "sha512-256", NID_sha512_256, 9, &kObjectData[6187], 0},
};
static const uint16_t kNIDsInShortNameOrder[] = {
@@ -8959,6 +8970,7 @@
672 /* SHA256 */,
673 /* SHA384 */,
674 /* SHA512 */,
+ 962 /* SHA512-256 */,
188 /* SMIME */,
167 /* SMIME-CAPS */,
100 /* SN */,
@@ -10632,6 +10644,7 @@
673 /* sha384 */,
669 /* sha384WithRSAEncryption */,
674 /* sha512 */,
+ 962 /* sha512-256 */,
670 /* sha512WithRSAEncryption */,
42 /* shaWithRSAEncryption */,
52 /* signingTime */,
@@ -11391,6 +11404,7 @@
673 /* 2.16.840.1.101.3.4.2.2 (OBJ_sha384) */,
674 /* 2.16.840.1.101.3.4.2.3 (OBJ_sha512) */,
675 /* 2.16.840.1.101.3.4.2.4 (OBJ_sha224) */,
+ 962 /* 2.16.840.1.101.3.4.2.6 (OBJ_sha512_256) */,
802 /* 2.16.840.1.101.3.4.3.1 (OBJ_dsa_with_SHA224) */,
803 /* 2.16.840.1.101.3.4.3.2 (OBJ_dsa_with_SHA256) */,
71 /* 2.16.840.1.113730.1.1 (OBJ_netscape_cert_type) */,
diff --git a/crypto/obj/obj_mac.num b/crypto/obj/obj_mac.num
index f73ebf9..f110ee9 100644
--- a/crypto/obj/obj_mac.num
+++ b/crypto/obj/obj_mac.num
@@ -950,3 +950,4 @@
CECPQ2 959
ED448 960
X448 961
+sha512_256 962
diff --git a/crypto/obj/objects.txt b/crypto/obj/objects.txt
index 798da1e..b88342d 100644
--- a/crypto/obj/objects.txt
+++ b/crypto/obj/objects.txt
@@ -905,6 +905,7 @@
nist_hashalgs 2 : SHA384 : sha384
nist_hashalgs 3 : SHA512 : sha512
nist_hashalgs 4 : SHA224 : sha224
+nist_hashalgs 6 : SHA512-256 : sha512-256
# OIDs for dsa-with-sha224 and dsa-with-sha256
!Alias dsa_with_sha2 nistAlgorithms 3
diff --git a/include/openssl/digest.h b/include/openssl/digest.h
index c3ceb7f..7b0ed06 100644
--- a/include/openssl/digest.h
+++ b/include/openssl/digest.h
@@ -83,6 +83,7 @@
OPENSSL_EXPORT const EVP_MD *EVP_sha256(void);
OPENSSL_EXPORT const EVP_MD *EVP_sha384(void);
OPENSSL_EXPORT const EVP_MD *EVP_sha512(void);
+OPENSSL_EXPORT const EVP_MD *EVP_sha512_256(void);
// EVP_md5_sha1 is a TLS-specific |EVP_MD| which computes the concatenation of
// MD5 and SHA-1, as used in TLS 1.1 and below.
diff --git a/include/openssl/nid.h b/include/openssl/nid.h
index a15f4e3..bf7f3da 100644
--- a/include/openssl/nid.h
+++ b/include/openssl/nid.h
@@ -4246,6 +4246,11 @@
#define NID_X448 961
#define OBJ_X448 1L, 3L, 101L, 111L
+#define SN_sha512_256 "SHA512-256"
+#define LN_sha512_256 "sha512-256"
+#define NID_sha512_256 962
+#define OBJ_sha512_256 2L, 16L, 840L, 1L, 101L, 3L, 4L, 2L, 6L
+
#if defined(__cplusplus)
} /* extern C */
diff --git a/include/openssl/sha.h b/include/openssl/sha.h
index b163e6a..b113798 100644
--- a/include/openssl/sha.h
+++ b/include/openssl/sha.h
@@ -261,6 +261,32 @@
};
+// SHA-512-256
+//
+// See https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf section 5.3.6
+
+#define SHA512_256_DIGEST_LENGTH 32
+
+// SHA512_256_Init initialises |sha| and returns 1.
+OPENSSL_EXPORT int SHA512_256_Init(SHA512_CTX *sha);
+
+// SHA512_256_Update adds |len| bytes from |data| to |sha| and returns 1.
+OPENSSL_EXPORT int SHA512_256_Update(SHA512_CTX *sha, const void *data,
+ size_t len);
+
+// SHA512_256_Final adds the final padding to |sha| and writes the resulting
+// digest to |out|, which must have at least |SHA512_256_DIGEST_LENGTH| bytes of
+// space. It returns one on success and zero on programmer error.
+OPENSSL_EXPORT int SHA512_256_Final(uint8_t out[SHA512_256_DIGEST_LENGTH],
+ SHA512_CTX *sha);
+
+// SHA512_256 writes the digest of |len| bytes from |data| to |out| and returns
+// |out|. There must be at least |SHA512_256_DIGEST_LENGTH| bytes of space in
+// |out|.
+OPENSSL_EXPORT uint8_t *SHA512_256(const uint8_t *data, size_t len,
+ uint8_t out[SHA512_256_DIGEST_LENGTH]);
+
+
#if defined(__cplusplus)
} // extern C
#endif
diff --git a/tool/digest.cc b/tool/digest.cc
index 7b6c88b..742fa7f 100644
--- a/tool/digest.cc
+++ b/tool/digest.cc
@@ -474,3 +474,7 @@
bool SHA512Sum(const std::vector<std::string> &args) {
return DigestSum(EVP_sha512(), args);
}
+
+bool SHA512256Sum(const std::vector<std::string> &args) {
+ return DigestSum(EVP_sha512_256(), args);
+}
diff --git a/tool/internal.h b/tool/internal.h
index b626270..4cace9d 100644
--- a/tool/internal.h
+++ b/tool/internal.h
@@ -87,6 +87,7 @@
bool SHA256Sum(const std::vector<std::string> &args);
bool SHA384Sum(const std::vector<std::string> &args);
bool SHA512Sum(const std::vector<std::string> &args);
+bool SHA512256Sum(const std::vector<std::string> &args);
bool Server(const std::vector<std::string> &args);
bool Sign(const std::vector<std::string> &args);
bool Speed(const std::vector<std::string> &args);
diff --git a/tool/tool.cc b/tool/tool.cc
index 670d4e7..d278535 100644
--- a/tool/tool.cc
+++ b/tool/tool.cc
@@ -58,6 +58,7 @@
{ "sha256sum", SHA256Sum },
{ "sha384sum", SHA384Sum },
{ "sha512sum", SHA512Sum },
+ { "sha512256sum", SHA512256Sum },
{ "sign", Sign },
{ "speed", Speed },
{ "", nullptr },