Skip to content

Instantly share code, notes, and snippets.

@aalness
Last active March 10, 2023 10:15
Show Gist options
  • Save aalness/577c7a6da1e669a07db9 to your computer and use it in GitHub Desktop.
Save aalness/577c7a6da1e669a07db9 to your computer and use it in GitHub Desktop.
Benchmark SHA256 for libsecp256k1 / crypto++ / openssl
#include <string.h>
#include <sys/time.h>
#include <iostream>
#include <openssl/sha.h>
#include <openssl/rand.h>
#include "secp256k1/src/hash_impl.h"
#include "cryptopp/sha.h"
static const size_t NUM_RUNS = 300000UL;
static double msecs(void)
{
struct timeval te;
gettimeofday(&te, NULL);
double msecs = te.tv_sec*1000.0 + te.tv_usec/1000.0;
return msecs;
}
static void openssl(const std::string& message, unsigned char* out)
{
SHA256_CTX sha256;
SHA256_Init(&sha256);
SHA256_Update(&sha256, message.c_str(), message.length());
SHA256_Final(out, &sha256);
}
static void cryptopp(const std::string& message, unsigned char* out)
{
CryptoPP::SHA256 hash;
hash.Update((const byte*)message.c_str(), message.length());
hash.Final(out);
}
static void secp256k1(const std::string& message, unsigned char* out)
{
secp256k1_sha256_t hasher;
secp256k1_sha256_initialize(&hasher);
secp256k1_sha256_write(&hasher, (const unsigned char*)message.c_str(), message.length());
secp256k1_sha256_finalize(&hasher, out);
}
int main(int ac, char *av[])
{
if (ac != 2)
{
std::cout << "usage: " << av[0] << " <message size>" << std::endl;
return 1;
}
const size_t size = strtoul(av[1], 0, 0);
assert(size);
std::cout << "size: " << size << ", num runs: " << NUM_RUNS << std::endl;
// test correctness
for (size_t i = 0; i < 1000; ++i)
{
std::string message;
message.resize(size);
assert(RAND_bytes((unsigned char*)&message[0], size) == 1);
unsigned char out[32], out2[32], out3[32];
openssl(message, out);
cryptopp(message, out2);
secp256k1(message, out3);
assert(!memcmp(out, out2, 32));
assert(!memcmp(out, out3, 32));
}
std::string message;
message.resize(size);
assert(RAND_bytes((unsigned char*)&message[0], size) == 1);
double before, after;
before = msecs();
for (size_t i = 0; i < NUM_RUNS; ++i)
{
unsigned char out[32];
cryptopp(message, out);
}
after = msecs();
std::cout << " cryptopp took: " << (after-before) << "ms" << std::endl;
before = msecs();
for (size_t i = 0; i < NUM_RUNS; ++i)
{
unsigned char out[32];
openssl(message, out);
}
after = msecs();
std::cout << " openssl took: " << (after-before) << "ms" << std::endl;
before = msecs();
for (size_t i = 0; i < NUM_RUNS; ++i)
{
unsigned char out[32];
secp256k1(message, out);
}
after = msecs();
std::cout << "libsecp256k1 took: " << (after-before) << "ms" << std::endl;
return 0;
}
@aalness
Copy link
Author

aalness commented Dec 14, 2014

I don't think these #s are particularly damning or anything. For the normal workload of libsecp256k1 (on order of 32 bytes) it is perfectly fine. At least it would be remarkable if the difference mattered but we'd have much bigger problems to deal with in that case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment