2023-10-18 06:43:18 +00:00
|
|
|
/*
|
|
|
|
* The MIT License (MIT)
|
|
|
|
*
|
|
|
|
* Copyright (c) 2015 K. Isom <coder@kyleisom.net>
|
|
|
|
*
|
|
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
|
* copy of this software and associated documentation files (the "Software"),
|
|
|
|
* to deal in the Software without restriction, including without limitation
|
|
|
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
|
|
* and/or sell copies of the Software, and to permit persons to whom the
|
|
|
|
* Software is furnished to do so, subject to the following conditions:
|
|
|
|
*
|
|
|
|
* The above copyright notice and this permission notice shall be included in
|
|
|
|
* all copies or substantial portions of the Software.
|
|
|
|
*
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
|
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
|
|
* IN THE SOFTWARE.
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef NDEBUG
|
|
|
|
#undef NDEBUG
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#include <cassert>
|
|
|
|
#include <chrono>
|
|
|
|
#include <cstring>
|
|
|
|
#include <algorithm>
|
|
|
|
#include <cstdio>
|
|
|
|
#include <iostream>
|
|
|
|
|
|
|
|
#include <emsha/emsha.h>
|
|
|
|
#include <emsha/sha256.h>
|
|
|
|
#include <emsha/hmac.h>
|
|
|
|
|
|
|
|
|
|
|
|
// Number of test iterations.
|
2023-10-18 10:39:27 +00:00
|
|
|
static constexpr std::uint32_t ITERS = 32768;
|
2023-10-18 06:43:18 +00:00
|
|
|
|
|
|
|
// The key used for HMAC.
|
|
|
|
static constexpr std::uint8_t k[] = {
|
|
|
|
0xc5, 0xb6, 0x80, 0xac, 0xdc, 0xf4, 0xff, 0xa1,
|
|
|
|
0x37, 0x05, 0xc0, 0x71, 0x11, 0x24, 0x31, 0x7c,
|
|
|
|
0xa5, 0xa2, 0xcf, 0x4d, 0x33, 0x00, 0x56, 0x4f,
|
|
|
|
0x69, 0x0f, 0x76, 0x70, 0x87, 0xd9, 0x35, 0xce,
|
|
|
|
0xa3, 0xad, 0xa3, 0x4f, 0x30, 0xe2, 0x7c, 0x58,
|
|
|
|
0x88, 0xd4, 0x89, 0x6a, 0xb5, 0xe0, 0x97, 0x1c,
|
|
|
|
0x7a, 0x69, 0x65, 0xc7, 0x61, 0x0d, 0x6d, 0xb6,
|
|
|
|
0x9b, 0x0e, 0x56, 0xd7, 0x0f, 0x5a, 0x01, 0x50,
|
|
|
|
};
|
|
|
|
static constexpr std::uint32_t kl = sizeof(k) / sizeof(k[0]);
|
|
|
|
|
|
|
|
// The message provided to both SHA-256 and HMAC-SHA-256; it is
|
|
|
|
// "The fugacity of a constituent in a mixture of gases at a given
|
|
|
|
// temperature is proportional to its mole fraction. Lewis-Randall Rule",
|
|
|
|
// chosen as one of the longer test vectors.
|
|
|
|
static const std::uint8_t m[] = {
|
|
|
|
0x54, 0x68, 0x65, 0x20, 0x66, 0x75, 0x67, 0x61,
|
|
|
|
0x63, 0x69, 0x74, 0x79, 0x20, 0x6f, 0x66, 0x20,
|
|
|
|
0x61, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x69,
|
|
|
|
0x74, 0x75, 0x65, 0x6e, 0x74, 0x20, 0x69, 0x6e,
|
|
|
|
0x20, 0x61, 0x20, 0x6d, 0x69, 0x78, 0x74, 0x75,
|
|
|
|
0x72, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x67, 0x61,
|
|
|
|
0x73, 0x65, 0x73, 0x20, 0x61, 0x74, 0x20, 0x61,
|
|
|
|
0x20, 0x67, 0x69, 0x76, 0x65, 0x6e, 0x20, 0x74,
|
|
|
|
0x65, 0x6d, 0x70, 0x65, 0x72, 0x61, 0x74, 0x75,
|
|
|
|
0x72, 0x65, 0x20, 0x69, 0x73, 0x20, 0x70, 0x72,
|
|
|
|
0x6f, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6f, 0x6e,
|
|
|
|
0x61, 0x6c, 0x20, 0x74, 0x6f, 0x20, 0x69, 0x74,
|
|
|
|
0x73, 0x20, 0x6d, 0x6f, 0x6c, 0x65, 0x20, 0x66,
|
|
|
|
0x72, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e,
|
|
|
|
0x20, 0x20, 0x4c, 0x65, 0x77, 0x69, 0x73, 0x2d,
|
|
|
|
0x52, 0x61, 0x6e, 0x64, 0x61, 0x6c, 0x6c, 0x20,
|
|
|
|
0x52, 0x75, 0x6c, 0x65
|
|
|
|
};
|
|
|
|
|
|
|
|
// d is the expected result of SHA256(m).
|
|
|
|
static constexpr std::uint8_t d[emsha::SHA256_HASH_SIZE] = {
|
|
|
|
0x39, 0x55, 0x85, 0xce, 0x30, 0x61, 0x7b, 0x62,
|
|
|
|
0xc8, 0x0b, 0x93, 0xe8, 0x20, 0x8c, 0xe8, 0x66,
|
|
|
|
0xd4, 0xed, 0xc8, 0x11, 0xa1, 0x77, 0xfd, 0xb4,
|
|
|
|
0xb8, 0x2d, 0x39, 0x11, 0xd8, 0x69, 0x64, 0x23
|
|
|
|
};
|
|
|
|
|
|
|
|
// t is the expected result of HMAC-SHA-256(k, m).
|
|
|
|
static constexpr std::uint8_t t[emsha::SHA256_HASH_SIZE] = {
|
|
|
|
0xbb, 0xc4, 0x7c, 0x35, 0x33, 0x4b, 0x9d, 0x90,
|
|
|
|
0xee, 0x20, 0x88, 0x30, 0xe1, 0x1a, 0x0f, 0xf3,
|
|
|
|
0xf4, 0x7d, 0xcc, 0xb0, 0xc5, 0xfb, 0x83, 0xe5,
|
|
|
|
0xc2, 0xf5, 0xa7, 0x94, 0x50, 0xb6, 0xe0, 0xe0,
|
|
|
|
};
|
|
|
|
|
|
|
|
// dig is used to store the output of SHA-256 and HMAC-SHA-256.
|
|
|
|
static std::uint8_t dig[emsha::SHA256_HASH_SIZE];
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
init()
|
|
|
|
{
|
|
|
|
std::fill(dig, dig + emsha::SHA256_HASH_SIZE, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
iterateSHA()
|
|
|
|
{
|
|
|
|
emsha::SHA256 ctx;
|
2023-10-18 10:39:27 +00:00
|
|
|
int cmp = 0;
|
|
|
|
emsha::EMSHAResult res;
|
2023-10-18 06:43:18 +00:00
|
|
|
|
|
|
|
res = ctx.Update(m, sizeof(m));
|
2023-10-18 10:39:27 +00:00
|
|
|
assert(emsha::EMSHAResult::OK == res);
|
2023-10-18 06:43:18 +00:00
|
|
|
res = ctx.Result(dig);
|
2023-10-18 10:39:27 +00:00
|
|
|
assert(emsha::EMSHAResult::OK == res);
|
2023-10-18 06:43:18 +00:00
|
|
|
|
|
|
|
cmp = std::memcmp(dig, d, emsha::SHA256_HASH_SIZE);
|
|
|
|
assert(0 == cmp);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
iterateHMAC()
|
|
|
|
{
|
|
|
|
emsha::HMAC ctx(k, kl);
|
2023-10-18 10:39:27 +00:00
|
|
|
int cmp = 0;
|
|
|
|
emsha::EMSHAResult res;
|
2023-10-18 06:43:18 +00:00
|
|
|
|
|
|
|
res = ctx.Update(m, sizeof(m));
|
2023-10-18 10:39:27 +00:00
|
|
|
assert(emsha::EMSHAResult::OK == res);
|
2023-10-18 06:43:18 +00:00
|
|
|
res = ctx.Result(dig);
|
2023-10-18 10:39:27 +00:00
|
|
|
assert(emsha::EMSHAResult::OK == res);
|
2023-10-18 06:43:18 +00:00
|
|
|
|
|
|
|
cmp = std::memcmp(dig, t, emsha::SHA256_HASH_SIZE);
|
|
|
|
assert(0 == cmp);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
iterateSHASP()
|
|
|
|
{
|
|
|
|
int cmp = 0;
|
|
|
|
|
2023-10-18 10:39:27 +00:00
|
|
|
assert(emsha::EMSHAResult::OK == emsha::SHA256Digest(m, sizeof(m), dig));
|
2023-10-18 06:43:18 +00:00
|
|
|
cmp = std::memcmp(dig, d, emsha::SHA256_HASH_SIZE);
|
|
|
|
assert(0 == cmp);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
iterateHMACSP()
|
|
|
|
{
|
2023-10-18 10:39:27 +00:00
|
|
|
int cmp = 0;
|
|
|
|
emsha::EMSHAResult res;
|
2023-10-18 06:43:18 +00:00
|
|
|
|
|
|
|
res = emsha::ComputeHMAC(k, kl, m, sizeof(m), dig);
|
2023-10-18 10:39:27 +00:00
|
|
|
assert(emsha::EMSHAResult::OK == res);
|
2023-10-18 06:43:18 +00:00
|
|
|
|
|
|
|
cmp = std::memcmp(dig, t, emsha::SHA256_HASH_SIZE);
|
|
|
|
assert(0 == cmp);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
iterate(const std::string &label, void(iteration)(void))
|
|
|
|
{
|
|
|
|
std::cout << "=== " << label << " ===" << std::endl;
|
|
|
|
auto start = std::chrono::steady_clock::now();
|
|
|
|
|
|
|
|
for (std::uint32_t i = 0; i < ITERS; i++) {
|
|
|
|
iteration();
|
|
|
|
}
|
|
|
|
|
|
|
|
auto end = std::chrono::steady_clock::now();
|
|
|
|
auto delta = (end - start);
|
|
|
|
|
|
|
|
std::cout << "Total time: "
|
|
|
|
<< std::chrono::duration<double, std::milli>(delta).count()
|
|
|
|
<< " ms" << std::endl;
|
|
|
|
std::cout << "Average over " << ITERS << " tests: "
|
|
|
|
<< std::chrono::duration<double, std::nano>(delta).count() / ITERS
|
|
|
|
<< " ns" << std::endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
coldStart()
|
|
|
|
{
|
|
|
|
std::cout << "=== SHA-256 cold start ===\n";
|
|
|
|
auto start = std::chrono::steady_clock::now();
|
|
|
|
|
|
|
|
iterateSHA();
|
|
|
|
|
|
|
|
auto end = std::chrono::steady_clock::now();
|
|
|
|
auto delta = (end - start);
|
|
|
|
|
|
|
|
std::cout << "Total time: "
|
|
|
|
<< std::chrono::duration<double, std::nano>(delta).count()
|
|
|
|
<< " ns" << std::endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
main()
|
|
|
|
{
|
|
|
|
init();
|
|
|
|
|
|
|
|
coldStart();
|
|
|
|
iterate("SHA-256", iterateSHA);
|
|
|
|
iterate("SHA-256 single-pass", iterateSHASP);
|
|
|
|
iterate("HMAC-SHA-256", iterateHMAC);
|
|
|
|
iterate("HMAC-SHA-256 single-pass", iterateHMACSP);
|
|
|
|
}
|