From 050110a4dca43dd3a28e181551e0e73e0e786b7f Mon Sep 17 00:00:00 2001 From: arnaucube Date: Tue, 18 Apr 2023 12:42:54 +0200 Subject: [PATCH] add initial NIFS fold instance & witness --- README.md | 9 ++++++ src/lib.rs | 10 +++++++ src/nifs.rs | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/r1cs.rs | 34 +++++++++++++++++++++++ 4 files changed, 133 insertions(+) create mode 100644 README.md create mode 100644 src/lib.rs create mode 100644 src/nifs.rs create mode 100644 src/r1cs.rs diff --git a/README.md b/README.md new file mode 100644 index 0000000..05edad6 --- /dev/null +++ b/README.md @@ -0,0 +1,9 @@ +# nova-study + +Implementation of [Nova](https://eprint.iacr.org/2021/370.pdf) using [arkworks-rs](https://github.com/arkworks-rs/) just for learning purposes. + +> Warning: Implementation from scratch to learn the internals of Nova. Do not use in production. + +This repo is an ongoing implementation, not to be used but just to understand and experiment with the internals of the scheme and try experimental combinations. + +Thanks to [levs57](https://twitter.com/levs57) for clarifications on the Nova folding. diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..e76e3b9 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,10 @@ +#![allow(non_snake_case)] +#![allow(non_camel_case_types)] +#![allow(non_upper_case_globals)] +#![allow(unused)] // TMP + +mod nifs; +mod pedersen; +mod r1cs; +mod transcript; +mod utils; diff --git a/src/nifs.rs b/src/nifs.rs new file mode 100644 index 0000000..4707e84 --- /dev/null +++ b/src/nifs.rs @@ -0,0 +1,80 @@ +use ark_ec::AffineRepr; +use ark_std::ops::Add; +use std::marker::PhantomData; + +use crate::pedersen::Commitment; +use crate::r1cs::*; +use crate::transcript::Transcript; +use crate::utils::*; + +// Phi: φ in the paper (later 𝖴), a folded instance +pub struct Phi { + cmE: Commitment, + u: C::ScalarField, + cmW: Commitment, + x: Vec, +} + +// FWit: Folded Witness +pub struct FWit { + E: Vec, + rE: C::ScalarField, + W: Vec, + rW: C::ScalarField, +} + +pub struct NIFS { + _phantom: PhantomData, +} + +impl NIFS { + pub fn fold_witness( + r: C::ScalarField, + fw1: FWit, + fw2: FWit, + T: Vec, + ) -> FWit { + let r2 = r * r; + let E: Vec = vec_add( + // TODO this syntax will be simplified with future operators impl + vec_add(fw1.E, vector_elem_product(&T, &r)), + vector_elem_product(&fw2.E, &r2), + ); + let rE = fw1.rE + r * fw2.rE; + let W = vec_add(fw1.W, vector_elem_product(&fw2.W, &r)); + let rW = fw1.rW + r * fw2.rW; + FWit:: { + E: E.into(), + rE, + W: W.into(), + rW, + } + } + + pub fn fold_instance( + r: C::ScalarField, + phi1: Phi, + phi2: Phi, + cmT: Commitment, + ) -> Phi { + let r2 = r * r; + + let cmE = phi1.cmE.cm + cmT.cm.mul(r) + phi2.cmE.cm.mul(r2); + let u = phi1.u + r * phi2.u; + let cmW = phi1.cmW.cm + phi2.cmW.cm.mul(r); + let x = vec_add(phi1.x, vector_elem_product(&phi2.x, &r)); + + Phi:: { + cmE: Commitment:: { + cm: cmE.into(), + r: phi1.cmE.r, + }, + u, + cmW: Commitment:: { + cm: cmW.into(), + r: phi1.cmW.r, + }, + x, + } + } +} diff --git a/src/r1cs.rs b/src/r1cs.rs new file mode 100644 index 0000000..0885c32 --- /dev/null +++ b/src/r1cs.rs @@ -0,0 +1,34 @@ +use crate::pedersen; + +use ark_ff::fields::PrimeField; +use core::ops::Add; + +// this file contains an abstraction of R1CS struct, to later be plugged from arkworks +// ConstraintSystem or something similar. + +pub struct R1CS { + pub A: Vec>, + pub B: Vec>, + pub C: Vec>, +} + +pub struct RelaxedR1CS { + pub ABC: R1CS, + pub u: F, + pub E: F, +} + +impl R1CS { + pub fn relax(self) -> RelaxedR1CS { + RelaxedR1CS:: { + ABC: self, + u: F::one(), + E: F::zero(), + } + } +} +impl RelaxedR1CS { + pub fn fold(self, other: Self, r: F) -> Self { + unimplemented!(); + } +}