Improve normalization performance for 32bit

- Uses a similar approach to the latest 64bit _normalize.
- Add one useful optimization back into the 64bit _normalize too.

Performance of 'bench' improved by around 0.5% for the 32bit field (but tested on a 64-bit machine).
This commit is contained in:
Peter Dettman
2014-06-23 12:12:58 +07:00
parent f33793fb99
commit 42822baaa8
2 changed files with 47 additions and 72 deletions

View File

@@ -38,20 +38,20 @@ void static secp256k1_fe_normalize(secp256k1_fe_t *r) {
// Reduce t4 at the start so there will be at most a single carry from the first pass
uint64_t x = t4 >> 48; t4 &= 0x0FFFFFFFFFFFFULL;
uint64_t m;
// The first pass ensures the magnitude is 1, ...
t0 += x * 0x1000003D1ULL;
t1 += (t0 >> 52); t0 &= 0xFFFFFFFFFFFFFULL;
t2 += (t1 >> 52); t1 &= 0xFFFFFFFFFFFFFULL;
t3 += (t2 >> 52); t2 &= 0xFFFFFFFFFFFFFULL;
t4 += (t3 >> 52); t3 &= 0xFFFFFFFFFFFFFULL;
t2 += (t1 >> 52); t1 &= 0xFFFFFFFFFFFFFULL; m = t1;
t3 += (t2 >> 52); t2 &= 0xFFFFFFFFFFFFFULL; m &= t2;
t4 += (t3 >> 52); t3 &= 0xFFFFFFFFFFFFFULL; m &= t3;
// ... except for a possible carry at bit 48 of t4 (i.e. bit 256 of the field element)
assert(t4 >> 49 == 0);
// At most a single final reduction is needed; check if the value is >= the field characteristic
x = (t4 >> 48) | ((t4 == 0x0FFFFFFFFFFFFULL)
& ((t3 & t2 & t1) == 0xFFFFFFFFFFFFFULL)
x = (t4 >> 48) | ((t4 == 0x0FFFFFFFFFFFFULL) & (m == 0xFFFFFFFFFFFFFULL)
& (t0 >= 0xFFFFEFFFFFC2FULL));
// Apply the final reduction (for constant-time behaviour, we do it always)