Skip to content
Merged
Show file tree
Hide file tree
Changes from 12 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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
build/
.DS_Store
cmake-build-*/
.idea/
.venv
17 changes: 15 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,19 @@
cmake_minimum_required(VERSION 3.16)
project(mpt-crypto C CXX)

# --- Global Architecture Detection ---
include(CheckTypeSize)
# Check if the compiler supports __int128 (required for the optimized 64-bit code)
check_type_size("__int128" HAVE___INT128)

if (HAVE___INT128)
message(STATUS "Build: Detected 128-bit integer support.")
set(MPT_ARCH_DEFS SECP256K1_WIDEMUL_INT128)
else ()
message(STATUS "Build: No 128-bit support detected.")
set(MPT_ARCH_DEFS SECP256K1_WIDEMUL_INT64)
endif ()

# --- Find Dependencies ---
find_package(OpenSSL REQUIRED)
find_package(secp256k1 REQUIRED)
Expand All @@ -22,8 +35,8 @@ add_library(mpt-crypto
target_include_directories(mpt-crypto PUBLIC include)

# --- Set Compile Definitions ---
target_compile_definitions(mpt-crypto PRIVATE USE_SCALAR_8X32 USE_FIELD_10X26 ECMULT_WINDOW_SIZE=15
ECMULT_GEN_PREC_BITS=4)
# Pass the architecture flags (MPT_ARCH_DEFS) to the compiler
target_compile_definitions(mpt-crypto PRIVATE ECMULT_WINDOW_SIZE=15 ECMULT_GEN_PREC_BITS=4 PUBLIC ${MPT_ARCH_DEFS})

# --- Link Dependencies ---
target_link_libraries(mpt-crypto PUBLIC secp256k1::secp256k1 PUBLIC OpenSSL::Crypto)
Expand Down
11 changes: 2 additions & 9 deletions src/mpt_scalar.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,22 +36,15 @@
#include <string.h>
#include <openssl/crypto.h>

/* 1. Backend Configuration Definitions */
#ifndef USE_SCALAR_8X32
#define USE_SCALAR_8X32
#endif
#ifndef USE_FIELD_10X26
#define USE_FIELD_10X26
#endif

/* 2. Include low-level utilities first.
/* Include low-level utilities first.
On ARM64/Apple Silicon, the scalar math depends on 128-bit
integer helpers defined in these headers. */
#include <private/util.h>
#include <private/int128.h>
#include <private/int128_impl.h>

/* 3. Include the actual scalar implementations */
/* Include the actual scalar implementations */
#include <private/scalar.h>
#include <private/scalar_impl.h>

Expand Down
107 changes: 0 additions & 107 deletions tests/test_bulletproof.c

This file was deleted.

98 changes: 20 additions & 78 deletions tests/test_bulletproof_agg.c
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <stdlib.h>
#include <time.h>
#include <openssl/rand.h>
#include <secp256k1.h>

#include "secp256k1_mpt.h"
#include "test_utils.h"

/* ---- Aggregation parameters ---- */
#define M 2
Expand All @@ -15,45 +14,6 @@
/* ---- Benchmark parameters ---- */
#define VERIFY_RUNS 5

/* ---- Prototypes ---- */
int secp256k1_bulletproof_prove_agg(
const secp256k1_context* ctx,
unsigned char* proof_out,
size_t* proof_len,
const uint64_t* values,
const unsigned char* blindings_flat,
size_t m,
const secp256k1_pubkey* pk_base,
const unsigned char* context_id
);

int secp256k1_bulletproof_verify_agg(
const secp256k1_context* ctx,
const secp256k1_pubkey* G_vec,
const secp256k1_pubkey* H_vec,
const unsigned char* proof,
size_t proof_len,
const secp256k1_pubkey* commitment_C_vec,
size_t m,
const secp256k1_pubkey* pk_base,
const unsigned char* context_id
);

int secp256k1_bulletproof_create_commitment(
const secp256k1_context* ctx,
secp256k1_pubkey* commitment_C,
uint64_t value,
const unsigned char* blinding_factor,
const secp256k1_pubkey* pk_base
);

extern int secp256k1_mpt_get_generator_vector(
const secp256k1_context* ctx,
secp256k1_pubkey* vec,
size_t n,
const unsigned char* label,
size_t label_len
);

/* ---- Helpers ---- */

Expand All @@ -62,49 +22,32 @@ static inline double elapsed_ms(struct timespec a, struct timespec b) {
(b.tv_nsec - a.tv_nsec) / 1e6;
}

static void random_scalar(
const secp256k1_context* ctx,
unsigned char out[32]
) {
do {
RAND_bytes(out, 32);
} while (!secp256k1_ec_seckey_verify(ctx, out));
}

/* ---- Main ---- */
int main(void) {
printf("[TEST] Aggregated Bulletproof test (m = %d)\n", M);

/* ---- Context ---- */
secp256k1_context* ctx =
secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY);
EXPECT(ctx != NULL);

/* ---- Values ---- */
uint64_t values[M] = { 5000, 123456 };
unsigned char blindings[M][32];
secp256k1_pubkey commitments[M];

/**
* CONTEXT BINDING:
* In the production system, this ID is derived deterministically:
* TransactionContextID := H(TxType || Account || MPTokenIssuanceID || ...)
* * See [Spec Section 3.3.1] for the derivation rules.
* * For this library unit test, random bytes suffice to verify that the
* proof binds correctly to *whatever* context ID is provided.
*/
/* ---- Context Binding ---- */
unsigned char context_id[32];
RAND_bytes(context_id, 32);

EXPECT(RAND_bytes(context_id, 32) == 1);

secp256k1_pubkey pk_base;
/* Use the standard H generator from the library */
assert(secp256k1_mpt_get_h_generator(ctx, &pk_base));

/* Use the standard H generator from the library */
EXPECT(secp256k1_mpt_get_h_generator(ctx, &pk_base));

/* ---- Commitments ---- */
for (size_t i = 0; i < M; i++) {
random_scalar(ctx, blindings[i]);
assert(secp256k1_bulletproof_create_commitment(
EXPECT(secp256k1_bulletproof_create_commitment(
ctx,
&commitments[i],
values[i],
Expand All @@ -116,11 +59,11 @@ int main(void) {
const size_t n = BP_TOTAL_BITS(M);
secp256k1_pubkey* G_vec = malloc(n * sizeof(secp256k1_pubkey));
secp256k1_pubkey* H_vec = malloc(n * sizeof(secp256k1_pubkey));
assert(G_vec && H_vec);
EXPECT(G_vec && H_vec);

assert(secp256k1_mpt_get_generator_vector(
EXPECT(secp256k1_mpt_get_generator_vector(
ctx, G_vec, n, (const unsigned char*)"G", 1));
assert(secp256k1_mpt_get_generator_vector(
EXPECT(secp256k1_mpt_get_generator_vector(
ctx, H_vec, n, (const unsigned char*)"H", 1));

/* ---- Prove (timed) ---- */
Expand All @@ -132,7 +75,8 @@ int main(void) {
struct timespec t_p_start, t_p_end;
clock_gettime(CLOCK_MONOTONIC, &t_p_start);

assert(secp256k1_bulletproof_prove_agg(
/* Note: We cast the 2D array 'blindings' to flat pointer */
EXPECT(secp256k1_bulletproof_prove_agg(
ctx,
proof,
&proof_len,
Expand Down Expand Up @@ -167,10 +111,7 @@ int main(void) {

clock_gettime(CLOCK_MONOTONIC, &t_v_end);

if (!ok) {
printf("FAILED\n");
return 1;
}
EXPECT(ok);

printf("PASSED\n");
printf("[BENCH] Verification time (single): %.3f ms\n",
Expand All @@ -196,7 +137,7 @@ int main(void) {

clock_gettime(CLOCK_MONOTONIC, &te);

assert(ok);
EXPECT(ok);
total_ms += elapsed_ms(ts, te);
}

Expand All @@ -212,10 +153,11 @@ int main(void) {
unsigned char bad_blinding[32];
random_scalar(ctx, bad_blinding);

assert(secp256k1_bulletproof_create_commitment(
/* Create a fake commitment to (value + 1) to break the sum */
EXPECT(secp256k1_bulletproof_create_commitment(
ctx,
&bad_commitments[1],
values[1] + 1,
values[M - 1] + 1,
bad_blinding,
&pk_base));

Expand All @@ -231,8 +173,8 @@ int main(void) {
context_id);

if (ok) {
printf("FAILED (accepted invalid proof)\n");
return 1;
fprintf(stderr, "FAILED: Accepted invalid proof!\n");
exit(EXIT_FAILURE);
}

printf("PASSED (rejected invalid proof)\n");
Expand Down
Loading
Loading