]> Cypherpunks repositories - gostls13.git/commitdiff
crypto/subtle: simplify and speed up constant-time primitives
authorBryan A Ford <brynosaurus@gmail.com>
Sat, 10 Jun 2017 07:34:40 +0000 (09:34 +0200)
committerBrad Fitzpatrick <bradfitz@golang.org>
Fri, 10 Nov 2017 03:47:57 +0000 (03:47 +0000)
This changes improves the ConstantTimeByteEq and ConstantTimeEq
primitives to both simplify them and improve their performance.

Also, since there were no benchmarks for this package before,
this change adds benchmarks for ConstantTimeByteEq,
ConstantTimeEq, and ConstantTimeLessOrEq.

benchmarks on darwin/amd64, 10 runs on old vs new code:

name                    old time/op  new time/op  delta
ConstantTimeByteEq-4    2.28ns ±16%  1.53ns ± 2%  -33.09%  (p=0.000 n=10+9)
ConstantTimeEq-4        2.77ns ±10%  1.51ns ± 2%  -45.59%  (p=0.000 n=10+9)
ConstantTimeLessOrEq-4  1.52ns ± 8%  1.50ns ± 2%     ~     (p=0.866 n=9+9)

Change-Id: I29b8cbcf158e1f30411720db82d38b4ecd166b15
Reviewed-on: https://go-review.googlesource.com/45310
Reviewed-by: Adam Langley <agl@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Adam Langley <agl@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/crypto/subtle/constant_time.go
src/crypto/subtle/constant_time_test.go

index 11312b8dd444018e2e7feb9803b55d8b64d7d124..9f5fee87e3fc4c370776bd8bcb23e8426e4e2a29 100644 (file)
@@ -29,24 +29,12 @@ func ConstantTimeSelect(v, x, y int) int { return ^(v-1)&x | (v-1)&y }
 
 // ConstantTimeByteEq returns 1 if x == y and 0 otherwise.
 func ConstantTimeByteEq(x, y uint8) int {
-       z := ^(x ^ y)
-       z &= z >> 4
-       z &= z >> 2
-       z &= z >> 1
-
-       return int(z)
+       return int((uint32(x^y) - 1) >> 31)
 }
 
 // ConstantTimeEq returns 1 if x == y and 0 otherwise.
 func ConstantTimeEq(x, y int32) int {
-       z := ^(x ^ y)
-       z &= z >> 16
-       z &= z >> 8
-       z &= z >> 4
-       z &= z >> 2
-       z &= z >> 1
-
-       return int(z & 1)
+       return int((uint64(uint32(x^y)) - 1) >> 63)
 }
 
 // ConstantTimeCopy copies the contents of y into x (a slice of equal length)
index 619a454441d9570d3e10a1a930dbbdb95c657676..033301a6e4a87936d29bdb086607a97283a4eb0e 100644 (file)
@@ -125,3 +125,35 @@ func TestConstantTimeLessOrEq(t *testing.T) {
                }
        }
 }
+
+var benchmarkGlobal uint8
+
+func BenchmarkConstantTimeByteEq(b *testing.B) {
+       var x, y uint8
+
+       for i := 0; i < b.N; i++ {
+               x, y = uint8(ConstantTimeByteEq(x, y)), x
+       }
+
+       benchmarkGlobal = x
+}
+
+func BenchmarkConstantTimeEq(b *testing.B) {
+       var x, y int
+
+       for i := 0; i < b.N; i++ {
+               x, y = ConstantTimeEq(int32(x), int32(y)), x
+       }
+
+       benchmarkGlobal = uint8(x)
+}
+
+func BenchmarkConstantTimeLessOrEq(b *testing.B) {
+       var x, y int
+
+       for i := 0; i < b.N; i++ {
+               x, y = ConstantTimeLessOrEq(x, y), x
+       }
+
+       benchmarkGlobal = uint8(x)
+}