From ba2de1aa06335237c44885cb7e7a9964a3eae892 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Mon, 23 Mar 2020 19:48:28 -0500 Subject: [PATCH] secp256k1: Export AddNonConst. This exports the addJacobian func as AddNonConst in order to allow external callers to perform optimized elliptic curve point addition in Jacobian project coordinates in addition to more clearly indentifying that the function is not constant time. This is part of exposing the ec group operations so callers are not forced to round trip through big ints in affine space. --- dcrec/secp256k1/bench_test.go | 12 ++++++------ dcrec/secp256k1/curve.go | 16 ++++++++-------- dcrec/secp256k1/curve_test.go | 2 +- dcrec/secp256k1/ellipticadaptor.go | 2 +- dcrec/secp256k1/genstatics.go | 2 +- dcrec/secp256k1/signature.go | 4 ++-- 6 files changed, 19 insertions(+), 19 deletions(-) diff --git a/dcrec/secp256k1/bench_test.go b/dcrec/secp256k1/bench_test.go index 51a1c80d..a94cfc24 100644 --- a/dcrec/secp256k1/bench_test.go +++ b/dcrec/secp256k1/bench_test.go @@ -9,9 +9,9 @@ import ( "testing" ) -// BenchmarkAddJacobian benchmarks the secp256k1 curve addJacobian function with +// BenchmarkAddNonConst benchmarks the secp256k1 curve AddNonConst function with // Z values of 1 so that the associated optimizations are used. -func BenchmarkAddJacobian(b *testing.B) { +func BenchmarkAddNonConst(b *testing.B) { p1 := jacobianPointFromHex( "34f9460f0e4f08393d192b3c5133a6ba099aa0ad9fd54ebccfacdfa239ff49c6", "0b71ea9bd730fd8923f6d25a7a91e7dd7728a960686cb5a901bb419e0f2ca232", @@ -27,14 +27,14 @@ func BenchmarkAddJacobian(b *testing.B) { b.ResetTimer() var result JacobianPoint for i := 0; i < b.N; i++ { - addJacobian(&p1, &p2, &result) + AddNonConst(&p1, &p2, &result) } } -// BenchmarkAddJacobianNotZOne benchmarks the secp256k1 curve addJacobian +// BenchmarkAddNonConstNotZOne benchmarks the secp256k1 curve AddNonConst // function with Z values other than one so the optimizations associated with // Z=1 aren't used. -func BenchmarkAddJacobianNotZOne(b *testing.B) { +func BenchmarkAddNonConstNotZOne(b *testing.B) { x1 := new(FieldVal).SetHex("d3e5183c393c20e4f464acf144ce9ae8266a82b67f553af33eb37e88e7fd2718") y1 := new(FieldVal).SetHex("5b8f54deb987ec491fb692d3d48f3eebb9454b034365ad480dda0cf079651190") z1 := new(FieldVal).SetHex("2") @@ -48,7 +48,7 @@ func BenchmarkAddJacobianNotZOne(b *testing.B) { b.ResetTimer() var result JacobianPoint for i := 0; i < b.N; i++ { - addJacobian(&p1, &p2, &result) + AddNonConst(&p1, &p2, &result) } } diff --git a/dcrec/secp256k1/curve.go b/dcrec/secp256k1/curve.go index 608ab9de..097230ac 100644 --- a/dcrec/secp256k1/curve.go +++ b/dcrec/secp256k1/curve.go @@ -410,12 +410,12 @@ func addGeneric(p1, p2, result *JacobianPoint) { z3.Normalize() } -// addJacobian adds the passed Jacobian points together and stores the result -// in the provided result param. +// AddNonConst adds the passed Jacobian points together and stores the result in +// the provided result param in *non-constant* time. // // NOTE: The points must be normalized for this function to return the correct // result. The resulting point will be normalized. -func addJacobian(p1, p2, result *JacobianPoint) { +func AddNonConst(p1, p2, result *JacobianPoint) { // A point at infinity is the identity according to the group law for // elliptic curve cryptography. Thus, ∞ + P = P and P + ∞ = P. if (p1.X.IsZero() && p1.Y.IsZero()) || p1.Z.IsZero() { @@ -718,15 +718,15 @@ func scalarMultJacobian(k *ModNScalar, point, result *JacobianPoint) { doubleJacobian(&q, &q) if k1BytePos&0x80 == 0x80 { - addJacobian(&q, p1, &q) + AddNonConst(&q, p1, &q) } else if k1ByteNeg&0x80 == 0x80 { - addJacobian(&q, p1Neg, &q) + AddNonConst(&q, p1Neg, &q) } if k2BytePos&0x80 == 0x80 { - addJacobian(&q, p2, &q) + AddNonConst(&q, p2, &q) } else if k2ByteNeg&0x80 == 0x80 { - addJacobian(&q, p2Neg, &q) + AddNonConst(&q, p2Neg, &q) } k1BytePos <<= 1 k1ByteNeg <<= 1 @@ -759,7 +759,7 @@ func scalarBaseMultJacobian(k *ModNScalar, result *JacobianPoint) { pt.X.Set(&p[0]) pt.Y.Set(&p[1]) pt.Z.Set(&p[2]) - addJacobian(&q, &pt, &q) + AddNonConst(&q, &pt, &q) } result.Set(&q) diff --git a/dcrec/secp256k1/curve_test.go b/dcrec/secp256k1/curve_test.go index 28c01d64..c5c1990e 100644 --- a/dcrec/secp256k1/curve_test.go +++ b/dcrec/secp256k1/curve_test.go @@ -266,7 +266,7 @@ func TestAddJacobian(t *testing.T) { // Add the two points. var r JacobianPoint - addJacobian(&p1, &p2, &r) + AddNonConst(&p1, &p2, &r) // Ensure result matches expected. if !r.IsStrictlyEqual(&want) { diff --git a/dcrec/secp256k1/ellipticadaptor.go b/dcrec/secp256k1/ellipticadaptor.go index e46849e9..b35c9f17 100644 --- a/dcrec/secp256k1/ellipticadaptor.go +++ b/dcrec/secp256k1/ellipticadaptor.go @@ -121,7 +121,7 @@ func (curve *KoblitzCurve) Add(x1, y1, x2, y2 *big.Int) (*big.Int, *big.Int) { var p1, p2, result JacobianPoint bigAffineToJacobian(x1, y1, &p1) bigAffineToJacobian(x2, y2, &p2) - addJacobian(&p1, &p2, &result) + AddNonConst(&p1, &p2, &result) return jacobianToBigAffine(&result) } diff --git a/dcrec/secp256k1/genstatics.go b/dcrec/secp256k1/genstatics.go index 8ccb405e..1613856a 100644 --- a/dcrec/secp256k1/genstatics.go +++ b/dcrec/secp256k1/genstatics.go @@ -57,7 +57,7 @@ func (curve *KoblitzCurve) SerializedBytePoints() []byte { var point JacobianPoint for j := 0; j < 8; j++ { if i>>uint(j)&1 == 1 { - addJacobian(&point, &computingPoints[j], &point) + AddNonConst(&point, &computingPoints[j], &point) } } for i := 0; i < 10; i++ { diff --git a/dcrec/secp256k1/signature.go b/dcrec/secp256k1/signature.go index 0d56eced..d46d3050 100644 --- a/dcrec/secp256k1/signature.go +++ b/dcrec/secp256k1/signature.go @@ -255,7 +255,7 @@ func (sig *Signature) Verify(hash []byte, pubKey *PublicKey) bool { bigAffineToJacobian(pubKey.x, pubKey.y, &Q) scalarBaseMultJacobian(u1, &u1G) scalarMultJacobian(u2, &Q, &u2Q) - addJacobian(&u1G, &u2Q, &X) + AddNonConst(&u1G, &u2Q, &X) // Step 6. // @@ -781,7 +781,7 @@ func RecoverCompact(signature, hash []byte) (*PublicKey, bool, error) { var Q, u1G, u2X JacobianPoint scalarBaseMultJacobian(u1, &u1G) scalarMultJacobian(u2, &X, &u2X) - addJacobian(&u1G, &u2X, &Q) + AddNonConst(&u1G, &u2X, &Q) // Step 10. //