aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBryan A Ford <brynosaurus@gmail.com>2017-06-10 09:34:40 +0200
committerBrad Fitzpatrick <bradfitz@golang.org>2017-11-10 03:47:57 +0000
commitd58bf64d5acbcad1ae5b605228ce51038d4df631 (patch)
tree4e5a2fba8cec6466027d2920e90511464be97381 /src
parenta10884838aabb854e3a6595791c663bb16ca32ca (diff)
downloadgo-d58bf64d5acbcad1ae5b605228ce51038d4df631.tar.xz
crypto/subtle: simplify and speed up constant-time primitives
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>
Diffstat (limited to 'src')
-rw-r--r--src/crypto/subtle/constant_time.go16
-rw-r--r--src/crypto/subtle/constant_time_test.go32
2 files changed, 34 insertions, 14 deletions
diff --git a/src/crypto/subtle/constant_time.go b/src/crypto/subtle/constant_time.go
index 11312b8dd4..9f5fee87e3 100644
--- a/src/crypto/subtle/constant_time.go
+++ b/src/crypto/subtle/constant_time.go
@@ -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)
diff --git a/src/crypto/subtle/constant_time_test.go b/src/crypto/subtle/constant_time_test.go
index 619a454441..033301a6e4 100644
--- a/src/crypto/subtle/constant_time_test.go
+++ b/src/crypto/subtle/constant_time_test.go
@@ -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)
+}