From 2e6480a97fb11e29b25f5e808e3d674a10682ed3 Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Wed, 21 Sep 2022 15:41:14 -0700 Subject: [PATCH 01/24] Fibonacci example --- plonky2/examples/fibonacci.rs | 39 +++++++++++++++++++++++++++++++++++ plonky2/src/plonk/verifier.rs | 2 +- 2 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 plonky2/examples/fibonacci.rs diff --git a/plonky2/examples/fibonacci.rs b/plonky2/examples/fibonacci.rs new file mode 100644 index 00000000..4f968178 --- /dev/null +++ b/plonky2/examples/fibonacci.rs @@ -0,0 +1,39 @@ +use anyhow::Result; +use plonky2::iop::witness::PartialWitness; +use plonky2::plonk::circuit_builder::CircuitBuilder; +use plonky2::plonk::circuit_data::CircuitConfig; +use plonky2::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; +use plonky2::field::types::Field; +use plonky2::plonk::verifier::verify; + +fn main() -> Result<()> { + const D: usize = 2; + type C = PoseidonGoldilocksConfig; + type F = >::F; + + let config = CircuitConfig::standard_recursion_config(); + + let pw = PartialWitness::new(); + let mut builder = CircuitBuilder::::new(config); + + let zero_target = builder.zero(); + let one_target = builder.one(); + let mut prev_target = zero_target; + let mut cur_target = one_target; + for _ in 0..99 { + let temp = builder.add(prev_target, cur_target); + prev_target = cur_target; + cur_target = temp; + } + + let fib_100 = F::from_canonical_u64(3736710860384812976); + let fib_100_target = builder.constant(fib_100); + + builder.connect(fib_100_target, cur_target); + + let data = builder.build::(); + + let proof = data.prove(pw)?; + + verify(proof, &data.verifier_only, &data.common) +} diff --git a/plonky2/src/plonk/verifier.rs b/plonky2/src/plonk/verifier.rs index 6a4f3790..5a3f6a94 100644 --- a/plonky2/src/plonk/verifier.rs +++ b/plonky2/src/plonk/verifier.rs @@ -12,7 +12,7 @@ use crate::plonk::validate_shape::validate_proof_with_pis_shape; use crate::plonk::vanishing_poly::eval_vanishing_poly; use crate::plonk::vars::EvaluationVars; -pub(crate) fn verify, C: GenericConfig, const D: usize>( +pub fn verify, C: GenericConfig, const D: usize>( proof_with_pis: ProofWithPublicInputs, verifier_data: &VerifierOnlyCircuitData, common_data: &CommonCircuitData, From 849a89105abe4e52c6b3b1a622c06c8c4fbd5d42 Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Wed, 21 Sep 2022 15:41:21 -0700 Subject: [PATCH 02/24] fmt --- plonky2/examples/fibonacci.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plonky2/examples/fibonacci.rs b/plonky2/examples/fibonacci.rs index 4f968178..90e23295 100644 --- a/plonky2/examples/fibonacci.rs +++ b/plonky2/examples/fibonacci.rs @@ -1,9 +1,9 @@ use anyhow::Result; +use plonky2::field::types::Field; use plonky2::iop::witness::PartialWitness; use plonky2::plonk::circuit_builder::CircuitBuilder; use plonky2::plonk::circuit_data::CircuitConfig; use plonky2::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; -use plonky2::field::types::Field; use plonky2::plonk::verifier::verify; fn main() -> Result<()> { From 556507a9cd0c42e4f641df153f88aba42b75ac3e Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Wed, 21 Sep 2022 16:44:35 -0700 Subject: [PATCH 03/24] public input --- plonky2/examples/fibonacci.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plonky2/examples/fibonacci.rs b/plonky2/examples/fibonacci.rs index 90e23295..ed4610ea 100644 --- a/plonky2/examples/fibonacci.rs +++ b/plonky2/examples/fibonacci.rs @@ -28,6 +28,7 @@ fn main() -> Result<()> { let fib_100 = F::from_canonical_u64(3736710860384812976); let fib_100_target = builder.constant(fib_100); + builder.register_public_input(fib_100_target); builder.connect(fib_100_target, cur_target); @@ -35,5 +36,7 @@ fn main() -> Result<()> { let proof = data.prove(pw)?; + println!("Public inputs: {:?}", proof.clone().public_inputs); + verify(proof, &data.verifier_only, &data.common) } From 9756e06db249b7dac2cc19114c619a623f91210a Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Wed, 21 Sep 2022 16:50:14 -0700 Subject: [PATCH 04/24] reformat --- plonky2/examples/fibonacci.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plonky2/examples/fibonacci.rs b/plonky2/examples/fibonacci.rs index ed4610ea..27399d66 100644 --- a/plonky2/examples/fibonacci.rs +++ b/plonky2/examples/fibonacci.rs @@ -36,7 +36,7 @@ fn main() -> Result<()> { let proof = data.prove(pw)?; - println!("Public inputs: {:?}", proof.clone().public_inputs); + println!("100th Fibonacci number is: {:?}", proof.public_inputs[0]); verify(proof, &data.verifier_only, &data.common) } From 38d6f98f876be5e63ae0e1db8a5c7613e8392145 Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Wed, 21 Sep 2022 19:00:01 -0700 Subject: [PATCH 05/24] fixes, and new examples (fibonacci and square root) --- plonky2/examples/fibonacci.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/plonky2/examples/fibonacci.rs b/plonky2/examples/fibonacci.rs index 27399d66..9a090fc2 100644 --- a/plonky2/examples/fibonacci.rs +++ b/plonky2/examples/fibonacci.rs @@ -16,10 +16,8 @@ fn main() -> Result<()> { let pw = PartialWitness::new(); let mut builder = CircuitBuilder::::new(config); - let zero_target = builder.zero(); - let one_target = builder.one(); - let mut prev_target = zero_target; - let mut cur_target = one_target; + let mut prev_target = builder.zero(); + let mut cur_target = builder.one(); for _ in 0..99 { let temp = builder.add(prev_target, cur_target); prev_target = cur_target; @@ -36,7 +34,10 @@ fn main() -> Result<()> { let proof = data.prove(pw)?; - println!("100th Fibonacci number is: {:?}", proof.public_inputs[0]); + println!( + "100th Fibonacci number (mod |F|) is: {}", + proof.public_inputs[0] + ); verify(proof, &data.verifier_only, &data.common) } From 6d81968bbb0b5b2eb66aab96df467461940af3d2 Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Thu, 22 Sep 2022 06:50:00 -0700 Subject: [PATCH 06/24] use data.verify --- plonky2/examples/fibonacci.rs | 4 +--- plonky2/src/plonk/verifier.rs | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/plonky2/examples/fibonacci.rs b/plonky2/examples/fibonacci.rs index 9a090fc2..aabed559 100644 --- a/plonky2/examples/fibonacci.rs +++ b/plonky2/examples/fibonacci.rs @@ -4,7 +4,6 @@ use plonky2::iop::witness::PartialWitness; use plonky2::plonk::circuit_builder::CircuitBuilder; use plonky2::plonk::circuit_data::CircuitConfig; use plonky2::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; -use plonky2::plonk::verifier::verify; fn main() -> Result<()> { const D: usize = 2; @@ -31,7 +30,6 @@ fn main() -> Result<()> { builder.connect(fib_100_target, cur_target); let data = builder.build::(); - let proof = data.prove(pw)?; println!( @@ -39,5 +37,5 @@ fn main() -> Result<()> { proof.public_inputs[0] ); - verify(proof, &data.verifier_only, &data.common) + data.verify(proof) } diff --git a/plonky2/src/plonk/verifier.rs b/plonky2/src/plonk/verifier.rs index 5a3f6a94..6a4f3790 100644 --- a/plonky2/src/plonk/verifier.rs +++ b/plonky2/src/plonk/verifier.rs @@ -12,7 +12,7 @@ use crate::plonk::validate_shape::validate_proof_with_pis_shape; use crate::plonk::vanishing_poly::eval_vanishing_poly; use crate::plonk::vars::EvaluationVars; -pub fn verify, C: GenericConfig, const D: usize>( +pub(crate) fn verify, C: GenericConfig, const D: usize>( proof_with_pis: ProofWithPublicInputs, verifier_data: &VerifierOnlyCircuitData, common_data: &CommonCircuitData, From 8bd5f43c45f272aeab3e4a54e72a5f5b03c57451 Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Thu, 22 Sep 2022 06:50:50 -0700 Subject: [PATCH 07/24] oops, included other examples --- plonky2/examples/factorial.rs | 36 +++++++++++++++++++++++++++++++++ plonky2/examples/square_root.rs | 35 ++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 plonky2/examples/factorial.rs create mode 100644 plonky2/examples/square_root.rs diff --git a/plonky2/examples/factorial.rs b/plonky2/examples/factorial.rs new file mode 100644 index 00000000..6a2771f2 --- /dev/null +++ b/plonky2/examples/factorial.rs @@ -0,0 +1,36 @@ +use anyhow::Result; +use plonky2::field::types::Field; +use plonky2::iop::witness::PartialWitness; +use plonky2::plonk::circuit_builder::CircuitBuilder; +use plonky2::plonk::circuit_data::CircuitConfig; +use plonky2::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; + +fn main() -> Result<()> { + const D: usize = 2; + type C = PoseidonGoldilocksConfig; + type F = >::F; + + let config = CircuitConfig::standard_recursion_config(); + + let pw = PartialWitness::new(); + let mut builder = CircuitBuilder::::new(config); + + let mut cur_target = builder.one(); + for i in 2..101 { + let i_target = builder.constant(F::from_canonical_u32(i)); + cur_target = builder.mul(cur_target, i_target); + } + + let fact_100 = F::from_canonical_u64(3822706312645553057); + let fact_100_target = builder.constant(fact_100); + builder.register_public_input(fact_100_target); + + builder.connect(fact_100_target, cur_target); + + let data = builder.build::(); + let proof = data.prove(pw)?; + + println!("100 factorial (mod |F|) is: {}", proof.public_inputs[0]); + + data.verify(proof) +} diff --git a/plonky2/examples/square_root.rs b/plonky2/examples/square_root.rs new file mode 100644 index 00000000..3fce9030 --- /dev/null +++ b/plonky2/examples/square_root.rs @@ -0,0 +1,35 @@ +use anyhow::Result; +use plonky2::field::types::Field; +use plonky2::iop::witness::PartialWitness; +use plonky2::plonk::circuit_builder::CircuitBuilder; +use plonky2::plonk::circuit_data::CircuitConfig; +use plonky2::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; + +fn main() -> Result<()> { + const D: usize = 2; + type C = PoseidonGoldilocksConfig; + type F = >::F; + + let config = CircuitConfig::standard_recursion_config(); + + let pw = PartialWitness::new(); + let mut builder = CircuitBuilder::::new(config); + + let x = F::rand(); + let x_squared = x * x; + let x_target = builder.constant(x); + let x_squared_target = builder.constant(x_squared); + + let x_squared_computed = builder.mul(x_target, x_target); + builder.connect(x_squared_target, x_squared_computed); + + builder.register_public_input(x_target); + + let data = builder.build::(); + let proof = data.prove(pw)?; + + println!("Random field element: {}", x_squared); + println!("Its square root: {}", proof.public_inputs[0]); + + data.verify(proof) +} From 0381641b5c6f85c205441d5590152d9d861f1a15 Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Thu, 22 Sep 2022 07:03:24 -0700 Subject: [PATCH 08/24] addressed comments --- plonky2/examples/factorial.rs | 3 +-- plonky2/examples/fibonacci.rs | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/plonky2/examples/factorial.rs b/plonky2/examples/factorial.rs index 6a2771f2..bc30c7c2 100644 --- a/plonky2/examples/factorial.rs +++ b/plonky2/examples/factorial.rs @@ -20,11 +20,10 @@ fn main() -> Result<()> { let i_target = builder.constant(F::from_canonical_u32(i)); cur_target = builder.mul(cur_target, i_target); } + builder.register_public_input(cur_target); let fact_100 = F::from_canonical_u64(3822706312645553057); let fact_100_target = builder.constant(fact_100); - builder.register_public_input(fact_100_target); - builder.connect(fact_100_target, cur_target); let data = builder.build::(); diff --git a/plonky2/examples/fibonacci.rs b/plonky2/examples/fibonacci.rs index aabed559..2f8842e4 100644 --- a/plonky2/examples/fibonacci.rs +++ b/plonky2/examples/fibonacci.rs @@ -22,11 +22,10 @@ fn main() -> Result<()> { prev_target = cur_target; cur_target = temp; } + builder.register_public_input(cur_target); let fib_100 = F::from_canonical_u64(3736710860384812976); let fib_100_target = builder.constant(fib_100); - builder.register_public_input(fib_100_target); - builder.connect(fib_100_target, cur_target); let data = builder.build::(); From 44a1f4c3288a21b0d8d60d457b2794b2894ce024 Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Thu, 22 Sep 2022 09:33:42 -0700 Subject: [PATCH 09/24] no need to hard-code! --- plonky2/examples/factorial.rs | 4 ---- plonky2/examples/fibonacci.rs | 5 ----- 2 files changed, 9 deletions(-) diff --git a/plonky2/examples/factorial.rs b/plonky2/examples/factorial.rs index bc30c7c2..c4de7f65 100644 --- a/plonky2/examples/factorial.rs +++ b/plonky2/examples/factorial.rs @@ -22,10 +22,6 @@ fn main() -> Result<()> { } builder.register_public_input(cur_target); - let fact_100 = F::from_canonical_u64(3822706312645553057); - let fact_100_target = builder.constant(fact_100); - builder.connect(fact_100_target, cur_target); - let data = builder.build::(); let proof = data.prove(pw)?; diff --git a/plonky2/examples/fibonacci.rs b/plonky2/examples/fibonacci.rs index 2f8842e4..bd7e70a0 100644 --- a/plonky2/examples/fibonacci.rs +++ b/plonky2/examples/fibonacci.rs @@ -1,5 +1,4 @@ use anyhow::Result; -use plonky2::field::types::Field; use plonky2::iop::witness::PartialWitness; use plonky2::plonk::circuit_builder::CircuitBuilder; use plonky2::plonk::circuit_data::CircuitConfig; @@ -24,10 +23,6 @@ fn main() -> Result<()> { } builder.register_public_input(cur_target); - let fib_100 = F::from_canonical_u64(3736710860384812976); - let fib_100_target = builder.constant(fib_100); - builder.connect(fib_100_target, cur_target); - let data = builder.build::(); let proof = data.prove(pw)?; From ecdac53960f67ae10e2b464ffd3e675468bb2a5b Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Fri, 23 Sep 2022 09:33:14 -0700 Subject: [PATCH 10/24] fixes to fibonacci and factorial --- plonky2/examples/factorial.rs | 12 ++++++++---- plonky2/examples/fibonacci.rs | 18 +++++++++++++----- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/plonky2/examples/factorial.rs b/plonky2/examples/factorial.rs index c4de7f65..9f292372 100644 --- a/plonky2/examples/factorial.rs +++ b/plonky2/examples/factorial.rs @@ -1,6 +1,6 @@ use anyhow::Result; use plonky2::field::types::Field; -use plonky2::iop::witness::PartialWitness; +use plonky2::iop::witness::{PartialWitness, Witness}; use plonky2::plonk::circuit_builder::CircuitBuilder; use plonky2::plonk::circuit_data::CircuitConfig; use plonky2::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; @@ -12,20 +12,24 @@ fn main() -> Result<()> { let config = CircuitConfig::standard_recursion_config(); - let pw = PartialWitness::new(); let mut builder = CircuitBuilder::::new(config); - let mut cur_target = builder.one(); + let initial = builder.add_virtual_target(); + let mut cur_target = initial; for i in 2..101 { let i_target = builder.constant(F::from_canonical_u32(i)); cur_target = builder.mul(cur_target, i_target); } + 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)?; - println!("100 factorial (mod |F|) is: {}", proof.public_inputs[0]); + println!("100 factorial (mod |F|) is: {}", proof.public_inputs[1]); data.verify(proof) } diff --git a/plonky2/examples/fibonacci.rs b/plonky2/examples/fibonacci.rs index bd7e70a0..d7a47c02 100644 --- a/plonky2/examples/fibonacci.rs +++ b/plonky2/examples/fibonacci.rs @@ -1,5 +1,6 @@ use anyhow::Result; -use plonky2::iop::witness::PartialWitness; +use plonky2::field::types::Field; +use plonky2::iop::witness::{PartialWitness, Witness}; use plonky2::plonk::circuit_builder::CircuitBuilder; use plonky2::plonk::circuit_data::CircuitConfig; use plonky2::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; @@ -11,24 +12,31 @@ fn main() -> Result<()> { let config = CircuitConfig::standard_recursion_config(); - let pw = PartialWitness::new(); let mut builder = CircuitBuilder::::new(config); - let mut prev_target = builder.zero(); - let mut cur_target = builder.one(); + let initial_a = builder.add_virtual_target(); + let initial_b = builder.add_virtual_target(); + let mut prev_target = initial_a; + let mut cur_target = initial_b; for _ in 0..99 { let temp = builder.add(prev_target, cur_target); prev_target = cur_target; cur_target = temp; } + builder.register_public_input(initial_a); + builder.register_public_input(initial_b); builder.register_public_input(cur_target); + let mut pw = PartialWitness::new(); + pw.set_target(initial_a, F::ZERO); + pw.set_target(initial_b, F::ONE); + let data = builder.build::(); let proof = data.prove(pw)?; println!( "100th Fibonacci number (mod |F|) is: {}", - proof.public_inputs[0] + proof.public_inputs[2] ); data.verify(proof) From b271a71a74dd675d9cf42ad7c1b5add331ff6eb9 Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Fri, 23 Sep 2022 11:00:22 -0700 Subject: [PATCH 11/24] square root example: use generator --- plonky2/examples/square_root.rs | 53 ++++++++++++++++++++++++++------- 1 file changed, 43 insertions(+), 10 deletions(-) diff --git a/plonky2/examples/square_root.rs b/plonky2/examples/square_root.rs index 3fce9030..07f1d230 100644 --- a/plonky2/examples/square_root.rs +++ b/plonky2/examples/square_root.rs @@ -1,9 +1,36 @@ +use std::marker::PhantomData; + use anyhow::Result; use plonky2::field::types::Field; -use plonky2::iop::witness::PartialWitness; +use plonky2::hash::hash_types::RichField; +use plonky2::iop::generator::{SimpleGenerator, GeneratedValues}; +use plonky2::iop::target::Target; +use plonky2::iop::witness::{PartialWitness, PartitionWitness, Witness}; use plonky2::plonk::circuit_builder::CircuitBuilder; use plonky2::plonk::circuit_data::CircuitConfig; use plonky2::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; +use plonky2_field::extension::Extendable; + +#[derive(Debug)] +struct SquareGenerator, const D: usize> { + x: Target, + x_squared: Target, + _phantom: PhantomData, +} + +impl, const D: usize> SimpleGenerator for SquareGenerator +{ + fn dependencies(&self) -> Vec { + vec![self.x] + } + + fn run_once(&self, witness: &PartitionWitness, out_buffer: &mut GeneratedValues) { + let x = witness.get_target(self.x); + let x_squared = x * x; + + out_buffer.set_target(self.x_squared, x_squared); + } +} fn main() -> Result<()> { const D: usize = 2; @@ -12,23 +39,29 @@ fn main() -> Result<()> { let config = CircuitConfig::standard_recursion_config(); - let pw = PartialWitness::new(); let mut builder = CircuitBuilder::::new(config); - let x = F::rand(); - let x_squared = x * x; - let x_target = builder.constant(x); - let x_squared_target = builder.constant(x_squared); + let x = builder.add_virtual_target(); + let x_squared = builder.mul(x, x); - let x_squared_computed = builder.mul(x_target, x_target); - builder.connect(x_squared_target, x_squared_computed); + builder.register_public_input(x); + builder.register_public_input(x_squared); - builder.register_public_input(x_target); + builder.add_simple_generator(SquareGenerator:: { + x, + x_squared, + _phantom: PhantomData, + }); + + let x_value = F::rand(); + + let mut pw = PartialWitness::new(); + pw.set_target(x, x_value); let data = builder.build::(); let proof = data.prove(pw)?; - println!("Random field element: {}", x_squared); + println!("Random field element: {}", proof.public_inputs[1]); println!("Its square root: {}", proof.public_inputs[0]); data.verify(proof) From b21883c32152c844472e53d6412d3989c89a31db Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Fri, 23 Sep 2022 11:05:09 -0700 Subject: [PATCH 12/24] fmt --- plonky2/examples/square_root.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/plonky2/examples/square_root.rs b/plonky2/examples/square_root.rs index 07f1d230..86d53271 100644 --- a/plonky2/examples/square_root.rs +++ b/plonky2/examples/square_root.rs @@ -3,7 +3,7 @@ use std::marker::PhantomData; use anyhow::Result; use plonky2::field::types::Field; use plonky2::hash::hash_types::RichField; -use plonky2::iop::generator::{SimpleGenerator, GeneratedValues}; +use plonky2::iop::generator::{GeneratedValues, SimpleGenerator}; use plonky2::iop::target::Target; use plonky2::iop::witness::{PartialWitness, PartitionWitness, Witness}; use plonky2::plonk::circuit_builder::CircuitBuilder; @@ -18,8 +18,7 @@ struct SquareGenerator, const D: usize> { _phantom: PhantomData, } -impl, const D: usize> SimpleGenerator for SquareGenerator -{ +impl, const D: usize> SimpleGenerator for SquareGenerator { fn dependencies(&self) -> Vec { vec![self.x] } From 843baf1aa0c2618c7048413c30867f82675549c5 Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Fri, 23 Sep 2022 15:09:56 -0700 Subject: [PATCH 13/24] documentation --- plonky2/examples/factorial.rs | 7 ++++++- plonky2/examples/fibonacci.rs | 8 +++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/plonky2/examples/factorial.rs b/plonky2/examples/factorial.rs index 9f292372..518532c3 100644 --- a/plonky2/examples/factorial.rs +++ b/plonky2/examples/factorial.rs @@ -5,21 +5,26 @@ use plonky2::plonk::circuit_builder::CircuitBuilder; use plonky2::plonk::circuit_data::CircuitConfig; use plonky2::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; +/// An example of using Plonky2 to prove a statement of the form +/// "I know n * (n + 1) * ... * (n + 99)". +/// When n == 1, this is proving knowledge of 100!. fn main() -> Result<()> { const D: usize = 2; type C = PoseidonGoldilocksConfig; type F = >::F; let config = CircuitConfig::standard_recursion_config(); - let mut builder = CircuitBuilder::::new(config); + // The arithmetic circuit. let initial = builder.add_virtual_target(); let mut cur_target = initial; for i in 2..101 { let i_target = builder.constant(F::from_canonical_u32(i)); cur_target = builder.mul(cur_target, i_target); } + + // Public inputs are the initial value (provided below) and the result (which is generated). builder.register_public_input(initial); builder.register_public_input(cur_target); diff --git a/plonky2/examples/fibonacci.rs b/plonky2/examples/fibonacci.rs index d7a47c02..80bf8d8f 100644 --- a/plonky2/examples/fibonacci.rs +++ b/plonky2/examples/fibonacci.rs @@ -5,15 +5,18 @@ use plonky2::plonk::circuit_builder::CircuitBuilder; use plonky2::plonk::circuit_data::CircuitConfig; use plonky2::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; +/// An example of using Plonky2 to prove a statement of the form +/// "I know the 100th element of the Fibonacci sequence, starting with constants a and b." +/// When a == 0 and b == 1, this is proving knowledge of the 100th (standard) Fibonacci number. fn main() -> Result<()> { const D: usize = 2; type C = PoseidonGoldilocksConfig; type F = >::F; let config = CircuitConfig::standard_recursion_config(); - let mut builder = CircuitBuilder::::new(config); + // The arithmetic circuit. let initial_a = builder.add_virtual_target(); let initial_b = builder.add_virtual_target(); let mut prev_target = initial_a; @@ -23,10 +26,13 @@ fn main() -> Result<()> { prev_target = cur_target; cur_target = temp; } + + // Public inputs are the two initial values (provided below) and the result (which is generated). builder.register_public_input(initial_a); builder.register_public_input(initial_b); builder.register_public_input(cur_target); + // Provide initial values. let mut pw = PartialWitness::new(); pw.set_target(initial_a, F::ZERO); pw.set_target(initial_b, F::ONE); From bda96e84ee599355b239170341ff5c1e97d6f002 Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Fri, 23 Sep 2022 15:10:14 -0700 Subject: [PATCH 14/24] working on SquareRootGenerator instead of SquareGenerator --- plonky2/examples/square_root.rs | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/plonky2/examples/square_root.rs b/plonky2/examples/square_root.rs index 86d53271..0aab8283 100644 --- a/plonky2/examples/square_root.rs +++ b/plonky2/examples/square_root.rs @@ -12,25 +12,27 @@ use plonky2::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; use plonky2_field::extension::Extendable; #[derive(Debug)] -struct SquareGenerator, const D: usize> { +struct SquareRootGenerator, const D: usize> { x: Target, x_squared: Target, _phantom: PhantomData, } -impl, const D: usize> SimpleGenerator for SquareGenerator { +impl, const D: usize> SimpleGenerator for SquareRootGenerator { fn dependencies(&self) -> Vec { - vec![self.x] + vec![self.x_squared] } fn run_once(&self, witness: &PartitionWitness, out_buffer: &mut GeneratedValues) { - let x = witness.get_target(self.x); - let x_squared = x * x; + let x_squared = witness.get_target(self.x); + let s = F::from_canonical_u32(4294967295); + let x = - out_buffer.set_target(self.x_squared, x_squared); + out_buffer.set_target(self.x, x); } } +/// An example of using Plonky2 to prove a statement of the form fn main() -> Result<()> { const D: usize = 2; type C = PoseidonGoldilocksConfig; @@ -46,11 +48,11 @@ fn main() -> Result<()> { builder.register_public_input(x); builder.register_public_input(x_squared); - builder.add_simple_generator(SquareGenerator:: { - x, - x_squared, - _phantom: PhantomData, - }); + // builder.add_simple_generator(SquareGenerator:: { + // x, + // x_squared, + // _phantom: PhantomData, + // }); let x_value = F::rand(); From 880bc87bb13d1efa19506566b88438b7ce3e677b Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Mon, 26 Sep 2022 10:43:18 -0700 Subject: [PATCH 15/24] sqrt --- field/src/goldilocks_field.rs | 55 +++++++++++++++++++++++++++++++++ plonky2/examples/square_root.rs | 30 +++++++++++------- 2 files changed, 73 insertions(+), 12 deletions(-) diff --git a/field/src/goldilocks_field.rs b/field/src/goldilocks_field.rs index c1bb60b0..21235e63 100644 --- a/field/src/goldilocks_field.rs +++ b/field/src/goldilocks_field.rs @@ -280,6 +280,61 @@ impl DivAssign for GoldilocksField { } } +impl GoldilocksField { + pub fn is_quadratic_residue(&self) -> bool { + if self.is_zero() { + return true; + } + // This is based on Euler's criterion. + let power = Self::NEG_ONE.to_canonical_biguint() / 2u8; + let exp = self.exp_biguint(&power); + if exp == Self::ONE { + return true; + } + if exp == Self::NEG_ONE { + return false; + } + panic!("Unreachable") + } + + pub fn sqrt(&self) -> Option { + if self.is_zero() { + Some(*self) + } else if self.is_quadratic_residue() { + let t = (Self::order() - BigUint::from(1u32)) / (BigUint::from(2u32).pow(Self::TWO_ADICITY as u32)); + let mut z = Self::POWER_OF_TWO_GENERATOR.exp_biguint(&t); + let mut w = self.exp_biguint(&((t - BigUint::from(1u32)) / BigUint::from(2u32))); + let mut x = w * *self; + let mut b = x * w; + + let mut v = Self::TWO_ADICITY as usize; + + while !b.is_one() { + let mut k = 0usize; + let mut b2k = b; + while !b2k.is_one() { + b2k = b2k * b2k; + k += 1; + } + let j = v - k - 1; + w = z; + for _ in 0..j { + w = w * w; + } + + z = w * w; + b = b * z; + x = x * w; + v = k; + } + Some(x) + } else { + None + } + } + +} + /// Fast addition modulo ORDER for x86-64. /// This function is marked unsafe for the following reasons: /// - It is only correct if x + y < 2**64 + ORDER = 0x1ffffffff00000001. diff --git a/plonky2/examples/square_root.rs b/plonky2/examples/square_root.rs index 0aab8283..5cbdf02e 100644 --- a/plonky2/examples/square_root.rs +++ b/plonky2/examples/square_root.rs @@ -10,6 +10,7 @@ use plonky2::plonk::circuit_builder::CircuitBuilder; use plonky2::plonk::circuit_data::CircuitConfig; use plonky2::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; use plonky2_field::extension::Extendable; +use plonky2_field::goldilocks_field::GoldilocksField; #[derive(Debug)] struct SquareRootGenerator, const D: usize> { @@ -18,15 +19,14 @@ struct SquareRootGenerator, const D: usize> { _phantom: PhantomData, } -impl, const D: usize> SimpleGenerator for SquareRootGenerator { +impl SimpleGenerator for SquareRootGenerator { fn dependencies(&self) -> Vec { vec![self.x_squared] } - fn run_once(&self, witness: &PartitionWitness, out_buffer: &mut GeneratedValues) { - let x_squared = witness.get_target(self.x); - let s = F::from_canonical_u32(4294967295); - let x = + fn run_once(&self, witness: &PartitionWitness, out_buffer: &mut GeneratedValues) { + let x_squared = witness.get_target(self.x_squared); + let x = x_squared.sqrt().unwrap(); out_buffer.set_target(self.x, x); } @@ -48,16 +48,22 @@ fn main() -> Result<()> { builder.register_public_input(x); builder.register_public_input(x_squared); - // builder.add_simple_generator(SquareGenerator:: { - // x, - // x_squared, - // _phantom: PhantomData, - // }); + builder.add_simple_generator(SquareRootGenerator:: { + x, + x_squared, + _phantom: PhantomData, + }); - let x_value = F::rand(); + let x_squared_value = { + let mut val = F::rand(); + while !val.is_quadratic_residue() { + val = F::rand(); + } + val + }; let mut pw = PartialWitness::new(); - pw.set_target(x, x_value); + pw.set_target(x_squared, x_squared_value); let data = builder.build::(); let proof = data.prove(pw)?; From d239d3ffb56418f5dafecd901dbd75f2e9afb75c Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Mon, 26 Sep 2022 10:44:28 -0700 Subject: [PATCH 16/24] fix --- plonky2/examples/square_root.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/plonky2/examples/square_root.rs b/plonky2/examples/square_root.rs index 5cbdf02e..a19130fa 100644 --- a/plonky2/examples/square_root.rs +++ b/plonky2/examples/square_root.rs @@ -68,8 +68,12 @@ fn main() -> Result<()> { let data = builder.build::(); let proof = data.prove(pw)?; - println!("Random field element: {}", proof.public_inputs[1]); - println!("Its square root: {}", proof.public_inputs[0]); + let x_actual = proof.public_inputs[0]; + let x_squared_actual = proof.public_inputs[1]; + println!("Random field element: {}", x_squared_actual); + println!("Its square root: {}", x_actual); + + assert!(x_actual * x_actual == x_squared_actual); data.verify(proof) } From 59acd9436cd5981fb324b0c26171fc38d46569dd Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Mon, 26 Sep 2022 10:44:51 -0700 Subject: [PATCH 17/24] fmt --- field/src/goldilocks_field.rs | 4 ++-- plonky2/examples/square_root.rs | 6 +++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/field/src/goldilocks_field.rs b/field/src/goldilocks_field.rs index 21235e63..ef9e2c2b 100644 --- a/field/src/goldilocks_field.rs +++ b/field/src/goldilocks_field.rs @@ -301,7 +301,8 @@ impl GoldilocksField { if self.is_zero() { Some(*self) } else if self.is_quadratic_residue() { - let t = (Self::order() - BigUint::from(1u32)) / (BigUint::from(2u32).pow(Self::TWO_ADICITY as u32)); + let t = (Self::order() - BigUint::from(1u32)) + / (BigUint::from(2u32).pow(Self::TWO_ADICITY as u32)); let mut z = Self::POWER_OF_TWO_GENERATOR.exp_biguint(&t); let mut w = self.exp_biguint(&((t - BigUint::from(1u32)) / BigUint::from(2u32))); let mut x = w * *self; @@ -332,7 +333,6 @@ impl GoldilocksField { None } } - } /// Fast addition modulo ORDER for x86-64. diff --git a/plonky2/examples/square_root.rs b/plonky2/examples/square_root.rs index a19130fa..4e1a37d7 100644 --- a/plonky2/examples/square_root.rs +++ b/plonky2/examples/square_root.rs @@ -24,7 +24,11 @@ impl SimpleGenerator for SquareRootGenerator, out_buffer: &mut GeneratedValues) { + fn run_once( + &self, + witness: &PartitionWitness, + out_buffer: &mut GeneratedValues, + ) { let x_squared = witness.get_target(self.x_squared); let x = x_squared.sqrt().unwrap(); From 4668e8c5f8dac8bd6a4d5f2594cb9ccdc3252a62 Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Mon, 26 Sep 2022 10:45:20 -0700 Subject: [PATCH 18/24] clippy --- field/src/goldilocks_field.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/field/src/goldilocks_field.rs b/field/src/goldilocks_field.rs index ef9e2c2b..65315a01 100644 --- a/field/src/goldilocks_field.rs +++ b/field/src/goldilocks_field.rs @@ -324,8 +324,8 @@ impl GoldilocksField { } z = w * w; - b = b * z; - x = x * w; + b *= z; + x *= w; v = k; } Some(x) From 3bc1e65a7abfa2dd3c54c4048698b562c7e4746f Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Mon, 26 Sep 2022 11:11:41 -0700 Subject: [PATCH 19/24] fix --- field/src/goldilocks_field.rs | 2 +- plonky2/examples/square_root.rs | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/field/src/goldilocks_field.rs b/field/src/goldilocks_field.rs index 65315a01..537b1f11 100644 --- a/field/src/goldilocks_field.rs +++ b/field/src/goldilocks_field.rs @@ -303,7 +303,7 @@ impl GoldilocksField { } else if self.is_quadratic_residue() { let t = (Self::order() - BigUint::from(1u32)) / (BigUint::from(2u32).pow(Self::TWO_ADICITY as u32)); - let mut z = Self::POWER_OF_TWO_GENERATOR.exp_biguint(&t); + let mut z = Self::MULTIPLICATIVE_GROUP_GENERATOR.exp_biguint(&t); let mut w = self.exp_biguint(&((t - BigUint::from(1u32)) / BigUint::from(2u32))); let mut x = w * *self; let mut b = x * w; diff --git a/plonky2/examples/square_root.rs b/plonky2/examples/square_root.rs index 4e1a37d7..b20bf8e6 100644 --- a/plonky2/examples/square_root.rs +++ b/plonky2/examples/square_root.rs @@ -30,7 +30,9 @@ impl SimpleGenerator for SquareRootGenerator, ) { let x_squared = witness.get_target(self.x_squared); + dbg!(x_squared); let x = x_squared.sqrt().unwrap(); + dbg!(x); out_buffer.set_target(self.x, x); } From a053372176cc83c804fa9af6b44cc189808a7ecd Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Mon, 26 Sep 2022 11:19:09 -0700 Subject: [PATCH 20/24] cleanup and documentation --- field/src/goldilocks_field.rs | 2 +- plonky2/examples/square_root.rs | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/field/src/goldilocks_field.rs b/field/src/goldilocks_field.rs index 537b1f11..28d17a05 100644 --- a/field/src/goldilocks_field.rs +++ b/field/src/goldilocks_field.rs @@ -303,7 +303,7 @@ impl GoldilocksField { } else if self.is_quadratic_residue() { let t = (Self::order() - BigUint::from(1u32)) / (BigUint::from(2u32).pow(Self::TWO_ADICITY as u32)); - let mut z = Self::MULTIPLICATIVE_GROUP_GENERATOR.exp_biguint(&t); + let mut z = Self::POWER_OF_TWO_GENERATOR; let mut w = self.exp_biguint(&((t - BigUint::from(1u32)) / BigUint::from(2u32))); let mut x = w * *self; let mut b = x * w; diff --git a/plonky2/examples/square_root.rs b/plonky2/examples/square_root.rs index b20bf8e6..230b33aa 100644 --- a/plonky2/examples/square_root.rs +++ b/plonky2/examples/square_root.rs @@ -19,6 +19,8 @@ struct SquareRootGenerator, const D: usize> { _phantom: PhantomData, } +// We implement specifically for the Goldilocks field because it's currently the only field with +// the sqrt() function written. impl SimpleGenerator for SquareRootGenerator { fn dependencies(&self) -> Vec { vec![self.x_squared] @@ -30,15 +32,14 @@ impl SimpleGenerator for SquareRootGenerator, ) { let x_squared = witness.get_target(self.x_squared); - dbg!(x_squared); let x = x_squared.sqrt().unwrap(); - dbg!(x); out_buffer.set_target(self.x, x); } } /// An example of using Plonky2 to prove a statement of the form +/// "I know the square root of this field element." fn main() -> Result<()> { const D: usize = 2; type C = PoseidonGoldilocksConfig; From 33d97eff1cac1e6286662a7983c7f77be96e532c Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Mon, 26 Sep 2022 11:31:11 -0700 Subject: [PATCH 21/24] moved sqrt to PrimeField --- field/src/goldilocks_field.rs | 55 --------------------------------- field/src/types.rs | 53 +++++++++++++++++++++++++++++++ plonky2/examples/square_root.rs | 15 +++------ 3 files changed, 58 insertions(+), 65 deletions(-) diff --git a/field/src/goldilocks_field.rs b/field/src/goldilocks_field.rs index 28d17a05..c1bb60b0 100644 --- a/field/src/goldilocks_field.rs +++ b/field/src/goldilocks_field.rs @@ -280,61 +280,6 @@ impl DivAssign for GoldilocksField { } } -impl GoldilocksField { - pub fn is_quadratic_residue(&self) -> bool { - if self.is_zero() { - return true; - } - // This is based on Euler's criterion. - let power = Self::NEG_ONE.to_canonical_biguint() / 2u8; - let exp = self.exp_biguint(&power); - if exp == Self::ONE { - return true; - } - if exp == Self::NEG_ONE { - return false; - } - panic!("Unreachable") - } - - pub fn sqrt(&self) -> Option { - if self.is_zero() { - Some(*self) - } else if self.is_quadratic_residue() { - let t = (Self::order() - BigUint::from(1u32)) - / (BigUint::from(2u32).pow(Self::TWO_ADICITY as u32)); - let mut z = Self::POWER_OF_TWO_GENERATOR; - let mut w = self.exp_biguint(&((t - BigUint::from(1u32)) / BigUint::from(2u32))); - let mut x = w * *self; - let mut b = x * w; - - let mut v = Self::TWO_ADICITY as usize; - - while !b.is_one() { - let mut k = 0usize; - let mut b2k = b; - while !b2k.is_one() { - b2k = b2k * b2k; - k += 1; - } - let j = v - k - 1; - w = z; - for _ in 0..j { - w = w * w; - } - - z = w * w; - b *= z; - x *= w; - v = k; - } - Some(x) - } else { - None - } - } -} - /// Fast addition modulo ORDER for x86-64. /// This function is marked unsafe for the following reasons: /// - It is only correct if x + y < 2**64 + ORDER = 0x1ffffffff00000001. diff --git a/field/src/types.rs b/field/src/types.rs index ac94bcfa..7130b7f5 100644 --- a/field/src/types.rs +++ b/field/src/types.rs @@ -427,6 +427,59 @@ pub trait Field: pub trait PrimeField: Field { fn to_canonical_biguint(&self) -> BigUint; + + fn is_quadratic_residue(&self) -> bool { + if self.is_zero() { + return true; + } + // This is based on Euler's criterion. + let power = Self::NEG_ONE.to_canonical_biguint() / 2u8; + let exp = self.exp_biguint(&power); + if exp == Self::ONE { + return true; + } + if exp == Self::NEG_ONE { + return false; + } + panic!("Unreachable") + } + + fn sqrt(&self) -> Option { + if self.is_zero() { + Some(*self) + } else if self.is_quadratic_residue() { + let t = (Self::order() - BigUint::from(1u32)) + / (BigUint::from(2u32).pow(Self::TWO_ADICITY as u32)); + let mut z = Self::POWER_OF_TWO_GENERATOR; + let mut w = self.exp_biguint(&((t - BigUint::from(1u32)) / BigUint::from(2u32))); + let mut x = w * *self; + let mut b = x * w; + + let mut v = Self::TWO_ADICITY as usize; + + while !b.is_one() { + let mut k = 0usize; + let mut b2k = b; + while !b2k.is_one() { + b2k = b2k * b2k; + k += 1; + } + let j = v - k - 1; + w = z; + for _ in 0..j { + w = w * w; + } + + z = w * w; + b *= z; + x *= w; + v = k; + } + Some(x) + } else { + None + } + } } /// A finite field of order less than 2^64. diff --git a/plonky2/examples/square_root.rs b/plonky2/examples/square_root.rs index 230b33aa..d8b3bd69 100644 --- a/plonky2/examples/square_root.rs +++ b/plonky2/examples/square_root.rs @@ -1,7 +1,7 @@ use std::marker::PhantomData; use anyhow::Result; -use plonky2::field::types::Field; +use plonky2::field::types::{Field, PrimeField}; use plonky2::hash::hash_types::RichField; use plonky2::iop::generator::{GeneratedValues, SimpleGenerator}; use plonky2::iop::target::Target; @@ -10,7 +10,6 @@ use plonky2::plonk::circuit_builder::CircuitBuilder; use plonky2::plonk::circuit_data::CircuitConfig; use plonky2::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; use plonky2_field::extension::Extendable; -use plonky2_field::goldilocks_field::GoldilocksField; #[derive(Debug)] struct SquareRootGenerator, const D: usize> { @@ -19,18 +18,14 @@ struct SquareRootGenerator, const D: usize> { _phantom: PhantomData, } -// We implement specifically for the Goldilocks field because it's currently the only field with -// the sqrt() function written. -impl SimpleGenerator for SquareRootGenerator { +impl, const D: usize> SimpleGenerator + for SquareRootGenerator +{ fn dependencies(&self) -> Vec { vec![self.x_squared] } - fn run_once( - &self, - witness: &PartitionWitness, - out_buffer: &mut GeneratedValues, - ) { + fn run_once(&self, witness: &PartitionWitness, out_buffer: &mut GeneratedValues) { let x_squared = witness.get_target(self.x_squared); let x = x_squared.sqrt().unwrap(); From 20053ac4c70bf52f926f3628958b6144219fc3f0 Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Mon, 26 Sep 2022 15:58:28 -0700 Subject: [PATCH 22/24] documentation --- plonky2/examples/square_root.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plonky2/examples/square_root.rs b/plonky2/examples/square_root.rs index d8b3bd69..98ddc4e9 100644 --- a/plonky2/examples/square_root.rs +++ b/plonky2/examples/square_root.rs @@ -11,6 +11,8 @@ use plonky2::plonk::circuit_data::CircuitConfig; use plonky2::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; use plonky2_field::extension::Extendable; +/// A generator used by the prover to calculate the square root (`x`) of a given value +/// (`x_squared`), outside of the circuit, in order to supply it as an additional public input. #[derive(Debug)] struct SquareRootGenerator, const D: usize> { x: Target, @@ -56,6 +58,7 @@ fn main() -> Result<()> { _phantom: PhantomData, }); + // Randomly generate the value of x^2: any quadratic residue in the field works. let x_squared_value = { let mut val = F::rand(); while !val.is_quadratic_residue() { From 7d7269b26dae9736fd3a69b1719e69e9dc3b0973 Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Mon, 26 Sep 2022 16:17:04 -0700 Subject: [PATCH 23/24] nit --- plonky2/examples/square_root.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plonky2/examples/square_root.rs b/plonky2/examples/square_root.rs index 98ddc4e9..81216905 100644 --- a/plonky2/examples/square_root.rs +++ b/plonky2/examples/square_root.rs @@ -47,7 +47,7 @@ fn main() -> Result<()> { let mut builder = CircuitBuilder::::new(config); let x = builder.add_virtual_target(); - let x_squared = builder.mul(x, x); + let x_squared = builder.square(x); builder.register_public_input(x); builder.register_public_input(x_squared); From e2811550e13852bbf4c37a8c7dc01b253f405ffa Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Mon, 26 Sep 2022 20:34:17 -0700 Subject: [PATCH 24/24] addressed comments --- plonky2/examples/factorial.rs | 5 ++++- plonky2/examples/fibonacci.rs | 4 ++-- plonky2/examples/square_root.rs | 13 +++++-------- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/plonky2/examples/factorial.rs b/plonky2/examples/factorial.rs index 518532c3..bcdb35dc 100644 --- a/plonky2/examples/factorial.rs +++ b/plonky2/examples/factorial.rs @@ -34,7 +34,10 @@ fn main() -> Result<()> { let data = builder.build::(); let proof = data.prove(pw)?; - println!("100 factorial (mod |F|) is: {}", proof.public_inputs[1]); + println!( + "Factorial starting at {} is {}!", + proof.public_inputs[0], proof.public_inputs[1] + ); data.verify(proof) } diff --git a/plonky2/examples/fibonacci.rs b/plonky2/examples/fibonacci.rs index 80bf8d8f..6609fc1d 100644 --- a/plonky2/examples/fibonacci.rs +++ b/plonky2/examples/fibonacci.rs @@ -41,8 +41,8 @@ fn main() -> Result<()> { let proof = data.prove(pw)?; println!( - "100th Fibonacci number (mod |F|) is: {}", - proof.public_inputs[2] + "100th Fibonacci number mod |F| (starting with {}, {}) is: {}", + proof.public_inputs[0], proof.public_inputs[1], proof.public_inputs[2] ); data.verify(proof) diff --git a/plonky2/examples/square_root.rs b/plonky2/examples/square_root.rs index 81216905..0bc89f47 100644 --- a/plonky2/examples/square_root.rs +++ b/plonky2/examples/square_root.rs @@ -31,6 +31,8 @@ impl, const D: usize> SimpleGenerator let x_squared = witness.get_target(self.x_squared); let x = x_squared.sqrt().unwrap(); + println!("Square root: {}", x); + out_buffer.set_target(self.x, x); } } @@ -49,7 +51,6 @@ fn main() -> Result<()> { let x = builder.add_virtual_target(); let x_squared = builder.square(x); - builder.register_public_input(x); builder.register_public_input(x_squared); builder.add_simple_generator(SquareRootGenerator:: { @@ -71,14 +72,10 @@ fn main() -> Result<()> { pw.set_target(x_squared, x_squared_value); let data = builder.build::(); - let proof = data.prove(pw)?; + let proof = data.prove(pw.clone())?; - let x_actual = proof.public_inputs[0]; - let x_squared_actual = proof.public_inputs[1]; - println!("Random field element: {}", x_squared_actual); - println!("Its square root: {}", x_actual); - - assert!(x_actual * x_actual == x_squared_actual); + let x_squared_actual = proof.public_inputs[0]; + println!("Field element (square): {}", x_squared_actual); data.verify(proof) }