From fe9a28cd1e4f341105001496b135a58d09717647 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Tue, 19 Mar 2024 12:41:49 -0500 Subject: [PATCH] secp256k1: No allocs in slow scalar base mult path. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This moves the conversion of the base point represented in Jacobian coordinates outside of the slow scalar base multiplication path used in resource constrained environments to avoid unnecessary allocations. name old time/op new time/op delta -------------------------------------------------------------------------------- ScalarBaseMultNonConstSlow 91.9µs ± 1% 91.5µs ± 1% ~ (p=0.280 n=10+10) name old alloc/op new alloc/op delta -------------------------------------------------------------------------------- ScalarBaseMultNonConstSlow 64.0B ± 0% 0.0B -100.00% (p=0.000 n=10+10) name old allocs/op new allocs/op delta -------------------------------------------------------------------------------- ScalarBaseMultNonConstSlow 2.00 ± 0% 0.00 -100.00% (p=0.000 n=10+10) --- dcrec/secp256k1/curve.go | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/dcrec/secp256k1/curve.go b/dcrec/secp256k1/curve.go index 86765ade42..105f8935ec 100644 --- a/dcrec/secp256k1/curve.go +++ b/dcrec/secp256k1/curve.go @@ -1224,11 +1224,17 @@ func ScalarBaseMultNonConst(k *ModNScalar, result *JacobianPoint) { scalarBaseMultNonConst(k, result) } -// scalarBaseMultNonConstSlow computes k*G through ScalarMultNonConst. -func scalarBaseMultNonConstSlow(k *ModNScalar, result *JacobianPoint) { +// jacobianG is the secp256k1 base point converted to Jacobian coordinates and +// is defined here to avoid repeatedly converting it. +var jacobianG = func() JacobianPoint { var G JacobianPoint bigAffineToJacobian(curveParams.Gx, curveParams.Gy, &G) - ScalarMultNonConst(k, &G, result) + return G +}() + +// scalarBaseMultNonConstSlow computes k*G through ScalarMultNonConst. +func scalarBaseMultNonConstSlow(k *ModNScalar, result *JacobianPoint) { + ScalarMultNonConst(k, &jacobianG, result) } // scalarBaseMultNonConstFast computes k*G through the precomputed lookup