mirror of
https://github.com/serai-dex/serai.git
synced 2025-01-22 02:34:55 +00:00
Apply the optimized pow to dalek-ff-group
Saves ~40% from Monero hash_to_curve, assisting with #68.
This commit is contained in:
parent
c5256d9b06
commit
cc0c6fb5ac
1 changed files with 23 additions and 5 deletions
|
@ -8,7 +8,7 @@ use crypto_bigint::{Encoding, U256, U512};
|
||||||
|
|
||||||
use ff::{Field, PrimeField, FieldBits, PrimeFieldBits};
|
use ff::{Field, PrimeField, FieldBits, PrimeFieldBits};
|
||||||
|
|
||||||
use crate::{choice, constant_time, math, from_uint};
|
use crate::{constant_time, math, from_uint};
|
||||||
|
|
||||||
const FIELD_MODULUS: U256 =
|
const FIELD_MODULUS: U256 =
|
||||||
U256::from_be_hex("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed");
|
U256::from_be_hex("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed");
|
||||||
|
@ -155,11 +155,29 @@ impl FieldElement {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pow(&self, other: FieldElement) -> FieldElement {
|
pub fn pow(&self, other: FieldElement) -> FieldElement {
|
||||||
|
let mut table = [FieldElement(U256::ONE); 16];
|
||||||
|
table[1] = *self;
|
||||||
|
for i in 2 .. 16 {
|
||||||
|
table[i] = table[i - 1] * self;
|
||||||
|
}
|
||||||
|
|
||||||
let mut res = FieldElement(U256::ONE);
|
let mut res = FieldElement(U256::ONE);
|
||||||
let mut m = *self;
|
let mut bits = 0;
|
||||||
for bit in other.to_le_bits() {
|
for (i, bit) in other.to_le_bits().iter().rev().enumerate() {
|
||||||
res *= FieldElement::conditional_select(&FieldElement(U256::ONE), &m, choice(bit));
|
bits <<= 1;
|
||||||
m *= m;
|
let bit = *bit as u8;
|
||||||
|
assert_eq!(bit | 1, 1);
|
||||||
|
bits |= bit;
|
||||||
|
|
||||||
|
if ((i + 1) % 4) == 0 {
|
||||||
|
if i != 3 {
|
||||||
|
for _ in 0 .. 4 {
|
||||||
|
res *= res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
res *= table[usize::from(bits)];
|
||||||
|
bits = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue