Skip to content
Draft
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
11 changes: 11 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 11 additions & 6 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,17 @@ base64 = "0.21.5"
bcs = "0.1.3"
bitvec = "1.0.0"
blake2 = "0.10.0"
bnum = { version = "0.13.0" }
bs58 = "0.5.0"
clap = "4.4.6"
command-fds = "0.3"
console_error_panic_hook = { version = "0.1.6" }
criterion = { version = "0.5", features = [
"cargo_bench_support",
"html_reports",
] }
criterion = { version = "0.5", default-features = false }
#criterion = { version = "0.5", features = [
# "cargo_bench_support",
# "html_reports",
#] }
derivative = { version = "2.0", features = ["use_core"] }
elf = "0.7.2"
env_logger = "0.11.1"
getrandom = { version = "0.2.15", features = ["js"] }
Expand All @@ -61,8 +64,8 @@ libflate = "2"
log = "0.4.20"
num-bigint = { version = "0.4.4", features = ["rand", "serde"] }
num-integer = "0.1.45"
ocaml = { version = "0.22.2" }
ocaml-gen = { version = "1.0.0" }
#ocaml = { version = "0.22.2", optional = true }
#ocaml-gen = { version = "1.0.0", optional = true }
once_cell = "=1.21.3"
os_pipe = { version = "1.1.4", features = ["io_safety"] }
paste = "1.0.15"
Expand Down Expand Up @@ -90,6 +93,7 @@ tikv-jemallocator = { version = "0.5" }
tinytemplate = "1.1"
wasm-bindgen = "=0.2.89"
wasm-bindgen-test = ">=0.3.0"
zeroize = "1.7"

arkworks = { path = "crates/arkworks" }
arrabbiata = { path = "./arrabbiata", version = "0.1.0" }
Expand All @@ -115,6 +119,7 @@ turshi = { path = "./turshi", version = "0.1.0" }
utils = { path = "./utils", version = "0.1.0" }
wasm-types = { path = "./crates/wasm-types" }


[profile.release]
lto = true
panic = 'abort'
Expand Down
10 changes: 8 additions & 2 deletions curves/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,19 @@ license = "Apache-2.0"

[dependencies]
ark-bn254.workspace = true
ark-std.workspace = true
ark-ec.workspace = true
ark-ff.workspace = true
num-bigint.workspace = true
num-integer.workspace = true
bnum.workspace = true
ark-serialize.workspace = true
wasm-bindgen.workspace = true
derivative.workspace = true
zeroize.workspace = true

[dev-dependencies]
rand.workspace = true
ark-test-curves.workspace = true
ark-algebra-test-templates.workspace = true
ark-serialize.workspace = true
ark-std.workspace = true
ark-std.workspace = true
245 changes: 244 additions & 1 deletion curves/src/pasta/curves/pallas.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
use crate::pasta::*;
use crate::pasta::{wasm_friendly::BigInt, *};
use ark_ec::{
models::short_weierstrass::{Affine, Projective, SWCurveConfig},
CurveConfig,
};
use ark_ff::{MontFp, Zero};
use std::marker::PhantomData;

/// G_GENERATOR_X =
/// 1
Expand Down Expand Up @@ -73,3 +74,245 @@ impl SWCurveConfig for LegacyPallasParameters {
}

pub type LegacyPallas = Affine<LegacyPallasParameters>;

////////////////////////////////////////////////////////////////////////////
// WASM experimentation
////////////////////////////////////////////////////////////////////////////

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

impl CurveConfig for WasmPallasParameters {
type BaseField = crate::pasta::wasm_friendly::Fp9;

type ScalarField = crate::pasta::wasm_friendly::Fq9; // FIXME must be Fq9 of course

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

/// COFACTOR_INV = 1
// FIXME
const COFACTOR_INV: crate::pasta::wasm_friendly::Fq9 =
crate::pasta::wasm_friendly::Fp(BigInt::ONE, PhantomData);
}

pub type WasmPallas = Affine<WasmPallasParameters>;

pub type WasmProjectivePallas = Projective<WasmPallasParameters>;

//pub const G_GENERATOR_Y: Fp =
// MontFp!("12418654782883325593414442427049395787963493412651469444558597405572177144507");a
//
// BigInt::from_digits([
// 0x0, 0x1B74B5A3, 0x0A12937C, 0x53DFA9F0, 0x6378EE54, 0x8F655BD4, 0x333D4771, 0x19CF7A23,
// 0xCAED2ABB,
// ]),
pub const G_GENERATOR_Y_WASM: crate::pasta::wasm_friendly::Fp9 = crate::pasta::wasm_friendly::Fp(
BigInt::from_digits(crate::pasta::wasm_friendly::backend9::from_64x4([
0xBBA2DEAC32A7FC19,
0x1774D3334DB556F8,
0x45EE87360F9AFD35,
0xC73921A03A5B47B1,
])),
PhantomData,
);

impl SWCurveConfig for WasmPallasParameters {
const COEFF_A: Self::BaseField = crate::pasta::wasm_friendly::Fp(BigInt::ZERO, PhantomData);

const COEFF_B: Self::BaseField = crate::pasta::wasm_friendly::Fp(BigInt::FIVE, PhantomData);

const GENERATOR: Affine<Self> = Affine::new_unchecked(
crate::pasta::wasm_friendly::Fp(BigInt::ONE, PhantomData),
crate::pasta::wasm_friendly::Fp(BigInt::ZERO, PhantomData),
);
}

#[cfg(test)]
mod tests {
use super::*;

use crate::pasta::{
wasm_friendly::{wasm_fp::FpBackend, Fp9},
Fp,
};

#[test]
pub fn test_wasm_curve_basic_ops() {
// Constants with large bit sizes
let large_a: u32 = 0x1FFFFFFF; // 29 bits (max for a limb)
let large_b: u32 = 0x3FFFFFFF; // 30 bits

// Test Fp9 operations with large numbers
{
// Test conversion between Fp and Fp9 with large numbers
let x: Fp = Fp::from(large_a);
let x_fp9: Fp9 = x.into();
let x_back: Fp = x_fp9.into();
assert_eq!(
x, x_back,
"Conversion between Fp and Fp9 with large numbers failed"
);

// Create Fp9 elements with large components
let a: Fp = Fp::from(large_a);
let b: Fp = Fp::from(large_b);
let a_fp9: Fp9 = a.into();
let b_fp9: Fp9 = b.into();

// Test Fp9 addition with large numbers
let sum_fp9 = a_fp9 + b_fp9;
let expected_sum_fp9: Fp9 = (a + b).into();
assert_eq!(
sum_fp9, expected_sum_fp9,
"Fp9 addition with large numbers failed"
);

// Test Fp9 multiplication with large numbers
let prod_fp9 = a_fp9 * b_fp9;
let expected_prod_fp9: Fp9 = (a * b).into();
assert_eq!(
prod_fp9, expected_prod_fp9,
"Fp9 multiplication with large numbers failed"
);

// Test Fp9 squaring with large numbers
let square_fp9 = a_fp9 * a_fp9;
let expected_square_fp9: Fp9 = (a * a).into();
assert_eq!(
square_fp9, expected_square_fp9,
"Fp9 squaring with large numbers failed"
);
}

// Test consistency between Fp and Fp9 operations with large numbers
{
// Create random large Fp elements
let x: Fp = Fp::from(large_a) * Fp::from(0x12345678u64);
let y: Fp = Fp::from(large_b) * Fp::from(0x87654321u64);

// Compute product in Fp
let z_fp: Fp = x * y;

// Compute product in Fp9 and convert back
let x_fp9: Fp9 = x.into();
let y_fp9: Fp9 = y.into();
let z_fp9: Fp9 = x_fp9 * y_fp9;
let z_fp_from_fp9: Fp = z_fp9.into();

// Results should be equal
assert_eq!(
z_fp, z_fp_from_fp9,
"Inconsistency between Fp and Fp9 multiplication with large numbers"
);

// Test multiple operations in sequence
let result_fp = ((x * y) + x) * y;
let result_fp9: Fp = (((x_fp9 * y_fp9) + x_fp9) * y_fp9).into();
assert_eq!(
result_fp, result_fp9,
"Complex operation sequence inconsistent between Fp and Fp9"
);
}

// Test with numbers that would span multiple limbs
{
// Create Fp9 with non-trivial structure (not just embedding of Fp)
// This would require knowledge of how to construct a general Fp9 element

// For now, test with large random values
let r1: Fp = rand::random();
let r2: Fp = rand::random();

// Ensure these are large values by multiplying with our large constants
let large_r1 = r1 * Fp::from(large_a);
let large_r2 = r2 * Fp::from(large_b);

// Convert to Fp9
let r1_fp9: Fp9 = large_r1.into();
let r2_fp9: Fp9 = large_r2.into();

// Test operations
let sum_fp9 = r1_fp9 + r2_fp9;
let prod_fp9 = r1_fp9 * r2_fp9;

// Verify conversion back
let sum_fp: Fp = sum_fp9.into();
let prod_fp: Fp = prod_fp9.into();

assert_eq!(
sum_fp,
large_r1 + large_r2,
"Sum conversion inconsistent with large numbers"
);
assert_eq!(
prod_fp,
large_r1 * large_r2,
"Product conversion inconsistent with large numbers"
);
}
}

#[test]
pub fn test_naive_wasm_curve_basic_ops() {
{
//let x: Fp = rand::random();
let x: Fp = Fp::from(1u32);
let z: Fp9 = x.into();
let x2: Fp = z.into();
println!("x: {:?}", x);
println!("x limbs: {:?}", x.0 .0);
println!("z: {:?}", z);
println!("z limbs: {:?}", FpBackend::pack(z));
println!("x2: {:?}", x2);
assert!(x2 == x);
}

{
let x: Fp = rand::random();
let y: Fp = rand::random();
let z: Fp = x * y;
}

{
let x: Fp = rand::random();
let y: Fp = rand::random();
let x_fp9: Fp9 = x.into();
let y_fp9: Fp9 = y.into();
}

{
let x: Fp = rand::random();
let y: Fp = rand::random();

let x_fp9: Fp9 = From::from(x);
let y_fp9: Fp9 = From::from(y);
let z_fp9: Fp9 = x_fp9 * y_fp9;
}

{
let x: Fp = rand::random();
let y: Fp = rand::random();
let z: Fp = x * y;
let z: Fp = z * x;
}

{
let x: Fp = rand::random();
let y: Fp = rand::random();
let x_fp9: Fp9 = From::from(x);
let y_fp9: Fp9 = From::from(y);
let z_fp9: Fp9 = x_fp9 * y_fp9;
let z_fp9: Fp9 = z_fp9 * x_fp9;
}

{
let x: Fp = rand::random();
let y: Fp = rand::random();
let z: Fp = x * y;
let z: Fp = z * x;
let z: Fp = z * y;
let z: Fp = z * x;
}
}
}
7 changes: 7 additions & 0 deletions curves/src/pasta/fields/fp.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use super::fft::{FftParameters, Fp256Parameters};
use ark_ff::{
Field,
biginteger::BigInteger256 as BigInteger,
fields::{MontBackend, MontConfig},
Fp256,
Expand Down Expand Up @@ -79,3 +80,9 @@ impl super::fft::FpParameters for FpParameters {
// -(MODULUS^{-1} mod 2^64) mod 2^64
const INV: u64 = 11037532056220336127;
}

impl crate::pasta::wasm_friendly::MinimalField for Fp {
fn square_in_place(&mut self) -> &mut Self {
<Fp as Field>::square_in_place(self)
}
}
8 changes: 7 additions & 1 deletion curves/src/pasta/fields/fq.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use super::fft::{FftParameters, Fp256Parameters, FpParameters};
use ark_ff::{biginteger::BigInteger256 as BigInteger, Fp256};
use ark_ff::{biginteger::BigInteger256 as BigInteger, Fp256, Field};

pub struct FqParameters;

Expand Down Expand Up @@ -78,3 +78,9 @@ impl FpParameters for FqParameters {
// -(MODULUS^{-1} mod 2^64) mod 2^64
const INV: u64 = 10108024940646105087;
}

impl crate::pasta::wasm_friendly::MinimalField for Fq {
fn square_in_place(&mut self) -> &mut Self {
<Fq as Field>::square_in_place(self)
}
}
1 change: 1 addition & 0 deletions curves/src/pasta/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
pub mod curves;
pub mod fields;
pub mod wasm_friendly;

pub use curves::{
pallas::{Pallas, PallasParameters, ProjectivePallas},
Expand Down
Loading
Loading