aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2018-02-28 17:33:57 -0500
committerJack Lloyd <[email protected]>2018-02-28 17:33:57 -0500
commitc95b3967bf4213a36a0cceef5d578146b0afa9c7 (patch)
treeee090f93c8385d11ca1fcd421af272933ae63021 /src
parent3870a2a59a9940635a133fbe60ab05c9815a4d1c (diff)
Optimize P-521 reduction
ECDSA/ECDH both about 25% faster
Diffstat (limited to 'src')
-rw-r--r--src/lib/math/numbertheory/nistp_redc.cpp18
1 files changed, 17 insertions, 1 deletions
diff --git a/src/lib/math/numbertheory/nistp_redc.cpp b/src/lib/math/numbertheory/nistp_redc.cpp
index a2420e975..9d2e430d0 100644
--- a/src/lib/math/numbertheory/nistp_redc.cpp
+++ b/src/lib/math/numbertheory/nistp_redc.cpp
@@ -38,10 +38,26 @@ void redc_p521(BigInt& x, secure_vector<word>& ws)
x.mask_bits(521);
+ // Word-level carry will be zero
word carry = bigint_add3_nc(x.mutable_data(), x.data(), p_words, ws.data(), p_words);
BOTAN_ASSERT_EQUAL(carry, 0, "Final final carry in P-521 reduction");
- x.reduce_below(prime_p521(), ws);
+ // Now find the actual carry in bit 522
+ const uint8_t bit_522_set = x.word_at(p_full_words) >> (p_top_bits);
+
+ if(bit_522_set)
+ {
+#if (BOTAN_MP_WORD_BITS == 64)
+ static const word p521_words[9] = {
+ 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF,
+ 0x1FF };
+
+ bigint_sub2(x.mutable_data(), x.size(), p521_words, 9);
+#else
+ x -= prime_p521();
+#endif
+ }
}
#if defined(BOTAN_HAS_NIST_PRIME_REDUCERS_W32)