diff --git a/Cargo.lock b/Cargo.lock index c09ebf212b..8e7a4c094c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1082,6 +1082,7 @@ dependencies = [ "eyre", "goblin", "hex", + "num-bigint-dig", "openvm-build", "openvm-circuit", "openvm-cli-example-test", diff --git a/book/src/custom-extensions/algebra.md b/book/src/custom-extensions/algebra.md index c9a6b32f95..b5b00aea3e 100644 --- a/book/src/custom-extensions/algebra.md +++ b/book/src/custom-extensions/algebra.md @@ -141,3 +141,17 @@ pub fn main() { // Note that these assertions would fail, have we provided the `mod_idx` parameters wrongly. } ``` + +### Config parameters + +For the guest program to build successfully, all used moduli must be declared in the `.toml` config file in the following format: + +```toml +[app_vm_config.modular] +supported_modulus = ["115792089237316195423570985008687907853269984665640564039457584007908834671663"] + +[app_vm_config.fp2] +supported_modulus = ["115792089237316195423570985008687907853269984665640564039457584007908834671663"] +``` + +The `supported_modulus` parameter is a list of moduli that the guest program will use. They must be provided in decimal format in the `.toml` file. \ No newline at end of file diff --git a/crates/cli/Cargo.toml b/crates/cli/Cargo.toml index 759bb9624d..b780ff724f 100644 --- a/crates/cli/Cargo.toml +++ b/crates/cli/Cargo.toml @@ -47,6 +47,7 @@ prettytable-rs = "0.10" textwrap = "0.16.0" ctrlc = "3.4.2" toml = { workspace = true } +num-bigint-dig = { workspace = true, features = ["serde"] } [dev-dependencies] openvm-cli-example-test = { path = "example" } diff --git a/extensions/algebra/circuit/src/fp2_extension.rs b/extensions/algebra/circuit/src/fp2_extension.rs index f6276f0c4f..8942c47867 100644 --- a/extensions/algebra/circuit/src/fp2_extension.rs +++ b/extensions/algebra/circuit/src/fp2_extension.rs @@ -19,10 +19,14 @@ use openvm_stark_backend::p3_field::PrimeField32; use serde::{Deserialize, Serialize}; use strum::EnumCount; -use crate::fp2_chip::{Fp2AddSubChip, Fp2MulDivChip}; +use crate::{ + fp2_chip::{Fp2AddSubChip, Fp2MulDivChip}, + util::deserialize_vec_biguint_from_str, +}; #[derive(Clone, Debug, derive_new::new, Serialize, Deserialize)] pub struct Fp2Extension { + #[serde(deserialize_with = "deserialize_vec_biguint_from_str")] pub supported_modulus: Vec, } diff --git a/extensions/algebra/circuit/src/lib.rs b/extensions/algebra/circuit/src/lib.rs index ffddacc61a..7018513dcf 100644 --- a/extensions/algebra/circuit/src/lib.rs +++ b/extensions/algebra/circuit/src/lib.rs @@ -1,6 +1,8 @@ pub mod fp2_chip; pub mod modular_chip; +mod util; + mod fp2; pub use fp2::*; mod modular_extension; diff --git a/extensions/algebra/circuit/src/modular_extension.rs b/extensions/algebra/circuit/src/modular_extension.rs index 604a1ea8e2..ccce43ada0 100644 --- a/extensions/algebra/circuit/src/modular_extension.rs +++ b/extensions/algebra/circuit/src/modular_extension.rs @@ -20,13 +20,17 @@ use openvm_stark_backend::p3_field::PrimeField32; use serde::{Deserialize, Serialize}; use strum::EnumCount; -use crate::modular_chip::{ - ModularAddSubChip, ModularAddSubCoreChip, ModularIsEqualChip, ModularIsEqualCoreChip, - ModularMulDivChip, ModularMulDivCoreChip, +use crate::{ + modular_chip::{ + ModularAddSubChip, ModularAddSubCoreChip, ModularIsEqualChip, ModularIsEqualCoreChip, + ModularMulDivChip, ModularMulDivCoreChip, + }, + util::deserialize_vec_biguint_from_str, }; #[derive(Clone, Debug, derive_new::new, Serialize, Deserialize)] pub struct ModularExtension { + #[serde(deserialize_with = "deserialize_vec_biguint_from_str")] pub supported_modulus: Vec, } diff --git a/extensions/algebra/circuit/src/util.rs b/extensions/algebra/circuit/src/util.rs new file mode 100644 index 0000000000..54bdba4348 --- /dev/null +++ b/extensions/algebra/circuit/src/util.rs @@ -0,0 +1,16 @@ +use num_bigint_dig::BigUint; +use serde::Deserialize; + +pub(crate) fn deserialize_vec_biguint_from_str<'de, D>( + deserializer: D, +) -> Result, D::Error> +where + D: serde::Deserializer<'de>, +{ + let v: Vec = Deserialize::deserialize(deserializer)?; + let res = v.into_iter().map(|s| s.parse()).collect::>(); + if res.iter().any(|x| x.is_err()) { + return Err(serde::de::Error::custom("Failed to parse BigUint")); + } + Ok(res.into_iter().map(|x| x.unwrap()).collect()) +}