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