aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/pubkey
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2018-04-19 21:52:21 -0400
committerJack Lloyd <[email protected]>2018-04-19 21:53:03 -0400
commit33f4ceb178adf291109926fefc679949c8037404 (patch)
tree6f285c1cfe200222da4a886c24951b3709fc30d3 /src/lib/pubkey
parente7989a60634dce80124e9a4fa4f3c77c6cea2bbb (diff)
Add Fermat based inversion of P-384 field elements
Cuts about 100K cycles from the inversion, improving ECDSA sign by 10% and ECDH by ~2% Addition chain from https://briansmith.org/ecc-inversion-addition-chains-01 GH #1479
Diffstat (limited to 'src/lib/pubkey')
-rw-r--r--src/lib/pubkey/ec_group/curve_gfp.cpp72
1 files changed, 72 insertions, 0 deletions
diff --git a/src/lib/pubkey/ec_group/curve_gfp.cpp b/src/lib/pubkey/ec_group/curve_gfp.cpp
index b9ff7caaa..112213d6c 100644
--- a/src/lib/pubkey/ec_group/curve_gfp.cpp
+++ b/src/lib/pubkey/ec_group/curve_gfp.cpp
@@ -444,8 +444,80 @@ class CurveGFp_P384 final : public CurveGFp_NIST
const BigInt& get_p() const override { return prime_p384(); }
private:
void redc(BigInt& x, secure_vector<word>& ws) const override { redc_p384(x, ws); }
+ BigInt invert_element(const BigInt& x, secure_vector<word>& ws) const override;
};
+BigInt CurveGFp_P384::invert_element(const BigInt& x, secure_vector<word>& ws) const
+ {
+ BigInt r, x2, x3, x15, x30, tmp, rl;
+
+ r = x;
+ curve_sqr_tmp(r, tmp, ws);
+ curve_mul_tmp(r, x, tmp, ws);
+ x2 = r;
+
+ curve_sqr_tmp(r, tmp, ws);
+ curve_mul_tmp(r, x, tmp, ws);
+
+ x3 = r;
+
+ for(size_t i = 0; i != 3; ++i)
+ curve_sqr_tmp(r, tmp, ws);
+ curve_mul_tmp(r, x3, tmp, ws);
+
+ rl = r;
+ for(size_t i = 0; i != 6; ++i)
+ curve_sqr_tmp(r, tmp, ws);
+ curve_mul_tmp(r, rl, tmp, ws);
+
+ for(size_t i = 0; i != 3; ++i)
+ curve_sqr_tmp(r, tmp, ws);
+ curve_mul_tmp(r, x3, tmp, ws);
+
+ x15 = r;
+ for(size_t i = 0; i != 15; ++i)
+ curve_sqr_tmp(r, tmp, ws);
+ curve_mul_tmp(r, x15, tmp, ws);
+
+ x30 = r;
+ for(size_t i = 0; i != 30; ++i)
+ curve_sqr_tmp(r, tmp, ws);
+ curve_mul_tmp(r, x30, tmp, ws);
+
+ rl = r;
+ for(size_t i = 0; i != 60; ++i)
+ curve_sqr_tmp(r, tmp, ws);
+ curve_mul_tmp(r, rl, tmp, ws);
+
+ rl = r;
+ for(size_t i = 0; i != 120; ++i)
+ curve_sqr_tmp(r, tmp, ws);
+ curve_mul_tmp(r, rl, tmp, ws);
+
+ for(size_t i = 0; i != 15; ++i)
+ curve_sqr_tmp(r, tmp, ws);
+ curve_mul_tmp(r, x15, tmp, ws);
+
+ for(size_t i = 0; i != 31; ++i)
+ curve_sqr_tmp(r, tmp, ws);
+ curve_mul_tmp(r, x30, tmp, ws);
+
+ for(size_t i = 0; i != 2; ++i)
+ curve_sqr_tmp(r, tmp, ws);
+ curve_mul_tmp(r, x2, tmp, ws);
+
+ for(size_t i = 0; i != 94; ++i)
+ curve_sqr_tmp(r, tmp, ws);
+ curve_mul_tmp(r, x30, tmp, ws);
+
+ for(size_t i = 0; i != 2; ++i)
+ curve_sqr_tmp(r, tmp, ws);
+
+ curve_mul_tmp(r, x, tmp, ws);
+
+ return r;
+ }
+
#endif
/**