Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 18 additions & 17 deletions .github/workflows/cmake.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,28 +19,29 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
os: [ubuntu-latest,
macos-latest,
windows-latest]

steps:
- uses: actions/checkout@v3
- name: Prepare dependencies
run: |
if [ "$RUNNER_OS" == "Linux" ]; then
sudo apt-get update && \
sudo apt-get install -yq \
libboost-system-dev \
libboost-date-time-dev \
cmake \
graphviz doxygen
elif [ "$RUNNER_OS" == "Windows" ]; then
choco install boost-msvc-14.3 graphviz doxygen.install
elif [ "$RUNNER_OS" == "macOS" ]; then
brew install boost graphviz doxygen
else
echo "$RUNNER_OS not supported"
exit 1
fi
shell: bash
if [ "$RUNNER_OS" == "Linux" ]; then
sudo apt-get update && \
sudo apt-get install -yq \
libasio-dev \
libssl-dev zlib1g-dev \
cmake graphviz doxygen
elif [ "$RUNNER_OS" == "Windows" ]; then
VCPKG_DEFAULT_TRIPLET=x64-windows vcpkg install
elif [ "$RUNNER_OS" == "macOS" ]; then
brew install asio openssl zlib doxygen graphviz
else
echo "$RUNNER_OS not supported"
exit 1
fi
shell: bash
- name: Configure CMake
run: cmake -B build
shell: bash
Expand Down
33 changes: 27 additions & 6 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
cmake_minimum_required(VERSION 3.1.3)
cmake_minimum_required(VERSION 3.15.0 FATAL_ERROR)

project(oc-issuer VERSION 0.0.2 LANGUAGES CXX)

enable_language(C)
enable_language(CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_EXPORT_COMPILE_COMMANDS On)

set(CMAKE_POLICY_DEFAULT_CMP0077 NEW)
if(POLICY CMP0077)
cmake_policy(SET CMP0077 NEW)
endif()
Expand All @@ -14,7 +18,8 @@ else()
add_compile_options(-Wall -Wextra -pedantic)
endif()

project(oc-issuer VERSION 0.0.2 LANGUAGES CXX)

set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

include(FetchContent)

Expand All @@ -25,11 +30,12 @@ set(CROW_BUILD_EXAMPLES Off)
set(CROW_BUILD_TOOLS Off)
set(CROW_BUILD_TESTS Off)
set(CROW_BUILD_DOCS Off)
set(CROW_FEATURES "ssl;compression")

# add crow project to the build
FetchContent_Declare(crow
GIT_REPOSITORY https://github.com/CrowCpp/Crow.git
GIT_TAG v1.0+5
GIT_TAG v1.2.0
)

if(NOT crow_POPULATED)
Expand All @@ -46,6 +52,18 @@ if(NOT expected_POPULATED)
FetchContent_Populate(expected)
endif(NOT expected_POPULATED)

# add crypt++ (+cmake) library
#set(CRYPTOPP_BUILD_TESTING Off)
#set(CRYPTOPP_INSTALL Off)

#if(NOT cryptopp_POPULATED)
# FetchContent_Declare(cryptopp
# GIT_REPOSITORY https://github.com/abdes/cryptopp-cmake.git
# GIT_TAG CRYPTOPP_8_7_0_1)
# FetchContent_Populate(cryptopp)
# add_subdirectory(${cryptopp_SOURCE_DIR} ${cryptopp_BINARY_DIR})
#endif(NOT cryptopp_POPULATED)

include(CTest)
enable_testing()

Expand All @@ -54,7 +72,7 @@ set(CATCH_INSTALL_EXTRAS Off)
FetchContent_Declare(
Catch2
GIT_REPOSITORY https://github.com/catchorg/Catch2.git
GIT_TAG v3.3.1
GIT_TAG v3.6.0
)

FetchContent_MakeAvailable(Catch2)
Expand All @@ -77,14 +95,17 @@ set(LIB_SOURCES
src/big_int.hpp src/big_int.cpp )

add_library(oc-mint-lib ${LIB_SOURCES})
target_link_libraries(oc-mint-lib PUBLIC Crow::Crow)
target_link_libraries(oc-mint-lib PUBLIC Crow::Crow) # cryptopp::cryptopp)
target_include_directories(oc-mint-lib PUBLIC ${expected_SOURCE_DIR}/include src)

add_executable(${PROJECT_NAME} src/main.cpp)
target_link_libraries(${PROJECT_NAME} PRIVATE oc-mint-lib INTERFACE tl::expected::expected)

## these are unittests that can be run on any platform
add_executable(tests test/test_big_int.cpp test/test.cpp)
add_executable(tests test/test_big_int.cpp
test/test_json_s8n.cpp
test/test_crypto.cpp)

target_link_libraries(tests
oc-mint-lib
Catch2::Catch2WithMain)
Expand Down
250 changes: 250 additions & 0 deletions test/test_crypto.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,250 @@

#include <catch2/catch_test_macros.hpp>

//#include "cryptlib.h"
//#include "integer.h"
//#include "nbtheory.h"
//#include "osrng.h"
//#include "rsa.h"
//#include "sha.h"

#include <iostream>
#include <stdexcept>

/*
CryptoPP::Integer blind_signature(const CryptoPP::SecByteBlock &orig,
const CryptoPP::Integer &r,
const CryptoPP::RSA::PublicKey &pub_key,
const CryptoPP::RSA::PrivateKey &priv_key) {
using namespace CryptoPP;
using std::cout;
using std::endl;

// Convenience
const Integer &n = pub_key.GetModulus();
const Integer &e = pub_key.GetPublicExponent();
// const Integer &d = priv_key.GetPrivateExponent();

// For sizing the hashed message buffer. This should be SHA256 size.
const size_t sig_size = UnsignedMin(SHA256::BLOCKSIZE, n.ByteCount());
// Scratch
SecByteBlock buff_1, buff_2, buff_3;

Integer m(orig.data(), orig.size());
cout << "Message: " << std::hex << m << endl;

// Hash message per Rabin (1979)
buff_1.resize(sig_size);
SHA256 hash_1;
hash_1.CalculateTruncatedDigest(buff_1, buff_1.size(), orig, orig.size());

// H(m) as Integer
Integer hm(buff_1.data(), buff_1.size());
cout << "H(m): " << std::hex << hm << endl;

// Blinding factor
Integer b = a_exp_b_mod_c(r, e, n);
cout << "Random: " << std::hex << b << endl;

// Alice blinded message
Integer mm = a_times_b_mod_c(hm, b, n);
cout << "Blind msg: " << std::hex << mm << endl;

AutoSeededRandomPool prng;

// Bob sign
Integer ss = priv_key.CalculateInverse(prng, mm);
cout << "Blind sign: " << ss << endl;

return ss;
}

CryptoPP::Integer unblind_signature(const CryptoPP::Integer &ss,
const CryptoPP::Integer &r,
const CryptoPP::RSA::PublicKey &pub_key) {

const CryptoPP::Integer &n = pub_key.GetModulus();
CryptoPP::Integer s = a_times_b_mod_c(ss, r.InverseMod(n), n);
return s;
}

CryptoPP::Integer verify(CryptoPP::Integer const &ss,
const CryptoPP::Integer &r,
const CryptoPP::RSA::PublicKey &pub_key) {
CryptoPP::Integer s = unblind_signature(ss, r, pub_key);
CryptoPP::Integer v = pub_key.ApplyFunction(s);
return v;
}

TEST_CASE("cryptopp1", "[crypto]") {
using namespace CryptoPP;
using std::cout;
using std::endl;
using std::runtime_error;

// Bob artificially small key pair
AutoSeededRandomPool prng;
RSA::PrivateKey priv_key;

priv_key.GenerateRandomWithKeySize(prng, 64U);
RSA::PublicKey pub_key(priv_key);

// Convenience
const Integer &n = pub_key.GetModulus();
const Integer &e = pub_key.GetPublicExponent();
const Integer &d = priv_key.GetPrivateExponent();

// Print params
cout << "Pub mod: " << std::hex << pub_key.GetModulus() << endl;
cout << "Pub exp: " << std::hex << e << endl;
cout << "Priv mod: " << std::hex << priv_key.GetModulus() << endl;
cout << "Priv exp: " << std::hex << d << endl;
const char *MESSAGE = "secret";
SecByteBlock orig((const byte *) MESSAGE, 6U);

// Alice blinding
Integer r;
do {
r.Randomize(prng, Integer::One(), n - Integer::One());
} while (!RelativelyPrime(r, n));
CryptoPP::Integer ss = blind_signature(orig,
r,
pub_key,
priv_key);
// Alice checks s(s'(x)) = x. This is from Chaum's paper
Integer c = pub_key.ApplyFunction(ss);
cout << "Check sign: " << c << endl;
//if (c != mm) {
// throw runtime_error("Alice cross-check failed");
// }
// Alice remove blinding
Integer s = unblind_signature(ss, r, pub_key);
cout << "Unblind sign: " << s << endl;

// Eve verifies
Integer v = verify(ss, r, pub_key);
cout << "Verify: " << std::hex << v << endl;

// Scratch
SecByteBlock buff_2, buff_3;

// Convert to a string
size_t req = v.MinEncodedSize();
buff_2.resize(req);
v.Encode(&buff_2[0], buff_2.size());

// Hash message per Rabin (1979)
const size_t sig_size = UnsignedMin(SHA256::BLOCKSIZE, n.ByteCount());
buff_3.resize(sig_size);
SHA256 hash_2;
hash_2.CalculateTruncatedDigest(buff_3, buff_3.size(), orig, orig.size());

// Constant time compare
bool equal = buff_2.size() == buff_3.size() &&
VerifyBufsEqual(buff_2.data(), buff_3.data(), buff_3.size());

if (!equal) {
throw runtime_error("Eve verified failed");
}
cout << "Verified signature" << endl;


}
*/
/*
TEST_CASE("cryptopp", "[crypto]") {
using namespace CryptoPP;
using std::cout;
using std::endl;
using std::runtime_error;

// Bob artificially small key pair
AutoSeededRandomPool prng;
RSA::PrivateKey priv_key;

priv_key.GenerateRandomWithKeySize(prng, 64U);
RSA::PublicKey pub_key(priv_key);

// Convenience
const Integer &n = pub_key.GetModulus();
const Integer &e = pub_key.GetPublicExponent();
const Integer &d = priv_key.GetPrivateExponent();

// Print params
cout << "Pub mod: " << std::hex << pub_key.GetModulus() << endl;
cout << "Pub exp: " << std::hex << e << endl;
cout << "Priv mod: " << std::hex << priv_key.GetModulus() << endl;
cout << "Priv exp: " << std::hex << d << endl;

// For sizing the hashed message buffer. This should be SHA256 size.
const size_t sig_size = UnsignedMin(SHA256::BLOCKSIZE, n.ByteCount());

// Scratch
SecByteBlock buff_1, buff_2, buff_3;

// Alice original message to be signed by Bob
SecByteBlock orig((const byte *) "secret", 6U);
Integer m(orig.data(), orig.size());
cout << "Message: " << std::hex << m << endl;

// Hash message per Rabin (1979)
buff_1.resize(sig_size);
SHA256 hash_1;
hash_1.CalculateTruncatedDigest(buff_1, buff_1.size(), orig, orig.size());

// H(m) as Integer
Integer hm(buff_1.data(), buff_1.size());
cout << "H(m): " << std::hex << hm << endl;

// Alice blinding
Integer r;
do {
r.Randomize(prng, Integer::One(), n - Integer::One());
} while (!RelativelyPrime(r, n));

// Blinding factor
Integer b = a_exp_b_mod_c(r, e, n);
cout << "Random: " << std::hex << b << endl;

// Alice blinded message
Integer mm = a_times_b_mod_c(hm, b, n);
cout << "Blind msg: " << std::hex << mm << endl;

// Bob sign
Integer ss = priv_key.CalculateInverse(prng, mm);
cout << "Blind sign: " << ss << endl;

// Alice checks s(s'(x)) = x. This is from Chaum's paper
Integer c = pub_key.ApplyFunction(ss);
cout << "Check sign: " << c << endl;
if (c != mm) {
throw runtime_error("Alice cross-check failed");
}
// Alice remove blinding
Integer s = a_times_b_mod_c(ss, r.InverseMod(n), n);
cout << "Unblind sign: " << s << endl;

// Eve verifies
Integer v = pub_key.ApplyFunction(s);
cout << "Verify: " << std::hex << v << endl;

// Convert to a string
size_t req = v.MinEncodedSize();
buff_2.resize(req);
v.Encode(&buff_2[0], buff_2.size());

// Hash message per Rabin (1979)
buff_3.resize(sig_size);
SHA256 hash_2;
hash_2.CalculateTruncatedDigest(buff_3, buff_3.size(), orig, orig.size());

// Constant time compare
bool equal = buff_2.size() == buff_3.size() &&
VerifyBufsEqual(buff_2.data(), buff_3.data(), buff_3.size());

if (!equal) {
throw runtime_error("Eve verified failed");
}
cout << "Verified signature" << endl;
}
*/
2 changes: 1 addition & 1 deletion test/test.cpp → test/test_json_s8n.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ TEST_CASE( "PublicKey::to_json", "[to_json]" ) {
REQUIRE( json["modulus"].dump() == "\"" + k.modulus.to_string() + "\"" );
REQUIRE( json["public_exponent"].dump() == "\"" + k.public_exponent.to_string()+"\"" );
REQUIRE( json["type"].dump() == "\"rsa public key\"" );
REQUIRE( json.keys().size() == 3 );
REQUIRE( json.keys().size() == 3U );
}

TEST_CASE("RequestCDDCSerial::from_string", "[from_string]") {
Expand Down
Loading