diff --git a/docs/print.html b/docs/print.html index c42ce7a..e17d68c 100644 --- a/docs/print.html +++ b/docs/print.html @@ -1430,6 +1430,49 @@
Implementation:
+#![allow(unused)] +fn main() { +fn dot<F: Field>(a: &Vec<F>, b: &Vec<F>) -> F { + let mut result = F::zero(); + for (a_i, b_i) in a.iter().zip(b.iter()) { + result = result + a_i.clone() * b_i.clone(); + } + result +} + +#[derive(Debug, Clone)] +pub struct R1CS<F: Field> { + pub left: Vec<Vec<F>>, + pub right: Vec<Vec<F>>, + pub out: Vec<Vec<F>>, + pub m: usize, + pub d: usize, +} + +impl<F: Field> R1CS<F> { + pub fn new(left: Vec<Vec<F>>, right: Vec<Vec<F>>, out: Vec<Vec<F>>) -> Self { + let d = left.len(); + let m = if d == 0 { 0 } else { left[0].len() }; + R1CS { + left, + right, + out, + m, + d, + } + } + + pub fn is_satisfied(&self, a: &Vec<F>) -> bool { + let zero = F::zero(); + self.left + .iter() + .zip(self.right.iter()) + .zip(self.out.iter()) + .all(|((l, r), o)| dot(&l, &a) * dot(&r, &a) - dot(&o, &a) == zero) + } +} +}
Recall that the prover aims to demonstrate knowledge of a witness \(w\) without revealing it. This is equivalent to knowing a vector \(a\) that satisfies \((L \cdot a) \circ (R \cdot a) = O \cdot a\), where \(\circ\) denotes the Hadamard (element-wise) product. However, evaluating this equivalence directly requires \(\Omega(d)\) operations, where \(d\) is the number of rows. To improve efficiency, we can convert this matrix comparison to a polynomial comparison, leveraging the Schwartz-Zippel Lemma, which allows us to check polynomial equality with \(\Omega(1)\) evaluations.
Let's consider a simpler example to illustrate this concept. Suppose we want to test the equivalence \(Av = Bu\), where:
@@ -1480,6 +1523,59 @@#![allow(unused)]
+fn main() {
+#[derive(Debug, Clone)]
+pub struct QAP<'a, F: Field> {
+ pub r1cs: &'a R1CS<F>,
+ pub t: Polynomial<F>,
+}
+
+impl<'a, F: Field> QAP<'a, F> {
+ fn new(r1cs: &'a R1CS<F>) -> Self {
+ QAP {
+ r1cs: r1cs,
+ t: Polynomial::<F>::from_monomials(
+ &(1..=r1cs.d).map(|i| F::from_value(i)).collect::<Vec<F>>(),
+ ),
+ }
+ }
+
+ fn generate_polynomials(&self, a: &Vec<F>) -> (Polynomial<F>, Polynomial<F>, Polynomial<F>) {
+ let left_dot_products = self
+ .r1cs
+ .left
+ .iter()
+ .map(|v| dot(&v, &a))
+ .collect::<Vec<F>>();
+ let right_dot_products = self
+ .r1cs
+ .right
+ .iter()
+ .map(|v| dot(&v, &a))
+ .collect::<Vec<F>>();
+ let out_dot_products = self
+ .r1cs
+ .out
+ .iter()
+ .map(|v| dot(&v, &a))
+ .collect::<Vec<F>>();
+
+ let x = (1..=self.r1cs.m)
+ .map(|i| F::from_value(i))
+ .collect::<Vec<F>>();
+ let left_interpolated_polynomial = Polynomial::<F>::interpolate(&x, &left_dot_products);
+ let right_interpolated_polynomial = Polynomial::<F>::interpolate(&x, &right_dot_products);
+ let out_interpolated_polynomial = Polynomial::<F>::interpolate(&x, &out_dot_products);
+ (
+ left_interpolated_polynomial,
+ right_interpolated_polynomial,
+ out_interpolated_polynomial,
+ )
+ }
+}
+}
Before dealing with all of \(\ell(x)\), \(r(x)\), and \(o(x)\) at once, we design a protocol that allows the Prover \(\mathcal{A}\) to convince the Verifier \(\mathcal{B}\) that \(\mathcal{A}\) knows a specific polynomial. Let's denote this polynomial of degree \(n\) with coefficients in a finite field as:
\begin{equation} diff --git a/docs/searchindex.js b/docs/searchindex.js index fcc0549..f321267 100644 --- a/docs/searchindex.js +++ b/docs/searchindex.js @@ -1 +1 @@ -Object.assign(window.search, {"doc_urls":["index.html#-myzkp-building-zero-knowledge-proof-from-scratch-in-rust","index.html#index","index.html#-code-reference","index.html#--contributions-are-welcome","number_theory/index.html#basics-of-number-theory","number_theory/subsec1.html#computation-rule-and-properties","number_theory/subsec1.html#definition-binary-operation","number_theory/subsec1.html#definition-associative-property","number_theory/subsec1.html#definition-commutative-property","number_theory/subsec2.html#semigroup-group-ring-and-field","number_theory/subsec2.html#definition-semigroup","number_theory/subsec2.html#definition-abelian-semigroup","number_theory/subsec2.html#definition-identity-element","number_theory/subsec2.html#definition-monoid","number_theory/subsec2.html#definition-inverse","number_theory/subsec2.html#definition-group","number_theory/subsec2.html#definition-order-of-a-group","number_theory/subsec2.html#definition-ring","number_theory/subsec2.html#definition-communicative-ring","number_theory/subsec2.html#definition-field","number_theory/subsec2.html#definition-residue-class","number_theory/subsec2.html#definition-inverse-of-residue-class","number_theory/subsec2.html#lemma-221","number_theory/subsec2.html#theorem-222","number_theory/subsec2.html#theorem-bézouts-identity","number_theory/subsec2.html#theorem-223","number_theory/subsec2.html#definition-residue-class-ring","number_theory/subsec2.html#definition-primitive-residue-class","number_theory/subsec2.html#theorem-224","number_theory/subsec2.html#definition-primitive-residue-class-group","number_theory/subsec2.html#definition-eulers-totient-function","number_theory/subsec2.html#definition-order-of-an-element-within-a-group","number_theory/subsec2.html#definition-subgroup","number_theory/subsec2.html#definition-subgroup-generated-by-g","number_theory/subsec2.html#definition-cyclic-group","number_theory/subsec2.html#theorem-225","number_theory/subsec2.html#theorem-226","number_theory/subsec2.html#theorem-fermats-little-theorem","number_theory/subsec2.html#theorem-227","number_theory/subsec2.html#theorem-generalization-of-fermats-little-theorem","number_theory/subsec3.html#polynomials","number_theory/subsec3.html#definition-polynomial","number_theory/subsec3.html#definition-degree","number_theory/subsec3.html#definition-sum-of-polynomials","number_theory/subsec3.html#definition-product-of-polynomials","number_theory/subsec3.html#lemma-231","number_theory/subsec3.html#theorem-232","number_theory/subsec3.html#corollary","number_theory/subsec3.html#theorem-lagrange-interpolation","number_theory/subsec3.html#proposition-homomorphisms-of-lagrange-interpolation","number_theory/subsec4.html#galois-field","number_theory/subsec4.html#definition-irreducible-polynomial","number_theory/subsec4.html#definition-residue-class-modulo-a-polynomial","number_theory/subsec4.html#theorem","number_theory/subsec4.html#lemma-schwartz---zippel-lemma","number_theory/subsec5.html#elliptic-curve","number_theory/subsec5.html#definition-elliptic-curve","number_theory/subsec5.html#definition-mathbbf_p-rational-point","number_theory/subsec5.html#definition-the-point-at-infinity","number_theory/subsec5.html#definition-addition-on-elliptic-curve","number_theory/subsec5.html#definition-mordell-weil-group","number_theory/subsec5.html#definition-group-order","number_theory/subsec5.html#theorem-hasse-weil","number_theory/subsec5.html#definition-point-order","number_theory/subsec5.html#definition-field-extension","number_theory/subsec5.html#definition-algebraic-extension","number_theory/subsec5.html#definition-field-of-rational-functions","number_theory/subsec5.html#definition-coordinate-ring-of-an-elliptic-curve","number_theory/subsec5.html#definition-function-field-of-an-elliptic-curve","number_theory/subsec5.html#definition-zeropole-of-a-function","number_theory/subsec5.html#theorem-degree-genus-formula-for-elliptic-curves","number_theory/subsec5.html#definition-divisor-of-a-function-on-an-elliptic-curve","number_theory/subsec5.html#definition-divisor-on-an-elliptic-curve","number_theory/subsec5.html#definition-degreesum-of-a-divisor","number_theory/subsec5.html#theorem","number_theory/subsec6.html#pairing","number_theory/subsec6.html#definition-pairing","number_theory/subsec6.html#definition-the-weil-pairing","number_theory/subsec6.html#theorem","number_theory/subsec6.html#theorem-millers-algorithm","number_theory/subsec7.html#assumptions","number_theory/subsec7.html#assumption-discrete-logarithm-problem","number_theory/subsec7.html#assumption-elliptic-curve-discrete-logarithm-problem","number_theory/subsec7.html#assumption-knowledge-of-exponent-assumption","zksnark/index.html#basics-of-zk-snark","zksnark/subsec2.html#arithmetization","zksnark/subsec2.html#rank-1-constraint-system-r1cs","zksnark/subsec2.html#definition-r1cs","zksnark/subsec2.html#quadratic-arithmetic-program-qap","zksnark/subsec3.html#proving-single-polynomial","zksnark/subsec3.html#naive-approach","zksnark/subsec3.html#-schwartz-zippel-lemma","zksnark/subsec3.html#-discrete-logarithm-assumption","zksnark/subsec3.html#-knowledge-of-exponent-assumption","zksnark/subsec3.html#-zero-knowledge","zksnark/subsec3.html#-non-interactivity"],"index":{"documentStore":{"docInfo":{"0":{"body":28,"breadcrumbs":8,"title":7},"1":{"body":32,"breadcrumbs":2,"title":1},"10":{"body":43,"breadcrumbs":9,"title":2},"11":{"body":28,"breadcrumbs":10,"title":3},"12":{"body":42,"breadcrumbs":10,"title":3},"13":{"body":33,"breadcrumbs":9,"title":2},"14":{"body":45,"breadcrumbs":9,"title":2},"15":{"body":32,"breadcrumbs":9,"title":2},"16":{"body":20,"breadcrumbs":10,"title":3},"17":{"body":140,"breadcrumbs":9,"title":2},"18":{"body":18,"breadcrumbs":10,"title":3},"19":{"body":43,"breadcrumbs":9,"title":2},"2":{"body":18,"breadcrumbs":3,"title":2},"20":{"body":26,"breadcrumbs":10,"title":3},"21":{"body":39,"breadcrumbs":11,"title":4},"22":{"body":56,"breadcrumbs":9,"title":2},"23":{"body":73,"breadcrumbs":9,"title":2},"24":{"body":84,"breadcrumbs":10,"title":3},"25":{"body":53,"breadcrumbs":9,"title":2},"26":{"body":29,"breadcrumbs":11,"title":4},"27":{"body":17,"breadcrumbs":11,"title":4},"28":{"body":34,"breadcrumbs":9,"title":2},"29":{"body":63,"breadcrumbs":12,"title":5},"3":{"body":8,"breadcrumbs":3,"title":2},"30":{"body":47,"breadcrumbs":11,"title":4},"31":{"body":43,"breadcrumbs":12,"title":5},"32":{"body":53,"breadcrumbs":9,"title":2},"33":{"body":91,"breadcrumbs":11,"title":4},"34":{"body":55,"breadcrumbs":10,"title":3},"35":{"body":44,"breadcrumbs":9,"title":2},"36":{"body":49,"breadcrumbs":9,"title":2},"37":{"body":45,"breadcrumbs":11,"title":4},"38":{"body":34,"breadcrumbs":9,"title":2},"39":{"body":31,"breadcrumbs":12,"title":5},"4":{"body":0,"breadcrumbs":6,"title":3},"40":{"body":0,"breadcrumbs":5,"title":1},"41":{"body":74,"breadcrumbs":6,"title":2},"42":{"body":75,"breadcrumbs":6,"title":2},"43":{"body":76,"breadcrumbs":7,"title":3},"44":{"body":74,"breadcrumbs":7,"title":3},"45":{"body":33,"breadcrumbs":6,"title":2},"46":{"body":125,"breadcrumbs":6,"title":2},"47":{"body":42,"breadcrumbs":5,"title":1},"48":{"body":126,"breadcrumbs":7,"title":3},"49":{"body":98,"breadcrumbs":8,"title":4},"5":{"body":0,"breadcrumbs":9,"title":3},"50":{"body":23,"breadcrumbs":7,"title":2},"51":{"body":39,"breadcrumbs":8,"title":3},"52":{"body":202,"breadcrumbs":10,"title":5},"53":{"body":125,"breadcrumbs":6,"title":1},"54":{"body":71,"breadcrumbs":9,"title":4},"55":{"body":0,"breadcrumbs":7,"title":2},"56":{"body":53,"breadcrumbs":8,"title":3},"57":{"body":48,"breadcrumbs":9,"title":4},"58":{"body":43,"breadcrumbs":8,"title":3},"59":{"body":152,"breadcrumbs":9,"title":4},"6":{"body":38,"breadcrumbs":9,"title":3},"60":{"body":35,"breadcrumbs":9,"title":4},"61":{"body":27,"breadcrumbs":8,"title":3},"62":{"body":46,"breadcrumbs":8,"title":3},"63":{"body":113,"breadcrumbs":8,"title":3},"64":{"body":54,"breadcrumbs":8,"title":3},"65":{"body":59,"breadcrumbs":8,"title":3},"66":{"body":116,"breadcrumbs":9,"title":4},"67":{"body":111,"breadcrumbs":10,"title":5},"68":{"body":47,"breadcrumbs":10,"title":5},"69":{"body":122,"breadcrumbs":8,"title":3},"7":{"body":56,"breadcrumbs":9,"title":3},"70":{"body":49,"breadcrumbs":11,"title":6},"71":{"body":90,"breadcrumbs":10,"title":5},"72":{"body":60,"breadcrumbs":9,"title":4},"73":{"body":69,"breadcrumbs":8,"title":3},"74":{"body":82,"breadcrumbs":6,"title":1},"75":{"body":0,"breadcrumbs":5,"title":1},"76":{"body":83,"breadcrumbs":6,"title":2},"77":{"body":83,"breadcrumbs":7,"title":3},"78":{"body":174,"breadcrumbs":5,"title":1},"79":{"body":187,"breadcrumbs":7,"title":3},"8":{"body":26,"breadcrumbs":9,"title":3},"80":{"body":0,"breadcrumbs":6,"title":1},"81":{"body":51,"breadcrumbs":9,"title":4},"82":{"body":54,"breadcrumbs":11,"title":6},"83":{"body":141,"breadcrumbs":9,"title":4},"84":{"body":0,"breadcrumbs":6,"title":3},"85":{"body":148,"breadcrumbs":5,"title":1},"86":{"body":40,"breadcrumbs":9,"title":5},"87":{"body":618,"breadcrumbs":6,"title":2},"88":{"body":274,"breadcrumbs":8,"title":4},"89":{"body":82,"breadcrumbs":9,"title":3},"9":{"body":0,"breadcrumbs":11,"title":4},"90":{"body":178,"breadcrumbs":8,"title":2},"91":{"body":272,"breadcrumbs":9,"title":3},"92":{"body":390,"breadcrumbs":9,"title":3},"93":{"body":300,"breadcrumbs":9,"title":3},"94":{"body":290,"breadcrumbs":8,"title":2},"95":{"body":363,"breadcrumbs":8,"title":2}},"docs":{"0":{"body":"███╗ ███╗ ██╗ ██╗ ███████╗ ██╗ ██╗ ██████╗ ████╗ ████║ ╚██╗ ██╔╝ ╚══███╔╝ ██║ ██╔╝ ██╔══██╗ ██╔████╔██║ ╚████╔╝ ███╔╝ █████╔╝ ██████╔╝ ██║╚██╔╝██║ ╚██╔╝ ███╔╝ ██╔═██╗ ██╔═══╝ ██║ ╚═╝ ██║ ██║ ███████╗ ██║ ██╗ ██║ ╚═╝ ╚═╝ ╚═╝ ╚══════╝ ╚═╝ ╚═╝ ╚═╝ MyZKP is a Rust implementation of zero-knowledge protocols built entirely from scratch! This project serves as an educational resource for understanding and working with zero-knowledge proofs. ⚠️ Warning: This repository is a work in progress and may contain bugs or inaccuracies. Contributions and feedback are welcome!","breadcrumbs":"Introduction » 🚀 MyZKP: Building Zero Knowledge Proof from Scratch in Rust","id":"0","title":"🚀 MyZKP: Building Zero Knowledge Proof from Scratch in Rust"},"1":{"body":"🧮 Basic of Number Theory 📝 Computation Rule and Properties ⚙️ Semigroup, Group, Ring, and Field 🔢 Polynomials 🌐 Galois Field 📈 Elliptic Curve 🔗 Pairing 🤔 Useful Assumptions 🔒 Basic of zk-SNARKs ⚡ Arithmetization 🛠️ Proving Single Polynomial 🌟 Basic of zk-STARKs ✍️ TBD 💻 Basic of zkVM ✍️ TBD","breadcrumbs":"Introduction » Index","id":"1","title":"Index"},"10":{"body":"A pair \\((H, \\circ)\\), where \\(H\\) is a non-empty set and \\(\\circ\\) is an associative binary operation on \\(H\\), is called a semigroup. Example: The set of positive integers under multiplication modulo \\(n\\) forms a semigroup. For instance, with \\(n = 6\\), the elements \\(\\{1, 2, 3, 4, 5\\}\\) under multiplication modulo 6 form a semigroup, since multiplication modulo 6 is associative.","breadcrumbs":"Basics of Number Theory » Semigroup, Group, Ring, and Field » Definition: Semigroup","id":"10","title":"Definition: Semigroup"},"11":{"body":"A semigroup whose operation is commutative is called an abelian semigroup. Example: The set of natural numbers under addition modulo \\(n\\) forms an abelian semigroup. For \\(n = 7\\), addition modulo 7 is both associative and commutative, so it is an abelian semigroup.","breadcrumbs":"Basics of Number Theory » Semigroup, Group, Ring, and Field » Definition: Abelian Semigroup","id":"11","title":"Definition: Abelian Semigroup"},"12":{"body":"An element \\(e \\in H\\) is an identity element of \\(H\\) if it satisfies \\(e \\circ a = a \\circ e = a\\) for any \\(a \\in H\\). Example: 0 is the identity element for addition modulo \\(n\\). For example, \\(0 + a \\bmod 5 = a + 0 \\bmod 5 = a\\). Similarly, 1 is the identity element for multiplication modulo \\(n\\). For example, \\(1 \\times a \\bmod 7 = a \\times 1 \\bmod 7 = a\\).","breadcrumbs":"Basics of Number Theory » Semigroup, Group, Ring, and Field » Definition: Identity Element","id":"12","title":"Definition: Identity Element"},"13":{"body":"A semigroup with an identity element is called a monoid. Example: The set of non-negative integers under addition modulo \\(n\\) forms a monoid. For \\(n = 5\\), the set \\(\\{0, 1, 2, 3, 4\\}\\) under addition modulo 5 forms a monoid with 0 as the identity element.","breadcrumbs":"Basics of Number Theory » Semigroup, Group, Ring, and Field » Definition: Monoid","id":"13","title":"Definition: Monoid"},"14":{"body":"For an element \\(a \\in H\\), an element \\(b \\in H\\) is an inverse of \\(a\\) if \\(a \\circ b = b \\circ a = e\\), where \\(e\\) is the identity element. Example: In modulo \\(n\\) arithmetic (addition), the inverse of an element exists if it can cancel itself out to yield the identity element. In the set of integers modulo 7, the inverse of 3 is 5, because \\(3 \\times 5 \\bmod 7 = 1\\), where 1 is the identity element for multiplication.","breadcrumbs":"Basics of Number Theory » Semigroup, Group, Ring, and Field » Definition: Inverse","id":"14","title":"Definition: Inverse"},"15":{"body":"A monoid in which every element has an inverse is called a group. Example: The set of integers modulo a prime \\(p\\) under multiplication forms a group (Can you prove it?). For instance, in \\(\\mathbb{Z}/5\\mathbb{Z}\\), every non-zero element \\(\\{1 + 5\\mathbb{Z}, 2 + 5\\mathbb{Z}, 3 + 5\\mathbb{Z}, 4 + 5\\mathbb{Z}\\}\\) has an inverse, making it a group.","breadcrumbs":"Basics of Number Theory » Semigroup, Group, Ring, and Field » Definition: Group","id":"15","title":"Definition: Group"},"16":{"body":"The order of a group is the number of elements in the group. Example: The group of integers modulo 4 under addition has order 4, because the set of elements is \\(\\{0, 1, 2, 3\\}\\).","breadcrumbs":"Basics of Number Theory » Semigroup, Group, Ring, and Field » Definition: Order of a Group","id":"16","title":"Definition: Order of a Group"},"17":{"body":"A triple \\((R, +, \\cdot)\\) is a ring if \\((R, +)\\) is an abelian group, \\((R, \\cdot)\\) is a semigroup, and the distributive property holds: \\(x \\cdot (y + z) = (x \\cdot y) + (x \\cdot z)\\) and \\((x + y) \\cdot z = (x \\cdot z) + (y \\cdot z)\\) for all \\(x, y, z \\in R\\). Example: The set of integers with usual addition and multiplication modulo \\(n\\) forms a ring. For example, in \\(\\mathbb{Z}/6\\mathbb{Z}\\), addition and multiplication modulo 6 form a ring. Implementation: use num_bigint::BigInt;\nuse num_traits::{One, Zero};\nuse std::fmt;\nuse std::ops::{Add, Mul, Neg, Sub}; pub trait Ring: Sized + Clone + PartialEq + fmt::Display + Add