Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FEAT(curve): Add Stark252 curve #421

Closed
wants to merge 10 commits into from
Closed
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
4 changes: 2 additions & 2 deletions icicle/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ include_directories("${CMAKE_SOURCE_DIR}")


# when adding a new curve/field, append its name to the end of this list
set(SUPPORTED_CURVES bn254;bls12_381;bls12_377;bw6_761;grumpkin)
set(SUPPORTED_CURVES_WITH_POSEIDON bn254;bls12_381;bls12_377;bw6_761;grumpkin)
set(SUPPORTED_CURVES bn254;bls12_381;bls12_377;bw6_761;grumpkin;stark252)
set(SUPPORTED_CURVES_WITH_POSEIDON bn254;bls12_381;bls12_377;bw6_761;grumpkin;stark252)
SET(SUPPORTED_CURVES_WITHOUT_NTT grumpkin)

set(IS_CURVE_SUPPORTED FALSE)
Expand Down
3 changes: 3 additions & 0 deletions icicle/appUtils/poseidon/constants.cu
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ using namespace poseidon_constants_bw6_761;
#elif CURVE_ID == GRUMPKIN
#include "appUtils/poseidon/constants/grumpkin_poseidon.h"
using namespace poseidon_constants_grumpkin;
#elif CURVE_ID == STARK252
#include "appUtils/poseidon/constants/stark252_poseidon.h"
using namespace poseidon_constants_stark252;
#endif

namespace poseidon {
Expand Down
8 changes: 5 additions & 3 deletions icicle/appUtils/poseidon/constants/generate_parameters.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,13 @@

# Modify these
arity = 11
p = 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47 # grumpkin
p = 0x800000000000010ffffffffffffffffb781126dcae7b2321e66a241adc64d2f # stark
# p = 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47 # grumpkin
# p = 0x73EDA753299D7D483339D80809A1D80553BDA402FFFE5BFEFFFFFFFF00000001 # bls12-381
# p = 0x12ab655e9a2ca55660b44d1e5c37b00159aa76fed00000010a11800000000001 # bls12-377
# p = 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001 # bn254
# p = 0x1ae3a4617c510eac63b05c06ca1493b1a22d9f300f5138f1ef3622fba094800170b5d44300000008508c00000000001 # bw6-761
prime_bit_len = 255
prime_bit_len = 252
field_bytes = 32

# leave set to -1 if not sure
Expand All @@ -36,7 +37,8 @@
# primitive_element = 22 # bls12-377
# primitive_element = 5 # bn254
# primitive_element = 15 # bw6-761
primitive_element = 3 # grumpkin
# primitive_element = 3 # grumpkin
primitive_element = 3 # stark

# currently we only support alpha 5, if you need alpha other than 5 - feal free to reach out
alpha = 5
Expand Down
11,820 changes: 11,820 additions & 0 deletions icicle/appUtils/poseidon/constants/stark252_poseidon.h

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions icicle/curves/curve_config.cuh
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#define BLS12_377 3
#define BW6_761 4
#define GRUMPKIN 5
#define STARK252 6

#include "primitives/field.cuh"
#include "primitives/projective.cuh"
Expand All @@ -30,6 +31,9 @@ using namespace bw6_761;
#elif CURVE_ID == GRUMPKIN
#include "grumpkin_params.cuh"
using namespace grumpkin;
#elif CURVE_ID == STARK252
#include "stark252_params.cuh"
using namespace stark252;
#endif

/**
Expand Down
71 changes: 71 additions & 0 deletions icicle/curves/stark252_params.cuh
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#pragma once
#ifndef STARK_252_PARAMS_H
#define STARK_252_PARAMS_H

#include "utils/storage.cuh"

namespace stark252 {
// modulus = 3618502788666131213697322783095070105526743751716087489154079457884512865583
struct fp_config {
static constexpr unsigned limbs_count = 8;
static constexpr unsigned omegas_count = 1;
static constexpr unsigned modulus_bit_count = 252;
static constexpr unsigned num_of_reductions = 1;

static constexpr storage<limbs_count> modulus = {0xadc64d2f, 0x1e66a241, 0xcae7b232, 0xb781126d, 0xffffffff, 0xffffffff, 0x00000010, 0x08000000};
static constexpr storage<limbs_count> modulus_2 = {0x5b8c9a5e, 0x3ccd4483, 0x95cf6464, 0x6f0224db, 0xffffffff, 0xffffffff, 0x00000021, 0x10000000};
static constexpr storage<limbs_count> modulus_4 = {0xb71934bc, 0x799a8906, 0x2b9ec8c8, 0xde0449b7, 0xfffffffe, 0xffffffff, 0x00000043, 0x20000000};
static constexpr storage<limbs_count> neg_modulus = {0x5239b2d1, 0xe1995dbe, 0x35184dcd, 0x487eed92, 0x00000000, 0x00000000, 0xffffffef, 0xf7ffffff};
static constexpr storage<2 * limbs_count> modulus_wide = {0xadc64d2f, 0x1e66a241, 0xcae7b232, 0xb781126d, 0xffffffff, 0xffffffff, 0x00000010, 0x08000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000};
static constexpr storage<2 * limbs_count> modulus_squared = {0x01f94ea1, 0x33cc4bcb, 0x3385a741, 0xef31d230, 0x8dc40391, 0x005b5cc4, 0x0a9839be, 0x0e29314a, 0x0da20f7b, 0x810adcb9, 0xdcae7b19, 0xfb781126, 0x00000120, 0x10000000, 0x00000001, 0x00400000};
static constexpr storage<2 * limbs_count> modulus_squared_2 = {0x03f29d42, 0x67989796, 0x670b4e82, 0xde63a460, 0x1b880723, 0x00b6b989, 0x1530737c, 0x1c526294, 0x1b441ef6, 0x0215b972, 0xb95cf633, 0xf6f0224d, 0x00000241, 0x20000000, 0x00000002, 0x00800000};
static constexpr storage<2 * limbs_count> modulus_squared_4 = {0x07e53a84, 0xcf312f2c, 0xce169d04, 0xbcc748c0, 0x37100e47, 0x016d7312, 0x2a60e6f8, 0x38a4c528, 0x36883dec, 0x042b72e4, 0x72b9ec66, 0xede0449b, 0x00000483, 0x40000000, 0x00000004, 0x01000000};
static constexpr storage<limbs_count> m = {0x384d77b0, 0x189ec175, 0xd32e2267, 0x21fbb648, 0x00009081, 0x00000000, 0xffffffbc, 0x1fffffff};
static constexpr storage<limbs_count> one = {0x00000001, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000};
static constexpr storage<limbs_count> zero = {0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000};
static constexpr storage<limbs_count> montgomery_r = {0xf4fca74f, 0x51925a0b, 0x6df16bee, 0xc75ec4b4, 0x00000008, 0x00000000, 0xfffffdf1, 0x07ffffff};
static constexpr storage<limbs_count> montgomery_r_inv = {0x8b91307b, 0x81f69041, 0x65485708, 0xc0708974, 0x090c0159, 0xa541174a, 0xd6190374, 0x012bead2};

static constexpr storage_array<omegas_count, limbs_count> omega = {
{{0xadc64d2e, 0x1e66a241, 0xcae7b232, 0xb781126d, 0xffffffff, 0xffffffff, 0x00000010, 0x08000000},
}};

static constexpr storage_array<omegas_count, limbs_count> inv = {
{{0xd6e32698, 0x0f335120, 0xe573d919, 0xdbc08936, 0xffffffff, 0x7fffffff, 0x00000008, 0x04000000},
}};
};

// modulus = 3618502788666131213697322783095070105623107215331596699973092056135872020481 (2^251+17*2^192+1)
struct fq_config {
static constexpr unsigned limbs_count = 8;
static constexpr unsigned modulus_bit_count = 252;
static constexpr unsigned num_of_reductions = 1;
static constexpr storage<limbs_count> modulus = {0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000011, 0x08000000};
static constexpr storage<limbs_count> modulus_2 = {0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000022, 0x10000000};
static constexpr storage<limbs_count> modulus_4 = {0x00000004, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000044, 0x20000000};
static constexpr storage<limbs_count> neg_modulus = {0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffee, 0xf7ffffff};
static constexpr storage<2 * limbs_count> modulus_wide = {
0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000011, 0x08000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000};
static constexpr storage<2 * limbs_count> modulus_squared = {0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000022, 0x10000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000121, 0x10000000, 0x00000001, 0x00400000};
static constexpr storage<2 * limbs_count> modulus_squared_2 = {0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000044, 0x20000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000242, 0x20000000, 0x00000002, 0x00800000};
static constexpr storage<2 * limbs_count> modulus_squared_4 = {0x00000004, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000088, 0x40000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000484, 0x40000000, 0x00000004, 0x01000000};
static constexpr storage<limbs_count> m = {0x8c81fffb, 0x00000002, 0xfeccf000, 0xffffffff, 0x0000907f, 0x00000000, 0xffffffbc, 0x1fffffff};
static constexpr storage<limbs_count> one = {0x00000001, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000};
static constexpr storage<limbs_count> zero = {0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000};
static constexpr storage<limbs_count> montgomery_r = {0xffffffe1, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffffdf0, 0x07ffffff};
static constexpr storage<limbs_count> montgomery_r_inv = {0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000121, 0x10000000, 0x00000001, 0x00400000};
};

// G1 generators
static constexpr storage<fq_config::limbs_count> g1_gen_x = {0xc943cfca, 0x3d723d8b, 0x0d1819e0, 0xdeacfd9b, 0x5a40f0c7, 0x7beced41, 0x8599971b, 0x01ef15c1};
static constexpr storage<fq_config::limbs_count> g1_gen_y = {0x36e8dc1f, 0x2873000c, 0x1abe43a3, 0xde53ecd1, 0xdf46ec62, 0xb7be4801, 0x0aa49730, 0x00566806};

static constexpr storage<fq_config::limbs_count> weierstrass_b = {0x9cee9e89, 0xf4cdfcb9, 0x15c915c1, 0x609ad26c, 0x72f7a8c5, 0x150e596d, 0xefbe40de, 0x06f21413};
} // namespace stark252

#endif
1 change: 1 addition & 0 deletions wrappers/rust/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ members = [
"icicle-curves/icicle-bls12-381",
"icicle-curves/icicle-bn254",
"icicle-curves/icicle-grumpkin",
"icicle-curves/icicle-stark252",
]
exclude = [
"icicle-curves/icicle-curve-template",
Expand Down
29 changes: 29 additions & 0 deletions wrappers/rust/icicle-curves/icicle-stark252/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
[package]
name = "icicle-stark252"
version.workspace = true
edition.workspace = true
authors.workspace = true
description = "Rust wrapper for the CUDA implementation of stark252 elliptic curve by Ingonyama"
homepage.workspace = true
repository.workspace = true

[dependencies]
icicle-core = { workspace = true }
icicle-cuda-runtime = { workspace = true}
ark-ff = {version = "0.4.0", optional = true }
ark-ec = {version = "0.4.0", optional = true }

[build-dependencies]
cmake = "0.1.50"

[dev-dependencies]
ark-std = "0.4.0"
ark-ff = "0.4.0"
ark-ec = "0.4.0"
ark-poly = "0.4.0"
icicle-core = { path = "../../icicle-core", features = ["arkworks"] }
icicle-stark252 = { path = ".", features = ["arkworks"]}

[features]
default = []
arkworks = ["ark-ff", "ark-ec", "icicle-core/arkworks"]
24 changes: 24 additions & 0 deletions wrappers/rust/icicle-curves/icicle-stark252/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
use cmake::Config;

fn main() {
println!("cargo:rerun-if-env-changed=CXXFLAGS");
println!("cargo:rerun-if-changed=../../../../icicle");

// Base config
let mut config = Config::new("../../../../icicle");
config
.define("BUILD_TESTS", "OFF")
.define("CURVE", "stark252")
.define("CMAKE_BUILD_TYPE", "Release");

// Build
let out_dir = config
.build_target("icicle")
.build();

println!("cargo:rustc-link-search={}/build", out_dir.display());

println!("cargo:rustc-link-lib=ingo_stark252");
println!("cargo:rustc-link-lib=stdc++");
println!("cargo:rustc-link-lib=cudart");
}
89 changes: 89 additions & 0 deletions wrappers/rust/icicle-curves/icicle-stark252/src/curve.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
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_cuda_runtime::device_context::DeviceContext;
use icicle_cuda_runtime::error::CudaError;
use icicle_cuda_runtime::memory::HostOrDeviceSlice;
use ark_ff::fields::{Fp256, MontBackend, MontConfig};
use ark_ec::{
models::{short_weierstrass::SWCurveConfig, CurveConfig},
short_weierstrass::{Affine as ArkAffine, Projective as ArkProjective},
};
use ark_ff::{BigInt, Field as ArkField, MontFp, PrimeField, Zero};

pub(crate) const SCALAR_LIMBS: usize = 4;
pub(crate) const BASE_LIMBS: usize = 4;

// Fq config
#[derive(MontConfig)]
#[modulus = "3618502788666131213697322783095070105623107215331596699973092056135872020481"]
#[generator = "3"]
pub struct ArkFqConfig;
pub type Fq = Fp256<MontBackend<ArkFqConfig, 4>>;

// Fr config
#[derive(MontConfig)]
#[modulus = "3618502788666131213697322783095070105526743751716087489154079457884512865583"]
// Generated by adapting: https://github.com/arkworks-rs/algebra/blob/master/curves/bls12_377/scripts/base_field.sage#L7
#[generator = "3618502788666131213697322783095070105526743751716087489154079457884512865581"]
pub struct ArkFrConfig;
pub type Fr = Fp256<MontBackend<ArkFrConfig, 4>>;

/// G1_GENERATOR_X = 1
pub const G1_GENERATOR_X: Fq = MontFp!("87473945107800776645746498977432208364927860753324948115138248107286880660");

/// G1_GENERATOR_Y = 2
pub const G1_GENERATOR_Y: Fq = MontFp!("152666792071518830868575557812948353041420400780739481342941381225525861407");

#[derive(Clone, Default, PartialEq, Eq)]
pub struct ArkG1Config;

pub type ArkG1Affine = ArkAffine<ArkG1Config>;

impl CurveConfig for ArkG1Config {
type BaseField = Fq;
type ScalarField = Fr;

/// COFACTOR = 1
const COFACTOR: &'static [u64] = &[0x1];

/// COFACTOR_INV = COFACTOR^{-1} mod r = 1
const COFACTOR_INV: Fr = Fr::ONE;
}

impl SWCurveConfig for ArkG1Config {
/// COEFF_A = 0
const COEFF_A: Fq = Fq::ONE;

/// COEFF_B = 3
const COEFF_B: Fq = MontFp!("3141592653589793238462643383279502884197169399375105820974944592307816406665");

/// AFFINE_GENERATOR_COEFFS = (G1_GENERATOR_X, G1_GENERATOR_Y)
const GENERATOR: ArkG1Affine = ArkG1Affine::new_unchecked(G1_GENERATOR_X, G1_GENERATOR_Y);
}

impl_scalar_field!("stark252", stark252_sf, SCALAR_LIMBS, ScalarField, ScalarCfg, Fr);
impl_field!(BASE_LIMBS, BaseField, BaseCfg, Fq);
impl_curve!(
"stark252",
stark252,
CurveCfg,
ScalarField,
BaseField,
ArkG1Config,
G1Affine,
G1Projective
);

#[cfg(test)]
mod tests {
use super::{CurveCfg, ScalarField, BASE_LIMBS};
use icicle_core::curve::Curve;
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);
}
8 changes: 8 additions & 0 deletions wrappers/rust/icicle-curves/icicle-stark252/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
pub mod curve;
pub mod msm;
pub mod ntt;
pub mod poseidon;
pub mod tree;
pub mod vec_ops;

impl icicle_core::SNARKCurve for curve::CurveCfg {}
20 changes: 20 additions & 0 deletions wrappers/rust/icicle-curves/icicle-stark252/src/msm/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
use crate::curve::CurveCfg;
use icicle_core::{
curve::{Affine, Curve, Projective},
error::IcicleResult,
impl_msm,
msm::{MSMConfig, MSM},
traits::IcicleResultWrap,
};
use icicle_cuda_runtime::{error::CudaError, memory::HostOrDeviceSlice};

impl_msm!("stark252", stark252, CurveCfg);

#[cfg(test)]
pub(crate) mod tests {
use crate::curve::CurveCfg;
use icicle_core::impl_msm_tests;
use icicle_core::msm::tests::*;

impl_msm_tests!(CurveCfg);
}
22 changes: 22 additions & 0 deletions wrappers/rust/icicle-curves/icicle-stark252/src/ntt/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
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, DEFAULT_DEVICE_ID};
use icicle_cuda_runtime::error::CudaError;
use icicle_cuda_runtime::memory::HostOrDeviceSlice;

impl_ntt!("stark252", stark252, ScalarField, ScalarCfg);

#[cfg(test)]
pub(crate) mod tests {
use crate::curve::ScalarField;
use crate::ntt::DEFAULT_DEVICE_ID;
use icicle_core::impl_ntt_tests;
use icicle_core::ntt::tests::*;
use std::sync::OnceLock;

impl_ntt_tests!(ScalarField);
}
23 changes: 23 additions & 0 deletions wrappers/rust/icicle-curves/icicle-stark252/src/poseidon/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
use crate::curve::{ScalarCfg, ScalarField};

use icicle_core::error::IcicleResult;
use icicle_core::impl_poseidon;
use icicle_core::poseidon::{Poseidon, PoseidonConfig, PoseidonConstants};
use icicle_core::traits::IcicleResultWrap;
use icicle_cuda_runtime::device_context::DeviceContext;
use icicle_cuda_runtime::error::CudaError;
use icicle_cuda_runtime::memory::HostOrDeviceSlice;

use core::mem::MaybeUninit;

impl_poseidon!("stark252", stark252, ScalarField, ScalarCfg);

#[cfg(test)]
pub(crate) mod tests {
use crate::curve::ScalarField;
use icicle_core::poseidon::tests::*;
use icicle_core::{impl_poseidon_custom_config_test, impl_poseidon_tests};

impl_poseidon_tests!(ScalarField);
impl_poseidon_custom_config_test!(ScalarField, 32, "stark252", 56);
}
21 changes: 21 additions & 0 deletions wrappers/rust/icicle-curves/icicle-stark252/src/tree/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
use crate::curve::{ScalarCfg, ScalarField};

use icicle_core::error::IcicleResult;
use icicle_core::impl_tree_builder;
use icicle_core::poseidon::PoseidonConstants;
use icicle_core::traits::IcicleResultWrap;
use icicle_core::tree::{TreeBuilder, TreeBuilderConfig};
use icicle_cuda_runtime::device_context::DeviceContext;
use icicle_cuda_runtime::error::CudaError;
use icicle_cuda_runtime::memory::HostOrDeviceSlice;

impl_tree_builder!("stark252", stark252, ScalarField, ScalarCfg);

#[cfg(test)]
pub(crate) mod tests {
use crate::curve::ScalarField;
use icicle_core::impl_tree_builder_tests;
use icicle_core::tree::tests::*;

impl_tree_builder_tests!(ScalarField);
}
Loading