diff --git a/Cargo.toml b/Cargo.toml index 977a81e..0f0bf57 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,6 +7,7 @@ members = [ "[Fel87]feldman-verifiable-secret-sharing", "[Sch91]schnorr-discrete-log-proof-of-knowledge", "[PLO2]plonky2-fibonacci", + "[PLO2]plonky2-factorial", ] resolver = "2" diff --git a/[PLO2]plonky2-factorial/Cargo.toml b/[PLO2]plonky2-factorial/Cargo.toml new file mode 100644 index 0000000..62cc479 --- /dev/null +++ b/[PLO2]plonky2-factorial/Cargo.toml @@ -0,0 +1,7 @@ +[package] +edition = "2021" +name = "plonky2-factorial" +version = "0.1.0" + +[dependencies] +plonky2 = { git = "https://github.com/0xPolygonZero/plonky2" } diff --git a/[PLO2]plonky2-factorial/src/lib.rs b/[PLO2]plonky2-factorial/src/lib.rs new file mode 100644 index 0000000..28ae9f9 --- /dev/null +++ b/[PLO2]plonky2-factorial/src/lib.rs @@ -0,0 +1,52 @@ +#[cfg(test)] +mod tests { + use plonky2::{ + field::types::Field, + iop::witness::{PartialWitness, WitnessWrite}, + plonk::{ + circuit_builder::CircuitBuilder, + circuit_data::CircuitConfig, + config::{GenericConfig, PoseidonGoldilocksConfig}, + }, + }; + + #[test] + fn plonky2_factorial_example() { + // This constant defines the extension that we will + // use. Almost always it is going to be 2 + const D: usize = 2; + + // Generate configuration where we are using Golidilock's + // prime field, it's quadratic extension, Poseidon as the + // hashing function for the merkle tree in FRI stage, and + // the same Poseidon as the hasher for Fiat-Shamir (for + // challenge points generation). See `KeccakGoldilocksCo- + // -nfig`) for when to target Ethereum. + type C = PoseidonGoldilocksConfig; + + // Get the Field type that we are using + type F = >::F; + + let config = CircuitConfig::standard_recursion_config(); + + let mut builder = CircuitBuilder::::new(config); + + let initial = builder.add_virtual_target(); + let mut cur_target = initial; + for i in 2..101 { + let multiplier = builder.constant(F::from_canonical_u32(i)); + let cur_target = builder.mul(cur_target, multiplier); + } + + builder.register_public_input(initial); + builder.register_public_input(cur_target); + + let mut pw = PartialWitness::new(); + pw.set_target(initial, F::ONE); + + let data = builder.build::(); + let proof = data.prove(pw).unwrap(); + + core::assert!(data.verify(proof).is_ok()); + } +}