Source file src/crypto/internal/fips140/subtle/constant_time.go
1 // Copyright 2009 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package subtle 6 7 // ConstantTimeCompare returns 1 if the two slices, x and y, have equal contents 8 // and 0 otherwise. The time taken is a function of the length of the slices and 9 // is independent of the contents. If the lengths of x and y do not match it 10 // returns 0 immediately. 11 func ConstantTimeCompare(x, y []byte) int { 12 if len(x) != len(y) { 13 return 0 14 } 15 16 var v byte 17 18 for i := 0; i < len(x); i++ { 19 v |= x[i] ^ y[i] 20 } 21 22 return ConstantTimeByteEq(v, 0) 23 } 24 25 // ConstantTimeSelect returns x if v == 1 and y if v == 0. 26 // Its behavior is undefined if v takes any other value. 27 func ConstantTimeSelect(v, x, y int) int { return ^(v-1)&x | (v-1)&y } 28 29 // ConstantTimeByteEq returns 1 if x == y and 0 otherwise. 30 func ConstantTimeByteEq(x, y uint8) int { 31 return int((uint32(x^y) - 1) >> 31) 32 } 33 34 // ConstantTimeEq returns 1 if x == y and 0 otherwise. 35 func ConstantTimeEq(x, y int32) int { 36 return int((uint64(uint32(x^y)) - 1) >> 63) 37 } 38 39 // ConstantTimeCopy copies the contents of y into x (a slice of equal length) 40 // if v == 1. If v == 0, x is left unchanged. Its behavior is undefined if v 41 // takes any other value. 42 func ConstantTimeCopy(v int, x, y []byte) { 43 if len(x) != len(y) { 44 panic("subtle: slices have different lengths") 45 } 46 47 xmask := byte(v - 1) 48 ymask := byte(^(v - 1)) 49 for i := 0; i < len(x); i++ { 50 x[i] = x[i]&xmask | y[i]&ymask 51 } 52 } 53 54 // ConstantTimeLessOrEq returns 1 if x <= y and 0 otherwise. 55 // Its behavior is undefined if x or y are negative or > 2**31 - 1. 56 func ConstantTimeLessOrEq(x, y int) int { 57 x32 := int32(x) 58 y32 := int32(y) 59 return int(((x32 - y32 - 1) >> 31) & 1) 60 } 61