diff options
author | Jack Lloyd <[email protected]> | 2018-04-23 19:01:51 -0400 |
---|---|---|
committer | Jack Lloyd <[email protected]> | 2018-04-23 19:33:06 -0400 |
commit | d1479ede7bc01b60f67d6826611baf43987e941b (patch) | |
tree | 86deee3c166871aa58039c857196f2ef6be6b5e9 /src/lib/math | |
parent | c90d868a533c13501e8d6e3b71919501b9d70f9e (diff) |
Add BigInt::mod_sub
Diffstat (limited to 'src/lib/math')
-rw-r--r-- | src/lib/math/bigint/big_ops2.cpp | 49 | ||||
-rw-r--r-- | src/lib/math/bigint/bigint.h | 16 |
2 files changed, 65 insertions, 0 deletions
diff --git a/src/lib/math/bigint/big_ops2.cpp b/src/lib/math/bigint/big_ops2.cpp index 212a44fa0..242635257 100644 --- a/src/lib/math/bigint/big_ops2.cpp +++ b/src/lib/math/bigint/big_ops2.cpp @@ -95,6 +95,55 @@ BigInt& BigInt::operator-=(const BigInt& y) return (*this); } +BigInt& BigInt::mod_add(const BigInt& s, const BigInt& mod, secure_vector<word>& ws) + { + if(this->is_negative() || s.is_negative() || mod.is_negative()) + throw Invalid_Argument("BigInt::mod_add expects all arguments are positive"); + + // TODO add optimized version of this + *this += s; + this->reduce_below(mod, ws); + + return (*this); + } + +BigInt& BigInt::mod_sub(const BigInt& s, const BigInt& mod, secure_vector<word>& ws) + { + if(this->is_negative() || s.is_negative() || mod.is_negative()) + throw Invalid_Argument("BigInt::mod_sub expects all arguments are positive"); + + const size_t t_sw = sig_words(); + const size_t s_sw = s.sig_words(); + const size_t mod_sw = mod.sig_words(); + + if(t_sw > mod_sw || s_sw > mod_sw) + throw Invalid_Argument("BigInt::mod_sub args larger than modulus"); + + int32_t relative_size = bigint_cmp(data(), t_sw, s.data(), s_sw); + + if(relative_size >= 0) + { + // this >= s in which case just subtract + bigint_sub2(mutable_data(), t_sw, s.data(), s_sw); + } + else + { + // Otherwise we must sub s and then add p (or add (p - s) as here) + + ws.resize(mod_sw + 1); + + bigint_sub3(ws.data(), mod.data(), mod_sw, s.data(), s_sw); + + if(m_reg.size() < mod_sw) + grow_to(mod_sw); + + word carry = bigint_add2_nc(mutable_data(), m_reg.size(), ws.data(), mod_sw); + BOTAN_ASSERT_NOMSG(carry == 0); + } + + return (*this); + } + BigInt& BigInt::rev_sub(const word y[], size_t y_sw, secure_vector<word>& ws) { /* diff --git a/src/lib/math/bigint/bigint.h b/src/lib/math/bigint/bigint.h index eec7f6176..bb7a69541 100644 --- a/src/lib/math/bigint/bigint.h +++ b/src/lib/math/bigint/bigint.h @@ -266,6 +266,22 @@ class BOTAN_PUBLIC_API(2,0) BigInt final BigInt& rev_sub(const word y[], size_t y_size, secure_vector<word>& ws); /** + * Set *this to (*this + y) % mod + * @param y the BigInt to add - assumed y >= 0 and y < mod + * @param mod the positive modulus + * @param ws a temp workspace + */ + BigInt& mod_add(const BigInt& y, const BigInt& mod, secure_vector<word>& ws); + + /** + * Set *this to (*this - y) % mod + * @param y the BigInt to subtract - assumed y >= 0 and y < mod + * @param mod the positive modulus + * @param ws a temp workspace + */ + BigInt& mod_sub(const BigInt& y, const BigInt& mod, secure_vector<word>& ws); + + /** * Return *this below mod * * Assumes that *this is (if anything) only slightly larger than |