Skip to content

Commit

Permalink
Merge pull request planet-nine-app#49 from planet-nine-app/refactor-c…
Browse files Browse the repository at this point in the history
…pp-lib
  • Loading branch information
zach-planet-nine authored May 26, 2024
2 parents f29ed22 + 7e43f8e commit 0060a07
Show file tree
Hide file tree
Showing 7 changed files with 47 additions and 53 deletions.
2 changes: 1 addition & 1 deletion src/cpp/client/example/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ FetchContent_Declare(
# For an external executable fetch content from the sessionless
# git repo using options below instead of SOURCE_DIR
# GIT_REPOSITORY [email protected]:planet-nine-app/sessionless.git
# GIT_TAG main
# GIT_TAG <tag or SHA>
# SOURCE_SUBDIR src/cpp/client/lib
)
FetchContent_MakeAvailable(sessionless)
Expand Down
1 change: 0 additions & 1 deletion src/cpp/client/example/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ CMake and C++ compiler are required.

## Build the example
```shell
mkdir build
cmake -B ./build -S .
cd build
make
Expand Down
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
4 changes: 4 additions & 0 deletions src/cpp/client/lib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,16 @@ set(SECP256K1_BUILD_TESTS OFF)
set(SECP256K1_BUILD_EXHAUSTIVE_TESTS OFF)
set(SECP256K1_BUILD_BENCHMARK OFF)

set(CMAKE_BUILD_TYPE Release)
set(BUILD_SHARED_LIBS FALSE)

FetchContent_MakeAvailable(${SECP256K1_LIB_NAME})

#################################################
# Sessionless library

set(TARGET sessionless)
set(CMAKE_BUILD_TYPE Release)
project(${TARGET})
set(CMAKE_CXX_STANDARD 17)
add_library(${TARGET} STATIC src/sessionless.cpp)
Expand Down
1 change: 0 additions & 1 deletion src/cpp/client/lib/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ CMake and C++ compiler are required.

## Build the demo
```shell
mkdir build
cmake -B ./build -S .
cd build
make
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 0060a07

Please sign in to comment.