Skip to content

Commit

Permalink
Add explicit addition chains for P-256 scalar and k1 field/scalar inv…
Browse files Browse the repository at this point in the history
…ersions

Improves ECDSA signing perf by almost 5% and ~1% for ECDSA verify/ECDH
  • Loading branch information
randombit committed Jul 20, 2024
1 parent a46783c commit 0f2514b
Show file tree
Hide file tree
Showing 2 changed files with 209 additions and 3 deletions.
138 changes: 135 additions & 3 deletions src/lib/math/pcurves/pcurves_secp256k1/pcurves_secp256k1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,145 @@ class Params final : public EllipticCurveParameters<
};

// clang-format on

#if BOTAN_MP_WORD_BITS == 64
class Curve final : public EllipticCurve<Params, Secp256k1Rep> {};
typedef EllipticCurve<Params, Secp256k1Rep> Secp256k1Base;
#else
class Curve final : public EllipticCurve<Params> {};
typedef EllipticCurve<Params> Secp256k1Base;
#endif

class Curve final : public Secp256k1Base {
public:
// Return the square of the inverse of x
static FieldElement fe_invert2(const FieldElement& x) {
auto z = x.square();
z *= x;
auto t0 = z;
t0.square_n(2);
t0 *= z;
auto t1 = t0.square();
auto t2 = t1 * x;
t1 = t2;
t1.square_n(2);
t1 *= z;
auto t3 = t1;
t3.square_n(4);
t0 *= t3;
t3 = t0;
t3.square_n(11);
t0 *= t3;
t3 = t0;
t3.square_n(5);
t2 *= t3;
t3 = t2;
t3.square_n(27);
t2 *= t3;
t3 = t2;
t3.square_n(54);
t2 *= t3;
t3 = t2;
t3.square_n(108);
t2 *= t3;
t2.square_n(7);
t1 *= t2;
t1.square_n(23);
t0 *= t1;
t0.square_n(5);
t0 *= x;
t0.square_n(3);
z *= t0;
z.square_n(2);
return z;
}

static Scalar scalar_invert(const Scalar& x) {
auto z = x.square();
auto t2 = x * z;
auto t6 = t2 * z;
auto t5 = t6 * z;
auto t0 = t5 * z;
auto t3 = t0 * z;
auto t1 = t3 * z;
z = t1;
z.square_n(2);
z *= t3;
auto t4 = z.square();
auto t7 = t4 * x;
t4 = t7.square();
t4 *= x;
auto t9 = t4;
t9.square_n(3);
auto t10 = t9;
t10.square_n(2);
auto t11 = t10.square();
auto t8 = t11.square();
auto t12 = t8;
t12.square_n(7);
t11 *= t12;
t11.square_n(9);
t8 *= t11;
t11 = t8;
t11.square_n(6);
t10 *= t11;
t10.square_n(26);
t8 *= t10;
t10 = t8;
t10.square_n(4);
t9 *= t10;
t9.square_n(60);
t8 *= t9;
t7 *= t8;
t7.square_n(5);
t7 *= t3;
t7.square_n(3);
t7 *= t6;
t7.square_n(4);
t7 *= t6;
t7.square_n(4);
t7 *= t5;
t7.square_n(5);
t7 *= t1;
t7.square_n(2);
t7 *= t2;
t7.square_n(5);
t7 *= t5;
t7.square_n(6);
t7 *= t1;
t7.square_n(5);
t7 *= t3;
t7.square_n(4);
t7 *= t1;
t7.square_n(3);
t7 *= x;
t7.square_n(6);
t6 *= t7;
t6.square_n(10);
t6 *= t5;
t6.square_n(4);
t5 *= t6;
t5.square_n(9);
t4 *= t5;
t4.square_n(5);
t4 *= t0;
t4.square_n(6);
t3 *= t4;
t3.square_n(4);
t3 *= t1;
t3.square_n(5);
t2 *= t3;
t2.square_n(6);
t2 *= t1;
t2.square_n(10);
t1 *= t2;
t1.square_n(4);
t0 *= t1;
t0.square_n(6);
t0 *= x;
t0.square_n(8);
z *= t0;
return z;
}
};

} // namespace secp256k1

} // namespace
Expand Down
74 changes: 74 additions & 0 deletions src/lib/math/pcurves/pcurves_secp256r1/pcurves_secp256r1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,80 @@ class Curve final : public EllipticCurve<Params, Secp256r1Rep> {

return r;
}

static Scalar scalar_invert(const Scalar& x) {
auto t1 = x.square();
auto t5 = t1.square();
auto t2 = t5 * x;
auto t10 = t2 * x;
auto t3 = t2 * t5;
auto z = t10 * t3;
auto t9 = t3.square();
auto t4 = t10 * z;
auto t0 = t10 * t9;
auto t13 = t0 * t1;
auto t8 = t13 * t4;
t4 = t3 * t8;
auto t7 = t2 * t4;
t2 = t1 * t7;
auto t6 = t7 * t9;
t3 = t6 * t9;
t1 *= t3;
auto t12 = t3 * t9;
t5 *= t12;
auto t11 = t10 * t5;
t0 *= t11;
t9 *= t0;
t10 *= t9;
t4 *= t10;
t13 *= t4;
auto t14 = t13;
t14.square_n(8);
t13 *= t14;
t14 = t13;
t14.square_n(16);
t14 *= t13;
t14.square_n(48);
t14 *= t13;
t14.square_n(16);
t14 *= t13;
t14.square_n(16);
t14 *= t13;
t14.square_n(16);
t13 *= t14;
t13.square_n(6);
t13 *= t8;
t13.square_n(9);
t12 *= t13;
t12.square_n(8);
t11 *= t12;
t11.square_n(9);
t10 *= t11;
t10.square_n(8);
t9 *= t10;
t9.square_n(9);
t8 *= t9;
t8.square_n(8);
t7 *= t8;
t7.square_n(11);
t6 *= t7;
t6.square_n(9);
t5 *= t6;
t5.square_n(10);
t4 *= t5;
t4.square_n(8);
t3 *= t4;
t3.square_n(7);
t2 *= t3;
t2.square_n(10);
t1 *= t2;
t1.square_n(10);
t0 *= t1;
t0.square_n(6);
z *= t0;

return z;
}
};

} // namespace secp256r1
Expand Down

0 comments on commit 0f2514b

Please sign in to comment.