Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion labrador/src/commitments/ajtai_commitment.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::ring::rq_matrix::RqMatrix;
use crate::ring::rq_vector::RqVector;
use crate::ring::zq::Zq;
use crate::ring::zq::ZqLabrador;
type Zq = ZqLabrador;
use crate::ring::Norms;
use thiserror::Error;

Expand Down
5 changes: 4 additions & 1 deletion labrador/src/commitments/outer_commitments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@ use thiserror::Error;

use crate::{
commitments::common_instances::AjtaiInstances,
ring::{rq_matrix::RqMatrix, rq_vector::RqVector, zq::Zq},
ring::{rq_matrix::RqMatrix, rq_vector::RqVector},
};

use crate::ring::zq::ZqLabrador;
type Zq = ZqLabrador;

use super::ajtai_commitment::AjtaiScheme;

#[derive(Debug, Error)]
Expand Down
3 changes: 2 additions & 1 deletion labrador/src/core/aggregate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ use crate::relation::env_params::EnvironmentParameters;
use crate::ring::rq::Rq;
use crate::ring::rq_matrix::RqMatrix;
use crate::ring::rq_vector::RqVector;
use crate::ring::zq::Zq;
use crate::ring::zq::ZqLabrador;
type Zq = ZqLabrador;

use super::inner_product;

Expand Down
3 changes: 2 additions & 1 deletion labrador/src/core/jl.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::ring::rq_matrix::RqMatrix;
use crate::ring::rq_vector::RqVector;
use crate::ring::zq::Zq;
use crate::ring::zq::ZqLabrador;
type Zq = ZqLabrador;
use crate::ring::{self, Norms};

// LaBRADOR: Compact Proofs for R1CS from Module-SIS | Page 5 | Proving smallness section
Expand Down
4 changes: 3 additions & 1 deletion labrador/src/prover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ use crate::relation::{
statement::Statement,
witness::Witness,
};
use crate::ring::{rq_matrix::RqMatrix, rq_vector::RqVector, zq::Zq};
use crate::ring::zq::ZqLabrador;
use crate::ring::{rq_matrix::RqMatrix, rq_vector::RqVector};
type Zq = ZqLabrador;
use crate::transcript::{LabradorTranscript, Sponge};
use thiserror::Error;

Expand Down
6 changes: 4 additions & 2 deletions labrador/src/relation/env_params.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#![allow(clippy::as_conversions)]
use crate::ring::{rq::Rq, zq::Zq};
use crate::ring::rq::Rq;
use crate::ring::zq::ZqLabrador;
type Zq = ZqLabrador;

/// Security Parameter
pub const SECURITY_PARAMETER: usize = 128;
Expand Down Expand Up @@ -76,7 +78,7 @@ impl EnvironmentParameters {
EnvironmentParameters {
rank,
multiplicity,
b: Zq::new(base_b as u32),
b: Zq::new(base_b as u64),
b_1: base_b1,
t_1: parts_t1,
b_2: base_b2,
Expand Down
3 changes: 2 additions & 1 deletion labrador/src/relation/statement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ use crate::relation::witness::Witness;
use crate::ring::rq::Rq;
use crate::ring::rq_matrix::RqMatrix;
use crate::ring::rq_vector::RqVector;
use crate::ring::zq::Zq;
use crate::ring::zq::ZqLabrador;
type Zq = ZqLabrador;

use crate::core::inner_product;

Expand Down
2 changes: 1 addition & 1 deletion labrador/src/relation/witness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ impl Witness {
#[allow(clippy::as_conversions)]
let std = ((bound_sq as f64) / ((rank * multiplicity * Rq::DEGREE) as f64)).sqrt();
#[allow(clippy::as_conversions)]
let std = std as u32;
let std = std as u64;
loop {
let s: Vec<RqVector> = (0..multiplicity)
.map(|_| RqVector::random_with_bound(&mut rng(), rank, std))
Expand Down
111 changes: 29 additions & 82 deletions labrador/src/ring/rq.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//! Polynomial ring **R = Z_q[X]/(X^d + 1)** with `d = 64` and `q = u32::MAX`.

use crate::ring::zq::Zq;
use crate::ring::zq::ZqLabrador;
type Zq = ZqLabrador;
use crate::ring::Norms;
use core::ops::{Add, Mul, Sub};
use rand::distr::{Distribution, Uniform};
Expand Down Expand Up @@ -47,7 +48,7 @@ impl Rq {
}

/// Random coefficients in `(-bound, bound)`.
pub fn random_with_bound<R: Rng + CryptoRng>(rng: &mut R, bound: u32) -> Self {
pub fn random_with_bound<R: Rng + CryptoRng>(rng: &mut R, bound: u64) -> Self {
let uniform = Uniform::new_inclusive(Zq::ZERO, Zq::new(bound)).unwrap();
let mut coeffs = [Zq::ZERO; Self::DEGREE];
coeffs.iter_mut().for_each(|c| {
Expand All @@ -63,8 +64,9 @@ impl Rq {
/// Decomposes a polynomial into base-B representation:
/// p = p⁽⁰⁾ + p⁽¹⁾·B + p⁽²⁾·B² + ... + p⁽ᵗ⁻¹⁾·B^(t-1)
/// Where each p⁽ⁱ⁾ has small coefficients, using centered representatives
pub fn decompose(&self, base: Zq, num_parts: usize) -> Vec<Rq> {
let mut result = vec![Rq::zero(); num_parts];
pub fn decompose(&self, base: Zq, num_parts: u64) -> Vec<Rq> {
let mut result =
vec![Rq::zero(); usize::try_from(num_parts).expect("num_parts does not fit in usize")];
self.coeffs.iter().enumerate().for_each(|(index, coeff)| {
coeff
.decompose(base, num_parts)
Expand Down Expand Up @@ -498,7 +500,7 @@ mod decomposition_tests {
fn failure_test() {
let poly1 =
generate_rq_from_zq_vector(vec![-Zq::new(192), -Zq::new(0), -Zq::new(0), -Zq::new(0)]);
let decomposed = poly1.decompose(Zq::new(1802), 10);
let decomposed = poly1.decompose(Zq::new(1802), 10u64);

let mut result = Rq::zero();
let mut exponential_base = Zq::new(1);
Expand All @@ -514,7 +516,7 @@ mod decomposition_tests {
// Test case 1: Base 2 decomposition
let poly: Rq =
generate_rq_from_zq_vector(vec![Zq::new(5), Zq::new(3), Zq::new(7), Zq::new(1)]);
let parts = poly.decompose(Zq::TWO, 4);
let parts = poly.decompose(Zq::TWO, 4u64);

// Part 0: remainders mod 2 (no centering needed for base 2)
assert_eq!(
Expand Down Expand Up @@ -558,7 +560,7 @@ mod decomposition_tests {
fn test_decomposition_edge_cases() {
// Test zero polynomial
let zero_poly: Rq = generate_rq_from_zq_vector(vec![Zq::ZERO; 4]);
let parts = zero_poly.decompose(Zq::TWO, 2);
let parts = zero_poly.decompose(Zq::TWO, 2u64);
assert!(
// Check any polynomial is zero
parts
Expand All @@ -570,88 +572,33 @@ mod decomposition_tests {
// Test single part decomposition
let simple_poly: Rq =
generate_rq_from_zq_vector(vec![Zq::ONE, Zq::new(2), Zq::new(3), Zq::new(4)]);
let parts = simple_poly.decompose(Zq::TWO, 1);
let parts = simple_poly.decompose(Zq::TWO, 1u64);
assert_eq!(parts.len(), 1, "Single part decomposition length incorrect");
}

#[test]
fn test_decomposition_real_values() {
let poly1 = Rq {
coeffs: [
Zq::new(23071),
Zq::new(4294941461),
Zq::new(4084),
Zq::new(23413),
Zq::new(26902),
Zq::new(4294960817),
Zq::new(4294957829),
Zq::new(18248),
Zq::new(15293),
Zq::new(45978),
Zq::new(27197),
Zq::new(11233),
Zq::new(4294962536),
Zq::new(1196),
Zq::new(17083),
Zq::new(4294960822),
Zq::new(4294967103),
Zq::new(4294949429),
Zq::new(2926),
Zq::new(2742),
Zq::new(27552),
Zq::new(4294955871),
Zq::new(2917),
Zq::new(4294938904),
Zq::new(2288),
Zq::new(4294948781),
Zq::new(4294966588),
Zq::new(4294951307),
Zq::new(4294961210),
Zq::new(19355),
Zq::new(4294956913),
Zq::new(14940),
Zq::new(4294934068),
Zq::new(4294961161),
Zq::new(4294959017),
Zq::new(3339),
Zq::new(4294932967),
Zq::new(4294938251),
Zq::new(4294943006),
Zq::new(4294965167),
Zq::new(4294960800),
Zq::new(4161),
Zq::new(9213),
Zq::new(4294962556),
Zq::new(14299),
Zq::new(44418),
Zq::new(2438),
Zq::new(6583),
Zq::new(4294957783),
Zq::new(16),
Zq::new(4294941724),
Zq::new(4294966309),
Zq::new(4294966984),
Zq::new(4294956138),
Zq::new(1779),
Zq::new(29598),
Zq::new(16393),
Zq::new(728),
Zq::new(4294944371),
Zq::new(4294951792),
Zq::new(4294943824),
Zq::new(4294937618),
Zq::new(4294955208),
Zq::new(11235),
],
};
// Generate realistic test data
let mut rng = rand::rng();
let mut coeffs = [Zq::ZERO; 64];

// Use realistic values - either small or near the modulus
for c in coeffs.iter_mut() {
// Example: random values in range [-1000, 1000]
let val = rng.random_range(0..2001);
*c = if val > 1000 {
-Zq::new(val - 1000)
} else {
Zq::new(val)
};
}

let poly1 = Rq { coeffs };
let base = Zq::new(1802);
let decomposed = poly1.decompose(base, 2);
let decomposed = poly1.decompose(base, 2u64);

// Verify reconstruction
let reconstructed = &decomposed[0] + &(&decomposed[1] * &base);

assert_eq!(decomposed.len(), 2);
assert_eq!(reconstructed, poly1, "Base {base}: Reconstruction failed");
assert_eq!(reconstructed, poly1);
}

#[test]
Expand Down Expand Up @@ -725,7 +672,7 @@ mod decomposition_tests {
],
};
let base = Zq::new(1802);
let decomposed = poly1.decompose(base, 2);
let decomposed = poly1.decompose(base, 2u64);

// Verify reconstruction
for decomposed_poly in decomposed {
Expand Down
9 changes: 7 additions & 2 deletions labrador/src/ring/rq_matrix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ use crate::{core::inner_product, ring::rq_vector::RqVector};
use rand::{CryptoRng, Rng};
use std::ops::Mul;

use super::{rq::Rq, zq::Zq};
use crate::ring::rq::Rq;
use crate::ring::zq::ZqLabrador;
type Zq = ZqLabrador;

/// Matrix of polynomials in Rq
#[derive(Debug, Clone)]
Expand Down Expand Up @@ -99,7 +101,10 @@ impl RqMatrix {
let mut decomposed_vec = Vec::new();
for ring_vector in self.elements() {
for ring in ring_vector.elements() {
decomposed_vec.extend(ring.decompose(base, num_parts));
decomposed_vec.extend(ring.decompose(
base,
u64::try_from(num_parts).expect("num_parts does not fit in u64"),
));
}
}
RqVector::new(decomposed_vec)
Expand Down
10 changes: 6 additions & 4 deletions labrador/src/ring/rq_vector.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
//! Dynamic vector of `Rq` elements.

use crate::ring::zq::Zq;
use crate::ring::zq::ZqLabrador;
type Zq = ZqLabrador;

use crate::ring::{rq::Rq, Norms};
use core::ops::Mul;
use rand::{CryptoRng, Rng};
Expand Down Expand Up @@ -60,7 +62,7 @@ impl RqVector {
}

/// Random vector of given length with coefficients in `(-bound, bound)`.
pub fn random_with_bound<R: Rng + CryptoRng>(rng: &mut R, length: usize, bound: u32) -> Self {
pub fn random_with_bound<R: Rng + CryptoRng>(rng: &mut R, length: usize, bound: u64) -> Self {
Self {
elements: (0..length)
.map(|_| Rq::random_with_bound(rng, bound))
Expand All @@ -86,7 +88,7 @@ impl RqVector {
.iter()
.enumerate()
.for_each(|(index, poly)| {
poly.decompose(b, parts)
poly.decompose(b, u64::try_from(parts).expect("parts does not fit in u64"))
.into_iter()
.zip(result.iter_mut())
.for_each(|(decomposed_poly, decomposed_vec)| {
Expand Down Expand Up @@ -319,7 +321,7 @@ mod decomposition_tests {
use super::*;

fn default_base_and_parts() -> (Zq, usize) {
let base = Zq::new(2u32.pow(16));
let base = Zq::new(2u64.pow(16));
let parts = 3; // 32 / 16 + (additional parts)
(base, parts)
}
Expand Down
Loading