diff --git a/Cargo.lock b/Cargo.lock index 9f3d49d..d4dec01 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -26,6 +26,10 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "falcon_labrador" +version = "0.1.0" + [[package]] name = "getrandom" version = "0.3.1" diff --git a/Cargo.toml b/Cargo.toml index 6286f33..3b8b926 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,8 +5,9 @@ repository = "https://github.com/NethermindEth/LaBRADOR-rs" license = "Apache-2.0" [workspace] -members = [ +members = [ "labrador", + "falcon_labrador", ] resolver = "2" default-members = ["labrador"] diff --git a/README.md b/README.md index 6bf1dde..e6bf76a 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,13 @@ Docs for `labrador`: ```sh RUSTDOCFLAGS="--html-in-header katex-header.html" cargo doc --no-deps -p labrador --open ``` +Docs for `falcon aggregation with labrador`: + +```sh +RUSTDOCFLAGS="--html-in-header katex-header.html" cargo doc --no-deps -p falcon_labrador --open +``` + ## License -Apache 2.0 \ No newline at end of file +Apache 2.0 diff --git a/doc/falcon_labrador_docs/Changing-Modulus-Norm-Checks.md b/doc/falcon_labrador_docs/Changing-Modulus-Norm-Checks.md new file mode 100644 index 0000000..c266054 --- /dev/null +++ b/doc/falcon_labrador_docs/Changing-Modulus-Norm-Checks.md @@ -0,0 +1,115 @@ +# Changing the Modulus & Norm Checks +This document clarifies handling different moduli and verifying norm constraints in the process of adapting Falcon signatures for aggregation within the LaBRADOR proof system. + + +## Different Moduli +Falcon and LaBRADOR both operate over polynomial rings of the form $\mathcal{R}\_q = \mathbb{Z}\_q[X]/(X^d + 1)$, but they use different moduli: Falcon uses a smaller modulus $q$, while LaBRADOR requires a larger modulus $q' > q$. This difference arises because Falcon’s standard parameter sets do not meet the conditions for the Johnson-Lindenstrauss projection used in LaBRADOR. Therefore, we must lift Falcon signatures verification into a larger ring modulo $q'$, while ensuring compatibility and security. + + +## Falcon Signature Scheme +In Falcon, a signer uses their secret key to generate a signature consisting of two small polynomials $\mathbf{s}\_{i\_1}, \mathbf{s}\_{i\_2} \in \mathcal{R}\_q$ for a message $m\_i$. For verification, the signature must satisfy two conditions: +1. Verification Equation: + +$$\mathbf{s}\_{i\_1} + \mathbf{h}\_i \mathbf{s}\_{i\_2} = \mathbf{t}\_i \mod q \qquad (1)$$ + +Here, $\mathbf{h}\_i$ is the public key (a polynomial in $\mathcal{R}\_q$), $\mathbf{t}\_i = H(r\_i, m\_i)$ is the hash of the message $m\_i$ and a random salt $r\_i \in \\{0, 1\\}^{320}$, and $H$ is a cryptographic hash function. + +2. Norm Bound: + +$$\\|(\mathbf{s}\_{i\_1}, \mathbf{s}\_{i\_2}) \\|\_2 = \sqrt{\\| \mathbf{s}\_{i\_1} \|\_2^2 + \\| \mathbf{s}\_{i\_2} \\|\_2^2} \leq \beta \ll q \qquad (2)$$ + +The $\ell\_2$-norm bound $\beta$ ensures the signature is small, a critical property for Falcon’s security. + +Note that (1) and (2) hold modulo $q$, but not necessarily modulo $q'$ or over the integers ($\mathcal{R}$). + + +## Falcon Verification in LaBRADOR +To aggregate Falcon signatures in LaBRADOR, we need to adapt the verification process to work over $\mathcal{R}\_{q'} = \mathbb{Z}\_{q'}[X]/(X^d + 1)$. Since equation (1) is defined modulo $q$, we must rewrite it to be compatible with $q'$ while ensuring no wrap-around occurs. + +### Rewriting Equation (1) for Modulo $q'$ +Equation (1) does not naturally hold over the integers $( \mathcal{R} )$ or modulo $q'$. To address this, we introduce an additional witness polynomial $\mathbf{v}\_i \in \mathcal{R}\_{q'}$ and reformulate (1) as: + +$$\mathbf{s}\_{i\_1} + \mathbf{h}\_i \mathbf{s}\_{i\_2} + q \mathbf{v}\_i - \mathbf{t}\_i = \mathbf{0} \in \mathcal{R} \qquad (3) $$ + +This equation holds over the integers by construction, as $q \mathbf{v}\_i$ accounts for the difference modulo $q$. However, LaBRADOR operates over $\mathcal{R}\_{q'}$, so we need: + +$$\mathbf{s}\_{i\_1} + \mathbf{h}\_i \mathbf{s}\_{i\_2} + q \mathbf{v}\_i - \mathbf{t}\_i = \mathbf{0} \in \mathcal{R}\_{q'} \qquad (4)$$ + +For (4) to be equivalent to (3), the coefficients of the left-hand side must not wrap around modulo $q'$. This requires the infinity norm of the sum to be less than $q'/2$: + +$$\\| \mathbf{s}\_{i\_1} + \mathbf{h}\_i \mathbf{s}\_{i\_2} + q \mathbf{v}\_i - \mathbf{t}\_i \\|\_\infty < \frac{q'}{2} $$ + +To ensure this, we impose bounds on each term: + +$$\\| \mathbf{s}\_{i\_1} \\|\_\infty < \frac{q'}{6} \qquad +\\| \mathbf{h}\_i \mathbf{s}\_{i\_2} \\|\_\infty < \frac{q'}{6} \qquad +\\| q \mathbf{v}\_i \\|\_\infty < \frac{q'}{6}$$ + +This implies + +$$\\| \mathbf{s}\_{i\_1} \\|\_\infty < \frac{q'}{6} \qquad +\\| \mathbf{s}\_{i\_2} \\|\_\infty < \frac{q'}{6qd} \qquad +\\| q \mathbf{v}\_i \\|\_\infty < \frac{q'}{6q}$$ + +These bounds ensure the total sum stays within $\frac{q'}{2}$, preventing wrap-around. In LaBRADOR, $\mathbf{s}\_{i\_1}, \mathbf{s}\_{i\_2}, \mathbf{v}\_i$ are witnesses, and we prove (4) holds. + + +## Verifying the Norm Bound in LaBRADOR +Falcon’s norm condition (2) must also be proven in LaBRADOR without revealing $\mathbf{s}\_{i\_1}$ or $\mathbf{s}\_{i\_2}$. We rewrite: + +$$ \beta^2 - \\| \mathbf{s}\_{i\_1} \\|\_2^2 - \\| \mathbf{s}\_{i\_2} \\|\_2^2 \geq 0 $$ + +By Lagrange’s four-square theorem, any non-negative integer is the sum of four squares. Thus, we introduce four integer witnesses $\epsilon\_{i,0}, \epsilon\_{i,1}, \epsilon\_{i,2}, \epsilon\_{i,3}$ such that: + +$$ \beta^2 - \\| \mathbf{s}\_{i\_1} \\|\_2^2 - \\| \mathbf{s}\_{i\_2} \\|\_2^2 = \epsilon\_{i,0}^2 + \epsilon\_{i,1}^2 + \epsilon\_{i,2}^2 + \epsilon\_{i,3}^2 \qquad (5)$$ + +To fit LaBRADOR’s polynomial constraints, we represent each $\epsilon\_{i,j}$ as a polynomial of degree at most 3 + +$$ \mathbf{\epsilon}\_i = \epsilon\_{i,0} + \epsilon\_{i,1} X + \epsilon\_{i,2} X^2 + \epsilon\_{i,3} X^3 $$ + +The norm squared is computed using the conjugation automorphism $\sigma\_{-1}$, where $\\| \mathbf{v} \\|\_2^2 = \sigma\_{-1}(\mathbf{v}) \mathbf{v}$. We rewrite (5) as: + +$$ \sigma\_{-1}(\mathbf{\epsilon}\_i) \mathbf{\epsilon}\_i = \beta^2 - \sigma\_{-1}(\mathbf{s}\_{i\_1}) \mathbf{s}\_{i\_1} - \sigma\_{-1}(\mathbf{s}\_{i\_2}) \mathbf{s}\_{i\_2} \in \mathcal{R} $$ + +In LaBRADOR, this must hold modulo $q'$: + +$$ \sigma\_{-1}(\mathbf{\epsilon}\_i) \mathbf{\epsilon}\_i - (\beta^2 - \sigma\_{-1}(\mathbf{s}\_{i\_1}) \mathbf{s}\_{i\_1} - \sigma\_{-1}(\mathbf{s}\_{i\_2}) \mathbf{s}\_{i\_2}) = 0 \mod q' \qquad (6) $$ + +To avoid wrap-around, the infinity norm of the left-hand side must be less than $q'/2$: + +$$ \\| \sigma\_{-1}(\mathbf{\epsilon}\_i) \mathbf{\epsilon}\_i - (\beta^2 - \sigma\_{-1}(\mathbf{s}\_{i\_1}) \mathbf{s}\_{i\_1} - \sigma\_{-1}(\mathbf{s}\_{i\_2}) \mathbf{s}\_{i\_2}) \\|\_\infty < \frac{q'}{2} $$ + +This involves $2d + 4$ coefficients ( $2d$ from $\mathbf{s}\_{i\_1}$, $\mathbf{s}\_{i\_2}$, and 4 from $\mathbf{\epsilon}\_i $). Bounding each coefficient’s $\ell\_\infty$-norm by $\sqrt{\frac{q'}{2(2d + 4)}}$ ensures the sum stays within $q'/2$. + + +### Conjugation Automorphism Checks + +For a polynomial $\mathbf{f}(X) = a\_0 + a\_1 X + \cdots + a\_{d-1} X^{d-1}$, the conjugation automorphism is $\sigma\_{-1}(\mathbf{f}) = a\_0 + a\_1 X^{-1} + \cdots + a\_{d-1} X^{-(d-1)}$. In $\mathcal{R}\_{q'}$, $X^{-t}$ is computed modulo $X^d + 1$. We verify coefficients using dot product constraints: +1. Check the $j$-th coefficient equals a value $b$: + +$$ \sigma\_{-1}(X^j) \mathbf{a} = b \mod q'$$ + + +2. Check two coefficients $a\_j, c\_k$ match: + +$$ \sigma\_{-1}(X^j) \mathbf{a} = \sigma\_{-1}(X^k) \mathbf{c} \mod q'$$ + +For $\mathbf{\epsilon}\_i$, we ensure the degree is at most 3 by setting coefficients $\epsilon\_{i,4}, \ldots, \epsilon\_{i,d-1}$ to zero. For $\mathbf{s}\_{i\_1}, \mathbf{s}\_{i\_2}, \mathbf{\epsilon}\_i$, we verify the conjugation and coefficients match in (6). This requires approximately $4d n$ extra constraints for $n$ signatures. + + + +## Choosing the Modulus $q'$ +To satisfy all constraints, $q'$ must be sufficiently large. After computations for soundness and completeness: + +$$ q' > \frac{1024}{15} (d + 2) \beta^2 N$$ + +- Falcon-512: $q' > 2^{40.12} N$ +- Falcon-1024: $q' > 2^{42.16} N$ + +For $N = 2^{20}$ signatures: +- Falcon-512: $q' > 2^{60.12}$, so a 61-bit modulus suffices. +- Falcon-1024: $q' > 2^{62.16}$, so a 63-bit modulus is needed. + + +## Conclusion +This guide clarifies how to adapt Falcon signatures for LaBRADOR by changing the modulus and verifying norms. By rewriting the verification equation, introducing witnesses, and enforcing norm bounds, developers can implement a secure and correct aggregation system. \ No newline at end of file diff --git a/doc/falcon_labrador_docs/mainpage-doc.md b/doc/falcon_labrador_docs/mainpage-doc.md new file mode 100644 index 0000000..6514827 --- /dev/null +++ b/doc/falcon_labrador_docs/mainpage-doc.md @@ -0,0 +1,38 @@ +# Aggregating Falcon Signatures with LaBRADOR +This repository contains the implementation of *[Aggregating Falcon Signatures with LaBRADOR](https://eprint.iacr.org/2024/311.pdf)*. + +The main goal of the paper—and of this implementation—is to aggregate Falcon signatures using a **non‑interactive** (via the Fiat–Shamir heuristic) version of LaBRADOR, a post‑quantum lattice‑based argument‑of‑knowledge scheme with short proofs. +The approach is to define a signature‑aggregation scheme (AS) for Falcon that relies on a LaBRADOR‑based succinct non‑interactive argument of knowledge (SNARK). +In this SNARK we treat the signatures as **witnesses** and the messages and public keys as **statements**. +The result is a non‑sequential aggregation scheme that requires zero interaction between signers, and, thanks to the succinct proofs, the scheme is well suited to bandwidth‑constrained settings such as blockchains. + +These notes serve as a friendly introduction to the protocol and a prototype for the documentation. +This implementation assumes Falcon signature scheme and interactive version of LaBRADOR are implemented. + +## Overview +The implemented changes to LaBRADOR consist of the following steps: +- Changing the Modulus & Norm Checks +- Reformulating Constraints +- Working over Subring + +## Assumption +We assume a user aims to aggregate $N$ signatures, with $i$ indexing each signature, message, and public key. +For instance, $m\_i$ denotes the $i$-th message to be signed, $(\mathbf{s}\_{i\_1}, \mathbf{s}\_{i\_2})$ represents its signatures, and $pk\_i$ is the corresponding public key. + + +## Notation +Throughout this documentation let $q$ denote the modulus, and let $\mathbb{Z}_q$ be the ring of integers modulo $q$. +Define the polynomial rings $\mathcal{R} = \mathbb{Z}[X]/(X^d + 1)$ and $\mathcal{R}_q = \mathbb{Z}_q[X]/(X^d + 1).$ + +We use the following conventions. +- **Non‑bold letters** (elements in $\mathbb{Z}_q$) + - $s \in \mathbb{Z}_q$: scalar + - $\vec{s} \in \mathbb{Z}_q^n$: vector of length $n$ + - $A \in \mathbb{Z}_q^{m \times n}$: matrix with $m$ rows and $n$ columns + +- **Bold letters** (polynomial functions in $\mathcal{R}$ or $\mathcal{R}_q$) + - $\mathbf{s} \in \mathcal{R}$ or $\mathcal{R}_q$ + - $\vec{\mathbf{s}} \in (\mathcal{R}_q)^n$: vector of polynomials with length $n$ + - $\mathbf{A} \in (\mathcal{R}_q)^{m \times n}$: matrix of polynomials with $m$ rows and $n$ columns + +- $ct(\mathbf{f})$ denotes the constant term of the polynomial function $\mathbf{f} = a_0 + a_1X + \cdots + a_{d-1}X^{d-1},$ i.e. $ct(\mathbf{f}) = a_0$. diff --git a/doc/falcon_labrador_docs/reformulating-constraints.md b/doc/falcon_labrador_docs/reformulating-constraints.md new file mode 100644 index 0000000..6e0b484 --- /dev/null +++ b/doc/falcon_labrador_docs/reformulating-constraints.md @@ -0,0 +1,16 @@ +# Reformulating Constraints +In order to achieve an improvement in computational complexity, witnesses will be rewritten via a padding scheme. This new format, although increasing both in size and in the number of dot product constraints that are required, will significantly reduce the need for garbage polynomials, thereby providing a general increase in speed. + +## Padding Scheme +In this padding scheme, witness elements $w\_{1} \dots w\_{N}$ $\in \mathcal{R}\_{q\^{'}}$ along with other elements $w\_{1}\^{'} \dots w\_{N}\^{'} \in \mathcal{R}\_{q\^{'}}$ are such that $\lVert w\_{i} \rVert\_{2}\^{2} = ct(w\_{i}' w\_{i})$ (An example of $w\_{i}'$ being the conjugate automorphism of $w\_{i}$) can be rewritten as vectors of the form $\vec{u}\_{1}, \dots, \vec{u}\_{\lceil N \rho \rceil} \in \mathcal{R}\_{q'}\^{N}$ and $\vec{u}\_{1}', \dots, \vec{u}\_{\lceil N \rho \rceil}' \in \mathcal{R}\_{q'}\^{N}$ respectively, where $\rho = \lfloor \sqrt{N} \rfloor$. + +After following the padding equations described in the paper, we can think of each vector $\vec{u}\_{i}$ as a vector filled with zeros except for some locations where the original witness polynomials will be located: $\[0, 0, 0, \dots, w_{2\rho +1}, \dots, w_{3\rho}, \dots, 0, 0\]$. We can access each old witness polynomial using the index functions of the form: +$$index(i) = \lceil i \rho \rceil$$ +$$index'(i) = ((i-1) \mod \rho) + 1$$ + +for $u\_{i}$ and $u\_{i}'$ respectively. From this, it follows that we can write $\lVert w\_{i} \rVert\_{2}\^{2} = ct(w\_{i}'w\_{i}) = ct(\langle \vec{u}\_{index'(i)}', \vec{u}\_{index(i)} \rangle)$. + +Beyond adding dot product restrictions to check each zero element of the new witness vectors, we will also rewrite all the restrictions using the new witnesses as well as the index function. In order to rewrite the constraints, there will be extensive use of $\delta\_{i} \in \mathcal{R}\_{q'}\^{N}$, the vector with the $i$-th entry as $1$ (the identity of the ring) and all other elements as $0$. +As an example, we can rewrite Falcon's restrictions as: +$$\langle \delta\_{i}, \vec{u}\_{index(i)} \rangle + \langle h\_{i} \delta\_{i}, \vec{u}\_{index(i)} \rangle + \langle q \delta\_{i}, v \rangle - t\_{i} = 0$$ + diff --git a/labrador/doc/aggregation.md b/doc/labrador_docs/aggregation.md similarity index 100% rename from labrador/doc/aggregation.md rename to doc/labrador_docs/aggregation.md diff --git a/labrador/doc/ajtai_commitment.md b/doc/labrador_docs/ajtai_commitment.md similarity index 100% rename from labrador/doc/ajtai_commitment.md rename to doc/labrador_docs/ajtai_commitment.md diff --git a/labrador/doc/amortization.md b/doc/labrador_docs/amortization.md similarity index 100% rename from labrador/doc/amortization.md rename to doc/labrador_docs/amortization.md diff --git a/labrador/doc/arithmetic_circuit_translation.md b/doc/labrador_docs/arithmetic_circuit_translation.md similarity index 100% rename from labrador/doc/arithmetic_circuit_translation.md rename to doc/labrador_docs/arithmetic_circuit_translation.md diff --git a/labrador/doc/hierarchical_commitment.md b/doc/labrador_docs/hierarchical_commitment.md similarity index 100% rename from labrador/doc/hierarchical_commitment.md rename to doc/labrador_docs/hierarchical_commitment.md diff --git a/labrador/doc/mainpage-doc.md b/doc/labrador_docs/mainpage-doc.md similarity index 100% rename from labrador/doc/mainpage-doc.md rename to doc/labrador_docs/mainpage-doc.md diff --git a/labrador/doc/projections.md b/doc/labrador_docs/projections.md similarity index 100% rename from labrador/doc/projections.md rename to doc/labrador_docs/projections.md diff --git a/falcon_labrador/Cargo.toml b/falcon_labrador/Cargo.toml new file mode 100644 index 0000000..312e940 --- /dev/null +++ b/falcon_labrador/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "falcon_labrador" +version.workspace = true +edition.workspace = true +repository.workspace = true +license.workspace = true + +[dependencies] + diff --git a/falcon_labrador/src/lib.rs b/falcon_labrador/src/lib.rs new file mode 100644 index 0000000..f4e5d87 --- /dev/null +++ b/falcon_labrador/src/lib.rs @@ -0,0 +1,9 @@ +// Documentation + +// Main Introduction + +#![forbid(unsafe_code)] +#![deny(clippy::as_conversions)] +#![doc = include_str!("../../doc/falcon_labrador_docs/mainpage-doc.md")] +#![doc = include_str!("../../doc/falcon_labrador_docs/Changing-Modulus-Norm-Checks.md")] +#![doc = include_str!("../../doc/falcon_labrador_docs/reformulating-constraints.md")] diff --git a/labrador/src/lib.rs b/labrador/src/lib.rs index 525f7f1..2bd2616 100644 --- a/labrador/src/lib.rs +++ b/labrador/src/lib.rs @@ -3,19 +3,19 @@ // Main Introduction #![forbid(unsafe_code)] #![deny(clippy::as_conversions)] -#![doc = include_str!("../doc/mainpage-doc.md")] +#![doc = include_str!("../../doc/labrador_docs/mainpage-doc.md")] // Arithmetic Circuit Translation -#![doc = include_str!("../doc/arithmetic_circuit_translation.md")] +#![doc = include_str!("../../doc/labrador_docs/arithmetic_circuit_translation.md")] // Ajtai Commitment -#![doc = include_str!("../doc/ajtai_commitment.md")] +#![doc = include_str!("../../doc/labrador_docs/ajtai_commitment.md")] // Hierarchical Commitment -#![doc = include_str!("../doc/hierarchical_commitment.md")] +#![doc = include_str!("../../doc/labrador_docs/hierarchical_commitment.md")] // Projections -#![doc = include_str!("../doc/projections.md")] +#![doc = include_str!("../../doc/labrador_docs/projections.md")] // Aggregation -#![doc = include_str!("../doc/aggregation.md")] +#![doc = include_str!("../../doc/labrador_docs/aggregation.md")] // Amortization -#![doc = include_str!("../doc/amortization.md")] +#![doc = include_str!("../../doc/labrador_docs/amortization.md")] pub mod rq;