Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 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,2 +1,4 @@
build/
.DS_Store
.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. Enabling 64-bit optimizations.")
set(MPT_ARCH_DEFS SECP256K1_WIDEMUL_INT128 USE_FIELD_5X52 HAVE___INT128)
else ()
message(STATUS "Build: No 128-bit support detected. Using generic 32-bit arithmetic.")
set(MPT_ARCH_DEFS USE_SCALAR_8X32 USE_FIELD_10X26)
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.

92 changes: 24 additions & 68 deletions tests/test_bulletproof_agg.c
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
#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 +16,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 @@ -67,7 +29,10 @@ static void random_scalar(
unsigned char out[32]
) {
do {
RAND_bytes(out, 32);
if (RAND_bytes(out, 32) != 1) {
fprintf(stderr, "RAND_bytes failed\n");
exit(1);
}
} while (!secp256k1_ec_seckey_verify(ctx, out));
}

Expand All @@ -78,33 +43,25 @@ int main(void) {
/* ---- 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 +73,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 +89,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 +125,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 +151,7 @@ int main(void) {

clock_gettime(CLOCK_MONOTONIC, &te);

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

Expand All @@ -212,10 +167,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 +187,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