Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
600fa70
type: description
ludamad Oct 23, 2025
7fbba24
refactor: reorganize BN254 crypto module structure
ludamad Oct 23, 2025
e95e7ff
feat: add BN254 G1/G2 multiply operations to bbapi
ludamad Oct 23, 2025
543dd11
feat: add BN254 G1 multiply operation to bbapi
ludamad Oct 23, 2025
730b823
refactor: use barretenberg for BN254 G1 operations
ludamad Oct 23, 2025
f28c75a
refactor: use barretenberg for BN254 G1/G2 operations
ludamad Oct 23, 2025
f3ca72b
refactor: simplify BLS module organization
ludamad Oct 23, 2025
e40124f
refactor: convert BN254 class to free functions
ludamad Oct 23, 2025
f77f538
feat: add Bn254GetCurveConstants bbapi endpoint
ludamad Oct 23, 2025
8ed2bdc
refactor: replace GeneratorScalarMul with generic Mul operations
ludamad Oct 24, 2025
263a290
feat: generate curve constants from native binary at build time
ludamad Oct 24, 2025
2c933e3
refactor: use uint256_t msgpack serialization for curve moduli
ludamad Oct 24, 2025
ab042dd
refactor: optimize affine_element msgpack serialization
ludamad Oct 24, 2025
35baf9c
refactor: add field type branding and Grumpkin-BN254 conversions
ludamad Oct 24, 2025
7f9924c
refactor: merge curve_fields.ts into fields.ts
ludamad Oct 24, 2025
f0ad20e
Merge branch 'spy/valkeys' into ad/refactor/reorganize-bn254-crypto-m…
ludamad Oct 25, 2025
dbac000
feat(barretenberg/ts): add Grumpkin Point and poseidon2 crypto utilities
ludamad Oct 24, 2025
5ef1344
refactor(barretenberg/ts): add typed point classes and simplify field…
ludamad Oct 24, 2025
0ae589d
refactor(barretenberg/ts): remove Point alias, make GrumpkinPoint exp…
ludamad Oct 24, 2025
3820df0
refactor: centralize crypto primitives in barretenberg/ts
ludamad Oct 24, 2025
749e861
refactor: consolidate remaining crypto primitives in barretenberg/ts
ludamad Oct 25, 2025
e7e4231
refactor: consolidate all field functionality into barretenberg/ts
ludamad Oct 25, 2025
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
1 change: 1 addition & 0 deletions barretenberg/cpp/src/barretenberg/bb/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ if (NOT(FUZZING))
bb
main.cpp
cli.cpp
cli_curve_constants.cpp
)
target_link_libraries(
bb
Expand Down
12 changes: 12 additions & 0 deletions barretenberg/cpp/src/barretenberg/bb/cli.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@

namespace bb {

// Forward declaration for curve constants CLI command
void curve_constants_msgpack();

// TODO(https://github.com/AztecProtocol/barretenberg/issues/1257): Remove unused/seemingly unnecessary flags.
// TODO(https://github.com/AztecProtocol/barretenberg/issues/1258): Improve defaults.

Expand Down Expand Up @@ -523,6 +526,11 @@ int parse_and_run_cli_command(int argc, char* argv[])
msgpack_command->add_subcommand("schema", "Output a msgpack schema encoded as JSON to stdout.");
add_verbose_flag(msgpack_schema_command);

// Subcommand: msgpack curve_constants
CLI::App* msgpack_curve_constants_command =
msgpack_command->add_subcommand("curve_constants", "Output BN254 curve constants as msgpack to stdout.");
add_verbose_flag(msgpack_curve_constants_command);

// Subcommand: msgpack run
CLI::App* msgpack_run_command =
msgpack_command->add_subcommand("run", "Execute msgpack API commands from stdin or file.");
Expand Down Expand Up @@ -602,6 +610,10 @@ int parse_and_run_cli_command(int argc, char* argv[])
std::cout << bbapi::get_msgpack_schema_as_json() << std::endl;
return 0;
}
if (msgpack_curve_constants_command->parsed()) {
curve_constants_msgpack();
return 0;
}
if (msgpack_run_command->parsed()) {
return execute_msgpack_run(msgpack_input_file, max_clients);
}
Expand Down
90 changes: 90 additions & 0 deletions barretenberg/cpp/src/barretenberg/bb/cli_curve_constants.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/**
* @file cli_curve_constants.cpp
* @brief CLI command to output curve constants for all supported curves as msgpack
*/
#include "barretenberg/ecc/curves/bn254/bn254.hpp"
#include "barretenberg/ecc/curves/grumpkin/grumpkin.hpp"
#include "barretenberg/ecc/curves/secp256k1/secp256k1.hpp"
#include "barretenberg/ecc/curves/secp256r1/secp256r1.hpp"
#include "barretenberg/serialize/msgpack_impl.hpp"
#include <iostream>

namespace bb {

struct CurveConstants {
// BN254
uint256_t bn254_fr_modulus;
uint256_t bn254_fq_modulus;
bb::g1::affine_element bn254_g1_generator;
bb::g2::affine_element bn254_g2_generator;

// Grumpkin
uint256_t grumpkin_fr_modulus;
uint256_t grumpkin_fq_modulus;
grumpkin::g1::affine_element grumpkin_g1_generator;

// Secp256k1
uint256_t secp256k1_fr_modulus;
uint256_t secp256k1_fq_modulus;
secp256k1::g1::affine_element secp256k1_g1_generator;

// Secp256r1
uint256_t secp256r1_fr_modulus;
uint256_t secp256r1_fq_modulus;
secp256r1::g1::affine_element secp256r1_g1_generator;

MSGPACK_FIELDS(bn254_fr_modulus,
bn254_fq_modulus,
bn254_g1_generator,
bn254_g2_generator,
grumpkin_fr_modulus,
grumpkin_fq_modulus,
grumpkin_g1_generator,
secp256k1_fr_modulus,
secp256k1_fq_modulus,
secp256k1_g1_generator,
secp256r1_fr_modulus,
secp256r1_fq_modulus,
secp256r1_g1_generator);
};

CurveConstants get_curve_constants()
{
CurveConstants constants;

// BN254
constants.bn254_fr_modulus = uint256_t(bb::fr::modulus);
constants.bn254_fq_modulus = uint256_t(bb::fq::modulus);
constants.bn254_g1_generator = bb::g1::affine_element(bb::g1::one);
constants.bn254_g2_generator = bb::g2::affine_element(bb::g2::one);

// Grumpkin (note: grumpkin::fq is bb::fr, grumpkin::fr is bb::fq)
constants.grumpkin_fr_modulus = uint256_t(grumpkin::fr::modulus);
constants.grumpkin_fq_modulus = uint256_t(grumpkin::fq::modulus);
constants.grumpkin_g1_generator = grumpkin::g1::affine_element(grumpkin::g1::one);

// Secp256k1
constants.secp256k1_fr_modulus = uint256_t(secp256k1::fr::modulus);
constants.secp256k1_fq_modulus = uint256_t(secp256k1::fq::modulus);
constants.secp256k1_g1_generator = secp256k1::g1::affine_element(secp256k1::g1::one);

// Secp256r1
constants.secp256r1_fr_modulus = uint256_t(secp256r1::fr::modulus);
constants.secp256r1_fq_modulus = uint256_t(secp256r1::fq::modulus);
constants.secp256r1_g1_generator = secp256r1::g1::affine_element(secp256r1::g1::one);

return constants;
}

/**
* @brief CLI entry point for outputting curve constants as msgpack
*/
void curve_constants_msgpack()
{
CurveConstants constants = get_curve_constants();
msgpack::sbuffer buffer;
msgpack::pack(buffer, constants);
std::cout.write(buffer.data(), static_cast<std::streamsize>(buffer.size()));
}

} // namespace bb
15 changes: 15 additions & 0 deletions barretenberg/cpp/src/barretenberg/bbapi/bbapi_ecc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,19 @@ Bn254FrSqrt::Response Bn254FrSqrt::execute(BB_UNUSED BBApiRequest& request) &&
return { is_sqr, root };
}

Bn254G1Mul::Response Bn254G1Mul::execute(BB_UNUSED BBApiRequest& request) &&
{
return { point * scalar };
}

Bn254G2Mul::Response Bn254G2Mul::execute(BB_UNUSED BBApiRequest& request) &&
{
return { point * scalar };
}

Bn254G1IsOnCurve::Response Bn254G1IsOnCurve::execute(BB_UNUSED BBApiRequest& request) &&
{
return { point.on_curve() };
}

} // namespace bb::bbapi
63 changes: 63 additions & 0 deletions barretenberg/cpp/src/barretenberg/bbapi/bbapi_ecc.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
*/
#include "barretenberg/bbapi/bbapi_shared.hpp"
#include "barretenberg/common/named_union.hpp"
#include "barretenberg/ecc/curves/bn254/bn254.hpp"
#include "barretenberg/ecc/curves/bn254/fr.hpp"
#include "barretenberg/ecc/curves/grumpkin/grumpkin.hpp"
#include "barretenberg/ecc/curves/secp256k1/secp256k1.hpp"
Expand Down Expand Up @@ -205,4 +206,66 @@ struct Bn254FrSqrt {
bool operator==(const Bn254FrSqrt&) const = default;
};

/**
* @struct Bn254G1Mul
* @brief Multiply a BN254 G1 point by a scalar
*/
struct Bn254G1Mul {
static constexpr const char MSGPACK_SCHEMA_NAME[] = "Bn254G1Mul";

struct Response {
static constexpr const char MSGPACK_SCHEMA_NAME[] = "Bn254G1MulResponse";
bb::g1::affine_element point;
MSGPACK_FIELDS(point);
bool operator==(const Response&) const = default;
};

bb::g1::affine_element point;
bb::fr scalar;
Response execute(BBApiRequest& request) &&;
MSGPACK_FIELDS(point, scalar);
bool operator==(const Bn254G1Mul&) const = default;
};

/**
* @struct Bn254G2Mul
* @brief Multiply a BN254 G2 point by a scalar
*/
struct Bn254G2Mul {
static constexpr const char MSGPACK_SCHEMA_NAME[] = "Bn254G2Mul";

struct Response {
static constexpr const char MSGPACK_SCHEMA_NAME[] = "Bn254G2MulResponse";
bb::g2::affine_element point;
MSGPACK_FIELDS(point);
bool operator==(const Response&) const = default;
};

bb::g2::affine_element point;
bb::fr scalar;
Response execute(BBApiRequest& request) &&;
MSGPACK_FIELDS(point, scalar);
bool operator==(const Bn254G2Mul&) const = default;
};

/**
* @struct Bn254G1IsOnCurve
* @brief Check if a BN254 G1 point is on the curve
*/
struct Bn254G1IsOnCurve {
static constexpr const char MSGPACK_SCHEMA_NAME[] = "Bn254G1IsOnCurve";

struct Response {
static constexpr const char MSGPACK_SCHEMA_NAME[] = "Bn254G1IsOnCurveResponse";
bool is_on_curve;
MSGPACK_FIELDS(is_on_curve);
bool operator==(const Response&) const = default;
};

bb::g1::affine_element point;
Response execute(BBApiRequest& request) &&;
MSGPACK_FIELDS(point);
bool operator==(const Bn254G1IsOnCurve&) const = default;
};

} // namespace bb::bbapi
6 changes: 6 additions & 0 deletions barretenberg/cpp/src/barretenberg/bbapi/bbapi_execute.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ using Command = NamedUnion<CircuitProve,
Secp256k1GetRandomFr,
Secp256k1Reduce512,
Bn254FrSqrt,
Bn254G1Mul,
Bn254G2Mul,
Bn254G1IsOnCurve,
SchnorrComputePublicKey,
SchnorrConstructSignature,
SchnorrVerifySignature,
Expand Down Expand Up @@ -98,6 +101,9 @@ using CommandResponse = NamedUnion<CircuitProve::Response,
Secp256k1GetRandomFr::Response,
Secp256k1Reduce512::Response,
Bn254FrSqrt::Response,
Bn254G1Mul::Response,
Bn254G2Mul::Response,
Bn254G1IsOnCurve::Response,
SchnorrComputePublicKey::Response,
SchnorrConstructSignature::Response,
SchnorrVerifySignature::Response,
Expand Down
73 changes: 57 additions & 16 deletions barretenberg/cpp/src/barretenberg/ecc/groups/affine_element.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#pragma once

#include "barretenberg/common/assert.hpp"
#include "barretenberg/common/serialize.hpp"
#include "barretenberg/ecc/curves/bn254/fq2.hpp"
#include "barretenberg/ecc/curves/bn254/fr.hpp"
Expand Down Expand Up @@ -201,44 +202,84 @@ template <typename Fq_, typename Fr_, typename Params_> class alignas(64) affine
Fq x;
Fq y;

// Note: only applicable to field-templated curves (i.e. not something like G2).
// Concept to detect if Fq is a field2 type
template <typename T>
static constexpr bool is_field2_v = requires(T t) {
t.c0;
t.c1;
};

// Msgpack serialization optimized for single uint256_t or array of uint256_t
struct MsgpackRawAffineElement {
uint256_t x{};
uint256_t y{};
// For regular fields (uint256_t), use uint256_t directly
// For field2 types, use std::array<uint256_t, 2>
using FieldType = std::conditional_t<is_field2_v<Fq>, std::array<uint256_t, 2>, uint256_t>;

FieldType x{};
FieldType y{};
MSGPACK_FIELDS(x, y);
};

void msgpack_pack(auto& packer) const
{
MsgpackRawAffineElement raw_element{};

if (is_point_at_infinity()) {
// If we are a point at infinity, just set all bits to 1
// We only need this case because the below gets mangled converting from montgomery for infinity points
// Set all bits to 1 for infinity representation
constexpr uint256_t all_ones = {
0xffffffffffffffffUL, 0xffffffffffffffffUL, 0xffffffffffffffffUL, 0xffffffffffffffffUL
};
raw_element = { all_ones, all_ones };

if constexpr (is_field2_v<Fq>) {
raw_element.x = { all_ones, all_ones };
raw_element.y = { all_ones, all_ones };
} else {
raw_element.x = all_ones;
raw_element.y = all_ones;
}
} else {
// Note: internally calls from_montgomery_form()
raw_element = { x, y };
// Note: field assignment operators internally call from_montgomery_form()
if constexpr (is_field2_v<Fq>) {
raw_element.x = { x.c0, x.c1 };
raw_element.y = { y.c0, y.c1 };
} else {
raw_element.x = x;
raw_element.y = y;
}
}
packer.pack(raw_element);
}

void msgpack_unpack(auto o)
{
using namespace serialize;
MsgpackRawAffineElement raw_element = o;
// If we are point and infinity, the serialized bits will be all ones.

// Check if this is point at infinity (all bits set)
constexpr uint256_t all_ones = {
0xffffffffffffffffUL, 0xffffffffffffffffUL, 0xffffffffffffffffUL, 0xffffffffffffffffUL
};
if (raw_element.x == all_ones && raw_element.y == all_ones) {
// If we are infinity, just set all bits to 1
// We only need this case because the below gets mangled converting from montgomery for infinity points

bool is_infinity;
if constexpr (is_field2_v<Fq>) {
is_infinity = (raw_element.x[0] == all_ones && raw_element.x[1] == all_ones &&
raw_element.y[0] == all_ones && raw_element.y[1] == all_ones);
} else {
is_infinity = (raw_element.x == all_ones && raw_element.y == all_ones);
}

if (is_infinity) {
self_set_infinity();
} else {
// Note: internally calls to_montgomery_form()
x = raw_element.x;
y = raw_element.y;
// Note: field assignment operators internally call to_montgomery_form()
if constexpr (is_field2_v<Fq>) {
x.c0 = raw_element.x[0];
x.c1 = raw_element.x[1];
y.c0 = raw_element.y[0];
y.c1 = raw_element.y[1];
} else {
x = raw_element.x;
y = raw_element.y;
}
}
}
void msgpack_schema(auto& packer) const
Expand Down
Loading
Loading