1
2
3
4
5 package subtle
6
7 import (
8 "crypto/internal/constanttime"
9 "crypto/internal/fips140deps/byteorder"
10 "math/bits"
11 )
12
13
14
15
16
17 func ConstantTimeCompare(x, y []byte) int {
18 if len(x) != len(y) {
19 return 0
20 }
21
22 var v byte
23
24 for i := 0; i < len(x); i++ {
25 v |= x[i] ^ y[i]
26 }
27
28 return constanttime.ByteEq(v, 0)
29 }
30
31
32
33
34
35 func ConstantTimeLessOrEqBytes(x, y []byte) int {
36 if len(x) != len(y) {
37 return 0
38 }
39
40
41
42 var b uint64
43 for len(x) > 8 {
44 x0 := byteorder.BEUint64(x[len(x)-8:])
45 y0 := byteorder.BEUint64(y[len(y)-8:])
46 _, b = bits.Sub64(y0, x0, b)
47 x = x[:len(x)-8]
48 y = y[:len(y)-8]
49 }
50 if len(x) > 0 {
51 xb := make([]byte, 8)
52 yb := make([]byte, 8)
53 copy(xb[8-len(x):], x)
54 copy(yb[8-len(y):], y)
55 x0 := byteorder.BEUint64(xb)
56 y0 := byteorder.BEUint64(yb)
57 _, b = bits.Sub64(y0, x0, b)
58 }
59 return int(b ^ 1)
60 }
61
62
63
64
65 func ConstantTimeCopy(v int, x, y []byte) {
66 if len(x) != len(y) {
67 panic("subtle: slices have different lengths")
68 }
69
70 xmask := byte(v - 1)
71 ymask := byte(^(v - 1))
72 for i := 0; i < len(x); i++ {
73 x[i] = x[i]&xmask | y[i]&ymask
74 }
75 }
76
View as plain text