Allow any integer type to use CT.isEqual(). (#51)
* Allow any integer type to use CT.isEqual(). * Add tests for different integer types.
This commit is contained in:
parent
a5560c1ea6
commit
4c695e5933
|
@ -11,9 +11,15 @@
|
|||
|
||||
type
|
||||
CT* = object
|
||||
AnyByte* = byte | char
|
||||
|
||||
proc isEqual*[A: AnyByte, B: AnyByte](c: typedesc[CT], a: openArray[A],
|
||||
when sizeof(int) == 8:
|
||||
type
|
||||
AnyItem* = byte|char|int8|uint16|int16|uint32|int32|uint64|int64|uint|int
|
||||
elif sizeof(int) == 4:
|
||||
type
|
||||
AnyItem* = byte|char|int8|uint16|int16|uint32|int32|uint|int
|
||||
|
||||
proc isEqual*[A: AnyItem, B: AnyItem](c: typedesc[CT], a: openArray[A],
|
||||
b: openArray[B]): bool {.
|
||||
raises: [Defect] .} =
|
||||
## Perform constant time comparison of two arrays ``a`` and ``b``.
|
||||
|
@ -25,11 +31,15 @@ proc isEqual*[A: AnyByte, B: AnyByte](c: typedesc[CT], a: openArray[A],
|
|||
## part of array's content is equal to another array's content if arrays
|
||||
## lengths are different.
|
||||
##
|
||||
## Beware that arrays ``a`` and ``b`` MUST NOT BE empty.
|
||||
## Beware that arrays ``a`` and ``b`` MUST NOT BE empty. Types ``A`` and
|
||||
## ``B`` should be equal in size, e.g. ``(sizeof(A) == sizeof(B))``
|
||||
doAssert(len(a) > 0 and len(b) > 0)
|
||||
doAssert(sizeof(A) == sizeof(B))
|
||||
var count = min(len(a), len(b))
|
||||
var res = 0
|
||||
var res = 0'u
|
||||
while count > 0:
|
||||
dec(count)
|
||||
res = res or int(int(a[count]) xor int(b[count]))
|
||||
(res == 0)
|
||||
let av = when A is uint: a[count] else: uint(a[count])
|
||||
let bv = when B is uint: b[count] else: uint(b[count])
|
||||
res = res or (av xor bv)
|
||||
(res == 0'u)
|
||||
|
|
|
@ -28,6 +28,26 @@ suite "Constant-time operations test suite":
|
|||
seq4 = @byteArr4
|
||||
seq5 = @byteArr5
|
||||
|
||||
int8Arr = [1'i8, 2'i8, 3'i8]
|
||||
int16Arr = [1'i16, 2'i16, 3'i16]
|
||||
int32Arr = [1'i32, 2'i32, 3'i32]
|
||||
intArr = [1, 2, 3]
|
||||
|
||||
uint8Arr = [1'u8, 2'u8, 3'u8]
|
||||
uint16Arr = [1'u16, 2'u16, 3'u16]
|
||||
uint32Arr = [1'u32, 2'u32, 3'u32]
|
||||
uintArr = [1'u, 2'u, 3'u]
|
||||
|
||||
var
|
||||
emptyArray: array[0, byte]
|
||||
emptyString = ""
|
||||
emptySeq = newSeq[byte]()
|
||||
|
||||
when sizeof(int) == 8:
|
||||
let
|
||||
int64Arr = [1'i64, 2'i64, 3'i64]
|
||||
uint64Arr = [1'u64, 2'u64, 3'u64]
|
||||
|
||||
check:
|
||||
CT.isEqual(charArr1, charArr1) == true
|
||||
CT.isEqual(charArr1, byteArr1) == true
|
||||
|
@ -53,3 +73,33 @@ suite "Constant-time operations test suite":
|
|||
CT.isEqual(str1, byteArr5) == false
|
||||
CT.isEqual(seq1, str5) == false
|
||||
CT.isEqual(charArr1, seq5) == false
|
||||
|
||||
CT.isEqual(int8Arr, int8Arr) == true
|
||||
CT.isEqual(int8Arr, uint8Arr) == true
|
||||
CT.isEqual(int16Arr, int16Arr) == true
|
||||
CT.isEqual(int16Arr, uint16Arr) == true
|
||||
CT.isEqual(int32Arr, int32Arr) == true
|
||||
CT.isEqual(int32Arr, uint32Arr) == true
|
||||
CT.isEqual(intArr, intArr) == true
|
||||
CT.isEqual(intArr, uintArr) == true
|
||||
|
||||
when sizeof(int) == 8:
|
||||
check:
|
||||
CT.isEqual(int64Arr, int64Arr) == true
|
||||
CT.isEqual(int64Arr, uint64Arr) == true
|
||||
|
||||
# Empty arrays
|
||||
expect(AssertionError):
|
||||
discard CT.isEqual(emptyArray, emptyArray)
|
||||
expect(AssertionError):
|
||||
discard CT.isEqual(emptyArray, emptyString)
|
||||
expect(AssertionError):
|
||||
discard CT.isEqual(emptyArray, emptySeq)
|
||||
|
||||
# Arrays, where T is different type size
|
||||
expect(AssertionError):
|
||||
discard CT.isEqual(int8Arr, int16Arr)
|
||||
expect(AssertionError):
|
||||
discard CT.isEqual(int16Arr, int32Arr)
|
||||
expect(AssertionError):
|
||||
discard CT.isEqual(int8Arr, intArr)
|
||||
|
|
Loading…
Reference in New Issue