From 96fe5bf28371386ef902dd43bc54ca30d89e21f3 Mon Sep 17 00:00:00 2001 From: DmytroTym Date: Wed, 24 Jan 2024 11:51:22 +0200 Subject: [PATCH] G2 fix and BW6 scalar field on the Rust side (#341) * BW scalar field is now the same as BLS base field in Rust * G2 fixed and added into Rust --- .github/workflows/main-test.yml | 4 +- icicle/CMakeLists.txt | 4 + icicle/appUtils/msm/msm.cu | 24 +++- icicle/appUtils/msm/msm.cuh | 3 +- icicle/appUtils/ntt/ntt.cu | 10 +- icicle/appUtils/ntt/ntt.cuh | 6 +- icicle/curves/curve_config.cuh | 27 ++++- icicle/primitives/extension_field.cuh | 10 +- icicle/primitives/field.cuh | 7 -- icicle/primitives/projective.cu | 10 +- icicle/utils/mont.cu | 24 ++++ wrappers/rust/icicle-core/Cargo.toml | 8 +- wrappers/rust/icicle-core/src/curve.rs | 112 ++++++++++-------- wrappers/rust/icicle-core/src/field.rs | 70 ++++++----- wrappers/rust/icicle-core/src/msm/mod.rs | 31 +++-- wrappers/rust/icicle-core/src/ntt/mod.rs | 31 +++-- wrappers/rust/icicle-core/src/ntt/tests.rs | 6 +- wrappers/rust/icicle-core/src/traits.rs | 4 +- .../icicle-curves/icicle-bls12-377/Cargo.toml | 3 + .../icicle-curves/icicle-bls12-377/build.rs | 44 +++++-- .../icicle-bls12-377/src/curve.rs | 46 ++++++- .../icicle-bls12-377/src/msm/mod.rs | 16 ++- .../icicle-bls12-377/src/ntt/mod.rs | 6 +- .../icicle-curves/icicle-bls12-381/Cargo.toml | 1 + .../icicle-curves/icicle-bls12-381/build.rs | 21 +++- .../icicle-bls12-381/src/curve.rs | 43 ++++++- .../icicle-bls12-381/src/msm/mod.rs | 16 ++- .../icicle-bls12-381/src/ntt/mod.rs | 2 +- .../icicle-curves/icicle-bn254/Cargo.toml | 1 + .../rust/icicle-curves/icicle-bn254/build.rs | 21 +++- .../icicle-curves/icicle-bn254/src/curve.rs | 43 ++++++- .../icicle-curves/icicle-bn254/src/msm/mod.rs | 16 ++- .../icicle-curves/icicle-bn254/src/ntt/mod.rs | 2 +- .../icicle-curves/icicle-bw6-761/Cargo.toml | 6 +- .../icicle-curves/icicle-bw6-761/build.rs | 19 --- .../icicle-curves/icicle-bw6-761/src/curve.rs | 49 ++++++-- .../icicle-bw6-761/src/msm/mod.rs | 16 ++- .../icicle-bw6-761/src/ntt/mod.rs | 12 -- 38 files changed, 536 insertions(+), 238 deletions(-) delete mode 100644 wrappers/rust/icicle-curves/icicle-bw6-761/build.rs diff --git a/.github/workflows/main-test.yml b/.github/workflows/main-test.yml index 25e4e545..fdd9ff03 100644 --- a/.github/workflows/main-test.yml +++ b/.github/workflows/main-test.yml @@ -50,8 +50,8 @@ jobs: working-directory: ./wrappers/rust if: needs.check-changed-files.outputs.rust == 'true' || needs.check-changed-files.outputs.cpp_cuda == 'true' # Running tests from the root workspace will run all workspace members' tests by default - #TODO: remove test-threads once thread safety is finalized - run: cargo test --release --verbose -- --test-threads=1 + # We need to limit the number of threads to avoid running out of memory on weaker machines + run: cargo test --release --verbose --features=g2 -- --test-threads=2 test-cpp-linux: name: Test C++ on Linux diff --git a/icicle/CMakeLists.txt b/icicle/CMakeLists.txt index 55942b22..e7f283b5 100644 --- a/icicle/CMakeLists.txt +++ b/icicle/CMakeLists.txt @@ -84,6 +84,10 @@ if (NOT IS_CURVE_SUPPORTED) message( FATAL_ERROR "The value of CURVE variable: ${CURVE} is not one of the supported curves: ${SUPPORTED_CURVES}" ) endif () +if (G2_DEFINED STREQUAL "ON") + set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -DG2_DEFINED=ON") +endif () + option(BUILD_TESTS "Build tests" OFF) if (NOT BUILD_TESTS) diff --git a/icicle/appUtils/msm/msm.cu b/icicle/appUtils/msm/msm.cu index af61b7be..4c48edb0 100644 --- a/icicle/appUtils/msm/msm.cu +++ b/icicle/appUtils/msm/msm.cu @@ -364,11 +364,10 @@ namespace msm { CHK_INIT_IF_RETURN(); const unsigned nof_scalars = batch_size * single_msm_size; // assuming scalars not shared between batch elements - const bool is_nof_points_valid = (nof_points == single_msm_size) || (nof_points == single_msm_size * batch_size); + const bool is_nof_points_valid = ((single_msm_size * batch_size) % nof_points == 0); if (!is_nof_points_valid) { THROW_ICICLE_ERR( - IcicleError_t::InvalidArgument, "bucket_method_msm: #points must be either (1) single_msm_size if sharing " - "points or (2) single_msm_size*batch_size"); + IcicleError_t::InvalidArgument, "bucket_method_msm: #points must be divisible by single_msm_size*batch_size"); } S* d_scalars; @@ -788,7 +787,8 @@ namespace msm { } } // namespace - extern "C" MSMConfig CONCAT_EXPAND(CURVE, DefaultMSMConfig)() + template + MSMConfig DefaultMSMConfig() { device_context::DeviceContext ctx = device_context::get_default_device_context(); MSMConfig config = { @@ -850,6 +850,11 @@ namespace msm { scalars, points, msm_size, config, out); } + /** + * Extern "C" version of [DefaultMSMConfig](@ref DefaultMSMConfig) function. + */ + extern "C" MSMConfig CONCAT_EXPAND(CURVE, DefaultMSMConfig)() { return DefaultMSMConfig(); } + #if defined(G2_DEFINED) /** @@ -860,7 +865,7 @@ namespace msm { * - `P` is the [projective representation](@ref g2_projective_t) of G2 curve points. * @return `cudaSuccess` if the execution was successful and an error code otherwise. */ - extern "C" cudaError_t G2MSMCuda( + extern "C" cudaError_t CONCAT_EXPAND(CURVE, G2MSMCuda)( curve_config::scalar_t* scalars, curve_config::g2_affine_t* points, int msm_size, @@ -871,6 +876,15 @@ namespace msm { scalars, points, msm_size, config, out); } + /** + * Extern "C" version of [DefaultMSMConfig](@ref DefaultMSMConfig) function for the G2 curve + * (functionally no different than the default MSM config function for G1). + */ + extern "C" MSMConfig CONCAT_EXPAND(CURVE, G2DefaultMSMConfig)() + { + return DefaultMSMConfig(); + } + #endif } // namespace msm \ No newline at end of file diff --git a/icicle/appUtils/msm/msm.cuh b/icicle/appUtils/msm/msm.cuh index eecb374e..152d9b31 100644 --- a/icicle/appUtils/msm/msm.cuh +++ b/icicle/appUtils/msm/msm.cuh @@ -83,7 +83,8 @@ namespace msm { * A function that returns the default value of [MSMConfig](@ref MSMConfig) for the [MSM](@ref MSM) function. * @return Default value of [MSMConfig](@ref MSMConfig). */ - extern "C" MSMConfig DefaultMSMConfig(); + template + MSMConfig DefaultMSMConfig(); /** * A function that computes MSM: \f$ MSM(s_i, P_i) = \sum_{i=1}^N s_i \cdot P_i \f$. diff --git a/icicle/appUtils/ntt/ntt.cu b/icicle/appUtils/ntt/ntt.cu index 3e855f69..c1581531 100644 --- a/icicle/appUtils/ntt/ntt.cu +++ b/icicle/appUtils/ntt/ntt.cu @@ -417,12 +417,18 @@ namespace ntt { cudaError_t NTT(E* input, int size, NTTDir dir, NTTConfig& config, E* output) { CHK_INIT_IF_RETURN(); + if (size > Domain::max_size) { + std::cerr + << "NTT size is too large for the domain. Consider generating your domain with a higher order root of unity" + << '\n'; + throw -1; + } cudaStream_t& stream = config.ctx.stream; int batch_size = config.batch_size; int logn = int(log(size) / log(2)); int input_size_bytes = size * batch_size * sizeof(E); - bool are_inputs_on_device = config.are_inputs_on_device; // TODO: unify name to is_ + bool are_inputs_on_device = config.are_inputs_on_device; bool are_outputs_on_device = config.are_outputs_on_device; S* coset = nullptr; @@ -540,7 +546,7 @@ namespace ntt { * - `E` is the [scalar field](@ref scalar_t) of the curve; * @return `cudaSuccess` if the execution was successful and an error code otherwise. */ - extern "C" cudaError_t ECNTTCuda( + extern "C" cudaError_t CONCAT_EXPAND(CURVE, ECNTTCuda)( curve_config::projective_t* input, int size, NTTDir dir, diff --git a/icicle/appUtils/ntt/ntt.cuh b/icicle/appUtils/ntt/ntt.cuh index 10c70988..fec1fe4d 100644 --- a/icicle/appUtils/ntt/ntt.cuh +++ b/icicle/appUtils/ntt/ntt.cuh @@ -87,10 +87,12 @@ namespace ntt { * @return Default value of [NTTConfig](@ref NTTConfig). */ template - NTTConfig CONCAT_EXPAND(CURVE, DefaultNTTConfig)(); + NTTConfig DefaultNTTConfig(); /** - * A function that computes NTT or iNTT in-place. + * A function that computes NTT or iNTT in-place. It's necessary to call [InitDomain](@ref InitDomain) with an + * appropriate primitive root before calling this function (only one call to `InitDomain` should suffice for all + * NTTs). * @param input Input of the NTT. Length of this array needs to be \f$ size \cdot config.batch\_size \f$. Note * that if inputs are in Montgomery form, the outputs will be as well and vice-versa: non-Montgomery inputs produce * non-Montgomety outputs. diff --git a/icicle/curves/curve_config.cuh b/icicle/curves/curve_config.cuh index a99b138d..a9945bf3 100644 --- a/icicle/curves/curve_config.cuh +++ b/icicle/curves/curve_config.cuh @@ -28,17 +28,36 @@ using namespace bls12_377; using namespace bw6_761; #endif +/** + * @namespace curve_config + * Namespace with type definitions for short Weierstrass pairing-friendly [elliptic + * curves](https://hyperelliptic.org/EFD/g1p/auto-shortw.html). Here, concrete types are created in accordance + * with the `-DCURVE` env variable passed during build. + */ namespace curve_config { #if CURVE_ID == BW6_761 typedef bls12_377::fq_config fp_config; #endif + /** + * Scalar field of the curve. Is always a prime field. + */ typedef Field scalar_t; + /** + * Base field of G1 curve. Is always a prime field. + */ typedef Field point_field_t; static constexpr point_field_t generator_x = point_field_t{g1_gen_x}; static constexpr point_field_t generator_y = point_field_t{g1_gen_y}; static constexpr point_field_t b = point_field_t{weierstrass_b}; + /** + * [Projective representation](https://hyperelliptic.org/EFD/g1p/auto-shortw-projective.html) + * of G1 curve consisting of three coordinates of type [point_field_t](point_field_t). + */ typedef Projective projective_t; + /** + * Affine representation of G1 curve consisting of two coordinates of type [point_field_t](point_field_t). + */ typedef Affine affine_t; #if defined(G2_DEFINED) @@ -56,10 +75,16 @@ namespace curve_config { static constexpr g2_point_field_t g2_b = g2_point_field_t{point_field_t{weierstrass_b_g2_re}, point_field_t{weierstrass_b_g2_im}}; #endif + /** + * [Projective representation](https://hyperelliptic.org/EFD/g1p/auto-shortw-projective.html) of G2 curve. + */ typedef Projective g2_projective_t; + /** + * Affine representation of G1 curve. + */ typedef Affine g2_affine_t; #endif } // namespace curve_config -#endif +#endif \ No newline at end of file diff --git a/icicle/primitives/extension_field.cuh b/icicle/primitives/extension_field.cuh index 8c57ea53..072b76a0 100644 --- a/icicle/primitives/extension_field.cuh +++ b/icicle/primitives/extension_field.cuh @@ -38,14 +38,14 @@ public: static constexpr HOST_DEVICE_INLINE ExtensionField one() { return ExtensionField{FF::one(), FF::zero()}; } - static constexpr HOST_DEVICE_INLINE ExtensionField generator_x() + static constexpr HOST_DEVICE_INLINE ExtensionField ToMontgomery(const ExtensionField& xs) { - return ExtensionField{FF{CONFIG::g2_gen_x_re}, FF{CONFIG::g2_gen_x_im}}; + return ExtensionField{xs.real * FF{CONFIG::montgomery_r}, xs.imaginary * FF{CONFIG::montgomery_r}}; } - static constexpr HOST_DEVICE_INLINE ExtensionField generator_y() + static constexpr HOST_DEVICE_INLINE ExtensionField FromMontgomery(const ExtensionField& xs) { - return ExtensionField{FF{CONFIG::g2_gen_y_re}, FF{CONFIG::g2_gen_y_im}}; + return ExtensionField{xs.real * FF{CONFIG::montgomery_r_inv}, xs.imaginary * FF{CONFIG::montgomery_r_inv}}; } static HOST_INLINE ExtensionField rand_host() { return ExtensionField{FF::rand_host(), FF::rand_host()}; } @@ -155,4 +155,4 @@ public: FF xs_norm_squared = FF::sqr(xs.real) - i_sq_times_im; return xs_conjugate * ExtensionField{FF::inverse(xs_norm_squared), FF::zero()}; } -}; +}; \ No newline at end of file diff --git a/icicle/primitives/field.cuh b/icicle/primitives/field.cuh index 8dc1141c..5fd535be 100644 --- a/icicle/primitives/field.cuh +++ b/icicle/primitives/field.cuh @@ -750,13 +750,6 @@ public: return rs; } - static constexpr HOST_DEVICE_INLINE Field to_montgomery(const Field& xs) { return xs * Field{CONFIG::montgomery_r}; } - - static constexpr HOST_DEVICE_INLINE Field from_montgomery(const Field& xs) - { - return xs * Field{CONFIG::montgomery_r_inv}; - } - /** * This method reduces a Wide number `xs` modulo `p` and returns the result as a Field element. * diff --git a/icicle/primitives/projective.cu b/icicle/primitives/projective.cu index 91edfb48..845f489c 100644 --- a/icicle/primitives/projective.cu +++ b/icicle/primitives/projective.cu @@ -37,7 +37,7 @@ extern "C" void CONCAT_EXPAND(CURVE, GenerateAffinePoints)(affine_t* points, int #define g2_affine_t curve_config::g2_affine_t #define g2_point_field_t curve_config::g2_point_field_t -extern "C" bool EqG2(g2_projective_t* point1, g2_projective_t* point2) +extern "C" bool CONCAT_EXPAND(CURVE, G2Eq)(g2_projective_t* point1, g2_projective_t* point2) { return (*point1 == *point2) && !((point1->x == g2_point_field_t::zero()) && (point1->y == g2_point_field_t::zero()) && @@ -46,17 +46,17 @@ extern "C" bool EqG2(g2_projective_t* point1, g2_projective_t* point2) (point2->z == g2_point_field_t::zero())); } -extern "C" void ToAffineG2(g2_projective_t* point, affine_t* point_out) +extern "C" void CONCAT_EXPAND(CURVE, G2ToAffine)(g2_projective_t* point, g2_affine_t* point_out) { - *point_out = projective_t::to_affine(*point); + *point_out = g2_projective_t::to_affine(*point); } -extern "C" void GenerateProjectivePointsG2(g2_projective_t* points, int size) +extern "C" void CONCAT_EXPAND(CURVE, G2GenerateProjectivePoints)(g2_projective_t* points, int size) { g2_projective_t::RandHostMany(points, size); } -extern "C" void GenerateAffinePointsG2(g2_affine_t* points, int size) +extern "C" void CONCAT_EXPAND(CURVE, G2GenerateAffinePoints)(g2_affine_t* points, int size) { g2_projective_t::RandHostManyAffine(points, size); } diff --git a/icicle/utils/mont.cu b/icicle/utils/mont.cu index 4b955fe0..1ec0dfa2 100644 --- a/icicle/utils/mont.cu +++ b/icicle/utils/mont.cu @@ -33,4 +33,28 @@ namespace mont { return FromMontgomery(d_inout, n, ctx.stream, d_inout); } } + +#if defined(G2_DEFINED) + + extern "C" cudaError_t CONCAT_EXPAND(CURVE, G2AffineConvertMontgomery)( + curve_config::g2_affine_t* d_inout, size_t n, bool is_into, device_context::DeviceContext& ctx) + { + if (is_into) { + return ToMontgomery(d_inout, n, ctx.stream, d_inout); + } else { + return FromMontgomery(d_inout, n, ctx.stream, d_inout); + } + } + + extern "C" cudaError_t CONCAT_EXPAND(CURVE, G2ProjectiveConvertMontgomery)( + curve_config::g2_projective_t* d_inout, size_t n, bool is_into, device_context::DeviceContext& ctx) + { + if (is_into) { + return ToMontgomery(d_inout, n, ctx.stream, d_inout); + } else { + return FromMontgomery(d_inout, n, ctx.stream, d_inout); + } + } + +#endif } // namespace mont \ No newline at end of file diff --git a/wrappers/rust/icicle-core/Cargo.toml b/wrappers/rust/icicle-core/Cargo.toml index c2d0c4bd..fa158792 100644 --- a/wrappers/rust/icicle-core/Cargo.toml +++ b/wrappers/rust/icicle-core/Cargo.toml @@ -17,15 +17,9 @@ ark-ec = { version = "0.4.0", optional = true, features = [ "parallel" ] } ark-poly = { version = "0.4.0", optional = true } ark-std = { version = "0.4.0", optional = true } -# [build-dependencies] -# cc = { version = "1.0", features = ["parallel"] } -# cmake = "*" -# bindgen = "*" -# libc = "*" #TODO: move libc dependencies to build - [features] default = [] arkworks = ["ark-ff", "ark-ec", "ark-poly", "ark-std"] -# TODO: impl G2 and EC NTT g2 = [] +# TODO: impl EC NTT ec_ntt = [] diff --git a/wrappers/rust/icicle-core/src/curve.rs b/wrappers/rust/icicle-core/src/curve.rs index dcf016ab..a688114a 100644 --- a/wrappers/rust/icicle-core/src/curve.rs +++ b/wrappers/rust/icicle-core/src/curve.rs @@ -204,68 +204,83 @@ where macro_rules! impl_curve { ( $curve_prefix:literal, + $curve_prefix_ident:ident, $curve:ident, $scalar_field:ident, - $base_field:ident + $base_field:ident, + $ark_config:ident, + $affine_type:ident, + $projective_type:ident ) => { #[derive(Debug, PartialEq, Copy, Clone)] pub struct $curve {} - pub type G1Affine = Affine<$curve>; - pub type G1Projective = Projective<$curve>; + pub type $affine_type = Affine<$curve>; + pub type $projective_type = Projective<$curve>; - extern "C" { - #[link_name = concat!($curve_prefix, "Eq")] - fn eq(point1: *const G1Projective, point2: *const G1Projective) -> bool; - #[link_name = concat!($curve_prefix, "ToAffine")] - fn proj_to_affine(point: *const G1Projective, point_out: *mut G1Affine); - #[link_name = concat!($curve_prefix, "GenerateProjectivePoints")] - fn generate_projective_points(points: *mut G1Projective, size: usize); - #[link_name = concat!($curve_prefix, "GenerateAffinePoints")] - fn generate_affine_points(points: *mut G1Affine, size: usize); - #[link_name = concat!($curve_prefix, "AffineConvertMontgomery")] - fn _convert_affine_montgomery( - points: *mut G1Affine, - size: usize, - is_into: bool, - ctx: *const DeviceContext, - ) -> CudaError; - #[link_name = concat!($curve_prefix, "ProjectiveConvertMontgomery")] - fn _convert_projective_montgomery( - points: *mut G1Projective, - size: usize, - is_into: bool, - ctx: *const DeviceContext, - ) -> CudaError; + mod $curve_prefix_ident { + use super::{$affine_type, $projective_type, CudaError, DeviceContext}; + + extern "C" { + #[link_name = concat!($curve_prefix, "Eq")] + pub(crate) fn eq(point1: *const $projective_type, point2: *const $projective_type) -> bool; + #[link_name = concat!($curve_prefix, "ToAffine")] + pub(crate) fn proj_to_affine(point: *const $projective_type, point_out: *mut $affine_type); + #[link_name = concat!($curve_prefix, "GenerateProjectivePoints")] + pub(crate) fn generate_projective_points(points: *mut $projective_type, size: usize); + #[link_name = concat!($curve_prefix, "GenerateAffinePoints")] + pub(crate) fn generate_affine_points(points: *mut $affine_type, size: usize); + #[link_name = concat!($curve_prefix, "AffineConvertMontgomery")] + pub(crate) fn _convert_affine_montgomery( + points: *mut $affine_type, + size: usize, + is_into: bool, + ctx: *const DeviceContext, + ) -> CudaError; + #[link_name = concat!($curve_prefix, "ProjectiveConvertMontgomery")] + pub(crate) fn _convert_projective_montgomery( + points: *mut $projective_type, + size: usize, + is_into: bool, + ctx: *const DeviceContext, + ) -> CudaError; + } } impl Curve for $curve { type BaseField = $base_field; type ScalarField = $scalar_field; - fn eq_proj(point1: *const G1Projective, point2: *const G1Projective) -> bool { - unsafe { eq(point1, point2) } + fn eq_proj(point1: *const $projective_type, point2: *const $projective_type) -> bool { + unsafe { $curve_prefix_ident::eq(point1, point2) } } - fn to_affine(point: *const Projective<$curve>, point_out: *mut Affine<$curve>) { - unsafe { proj_to_affine(point, point_out) }; + fn to_affine(point: *const $projective_type, point_out: *mut $affine_type) { + unsafe { $curve_prefix_ident::proj_to_affine(point, point_out) }; } - fn generate_random_projective_points(size: usize) -> Vec { - let mut res = vec![G1Projective::zero(); size]; - unsafe { generate_projective_points(&mut res[..] as *mut _ as *mut G1Projective, size) }; - res - } - - fn generate_random_affine_points(size: usize) -> Vec { - let mut res = vec![G1Affine::zero(); size]; - unsafe { generate_affine_points(&mut res[..] as *mut _ as *mut G1Affine, size) }; - res - } - - fn convert_affine_montgomery(points: &mut HostOrDeviceSlice, is_into: bool) -> CudaError { + fn generate_random_projective_points(size: usize) -> Vec<$projective_type> { + let mut res = vec![$projective_type::zero(); size]; unsafe { - _convert_affine_montgomery( + $curve_prefix_ident::generate_projective_points( + &mut res[..] as *mut _ as *mut $projective_type, + size, + ) + }; + res + } + + fn generate_random_affine_points(size: usize) -> Vec<$affine_type> { + let mut res = vec![$affine_type::zero(); size]; + unsafe { + $curve_prefix_ident::generate_affine_points(&mut res[..] as *mut _ as *mut $affine_type, size) + }; + res + } + + fn convert_affine_montgomery(points: &mut HostOrDeviceSlice<$affine_type>, is_into: bool) -> CudaError { + unsafe { + $curve_prefix_ident::_convert_affine_montgomery( points.as_mut_ptr(), points.len(), is_into, @@ -274,9 +289,12 @@ macro_rules! impl_curve { } } - fn convert_projective_montgomery(points: &mut HostOrDeviceSlice, is_into: bool) -> CudaError { + fn convert_projective_montgomery( + points: &mut HostOrDeviceSlice<$projective_type>, + is_into: bool, + ) -> CudaError { unsafe { - _convert_projective_montgomery( + $curve_prefix_ident::_convert_projective_montgomery( points.as_mut_ptr(), points.len(), is_into, @@ -286,7 +304,7 @@ macro_rules! impl_curve { } #[cfg(feature = "arkworks")] - type ArkSWConfig = ArkG1Config; + type ArkSWConfig = $ark_config; } }; } diff --git a/wrappers/rust/icicle-core/src/field.rs b/wrappers/rust/icicle-core/src/field.rs index c86de341..84538838 100644 --- a/wrappers/rust/icicle-core/src/field.rs +++ b/wrappers/rust/icicle-core/src/field.rs @@ -2,7 +2,7 @@ use crate::traits::ArkConvertible; use crate::traits::{FieldConfig, FieldImpl, MontgomeryConvertible}; #[cfg(feature = "arkworks")] -use ark_ff::{BigInteger, PrimeField}; +use ark_ff::{BigInteger, Field as ArkField, PrimeField}; use icicle_cuda_runtime::error::CudaError; use icicle_cuda_runtime::memory::HostOrDeviceSlice; use std::fmt::{Debug, Display}; @@ -100,6 +100,7 @@ impl FieldImpl for Field { } } +#[doc(hidden)] pub trait MontgomeryConvertibleField { fn to_mont(values: &mut HostOrDeviceSlice) -> CudaError; fn from_mont(values: &mut HostOrDeviceSlice) -> CudaError; @@ -123,12 +124,19 @@ impl ArkConvertible for Field Self::ArkEquivalent { - F::ArkField::from_le_bytes_mod_order(&self.to_bytes_le()) + F::ArkField::from_random_bytes(&self.to_bytes_le()).unwrap() } fn from_ark(ark: Self::ArkEquivalent) -> Self { - let ark_bigint: ::BigInt = ark.into(); - Self::from_bytes_le(&ark_bigint.to_bytes_le()) + let ark_bytes: Vec = ark + .to_base_prime_field_elements() + .map(|x| { + x.into_bigint() + .to_bytes_le() + }) + .flatten() + .collect(); + Self::from_bytes_le(&ark_bytes) } } @@ -156,6 +164,7 @@ macro_rules! impl_field { macro_rules! impl_scalar_field { ( $field_prefix:literal, + $field_prefix_ident:ident, $num_limbs:ident, $field_name:ident, $field_cfg:ident, @@ -163,45 +172,52 @@ macro_rules! impl_scalar_field { ) => { impl_field!($num_limbs, $field_name, $field_cfg, $ark_equiv); - extern "C" { - #[link_name = concat!($field_prefix, "GenerateScalars")] - fn generate_scalars(scalars: *mut $field_name, size: usize); + mod $field_prefix_ident { + use crate::curve::{get_default_device_context, $field_name, CudaError, DeviceContext, HostOrDeviceSlice}; - #[link_name = concat!($field_prefix, "ScalarConvertMontgomery")] - fn _convert_scalars_montgomery( - scalars: *mut $field_name, - size: usize, + extern "C" { + #[link_name = concat!($field_prefix, "GenerateScalars")] + pub(crate) fn generate_scalars(scalars: *mut $field_name, size: usize); + + #[link_name = concat!($field_prefix, "ScalarConvertMontgomery")] + fn _convert_scalars_montgomery( + scalars: *mut $field_name, + size: usize, + is_into: bool, + ctx: *const DeviceContext, + ) -> CudaError; + } + + pub(crate) fn convert_scalars_montgomery( + scalars: &mut HostOrDeviceSlice<$field_name>, is_into: bool, - ctx: *const DeviceContext, - ) -> CudaError; + ) -> CudaError { + unsafe { + _convert_scalars_montgomery( + scalars.as_mut_ptr(), + scalars.len(), + is_into, + &get_default_device_context() as *const _ as *const DeviceContext, + ) + } + } } impl GenerateRandom<$field_name> for $field_cfg { fn generate_random(size: usize) -> Vec<$field_name> { let mut res = vec![$field_name::zero(); size]; - unsafe { generate_scalars(&mut res[..] as *mut _ as *mut $field_name, size) }; + unsafe { $field_prefix_ident::generate_scalars(&mut res[..] as *mut _ as *mut $field_name, size) }; res } } - fn convert_scalars_montgomery(scalars: &mut HostOrDeviceSlice<$field_name>, is_into: bool) -> CudaError { - unsafe { - _convert_scalars_montgomery( - scalars.as_mut_ptr(), - scalars.len(), - is_into, - &get_default_device_context() as *const _ as *const DeviceContext, - ) - } - } - impl MontgomeryConvertibleField<$field_name> for $field_cfg { fn to_mont(values: &mut HostOrDeviceSlice<$field_name>) -> CudaError { - convert_scalars_montgomery(values, true) + $field_prefix_ident::convert_scalars_montgomery(values, true) } fn from_mont(values: &mut HostOrDeviceSlice<$field_name>) -> CudaError { - convert_scalars_montgomery(values, false) + $field_prefix_ident::convert_scalars_montgomery(values, false) } } }; diff --git a/wrappers/rust/icicle-core/src/msm/mod.rs b/wrappers/rust/icicle-core/src/msm/mod.rs index d23bd4a2..cf733da2 100644 --- a/wrappers/rust/icicle-core/src/msm/mod.rs +++ b/wrappers/rust/icicle-core/src/msm/mod.rs @@ -122,20 +122,25 @@ pub fn get_default_msm_config>() -> MSMConfig<'static> { macro_rules! impl_msm { ( $curve_prefix:literal, + $curve_prefix_indent:ident, $curve:ident ) => { - extern "C" { - #[link_name = concat!($curve_prefix, "MSMCuda")] - fn msm_cuda( - scalars: *const <$curve as Curve>::ScalarField, - points: *const Affine<$curve>, - count: i32, - config: &MSMConfig, - out: *mut Projective<$curve>, - ) -> CudaError; + mod $curve_prefix_indent { + use super::{$curve, Affine, CudaError, Curve, MSMConfig, Projective}; - #[link_name = concat!($curve_prefix, "DefaultMSMConfig")] - fn default_msm_config() -> MSMConfig<'static>; + extern "C" { + #[link_name = concat!($curve_prefix, "MSMCuda")] + pub(crate) fn msm_cuda( + scalars: *const <$curve as Curve>::ScalarField, + points: *const Affine<$curve>, + count: i32, + config: &MSMConfig, + out: *mut Projective<$curve>, + ) -> CudaError; + + #[link_name = concat!($curve_prefix, "DefaultMSMConfig")] + pub(crate) fn default_msm_config() -> MSMConfig<'static>; + } } impl MSM<$curve> for $curve { @@ -146,7 +151,7 @@ macro_rules! impl_msm { results: &mut HostOrDeviceSlice>, ) -> IcicleResult<()> { unsafe { - msm_cuda( + $curve_prefix_indent::msm_cuda( scalars.as_ptr(), points.as_ptr(), (scalars.len() / results.len()) as i32, @@ -158,7 +163,7 @@ macro_rules! impl_msm { } fn get_default_msm_config() -> MSMConfig<'static> { - unsafe { default_msm_config() } + unsafe { $curve_prefix_indent::default_msm_config() } } } }; diff --git a/wrappers/rust/icicle-core/src/ntt/mod.rs b/wrappers/rust/icicle-core/src/ntt/mod.rs index ffd41a6c..27d51240 100644 --- a/wrappers/rust/icicle-core/src/ntt/mod.rs +++ b/wrappers/rust/icicle-core/src/ntt/mod.rs @@ -151,21 +151,26 @@ where macro_rules! impl_ntt { ( $field_prefix:literal, + $field_prefix_ident:ident, $field:ident, $field_config:ident ) => { - extern "C" { - #[link_name = concat!($field_prefix, "NTTCuda")] - fn ntt_cuda( - input: *const $field, - size: i32, - dir: NTTDir, - config: &NTTConfig<$field>, - output: *mut $field, - ) -> CudaError; + mod $field_prefix_ident { + use crate::ntt::{$field, $field_config, CudaError, DeviceContext, NTTConfig, NTTDir}; - #[link_name = concat!($field_prefix, "InitializeDomain")] - fn initialize_ntt_domain(primitive_root: $field, ctx: &DeviceContext) -> CudaError; + extern "C" { + #[link_name = concat!($field_prefix, "NTTCuda")] + pub(crate) fn ntt_cuda( + input: *const $field, + size: i32, + dir: NTTDir, + config: &NTTConfig<$field>, + output: *mut $field, + ) -> CudaError; + + #[link_name = concat!($field_prefix, "InitializeDomain")] + pub(crate) fn initialize_ntt_domain(primitive_root: $field, ctx: &DeviceContext) -> CudaError; + } } impl NTT<$field> for $field_config { @@ -176,7 +181,7 @@ macro_rules! impl_ntt { output: &mut HostOrDeviceSlice<$field>, ) -> IcicleResult<()> { unsafe { - ntt_cuda( + $field_prefix_ident::ntt_cuda( input.as_ptr(), (input.len() / (cfg.batch_size as usize)) as i32, dir, @@ -188,7 +193,7 @@ macro_rules! impl_ntt { } fn initialize_domain(primitive_root: $field, ctx: &DeviceContext) -> IcicleResult<()> { - unsafe { initialize_ntt_domain(primitive_root, ctx).wrap() } + unsafe { $field_prefix_ident::initialize_ntt_domain(primitive_root, ctx).wrap() } } fn get_default_ntt_config() -> NTTConfig<'static, $field> { diff --git a/wrappers/rust/icicle-core/src/ntt/tests.rs b/wrappers/rust/icicle-core/src/ntt/tests.rs index b4f9f609..e2b86baf 100644 --- a/wrappers/rust/icicle-core/src/ntt/tests.rs +++ b/wrappers/rust/icicle-core/src/ntt/tests.rs @@ -1,4 +1,4 @@ -use ark_ff::{FftField, One, PrimeField}; +use ark_ff::{FftField, Field as ArkField, One}; use ark_poly::{EvaluationDomain, GeneralEvaluationDomain}; use ark_std::{ops::Neg, test_rng, UniformRand}; use icicle_cuda_runtime::device_context::get_default_device_context; @@ -157,7 +157,7 @@ where pub fn check_ntt_arbitrary_coset() where - F::ArkEquivalent: FftField + PrimeField, + F::ArkEquivalent: FftField + ArkField, ::Config: NTT + GenerateRandom, { let mut seed = test_rng(); @@ -179,7 +179,7 @@ where let mut ark_scalars = scalars .as_slice() .iter() - .map(|v| F::ArkEquivalent::from_le_bytes_mod_order(&v.to_bytes_le())) + .map(|v| F::ArkEquivalent::from_random_bytes(&v.to_bytes_le()).unwrap()) .collect::>(); let mut config = get_default_ntt_config(); diff --git a/wrappers/rust/icicle-core/src/traits.rs b/wrappers/rust/icicle-core/src/traits.rs index 14b8125a..9cfa7e30 100644 --- a/wrappers/rust/icicle-core/src/traits.rs +++ b/wrappers/rust/icicle-core/src/traits.rs @@ -1,6 +1,6 @@ use crate::error::IcicleResult; #[cfg(feature = "arkworks")] -use ark_ff::PrimeField; +use ark_ff::Field as ArkField; use icicle_cuda_runtime::{error::CudaError, memory::HostOrDeviceSlice}; use std::{fmt::Debug, mem::MaybeUninit}; @@ -12,7 +12,7 @@ pub trait GenerateRandom { #[doc(hidden)] pub trait FieldConfig: Debug + PartialEq + Copy + Clone { #[cfg(feature = "arkworks")] - type ArkField: PrimeField; + type ArkField: ArkField; } pub trait FieldImpl: Debug + PartialEq + Copy + Clone + Into + From { diff --git a/wrappers/rust/icicle-curves/icicle-bls12-377/Cargo.toml b/wrappers/rust/icicle-curves/icicle-bls12-377/Cargo.toml index aa351689..f0338f8b 100644 --- a/wrappers/rust/icicle-curves/icicle-bls12-377/Cargo.toml +++ b/wrappers/rust/icicle-curves/icicle-bls12-377/Cargo.toml @@ -26,4 +26,7 @@ icicle-bls12-377 = { path = ".", features = ["arkworks"] } [features] default = [] +bw6-761 = [] +bw6-761-g2 = ["bw6-761"] +g2 = ["icicle-core/g2"] arkworks = ["ark-bls12-377", "icicle-core/arkworks"] diff --git a/wrappers/rust/icicle-curves/icicle-bls12-377/build.rs b/wrappers/rust/icicle-curves/icicle-bls12-377/build.rs index 6055c6d2..e3c25ce8 100644 --- a/wrappers/rust/icicle-curves/icicle-bls12-377/build.rs +++ b/wrappers/rust/icicle-curves/icicle-bls12-377/build.rs @@ -4,16 +4,46 @@ fn main() { println!("cargo:rerun-if-env-changed=CXXFLAGS"); println!("cargo:rerun-if-changed=../../../../icicle"); - let out_dir = Config::new("../../../../icicle") - .define("BUILD_TESTS", "OFF") //TODO: feature - .define("CURVE", "bls12_377") - .define("CMAKE_BUILD_TYPE", "Release") - .build_target("icicle") - .build(); + // Base config + let mut config = Config::new("../../../../icicle"); + config + .define("BUILD_TESTS", "OFF") + .define("CURVE", "bls12_377") + .define("CMAKE_BUILD_TYPE", "Release"); + + // Optional Features + #[cfg(feature = "g2")] + config.define("G2_DEFINED", "ON"); + + // Build + let out_dir = config + .build_target("icicle") + .build(); println!("cargo:rustc-link-search={}/build", out_dir.display()); - println!("cargo:rustc-link-lib=ingo_bls12_377"); + + if cfg!(feature = "bw6-761") { + // Base config + let mut config = Config::new("../../../../icicle"); + config + .define("BUILD_TESTS", "OFF") + .define("CURVE", "bw6_761") + .define("CMAKE_BUILD_TYPE", "Release"); + + // Optional Features + #[cfg(feature = "bw6-761-g2")] + config.define("G2_DEFINED", "ON"); + + // Build + let out_dir = config + .build_target("icicle") + .build(); + + println!("cargo:rustc-link-search={}/build", out_dir.display()); + println!("cargo:rustc-link-lib=ingo_bw6_761"); + } + println!("cargo:rustc-link-lib=stdc++"); println!("cargo:rustc-link-lib=cudart"); } diff --git a/wrappers/rust/icicle-curves/icicle-bls12-377/src/curve.rs b/wrappers/rust/icicle-curves/icicle-bls12-377/src/curve.rs index b235d817..3a3779d4 100644 --- a/wrappers/rust/icicle-curves/icicle-bls12-377/src/curve.rs +++ b/wrappers/rust/icicle-curves/icicle-bls12-377/src/curve.rs @@ -1,5 +1,7 @@ #[cfg(feature = "arkworks")] use ark_bls12_377::{g1::Config as ArkG1Config, Fq, Fr}; +#[cfg(all(feature = "arkworks", feature = "g2"))] +use ark_bls12_377::{g2::Config as ArkG2Config, Fq2}; use icicle_core::curve::{Affine, Curve, Projective}; use icicle_core::field::{Field, MontgomeryConvertibleField}; use icicle_core::traits::{FieldConfig, FieldImpl, GenerateRandom}; @@ -10,21 +12,53 @@ use icicle_cuda_runtime::memory::HostOrDeviceSlice; pub(crate) const SCALAR_LIMBS: usize = 4; pub(crate) const BASE_LIMBS: usize = 6; +#[cfg(feature = "g2")] +pub(crate) const G2_BASE_LIMBS: usize = 12; -impl_scalar_field!("bls12_377", SCALAR_LIMBS, ScalarField, ScalarCfg, Fr); +impl_scalar_field!("bls12_377", bls12_377_sf, SCALAR_LIMBS, ScalarField, ScalarCfg, Fr); +#[cfg(feature = "bw6-761")] +impl_scalar_field!("bw6_761", bw6_761_sf, BASE_LIMBS, BaseField, BaseCfg, Fq); +#[cfg(not(feature = "bw6-761"))] impl_field!(BASE_LIMBS, BaseField, BaseCfg, Fq); -impl_curve!("bls12_377", CurveCfg, ScalarField, BaseField); +#[cfg(feature = "g2")] +impl_field!(G2_BASE_LIMBS, G2BaseField, G2BaseCfg, Fq2); +impl_curve!( + "bls12_377", + bls12_377, + CurveCfg, + ScalarField, + BaseField, + ArkG1Config, + G1Affine, + G1Projective +); +#[cfg(feature = "g2")] +impl_curve!( + "bls12_377G2", + bls12_377_g2, + G2CurveCfg, + ScalarField, + G2BaseField, + ArkG2Config, + G2Affine, + G2Projective +); #[cfg(test)] mod tests { - use super::ScalarField; - use super::{CurveCfg, BASE_LIMBS}; + use super::{CurveCfg, ScalarField, BASE_LIMBS}; + #[cfg(feature = "g2")] + use super::{G2CurveCfg, G2_BASE_LIMBS}; use icicle_core::curve::Curve; - use icicle_core::impl_curve_tests; - use icicle_core::impl_field_tests; use icicle_core::tests::*; use icicle_core::traits::FieldImpl; + use icicle_core::{impl_curve_tests, impl_field_tests}; impl_field_tests!(ScalarField); impl_curve_tests!(BASE_LIMBS, CurveCfg); + #[cfg(feature = "g2")] + mod g2 { + use super::*; + impl_curve_tests!(G2_BASE_LIMBS, G2CurveCfg); + } } diff --git a/wrappers/rust/icicle-curves/icicle-bls12-377/src/msm/mod.rs b/wrappers/rust/icicle-curves/icicle-bls12-377/src/msm/mod.rs index a27b436b..9dae392c 100644 --- a/wrappers/rust/icicle-curves/icicle-bls12-377/src/msm/mod.rs +++ b/wrappers/rust/icicle-curves/icicle-bls12-377/src/msm/mod.rs @@ -1,4 +1,6 @@ use crate::curve::CurveCfg; +#[cfg(feature = "g2")] +use crate::curve::G2CurveCfg; use icicle_core::{ curve::{Affine, Curve, Projective}, error::IcicleResult, @@ -9,14 +11,22 @@ use icicle_core::{ use icicle_cuda_runtime::error::CudaError; use icicle_cuda_runtime::memory::HostOrDeviceSlice; -impl_msm!("bls12_377", CurveCfg); +impl_msm!("bls12_377", bls12_377, CurveCfg); +#[cfg(feature = "g2")] +impl_msm!("bls12_377G2", bls12_377_g2, G2CurveCfg); #[cfg(test)] pub(crate) mod tests { + use crate::curve::CurveCfg; + #[cfg(feature = "g2")] + use crate::curve::G2CurveCfg; use icicle_core::impl_msm_tests; use icicle_core::msm::tests::*; - use crate::curve::CurveCfg; - impl_msm_tests!(CurveCfg); + #[cfg(feature = "g2")] + mod g2 { + use super::*; + impl_msm_tests!(G2CurveCfg); + } } diff --git a/wrappers/rust/icicle-curves/icicle-bls12-377/src/ntt/mod.rs b/wrappers/rust/icicle-curves/icicle-bls12-377/src/ntt/mod.rs index f98a7ff9..543f9fb4 100644 --- a/wrappers/rust/icicle-curves/icicle-bls12-377/src/ntt/mod.rs +++ b/wrappers/rust/icicle-curves/icicle-bls12-377/src/ntt/mod.rs @@ -1,3 +1,5 @@ +#[cfg(feature = "bw6-761")] +use crate::curve::{BaseCfg, BaseField}; use crate::curve::{ScalarCfg, ScalarField}; use icicle_core::error::IcicleResult; @@ -8,7 +10,9 @@ use icicle_cuda_runtime::device_context::DeviceContext; use icicle_cuda_runtime::error::CudaError; use icicle_cuda_runtime::memory::HostOrDeviceSlice; -impl_ntt!("bls12_377", ScalarField, ScalarCfg); +impl_ntt!("bls12_377", bls12_377, ScalarField, ScalarCfg); +#[cfg(feature = "bw6-761")] +impl_ntt!("bw6_761", bw6_761, BaseField, BaseCfg); #[cfg(test)] pub(crate) mod tests { diff --git a/wrappers/rust/icicle-curves/icicle-bls12-381/Cargo.toml b/wrappers/rust/icicle-curves/icicle-bls12-381/Cargo.toml index 22d91e92..b34ea328 100644 --- a/wrappers/rust/icicle-curves/icicle-bls12-381/Cargo.toml +++ b/wrappers/rust/icicle-curves/icicle-bls12-381/Cargo.toml @@ -26,4 +26,5 @@ icicle-bls12-381 = { path = ".", features = ["arkworks"] } [features] default = [] +g2 = ["icicle-core/g2"] arkworks = ["ark-bls12-381", "icicle-core/arkworks"] diff --git a/wrappers/rust/icicle-curves/icicle-bls12-381/build.rs b/wrappers/rust/icicle-curves/icicle-bls12-381/build.rs index 01ebdb6a..8589d66d 100644 --- a/wrappers/rust/icicle-curves/icicle-bls12-381/build.rs +++ b/wrappers/rust/icicle-curves/icicle-bls12-381/build.rs @@ -4,12 +4,21 @@ fn main() { println!("cargo:rerun-if-env-changed=CXXFLAGS"); println!("cargo:rerun-if-changed=../../../../icicle"); - let out_dir = Config::new("../../../../icicle") - .define("BUILD_TESTS", "OFF") //TODO: feature - .define("CURVE", "bls12_381") - .define("CMAKE_BUILD_TYPE", "Release") - .build_target("icicle") - .build(); + // Base config + let mut config = Config::new("../../../../icicle"); + config + .define("BUILD_TESTS", "OFF") + .define("CURVE", "bls12_381") + .define("CMAKE_BUILD_TYPE", "Release"); + + // Optional Features + #[cfg(feature = "g2")] + config.define("G2_DEFINED", "ON"); + + // Build + let out_dir = config + .build_target("icicle") + .build(); println!("cargo:rustc-link-search={}/build", out_dir.display()); diff --git a/wrappers/rust/icicle-curves/icicle-bls12-381/src/curve.rs b/wrappers/rust/icicle-curves/icicle-bls12-381/src/curve.rs index 7cceb45d..d4a6c2f2 100644 --- a/wrappers/rust/icicle-curves/icicle-bls12-381/src/curve.rs +++ b/wrappers/rust/icicle-curves/icicle-bls12-381/src/curve.rs @@ -1,5 +1,7 @@ #[cfg(feature = "arkworks")] use ark_bls12_381::{g1::Config as ArkG1Config, Fq, Fr}; +#[cfg(all(feature = "arkworks", feature = "g2"))] +use ark_bls12_381::{g2::Config as ArkG2Config, Fq2}; use icicle_core::curve::{Affine, Curve, Projective}; use icicle_core::field::{Field, MontgomeryConvertibleField}; use icicle_core::traits::{FieldConfig, FieldImpl, GenerateRandom}; @@ -10,21 +12,50 @@ use icicle_cuda_runtime::memory::HostOrDeviceSlice; pub(crate) const SCALAR_LIMBS: usize = 4; pub(crate) const BASE_LIMBS: usize = 6; +#[cfg(feature = "g2")] +pub(crate) const G2_BASE_LIMBS: usize = 12; -impl_scalar_field!("bls12_381", SCALAR_LIMBS, ScalarField, ScalarCfg, Fr); +impl_scalar_field!("bls12_381", bls12_381_sf, SCALAR_LIMBS, ScalarField, ScalarCfg, Fr); impl_field!(BASE_LIMBS, BaseField, BaseCfg, Fq); -impl_curve!("bls12_381", CurveCfg, ScalarField, BaseField); +#[cfg(feature = "g2")] +impl_field!(G2_BASE_LIMBS, G2BaseField, G2BaseCfg, Fq2); +impl_curve!( + "bls12_381", + bls12_381, + CurveCfg, + ScalarField, + BaseField, + ArkG1Config, + G1Affine, + G1Projective +); +#[cfg(feature = "g2")] +impl_curve!( + "bls12_381G2", + bls12_381_g2, + G2CurveCfg, + ScalarField, + G2BaseField, + ArkG2Config, + G2Affine, + G2Projective +); #[cfg(test)] mod tests { - use super::ScalarField; - use super::{CurveCfg, BASE_LIMBS}; + use super::{CurveCfg, ScalarField, BASE_LIMBS}; + #[cfg(feature = "g2")] + use super::{G2CurveCfg, G2_BASE_LIMBS}; use icicle_core::curve::Curve; - use icicle_core::impl_curve_tests; - use icicle_core::impl_field_tests; use icicle_core::tests::*; use icicle_core::traits::FieldImpl; + use icicle_core::{impl_curve_tests, impl_field_tests}; impl_field_tests!(ScalarField); impl_curve_tests!(BASE_LIMBS, CurveCfg); + #[cfg(feature = "g2")] + mod g2 { + use super::*; + impl_curve_tests!(G2_BASE_LIMBS, G2CurveCfg); + } } diff --git a/wrappers/rust/icicle-curves/icicle-bls12-381/src/msm/mod.rs b/wrappers/rust/icicle-curves/icicle-bls12-381/src/msm/mod.rs index 2b7c16ee..34501915 100644 --- a/wrappers/rust/icicle-curves/icicle-bls12-381/src/msm/mod.rs +++ b/wrappers/rust/icicle-curves/icicle-bls12-381/src/msm/mod.rs @@ -1,4 +1,6 @@ use crate::curve::CurveCfg; +#[cfg(feature = "g2")] +use crate::curve::G2CurveCfg; use icicle_core::{ curve::{Affine, Curve, Projective}, error::IcicleResult, @@ -9,14 +11,22 @@ use icicle_core::{ use icicle_cuda_runtime::error::CudaError; use icicle_cuda_runtime::memory::HostOrDeviceSlice; -impl_msm!("bls12_381", CurveCfg); +impl_msm!("bls12_381", bls12_381, CurveCfg); +#[cfg(feature = "g2")] +impl_msm!("bls12_381G2", bls12_381_g2, G2CurveCfg); #[cfg(test)] pub(crate) mod tests { + use crate::curve::CurveCfg; + #[cfg(feature = "g2")] + use crate::curve::G2CurveCfg; use icicle_core::impl_msm_tests; use icicle_core::msm::tests::*; - use crate::curve::CurveCfg; - impl_msm_tests!(CurveCfg); + #[cfg(feature = "g2")] + mod g2 { + use super::*; + impl_msm_tests!(G2CurveCfg); + } } diff --git a/wrappers/rust/icicle-curves/icicle-bls12-381/src/ntt/mod.rs b/wrappers/rust/icicle-curves/icicle-bls12-381/src/ntt/mod.rs index bd5b122c..755e7834 100644 --- a/wrappers/rust/icicle-curves/icicle-bls12-381/src/ntt/mod.rs +++ b/wrappers/rust/icicle-curves/icicle-bls12-381/src/ntt/mod.rs @@ -8,7 +8,7 @@ use icicle_cuda_runtime::device_context::DeviceContext; use icicle_cuda_runtime::error::CudaError; use icicle_cuda_runtime::memory::HostOrDeviceSlice; -impl_ntt!("bls12_381", ScalarField, ScalarCfg); +impl_ntt!("bls12_381", bls12_381, ScalarField, ScalarCfg); #[cfg(test)] pub(crate) mod tests { diff --git a/wrappers/rust/icicle-curves/icicle-bn254/Cargo.toml b/wrappers/rust/icicle-curves/icicle-bn254/Cargo.toml index 523c17a8..06da60b4 100644 --- a/wrappers/rust/icicle-curves/icicle-bn254/Cargo.toml +++ b/wrappers/rust/icicle-curves/icicle-bn254/Cargo.toml @@ -26,4 +26,5 @@ icicle-bn254 = { path = ".", features = ["arkworks"] } [features] default = [] +g2 = ["icicle-core/g2"] arkworks = ["ark-bn254", "icicle-core/arkworks"] diff --git a/wrappers/rust/icicle-curves/icicle-bn254/build.rs b/wrappers/rust/icicle-curves/icicle-bn254/build.rs index 49d87fb3..342142a8 100644 --- a/wrappers/rust/icicle-curves/icicle-bn254/build.rs +++ b/wrappers/rust/icicle-curves/icicle-bn254/build.rs @@ -4,12 +4,21 @@ fn main() { println!("cargo:rerun-if-env-changed=CXXFLAGS"); println!("cargo:rerun-if-changed=../../../../icicle"); - let out_dir = Config::new("../../../../icicle") - .define("BUILD_TESTS", "OFF") //TODO: feature - .define("CURVE", "bn254") - .define("CMAKE_BUILD_TYPE", "Release") - .build_target("icicle") - .build(); + // Base config + let mut config = Config::new("../../../../icicle"); + config + .define("BUILD_TESTS", "OFF") + .define("CURVE", "bn254") + .define("CMAKE_BUILD_TYPE", "Release"); + + // Optional Features + #[cfg(feature = "g2")] + config.define("G2_DEFINED", "ON"); + + // Build + let out_dir = config + .build_target("icicle") + .build(); println!("cargo:rustc-link-search={}/build", out_dir.display()); diff --git a/wrappers/rust/icicle-curves/icicle-bn254/src/curve.rs b/wrappers/rust/icicle-curves/icicle-bn254/src/curve.rs index 4112383e..2e76c239 100644 --- a/wrappers/rust/icicle-curves/icicle-bn254/src/curve.rs +++ b/wrappers/rust/icicle-curves/icicle-bn254/src/curve.rs @@ -1,5 +1,7 @@ #[cfg(feature = "arkworks")] use ark_bn254::{g1::Config as ArkG1Config, Fq, Fr}; +#[cfg(all(feature = "arkworks", feature = "g2"))] +use ark_bn254::{g2::Config as ArkG2Config, Fq2}; use icicle_core::curve::{Affine, Curve, Projective}; use icicle_core::field::{Field, MontgomeryConvertibleField}; use icicle_core::traits::{FieldConfig, FieldImpl, GenerateRandom}; @@ -10,21 +12,50 @@ use icicle_cuda_runtime::memory::HostOrDeviceSlice; pub(crate) const SCALAR_LIMBS: usize = 4; pub(crate) const BASE_LIMBS: usize = 4; +#[cfg(feature = "g2")] +pub(crate) const G2_BASE_LIMBS: usize = 8; -impl_scalar_field!("bn254", SCALAR_LIMBS, ScalarField, ScalarCfg, Fr); +impl_scalar_field!("bn254", bn254_sf, SCALAR_LIMBS, ScalarField, ScalarCfg, Fr); impl_field!(BASE_LIMBS, BaseField, BaseCfg, Fq); -impl_curve!("bn254", CurveCfg, ScalarField, BaseField); +#[cfg(feature = "g2")] +impl_field!(G2_BASE_LIMBS, G2BaseField, G2BaseCfg, Fq2); +impl_curve!( + "bn254", + bn254, + CurveCfg, + ScalarField, + BaseField, + ArkG1Config, + G1Affine, + G1Projective +); +#[cfg(feature = "g2")] +impl_curve!( + "bn254G2", + bn254_g2, + G2CurveCfg, + ScalarField, + G2BaseField, + ArkG2Config, + G2Affine, + G2Projective +); #[cfg(test)] mod tests { - use super::ScalarField; - use super::{CurveCfg, BASE_LIMBS}; + use super::{CurveCfg, ScalarField, BASE_LIMBS}; + #[cfg(feature = "g2")] + use super::{G2CurveCfg, G2_BASE_LIMBS}; use icicle_core::curve::Curve; - use icicle_core::impl_curve_tests; - use icicle_core::impl_field_tests; use icicle_core::tests::*; use icicle_core::traits::FieldImpl; + use icicle_core::{impl_curve_tests, impl_field_tests}; impl_field_tests!(ScalarField); impl_curve_tests!(BASE_LIMBS, CurveCfg); + #[cfg(feature = "g2")] + mod g2 { + use super::*; + impl_curve_tests!(G2_BASE_LIMBS, G2CurveCfg); + } } diff --git a/wrappers/rust/icicle-curves/icicle-bn254/src/msm/mod.rs b/wrappers/rust/icicle-curves/icicle-bn254/src/msm/mod.rs index b1b012eb..d4f3b63f 100644 --- a/wrappers/rust/icicle-curves/icicle-bn254/src/msm/mod.rs +++ b/wrappers/rust/icicle-curves/icicle-bn254/src/msm/mod.rs @@ -1,4 +1,6 @@ use crate::curve::CurveCfg; +#[cfg(feature = "g2")] +use crate::curve::G2CurveCfg; use icicle_core::{ curve::{Affine, Curve, Projective}, error::IcicleResult, @@ -8,14 +10,22 @@ use icicle_core::{ }; use icicle_cuda_runtime::{error::CudaError, memory::HostOrDeviceSlice}; -impl_msm!("bn254", CurveCfg); +impl_msm!("bn254", bn254, CurveCfg); +#[cfg(feature = "g2")] +impl_msm!("bn254G2", bn254_g2, G2CurveCfg); #[cfg(test)] pub(crate) mod tests { + use crate::curve::CurveCfg; + #[cfg(feature = "g2")] + use crate::curve::G2CurveCfg; use icicle_core::impl_msm_tests; use icicle_core::msm::tests::*; - use crate::curve::CurveCfg; - impl_msm_tests!(CurveCfg); + #[cfg(feature = "g2")] + mod g2 { + use super::*; + impl_msm_tests!(G2CurveCfg); + } } diff --git a/wrappers/rust/icicle-curves/icicle-bn254/src/ntt/mod.rs b/wrappers/rust/icicle-curves/icicle-bn254/src/ntt/mod.rs index 29f63875..639c4ce1 100644 --- a/wrappers/rust/icicle-curves/icicle-bn254/src/ntt/mod.rs +++ b/wrappers/rust/icicle-curves/icicle-bn254/src/ntt/mod.rs @@ -8,7 +8,7 @@ use icicle_cuda_runtime::device_context::DeviceContext; use icicle_cuda_runtime::error::CudaError; use icicle_cuda_runtime::memory::HostOrDeviceSlice; -impl_ntt!("bn254", ScalarField, ScalarCfg); +impl_ntt!("bn254", bn254, ScalarField, ScalarCfg); #[cfg(test)] pub(crate) mod tests { diff --git a/wrappers/rust/icicle-curves/icicle-bw6-761/Cargo.toml b/wrappers/rust/icicle-curves/icicle-bw6-761/Cargo.toml index b414236c..4cd28219 100644 --- a/wrappers/rust/icicle-curves/icicle-bw6-761/Cargo.toml +++ b/wrappers/rust/icicle-curves/icicle-bw6-761/Cargo.toml @@ -3,13 +3,14 @@ name = "icicle-bw6-761" version = "1.0.0" edition = "2021" authors = [ "Ingonyama" ] -description = "Rust wrapper for the CUDA implementation of BN254 pairing friendly elliptic curve by Ingonyama" +description = "Rust wrapper for the CUDA implementation of BW6-761 pairing friendly elliptic curve by Ingonyama" homepage = "https://www.ingonyama.com" repository = "https://github.com/ingonyama-zk/icicle" [dependencies] icicle-core = { path = "../../icicle-core" } icicle-cuda-runtime = { path = "../../icicle-cuda-runtime" } +icicle-bls12-377 = { path = "../../icicle-curves/icicle-bls12-377", features = ["bw6-761"] } ark-bw6-761 = { version = "0.4.0", optional = true } [build-dependencies] @@ -26,4 +27,5 @@ icicle-bw6-761 = { path = ".", features = ["arkworks"] } [features] default = [] -arkworks = ["ark-bw6-761", "icicle-core/arkworks"] +g2 = ["icicle-bls12-377/bw6-761-g2"] +arkworks = ["ark-bw6-761", "icicle-core/arkworks", "icicle-bls12-377/arkworks"] diff --git a/wrappers/rust/icicle-curves/icicle-bw6-761/build.rs b/wrappers/rust/icicle-curves/icicle-bw6-761/build.rs deleted file mode 100644 index 8d6c6efa..00000000 --- a/wrappers/rust/icicle-curves/icicle-bw6-761/build.rs +++ /dev/null @@ -1,19 +0,0 @@ -use cmake::Config; - -fn main() { - println!("cargo:rerun-if-env-changed=CXXFLAGS"); - println!("cargo:rerun-if-changed=../../../../icicle"); - - let out_dir = Config::new("../../../../icicle") - .define("BUILD_TESTS", "OFF") //TODO: feature - .define("CURVE", "bw6_761") - .define("CMAKE_BUILD_TYPE", "Release") - .build_target("icicle") - .build(); - - println!("cargo:rustc-link-search={}/build", out_dir.display()); - - println!("cargo:rustc-link-lib=ingo_bw6_761"); - println!("cargo:rustc-link-lib=stdc++"); - println!("cargo:rustc-link-lib=cudart"); -} diff --git a/wrappers/rust/icicle-curves/icicle-bw6-761/src/curve.rs b/wrappers/rust/icicle-curves/icicle-bw6-761/src/curve.rs index f6d3bf5d..a9eb864e 100644 --- a/wrappers/rust/icicle-curves/icicle-bw6-761/src/curve.rs +++ b/wrappers/rust/icicle-curves/icicle-bw6-761/src/curve.rs @@ -1,30 +1,57 @@ +#[cfg(all(feature = "arkworks", feature = "g2"))] +use ark_bw6_761::g2::Config as ArkG2Config; #[cfg(feature = "arkworks")] -use ark_bw6_761::{g1::Config as ArkG1Config, Fq, Fr}; +use ark_bw6_761::{g1::Config as ArkG1Config, Fq}; +use icicle_bls12_377::curve::BaseField as bls12_377BaseField; use icicle_core::curve::{Affine, Curve, Projective}; -use icicle_core::field::{Field, MontgomeryConvertibleField}; -use icicle_core::traits::{FieldConfig, FieldImpl, GenerateRandom}; -use icicle_core::{impl_curve, impl_field, impl_scalar_field}; +use icicle_core::field::Field; +use icicle_core::traits::FieldConfig; +use icicle_core::{impl_curve, impl_field}; use icicle_cuda_runtime::device_context::{get_default_device_context, DeviceContext}; use icicle_cuda_runtime::error::CudaError; use icicle_cuda_runtime::memory::HostOrDeviceSlice; -pub(crate) const SCALAR_LIMBS: usize = 6; pub(crate) const BASE_LIMBS: usize = 12; -impl_scalar_field!("bw6_761", SCALAR_LIMBS, ScalarField, ScalarCfg, Fr); impl_field!(BASE_LIMBS, BaseField, BaseCfg, Fq); -impl_curve!("bw6_761", CurveCfg, ScalarField, BaseField); +pub type ScalarField = bls12_377BaseField; +impl_curve!( + "bw6_761", + bw6_761, + CurveCfg, + ScalarField, + BaseField, + ArkG1Config, + G1Affine, + G1Projective +); +#[cfg(feature = "g2")] +impl_curve!( + "bw6_761G2", + bw6_761_g2, + G2CurveCfg, + ScalarField, + BaseField, + ArkG2Config, + G2Affine, + G2Projective +); #[cfg(test)] mod tests { - use super::ScalarField; - use super::{CurveCfg, BASE_LIMBS}; + #[cfg(feature = "g2")] + use super::G2CurveCfg; + use super::{CurveCfg, ScalarField, BASE_LIMBS}; use icicle_core::curve::Curve; - use icicle_core::impl_curve_tests; - use icicle_core::impl_field_tests; use icicle_core::tests::*; use icicle_core::traits::FieldImpl; + use icicle_core::{impl_curve_tests, impl_field_tests}; impl_field_tests!(ScalarField); impl_curve_tests!(BASE_LIMBS, CurveCfg); + #[cfg(feature = "g2")] + mod g2 { + use super::*; + impl_curve_tests!(BASE_LIMBS, G2CurveCfg); + } } diff --git a/wrappers/rust/icicle-curves/icicle-bw6-761/src/msm/mod.rs b/wrappers/rust/icicle-curves/icicle-bw6-761/src/msm/mod.rs index af65d360..5d78b118 100644 --- a/wrappers/rust/icicle-curves/icicle-bw6-761/src/msm/mod.rs +++ b/wrappers/rust/icicle-curves/icicle-bw6-761/src/msm/mod.rs @@ -1,4 +1,6 @@ use crate::curve::CurveCfg; +#[cfg(feature = "g2")] +use crate::curve::G2CurveCfg; use icicle_core::{ curve::{Affine, Curve, Projective}, error::IcicleResult, @@ -9,14 +11,22 @@ use icicle_core::{ use icicle_cuda_runtime::error::CudaError; use icicle_cuda_runtime::memory::HostOrDeviceSlice; -impl_msm!("bw6_761", CurveCfg); +impl_msm!("bw6_761", bw6_761, CurveCfg); +#[cfg(feature = "g2")] +impl_msm!("bw6_761G2", bw6_761_g2, G2CurveCfg); #[cfg(test)] pub(crate) mod tests { + use crate::curve::CurveCfg; + #[cfg(feature = "g2")] + use crate::curve::G2CurveCfg; use icicle_core::impl_msm_tests; use icicle_core::msm::tests::*; - use crate::curve::CurveCfg; - impl_msm_tests!(CurveCfg); + #[cfg(feature = "g2")] + mod g2 { + use super::*; + impl_msm_tests!(G2CurveCfg); + } } diff --git a/wrappers/rust/icicle-curves/icicle-bw6-761/src/ntt/mod.rs b/wrappers/rust/icicle-curves/icicle-bw6-761/src/ntt/mod.rs index 79bdaec9..7e3867e8 100644 --- a/wrappers/rust/icicle-curves/icicle-bw6-761/src/ntt/mod.rs +++ b/wrappers/rust/icicle-curves/icicle-bw6-761/src/ntt/mod.rs @@ -1,15 +1,3 @@ -use crate::curve::{ScalarCfg, ScalarField}; - -use icicle_core::error::IcicleResult; -use icicle_core::impl_ntt; -use icicle_core::ntt::{NTTConfig, NTTDir, NTT}; -use icicle_core::traits::IcicleResultWrap; -use icicle_cuda_runtime::device_context::DeviceContext; -use icicle_cuda_runtime::error::CudaError; -use icicle_cuda_runtime::memory::HostOrDeviceSlice; - -impl_ntt!("bw6_761", ScalarField, ScalarCfg); - #[cfg(test)] pub(crate) mod tests { use crate::curve::ScalarField;