1
0
Fork 0
mirror of synced 2025-09-24 04:40:05 +00:00

Merge pull request #1062 from Zokrates/improve-bits-solver

Improve bits solver
This commit is contained in:
Thibaut Schaeffer 2021-12-07 16:51:08 +01:00 committed by GitHub
commit 59e2b21e71
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 26 additions and 14 deletions

View file

@ -0,0 +1 @@
Improve the performance of the bit decomposition solver

View file

@ -132,22 +132,17 @@ impl Interpreter {
],
},
Solver::Bits(bit_width) => {
let padding = bit_width.saturating_sub(T::get_required_bits());
// get all the bits
let bits = inputs[0].to_bits_be();
let bit_width = bit_width - padding;
// only keep at most `bit_width` of them, starting from the least significant
let bits = bits[bits.len().saturating_sub(*bit_width)..].to_vec();
let num = inputs[0].clone();
(0..padding)
.map(|_| T::zero())
.chain((0..bit_width).rev().scan(num, |state, i| {
if T::from(2).pow(i) <= *state {
*state = (*state).clone() - T::from(2).pow(i);
Some(T::one())
} else {
Some(T::zero())
}
}))
// pad with zeroes so that the result is exactly `bit_width` long
(0..bit_width - bits.len())
.map(|_| 0)
.chain(bits)
.map(T::from)
.collect()
}
Solver::Xor => {

View file

@ -55,6 +55,7 @@ impl fmt::Debug for FieldParseError {
pub trait Field:
From<i32>
+ From<u8>
+ From<u32>
+ From<usize>
+ From<u128>
@ -101,6 +102,8 @@ pub trait Field:
/// Returns the largest value `m` such that there exist a number of bits `n` so that any value smaller or equal to
/// m` has a single `n`-bit decomposition
fn max_unique_value() -> Self;
/// Return the number of bits required to represent this element
fn to_bits_be(&self) -> Vec<u8>;
/// Returns the number of bits required to represent any element of this field type.
fn get_required_bits() -> usize;
/// Tries to parse a string into this representation
@ -184,6 +187,10 @@ mod prime_field {
self.value.to_biguint().unwrap()
}
fn to_bits_be(&self) -> Vec<u8> {
self.value.to_radix_be(2).1
}
fn to_byte_vector(&self) -> Vec<u8> {
match self.value.to_biguint() {
Option::Some(val) => val.to_bytes_le(),
@ -297,6 +304,15 @@ mod prime_field {
}
}
impl From<u8> for FieldPrime {
fn from(num: u8) -> Self {
let x = ToBigInt::to_bigint(&num).unwrap();
FieldPrime {
value: &x - x.div_floor(&*P) * &*P,
}
}
}
impl From<u32> for FieldPrime {
fn from(num: u32) -> Self {
let x = ToBigInt::to_bigint(&num).unwrap();