From: Alexander Yastrebov Date: Fri, 7 Feb 2025 11:29:34 +0000 (+0000) Subject: crypto/internal/fips140/edwards25519/field: speed up Element.Bytes X-Git-Tag: go1.25rc1~1134 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=9125e214a1d3341836d41ec3f297f42b9b141db1;p=gostls13.git crypto/internal/fips140/edwards25519/field: speed up Element.Bytes Write bytes in 64-bit chunks made from adjacent limbs. goos: linux goarch: amd64 pkg: crypto/internal/fips140/edwards25519/field cpu: Intel(R) Core(TM) i5-8350U CPU @ 1.70GHz │ HEAD~1 │ HEAD │ │ sec/op │ sec/op vs base │ Bytes-8 76.14n ± 3% 13.61n ± 3% -82.13% (p=0.000 n=10) │ HEAD~1 │ HEAD │ │ B/op │ B/op vs base │ Bytes-8 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ ¹ all samples are equal │ HEAD~1 │ HEAD │ │ allocs/op │ allocs/op vs base │ Bytes-8 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ ¹ all samples are equal Change-Id: Iaecc32da7fd8df96ff048e1e855a990f44dc9db5 GitHub-Last-Rev: d0e1583a4faf8cc3471af03437107cc0e5770d57 GitHub-Pull-Request: golang/go#71603 Reviewed-on: https://go-review.googlesource.com/c/go/+/647595 Reviewed-by: Filippo Valsorda Reviewed-by: Roland Shoemaker LUCI-TryBot-Result: Go LUCI Reviewed-by: Cherry Mui Auto-Submit: Filippo Valsorda --- diff --git a/src/crypto/internal/fips140/edwards25519/field/fe.go b/src/crypto/internal/fips140/edwards25519/field/fe.go index 2d76ba7274..21bedefa0c 100644 --- a/src/crypto/internal/fips140/edwards25519/field/fe.go +++ b/src/crypto/internal/fips140/edwards25519/field/fe.go @@ -233,18 +233,22 @@ func (v *Element) bytes(out *[32]byte) []byte { t := *v t.reduce() - var buf [8]byte - for i, l := range [5]uint64{t.l0, t.l1, t.l2, t.l3, t.l4} { - bitsOffset := i * 51 - byteorder.LEPutUint64(buf[:], l<= len(out) { - break - } - out[off] |= bb - } - } + // Pack five 51-bit limbs into four 64-bit words: + // + // 255 204 153 102 51 0 + // ├──l4──┼──l3──┼──l2──┼──l1──┼──l0──┤ + // ├───u3───┼───u2───┼───u1───┼───u0───┤ + // 256 192 128 64 0 + + u0 := t.l1<<51 | t.l0 + u1 := t.l2<<(102-64) | t.l1>>(64-51) + u2 := t.l3<<(153-128) | t.l2>>(128-102) + u3 := t.l4<<(204-192) | t.l3>>(192-153) + + byteorder.LEPutUint64(out[0*8:], u0) + byteorder.LEPutUint64(out[1*8:], u1) + byteorder.LEPutUint64(out[2*8:], u2) + byteorder.LEPutUint64(out[3*8:], u3) return out[:] } diff --git a/src/crypto/internal/fips140/edwards25519/field/fe_bench_test.go b/src/crypto/internal/fips140/edwards25519/field/fe_bench_test.go index 84fdf05a8e..fb80ca88fe 100644 --- a/src/crypto/internal/fips140/edwards25519/field/fe_bench_test.go +++ b/src/crypto/internal/fips140/edwards25519/field/fe_bench_test.go @@ -47,3 +47,11 @@ func BenchmarkMult32(b *testing.B) { x.Mult32(x, 0xaa42aa42) } } + +func BenchmarkBytes(b *testing.B) { + x := new(Element).One() + b.ResetTimer() + for i := 0; i < b.N; i++ { + x.Bytes() + } +}