Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix bounds (b, b_1, b_2) on logproof #262

Merged
merged 2 commits into from
Jun 27, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
6 changes: 3 additions & 3 deletions logproof/src/linear_relation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ where
* coefficients in the polynomials in `S`.
*/
pub fn b(&self) -> u64 {
Log2::log2(&self.bound) + 1
Log2::ceil_log2(&self.bound) + 1
}

/**
Expand Down Expand Up @@ -147,14 +147,14 @@ where
let b1 = m_big * d_big * bound_big + d_big * inf_norm_f;
let b1 = MontBackend::into_bigint(b1);

Log2::log2(&b1)
Log2::ceil_log2(&b1)
}

/**
* The number of bits needed to store values in `Fp<Q>`.
*/
pub fn b_2(&self) -> u64 {
Log2::log2(&Q::field_modulus()) + 1
Log2::ceil_log2(&Q::field_modulus())
}

/**
Expand Down
92 changes: 92 additions & 0 deletions logproof/src/math.rs
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,14 @@ pub trait Log2 {
* When the given value is zero.
*/
fn log2(x: &Self) -> u64;

/**
* Compute the ceiling of the log2 of the given value.
*
* # Panics
* When the given value is zero.
*/
fn ceil_log2(x: &Self) -> u64;
}

impl Log2 for u64 {
Expand All @@ -302,6 +310,28 @@ impl Log2 for u64 {

panic!("Value was zero.");
}

fn ceil_log2(x: &Self) -> u64 {
let ceil_factor = if x.is_power_of_two() { 0 } else { 1 };
Self::log2(x) + ceil_factor
}
}

fn is_power_of_two_bigint<const N: usize>(b: &BigInt<N>) -> bool {
let num_bits = b.num_bits();
let mut seen_a_one = false;

for n in 0..(num_bits as usize) {
let bit_set = b.get_bit(n);

if bit_set && seen_a_one {
return false;
} else if bit_set {
seen_a_one = true;
}
}

true
}

impl<const N: usize> Log2 for BigInt<N> {
Expand All @@ -319,6 +349,12 @@ impl<const N: usize> Log2 for BigInt<N> {

panic!("Value was zero.");
}

fn ceil_log2(x: &Self) -> u64 {
let ceil_factor = if is_power_of_two_bigint(x) { 0 } else { 1 };

Self::log2(x) + ceil_factor
}
}

/**
Expand Down Expand Up @@ -788,4 +824,60 @@ mod test {
assert_encoding(i8::MAX);
assert_encoding(42);
}

#[test]
fn big_int_pow_two() {
let options = [
(1u64, true),
(2, true),
(4, true),
(5, false),
(19, false),
(8192, true),
(8193, false),
];

for (value, expected) in options {
println!("{:?}, {:?}", value, expected);
let b: BigInt<1> = BigInt::from(value);
assert_eq!(is_power_of_two_bigint(&b), expected);
}

// Testing higher limbs
// value is 1 << 68
let b: BigInt<2> = BigInt!("295147905179352825856");
assert!(is_power_of_two_bigint(&b));

let b: BigInt<2> = BigInt!("295147905179352825857");
assert!(!is_power_of_two_bigint(&b));
}

#[test]
fn ceil_log2_u64() {
let options = [1u64, 2, 4, 5, 19, 8192, 8193];

for value in options {
let f = value as f64;
let expected = f.log2().ceil() as u64;

let calculated = Log2::ceil_log2(&value);

assert_eq!(calculated, expected);
}
}

#[test]
fn ceil_log2_bitint() {
let options = [1u64, 2, 4, 5, 19, 8192, 8193];

for value in options {
let f = value as f64;
let expected = f.log2().ceil() as u64;

let b: BigInt<1> = BigInt::from(value);
let calculated = Log2::ceil_log2(&b);

assert_eq!(calculated, expected);
}
}
}