Skip to content

Commit

Permalink
Reduce dependency on modern C++ features
Browse files Browse the repository at this point in the history
  • Loading branch information
Your Name committed May 25, 2024
1 parent 45acf0d commit 7e43f8e
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 50 deletions.
8 changes: 4 additions & 4 deletions src/cpp/client/example/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,20 +31,20 @@ int main(int argc, char *argv[])
}

std::cout << "public key -> "
<< toHexString(keys.publicKey.data(), keys.publicKey.size()) << std::endl;
<< toHexString(keys.publicKey, sizeof(keys.publicKey)) << std::endl;
std::cout << "private key -> "
<< toHexString(keys.privateKey.data(), keys.privateKey.size()) << std::endl;
<< toHexString(keys.privateKey, sizeof(keys.privateKey)) << std::endl;

const char *msg = "Here is a message";
Signature signature;
unsigned char signature[SIGNATURE_SIZE_BYTES];
if (!sessionless::sign((unsigned char *)msg, sizeof(msg), keys.privateKey, signature))
{
std::cout << "Failed to sign message" << std::endl;
return -1;
}

std::cout << "Message -> " << msg << std::endl
<< "Message signature -> " << toHexString(signature.data(), signature.size()) << std::endl;
<< "Message signature -> " << toHexString(signature, sizeof(signature)) << std::endl;

std::cout << "Verifying signature..." << std::endl;
if (!sessionless::verifySignature(signature, keys.publicKey, (unsigned char *)msg, sizeof(msg)))
Expand Down
55 changes: 22 additions & 33 deletions src/cpp/client/lib/src/sessionless.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
#include <secp256k1.h>
#include <random>
#include <ctime>
#include <iostream>

// Creating context is expensive, create one global context
static secp256k1_context *ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);

bool sessionless::generateKeys(Keys &keys)
{
Expand All @@ -16,91 +18,78 @@ bool sessionless::generateKeys(Keys &keys)
keys.privateKey[i] = rand() % 256;
}

secp256k1_context *ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);

if (!secp256k1_context_randomize(ctx, seed))
{
std::cout << "Failed to randomize context" << std::endl;
return false;
}

if (!secp256k1_ec_seckey_verify(ctx, keys.privateKey.data()))
if (!secp256k1_ec_seckey_verify(ctx, keys.privateKey))
{
std::cout << "Failed to verify secret key" << std::endl;
return false;
}

secp256k1_pubkey publicKeyStruct;
if (!secp256k1_ec_pubkey_create(ctx, &publicKeyStruct, keys.privateKey.data()))
if (!secp256k1_ec_pubkey_create(ctx, &publicKeyStruct, keys.privateKey))
{
std::cout << "Failed to create public key" << std::endl;
return false;
}

size_t len = keys.publicKey.size();
secp256k1_ec_pubkey_serialize(ctx, keys.publicKey.data(), &len,
size_t len = PUBLIC_KEY_SIZE_BYTES;
secp256k1_ec_pubkey_serialize(ctx, keys.publicKey, &len,
&publicKeyStruct, SECP256K1_EC_COMPRESSED);
if (len != PUBLIC_KEY_SIZE_BYTES)
{
std::cout << "Invalid public key size" << std::endl;
return false;
}

return true;
};

bool sessionless::sign(const unsigned char *message,
const size_t length,
const PrivateKey privateKey,
Signature &signature)
const size_t msgLengthBytes,
const unsigned char *privateKey,
unsigned char *signature)
{
secp256k1_ecdsa_signature ecdsa_signature;
unsigned char msg_hash[SHA256_SIZE_BYTES];
unsigned char msgHash[SHA256_SIZE_BYTES];
unsigned char tag[12] = "sessionless";

secp256k1_context *ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);

int ret = secp256k1_tagged_sha256(ctx, msg_hash, tag, sizeof(tag), message, length);
int ret = secp256k1_tagged_sha256(ctx, msgHash, tag, sizeof(tag), message, msgLengthBytes);

if (!secp256k1_ecdsa_sign(ctx, &ecdsa_signature, msg_hash, privateKey.data(), NULL, NULL))
if (!secp256k1_ecdsa_sign(ctx, &ecdsa_signature, msgHash, privateKey, NULL, NULL))
{
std::cout << "Failed ecdsa sign" << std::endl;
return false;
}

secp256k1_ecdsa_signature_serialize_compact(ctx, signature.data(), &ecdsa_signature);
secp256k1_ecdsa_signature_serialize_compact(ctx, signature, &ecdsa_signature);

return true;
};

bool sessionless::verifySignature(Signature signature,
PublicKey publicKey,
bool sessionless::verifySignature(const unsigned char *signature,
const unsigned char *publicKey,
const unsigned char *message,
const size_t length)
const size_t msgLengthBytes)
{
secp256k1_context *ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);
unsigned char msg_hash[SHA256_SIZE_BYTES];
unsigned char msgHash[SHA256_SIZE_BYTES];
const unsigned char tag[12] = "sessionless";

int ret = secp256k1_tagged_sha256(ctx, msg_hash, tag, sizeof(tag), message, length);
int ret = secp256k1_tagged_sha256(ctx, msgHash, tag, sizeof(tag), message, msgLengthBytes);

secp256k1_pubkey pubkey;
if (!secp256k1_ec_pubkey_parse(ctx, &pubkey, publicKey.data(), publicKey.size()))
if (!secp256k1_ec_pubkey_parse(ctx, &pubkey, publicKey, PUBLIC_KEY_SIZE_BYTES))
{
std::cout << "Failed to parse public key" << std::endl;
return false;
}

secp256k1_ecdsa_signature sig;
if (!secp256k1_ecdsa_signature_parse_compact(ctx, &sig, signature.data()))
if (!secp256k1_ecdsa_signature_parse_compact(ctx, &sig, signature))
{
std::cout << "Failed to parse signature" << std::endl;
return false;
}

if (!secp256k1_ecdsa_verify(ctx, &sig, msg_hash, &pubkey))
if (!secp256k1_ecdsa_verify(ctx, &sig, msgHash, &pubkey))
{
std::cout << "Signature verification failed" << std::endl;
return false;
}

Expand Down
29 changes: 16 additions & 13 deletions src/cpp/client/lib/src/sessionless.hpp
Original file line number Diff line number Diff line change
@@ -1,29 +1,32 @@
#ifndef SESSIONLESS_HPP
#define SESSIONLESS_HPP

#include <array>
#include <cstddef>

static constexpr size_t SHA256_SIZE_BYTES = 32;
static constexpr size_t PRIVATE_KEY_SIZE_BYTES = SHA256_SIZE_BYTES;
static constexpr size_t PUBLIC_KEY_SIZE_BYTES = 33;
static constexpr size_t SIGNATURE_SIZE_BYTES = 64;

using PublicKey = std::array<unsigned char, PUBLIC_KEY_SIZE_BYTES>;
using PrivateKey = std::array<unsigned char, PRIVATE_KEY_SIZE_BYTES>;
using Signature = std::array<unsigned char, SIGNATURE_SIZE_BYTES>;
#define SHA256_SIZE_BYTES 32
#define PRIVATE_KEY_SIZE_BYTES SHA256_SIZE_BYTES
#define PUBLIC_KEY_SIZE_BYTES 33
#define SIGNATURE_SIZE_BYTES 64

struct Keys
{
PublicKey publicKey;
PrivateKey privateKey;
unsigned char publicKey[PUBLIC_KEY_SIZE_BYTES];
unsigned char privateKey[PRIVATE_KEY_SIZE_BYTES];
};

namespace sessionless
{
bool generateKeys(Keys &keys);
bool sign(const unsigned char *message, const size_t length, const PrivateKey privateKey, Signature &signature);
bool verifySignature(Signature signature, PublicKey publicKey, const unsigned char *message, const size_t length);

bool sign(const unsigned char *message,
const size_t msgLengthBytes,
const unsigned char *privateKey,
unsigned char *signature);

bool verifySignature(const unsigned char *signature,
const unsigned char *publicKey,
const unsigned char *message,
const size_t msgLengthBytes);
};

#endif

0 comments on commit 7e43f8e

Please sign in to comment.