[go] cmd/compile: add intrinsics for subtle.ConstantTimeSelect

0 views
Skip to first unread message

Jorropo (Gerrit)

unread,
Oct 28, 2025, 2:29:27 AM (yesterday) Oct 28
to goph...@pubsubhelper.golang.org, golang-...@googlegroups.com, Michael Knyszek, Go LUCI, Keith Randall, Keith Randall, Filippo Valsorda, golang-co...@googlegroups.com

Jorropo submitted the change with unreviewed changes

Unreviewed changes

10 is the latest approved patch-set.
The change was submitted with unreviewed changes in the following files:

```
The name of the file: src/cmd/compile/internal/ssagen/intrinsics.go
Insertions: 1, Deletions: 1.

@@ -1603,7 +1603,7 @@
},
sys.AMD64)

- /******** crypto/internal/fips140/subtle ********/
+ /******** crypto/subtle ********/
// We implement a superset of the ConstantTimeSelect promise:
// ConstantTimeSelect returns x if v != 0 and y if v == 0.
add("crypto/subtle", "ConstantTimeSelect",
```

Change information

Commit message:
crypto/subtle,cmd/compile: add intrinsics for ConstantTimeSelect and *Eq

Targeting crypto/subtle rather than
crypto/internal/fips140/subtle after discussion with Filippo.

goos: linux
goarch: amd64
pkg: crypto/subtle
cpu: AMD Ryzen 5 3600 6-Core Processor
│ /tmp/old.logs │ /tmp/new.logs │
│ sec/op │ sec/op vs base │
ConstantTimeSelect-12 0.5246n ± 1% 0.5217n ± 2% ~ (p=0.118 n=10)
ConstantTimeByteEq-12 1.0415n ± 1% 0.5202n ± 2% -50.05% (p=0.000 n=10)
ConstantTimeEq-12 0.7813n ± 2% 0.7819n ± 0% ~ (p=0.897 n=10)
ConstantTimeLessOrEq-12 1.0415n ± 3% 0.7813n ± 1% -24.98% (p=0.000 n=10)
geomean 0.8166n 0.6381n -21.86%

The last three will become 1 lat-cycle (0.25ns) faster once #76066 is fixed.

The Select being that fast with the old code is really impressive.
I am pretty sure this happens because my CPU has BMI1&2 support and
a fusing unit able to translate non BMI code into BMI code.
This benchmark doesn't capture the CACHE gains from the shorter assembly.

It currently compiles as:
v17 = TESTQ <flags> v31 v31 // v != 0
v20 = CMOVQNE <int> v32 v33 v17 (y[int])

It is possible to remove the `TESTQ` by compiletime fusing it with the
compare in a pattern like this:
subtle.ConstantTimeSelect(subtle.ConstantTimeLessOrEq(left, right), right, left)

Saving 2 latency-cycles (1 with #76066 fixed).

Updates #76056
Change-Id: I61a1df99e97a1506f75dae13db529f43846d8f1e
Reviewed-by: Keith Randall <k...@golang.org>
Reviewed-by: Michael Knyszek <mkny...@google.com>
Reviewed-by: Keith Randall <k...@google.com>
Files:
  • M src/cmd/compile/internal/ssagen/intrinsics.go
  • M src/cmd/compile/internal/ssagen/intrinsics_test.go
  • M src/crypto/subtle/constant_time.go
  • M src/crypto/subtle/constant_time_test.go
Change size: M
Delta: 4 files changed, 88 insertions(+), 5 deletions(-)
Branch: refs/heads/master
Submit Requirements:
  • requirement satisfiedCode-Review: +1 by Keith Randall, +1 by Michael Knyszek, +2 by Keith Randall
  • requirement satisfiedTryBots-Pass: LUCI-TryBot-Result+1 by Go LUCI
Open in Gerrit
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: merged
Gerrit-Project: go
Gerrit-Branch: master
Gerrit-Change-Id: I61a1df99e97a1506f75dae13db529f43846d8f1e
Gerrit-Change-Number: 715045
Gerrit-PatchSet: 12
Gerrit-Owner: Jorropo <jorro...@gmail.com>
Gerrit-Reviewer: Filippo Valsorda <fil...@golang.org>
Gerrit-Reviewer: Jorropo <jorro...@gmail.com>
Gerrit-Reviewer: Keith Randall <k...@golang.org>
Gerrit-Reviewer: Keith Randall <k...@google.com>
Gerrit-Reviewer: Michael Knyszek <mkny...@google.com>
open
diffy
satisfied_requirement
Reply all
Reply to author
Forward
0 new messages