Merge pull request #1062 from Zokrates/improve-bits-solver
Improve bits solver
This commit is contained in:
commit
59e2b21e71
3 changed files with 26 additions and 14 deletions
1
changelogs/unreleased/1062-schaeff
Normal file
1
changelogs/unreleased/1062-schaeff
Normal file
|
@ -0,0 +1 @@
|
|||
Improve the performance of the bit decomposition solver
|
|
@ -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 => {
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in a new issue