diff options
author | Jack Lloyd <[email protected]> | 2018-12-24 12:40:50 -0500 |
---|---|---|
committer | Jack Lloyd <[email protected]> | 2018-12-24 12:40:50 -0500 |
commit | f0600586291da690f1e5d1eb2958052764c60192 (patch) | |
tree | 1755354c679e8e193db974c54927baeebf189692 /src | |
parent | 65f5388cff46ff1b80e85b9e5977d08d9bb165e0 (diff) |
Avoid conditional branch in Barrett for negative inputs
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/math/numbertheory/reducer.cpp | 31 |
1 files changed, 27 insertions, 4 deletions
diff --git a/src/lib/math/numbertheory/reducer.cpp b/src/lib/math/numbertheory/reducer.cpp index ec0071eac..5094ae420 100644 --- a/src/lib/math/numbertheory/reducer.cpp +++ b/src/lib/math/numbertheory/reducer.cpp @@ -7,6 +7,7 @@ #include <botan/reducer.h> #include <botan/internal/ct_utils.h> +#include <botan/internal/mp_core.h> #include <botan/divide.h> namespace Botan { @@ -41,6 +42,31 @@ BigInt Modular_Reducer::reduce(const BigInt& x) const return r; } +namespace { + +/* +* Like if(cnd) x.rev_sub(...) but in const time +*/ +void cnd_rev_sub(bool cnd, BigInt& x, const word y[], size_t y_sw, secure_vector<word>& ws) + { + if(x.sign() != BigInt::Positive) + throw Invalid_State("BigInt::sub_rev requires this is positive"); + + const size_t x_sw = x.sig_words(); + + const size_t max_words = std::max(x_sw, y_sw); + ws.resize(std::max(x_sw, y_sw)); + clear_mem(ws.data(), ws.size()); + x.grow_to(max_words); + + const int32_t relative_size = bigint_sub_abs(ws.data(), x.data(), x_sw, y, y_sw); + + x.cond_flip_sign((relative_size > 0) && cnd); + bigint_cnd_swap(cnd, x.mutable_data(), ws.data(), max_words); + } + +} + void Modular_Reducer::reduce(BigInt& t1, const BigInt& x, secure_vector<word>& ws) const { if(&t1 == &x) @@ -87,10 +113,7 @@ void Modular_Reducer::reduce(BigInt& t1, const BigInt& x, secure_vector<word>& w // Per HAC this step requires at most 2 subtractions t1.ct_reduce_below(m_modulus, ws, 2); - if(x.is_negative() && t1.is_nonzero()) - { - t1.rev_sub(m_modulus.data(), m_modulus.size(), ws); - } + cnd_rev_sub(t1.is_nonzero() && x.is_negative(), t1, m_modulus.data(), m_modulus.size(), ws); } } |