Skip to content

Commit 3b0450f

Browse files
diegokingstonjotabulaciosOppen
authored
Update docs (#986)
* fix readme link * add new references * update readme for polynomials * add readmes and links * add readme for cFFT * improve readme * add fiat-shamir * add info for hash * add example starks * polish readme * example folder * explain more starks * add example * fix typo * fix links * change to relative path * add application * add reference * add readme for msm * Update crates/math/src/polynomial/README.md Co-authored-by: Mario Rugiero <[email protected]> --------- Co-authored-by: jotabulacios <[email protected]> Co-authored-by: Mario Rugiero <[email protected]>
1 parent bded134 commit 3b0450f

File tree

12 files changed

+418
-9
lines changed

12 files changed

+418
-9
lines changed

Diff for: README.md

+7-3
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,11 @@ Below is a list of examples to understand lambdaworks and learn what you can bui
2424
- [Shamir's secret sharing](./examples/shamir_secret_sharing/)
2525
- [BabySNARK](./examples/baby-snark/)
2626
- [Pinocchio](./examples/pinocchio/)
27-
- [Using Circom with lambdaworks's Groth16](./provers/groth16/circom-adapter/src/README.md)
27+
- [Using Circom with lambdaworks's Groth16](./examples/prove-verify-circom/circom_lambdaworks_tutorial.md)
2828
- [Proving Fibonacci using Circom and lambdaworks](./examples/prove-verify-circom/circom_lambdaworks_tutorial.md)
2929

30-
- You can use Circom to generate circuits and use lambdaworks's capabilities to prove the execution with [Groth16](./provers/groth16/README.md).
31-
- You can use the [Stark prover](./provers/stark/src/) to define an algebraic intermediate representation (AIR) and prove the execution of a program
30+
- You can use Circom to generate circuits and use lambdaworks's capabilities to prove the execution with [Groth16](./crates/provers/groth16/README.md).
31+
- You can use the [Stark prover](./crates/provers/stark/README.md) to define an algebraic intermediate representation (AIR) and prove the execution of a program
3232

3333
## Why we built lambdaworks
3434

@@ -215,6 +215,10 @@ The following links, repos, companies and projects have been important in the de
215215
- [Gnark](https://github.com/Consensys/gnark)
216216
- [Constantine](https://github.com/mratsim/constantine)
217217
- [Plonky3](https://github.com/Plonky3/Plonky3)
218+
- [Stwo](https://github.com/starkware-libs/stwo/tree/dev)
219+
- [Binius](https://gitlab.com/IrreducibleOSS/binius)
220+
- [Zorch](https://github.com/vbuterin/zorch/tree/main)
221+
- [Jolt](https://github.com/a16z/jolt)
218222

219223
# Security
220224

Diff for: crates/crypto/README.md

+7
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,10 @@ This crate contains different cryptographic primitives needed for proof systems.
1818
- [Hash functions](./src/hash/)
1919
- [Fiat Shamir transformation](./src/fiat_shamir/)
2020
- [Polynomial commitment schemes](./src/commitments/)
21+
22+
For examples on:
23+
- How do Merkle trees work, refer to [Merkle CLI](../../examples/merkle-tree-cli/README.md)
24+
- Hash functions, refer to [Hash functions' readme](./src/hash/README.md)
25+
- Fiat-Shamir heuristic, refer to [Fiat-Shamir's readme](./src/fiat_shamir/README.md)
26+
- Polynomial commitment schemes, refer to [PCS's readme](./src/commitments/README.md)
27+

Diff for: crates/crypto/src/fiat_shamir/README.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Fiat-Shamir
2+
3+
This contains the basic functionality to implement the [Fiat-Shamir heuristic](https://en.wikipedia.org/wiki/Fiat%E2%80%93Shamir_heuristic) ([see also](https://link.springer.com/chapter/10.1007/3-540-47721-7_12)).
4+
5+
The transcript should be able to accept bytes or field elements and should output random challenges (field elements) from a uniform distribution.

Diff for: crates/crypto/src/hash/README.md

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Hash functions
2+
3+
This folder contains hash functions that are typically used in non-interactive proof systems. The hash functions we have implemented are:
4+
- [Monolith](./monolith/mod.rs)
5+
- [Poseidon](./poseidon/)
6+
- [Pedersen](./pedersen/)
7+
- [Rescue Prime](./rescue_prime/)
8+
9+
Pedersen is based on elliptic curves, while [Monolith](https://eprint.iacr.org/2023/1025), [Poseidon](https://eprint.iacr.org/2019/458.pdf) and [Rescue Prime](https://eprint.iacr.org/2020/1143) are algebraic hash functions.
10+
11+
For an introduction to hash functions, see [this intro](https://blog.alignedlayer.com/introduction-hash-functions-in-cryptography/) and [its follow-up](https://blog.alignedlayer.com/design-strategies-how-to-construct-a-hashing-mode-2/).

Diff for: crates/math/README.md

+2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ This crate contains all the relevant mathematical building blocks needed for pro
1616
- [Finite Fields](./src/field/README.md)
1717
- [Elliptic curves](./src/elliptic_curve/README.md)
1818
- [Polynomials - univariate and multivariate](./src/polynomial/README.md)
19+
- [CircleFFT](./src/circle/README.md)
1920
- [Large unsigned integers](./src/unsigned_integer/)
2021
- [Fast Fourier Transform](./src/fft/README.md)
2122
- [Optimized Multiscalar Multiplication](./src/msm/)
23+
- [Cyclic Group](./src/cyclic_group.rs)

Diff for: crates/math/src/circle/README.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Circle Fast-Fourier Transform (CircleFFT)
2+
3+
This folder contains all the necessary tools to work with the [circle FFT](https://eprint.iacr.org/2024/278), which is a suitable way of performing an analogue of the [radix-2 FFT algorithm](../fft/README.md) over fields which are not smooth. We say a finite field is smooth if the size of multiplicative group of the field is divisible by a sufficiently high power of 2. In the case of $\mathbb{Z}_p$, the previous sentence indicates that $p - 1 = 2^m c$, where $m$ is sufficiently large (for example, $2^{25}$), ensuring we can use the radix-2 Cooley-Tuckey algorithm for the FFT with vectors of size up to $2^{25}$.
4+
5+
For an introduction to circle STARKs, we recommend [our blog](https://blog.lambdaclass.com/an-introduction-to-circle-starks/) or [Vitalik's explanation](https://vitalik.eth.limo/general/2024/07/23/circlestarks.html).

Diff for: crates/math/src/elliptic_curve/README.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ let y = g2_affine.y();
118118

119119
One common operation for different proof systems is the Mutiscalar Multiplication (MSM), which is given by a set of points $P_0 , P_1 , P_2 , ... , P_n$ and scalars $a_0 , a_1 , a_2 ... n_n$ (the scalars belong to the scalar field of the elliptic curve, which is the field whose size matches the size of the elliptic curve's group):
120120
$$R = \sum_k a_k P_k$$
121-
This operation could be implemented by using `operate_with_self` with each point and scalar and then add the results using `operate_with`, but this is not efficient. lambdaworks provides an optimized [MSM using Pippenger's algorithm](https://github.com/lambdaclass/lambdaworks/blob/main/math/src/msm/pippenger.rs). A naïve version is given [here](https://github.com/lambdaclass/lambdaworks/blob/main/math/src/msm/naive.rs). Below we show how to use MSM in the context of a polynomial commitment scheme: the scalars are the coefficients of the polynomials and the points are provided by an SRS.
121+
This operation could be implemented by using `operate_with_self` with each point and scalar and then add the results using `operate_with`, but this is not efficient. lambdaworks provides an optimized [MSM using Pippenger's algorithm](../msm/pippenger.rs). A naïve version is given [here](../msm/naive.rs). Below we show how to use MSM in the context of a polynomial commitment scheme: the scalars are the coefficients of the polynomials and the points are provided by an SRS.
122122
```rust
123123
fn commit(&self, p: &Polynomial<FieldElement<F>>) -> Self::Commitment {
124124
let coefficients: Vec<_> = p
@@ -158,6 +158,8 @@ This allows us to reduce the amount of information we send to define a unique po
158158

159159
In many curves, the base field contains some spare bits (as is the case of BLS12-381 or BN254, but not secp256k1), which allows us to codify the extra bit into the free bits of the element. Depending on the number of spare bits, we could compress points in different ways.
160160

161+
Pairings and elliptic curve point compression and decompression are needed for [BLS signatures](https://www.ietf.org/archive/id/draft-irtf-cfrg-bls-signature-05.html) and in [EIP-4844](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-4844.md).
162+
161163
## References
162164

163165
- [HyperElliptic - formulae for EC addition and doubling](https://hyperelliptic.org/EFD/g1p/index.html)

Diff for: crates/math/src/fft/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# lambdaworks Fast Fourier Transform
22

3-
This folder contains the [fast Fourier transform](https://en.wikipedia.org/wiki/Fast_Fourier_transform) (FFT) over finite fields (also known as number theoretic transform, NTT). If you are unfamiliar with how lambdaworks handles fields, see [examples](https://github.com/lambdaclass/lambdaworks/blob/main/examples/README.md). Currently, the following algorithms are supported:
3+
This folder contains the [fast Fourier transform](https://en.wikipedia.org/wiki/Fast_Fourier_transform) (FFT) over finite fields (also known as number theoretic transform, NTT). If you are unfamiliar with how lambdaworks handles fields, see [examples](../../../../examples/README.md). Currently, the following algorithms are supported:
44
- Cooley-Tukey Radix-2
55
- Cooley-Tukey Radix-4
66

Diff for: crates/math/src/field/README.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -368,4 +368,5 @@ This defines a 6th degree extension over the scalar field of BLS12-381. We only
368368
- [High-Speed Algorithms & Architectures For Number-Theoretic Cryptosystems](https://www.microsoft.com/en-us/research/wp-content/uploads/1998/06/97Acar.pdf)
369369
- [Developer math survival kit](https://blog.lambdaclass.com/math-survival-kit-for-developers/)
370370
- [Montgomery Arithmetic from a Software Perspective](https://eprint.iacr.org/2017/1057.pdf)
371-
- [Guajardo, Kumar, Paar, Perzl - Efficient software implementation of finite fields with applications to Cryptography](https://www.sandeep.de/my/papers/2006_ActaApplMath_EfficientSoftFiniteF.pdf)
371+
- [Guajardo, Kumar, Paar, Perzl - Efficient software implementation of finite fields with applications to Cryptography](https://www.sandeep.de/my/papers/2006_ActaApplMath_EfficientSoftFiniteF.pdf)
372+
- [Ingonyama - Montgomery-Barrett duality](https://hackmd.io/@Ingonyama/Barret-Montgomery)

Diff for: crates/math/src/msm/README.md

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# lambdaworks MultiScalar Multiplication (MSM)
2+
3+
This contains implementations for the MultiScalar Multiplication (MSM):
4+
- Naïve
5+
- Pippenger
6+
7+
[Multiscalar multiplication](https://blog.lambdaclass.com/multiscalar-multiplication-strategies-and-challenges/) is an important primitive that appears in some polynomial commitment schemes and proof systems. It is also at the core of [EIP-4844](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-4844.md). Given a set of scalars in a [finite field](../field/README.md) $a_0, a_1, ..., a_n$ and [elliptic curve points](../elliptic_curve/README.md) $P_0, P_1, ... , P_n$, the MSM computes
8+
$$P = \sum_k a_k P_k$$
9+
where $a_k P_k$ is understood as applying the group operation with $P_k$ a number of $a_k$ times. For its application in a protocol, see [KZG](../../../crypto/src/commitments/README.md)

Diff for: crates/math/src/polynomial/README.md

+63
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,66 @@ let p = Polynomial::interpolate(&[FE::new(0), FE::new(1)], &[FE::new(2), FE::new
6666
```
6767

6868
Many polynomial operations can go faster by using the [Fast Fourier Transform](../fft/polynomial.rs).
69+
70+
## Multilinear polynomials
71+
72+
Multilinear polynomials are useful to define multilinear extensions of functions, which then play an important role in proof systems involving the [sumcheck protocol](../../../provers/sumcheck/README.md). There are two ways to define multilinear polynomials:
73+
- Dense
74+
- Sparse
75+
76+
Sparse is more convenient whenever the number of non-zero coefficients in the polynomial is small (compared to the length of the polynomial), avoiding the storage of unnecessary zeros. For dense multilinear polynomials we have the following structure, working over some field $F$:
77+
```rust
78+
pub struct DenseMultilinearPolynomial<F: IsField>
79+
where
80+
<F as IsField>::BaseType: Send + Sync,
81+
{
82+
evals: Vec<FieldElement<F>>,
83+
n_vars: usize,
84+
len: usize,
85+
}
86+
```
87+
The polynomial is assumed to be given in evaluation form over the binary strings of length $\{0 , 1 \}^{n_{vars}}$. We can also interpret this as the coefficients of the polynomial with respect to the Lagrange basis polynomials over $\{0 , 1 \}^{n_{vars}}$. There are $2^{n_{vars}}$ Lagrange polynomials, given by the formula:
88+
$L_k (x_0 , x_1 , ... , x_{n_{vars} - 1}) = \prod (x_j b_{kj} + (1 - x_j ) (1 - b_{kj} ))$
89+
where $b_{kj}$ are given by the binary decomposition of $k$, that is $k = \sum_j b_{kj} 2^j$. We can see that each such polynomial is equal to one over $\{b_{k0}, b_{k1} , ... b_{k (n_{vars} - 1)}}$ and zero for any other element in $\{0 , 1 \}^{n_{vars}}$. The polynomial is thus defined as
90+
$p (x_0 , x_1, ... , x_{n_{vars} - 1} ) = \sum_k p(b_{k0}, b_{k1} , ... , b_{k (n_{vars} - 1)}) L_k (x_0 , x_1, ... , x_{n_{vars} - 1} )$
91+
Sometimes, we will use $L_k (j)$ to refer to the evaluation of $L_k$ at the binary decomposition of $j$, that is $j = \sum_k b_{k}2^k$.
92+
93+
An advantage of Lagrange basis polynomials is that we can evaluate all $2^{n_{vars}}$ polynomials at a point $(r_0 , r_1 ... , r_{n_{vars} - 1})$ in $\mathcal{O}(2^{n_{vars}})$ operations (linear in the size of the number of polynomials). Refer to [Thaler's book](https://people.cs.georgetown.edu/jthaler/ProofsArgsAndZK.pdf) for more information.
94+
95+
To create a new polynomial, provide a list of evaluations of $p$; the length of this list should be a power of 2.
96+
```rust
97+
pub fn new(mut evals: Vec<FieldElement<F>>) -> Self {
98+
while !evals.len().is_power_of_two() {
99+
evals.push(FieldElement::zero());
100+
}
101+
let len = evals.len();
102+
DenseMultilinearPolynomial {
103+
n_vars: log_2(len),
104+
evals,
105+
len,
106+
}
107+
}
108+
```
109+
110+
Dense multilinear polynomials allow you to access the fields `n_vars`, `len` and `evals` with the methods `pub fn num_vars(&self) -> usize`, `pub fn len(&self) -> usize` and `pub fn evals(&self) -> &Vec<FieldElement<F>>`.
111+
112+
If you want to evaluate outside $\{0 , 1 \}^{n_{vars}}$, you can use the functions `pub fn evaluate(&self, r: Vec<FieldElement<F>>)` and `pub fn evaluate_with(evals: &[FieldElement<F>], r: &[FieldElement<F>])`, providing the point $r$ whose length must be $n_{vars}$. For evaluations over $\{0 , 1 \}^{n_{vars}}$, you can get the value directly from the list of evaluations defining the polynomial. For example,
113+
```rust
114+
// Example: Z = [1, 2, 1, 4]
115+
let z = vec![FE::one(), FE::from(2u64), FE::one(), FE::from(4u64)];
116+
// r = [4, 3]
117+
let r = vec![FE::from(4u64), FE::from(3u64)];
118+
let eval_with_lr = evaluate_with_lr(&z, &r);
119+
let poly = DenseMultilinearPolynomial::new(z);
120+
let eval = poly.evaluate(r).unwrap();
121+
assert_eq!(eval, FE::from(28u64));
122+
```
123+
124+
An important functionality is `pub fn to_univariate(&self) -> Polynomial<FieldElement<F>>`, which converts a multilinear polynomial into a univariate polynomial, by summing over all variables over $\{0 , 1 \}^{n_{vars} - 1}$, leaving $x_{n_{vars} - 1}$ as the only variable,
125+
$$f(x) = \sum_{(x_0 , x_1, ... , x_{n_{vars} - 2} ) \in \{0 , 1 \}^{n_{vars} - 1}} p(x_0 , x_1, ... , x_{n_{vars} - 2} , x)$$. For example,
126+
```rust
127+
let univar0 = prover.poly.to_univariate();
128+
```
129+
is used in the sumcheck protocol.
130+
131+
Multilinear polynomials can be added and multiplied by scalars.

0 commit comments

Comments
 (0)