Source file src/crypto/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 implements functions that are often useful in cryptographic 6 // code but require careful thought to use correctly. 7 package subtle 8 9 // ConstantTimeCompare returns 1 if the two slices, x and y, have equal contents 10 // and 0 otherwise. The time taken is a function of the length of the slices and 11 // is independent of the contents. 12 func ConstantTimeCompare(x, y []byte) int { 13 if len(x) != len(y) { 14 return 0 15 } 16 17 var v byte 18 19 for i := 0; i < len(x); i++ { 20 v |= x[i] ^ y[i] 21 } 22 23 return ConstantTimeByteEq(v, 0) 24 } 25 26 // ConstantTimeSelect returns x if v == 1 and y if v == 0. 27 // Its behavior is undefined if v takes any other value. 28 func ConstantTimeSelect(v, x, y int) int { return ^(v-1)&x | (v-1)&y } 29 30 // ConstantTimeByteEq returns 1 if x == y and 0 otherwise. 31 func ConstantTimeByteEq(x, y uint8) int { 32 return int((uint32(x^y) - 1) >> 31) 33 } 34 35 // ConstantTimeEq returns 1 if x == y and 0 otherwise. 36 func ConstantTimeEq(x, y int32) int { 37 return int((uint64(uint32(x^y)) - 1) >> 63) 38 } 39 40 // ConstantTimeCopy copies the contents of y into x (a slice of equal length) 41 // if v == 1. If v == 0, x is left unchanged. Its behavior is undefined if v 42 // takes any other value. 43 func ConstantTimeCopy(v int, x, y []byte) { 44 if len(x) != len(y) { 45 panic("subtle: slices have different lengths") 46 } 47 48 xmask := byte(v - 1) 49 ymask := byte(^(v - 1)) 50 for i := 0; i < len(x); i++ { 51 x[i] = x[i]&xmask | y[i]&ymask 52 } 53 } 54 55 // ConstantTimeLessOrEq returns 1 if x <= y and 0 otherwise. 56 // Its behavior is undefined if x or y are negative or > 2**31 - 1. 57 func ConstantTimeLessOrEq(x, y int) int { 58 x32 := int32(x) 59 y32 := int32(y) 60 return int(((x32 - y32 - 1) >> 31) & 1) 61 } 62