/**
* Tests run on initialization to ensure build is correct.
*/
+function err (fname: string, vector: string, expected: string, actual: string): void {
+ throw new Error(`${fname} build error from "${vector}": expected ${expected}; actual ${actual}`)
+}
+
+function xpass_equalbytes (vector: string, expected: StaticArray<u8>, actual: StaticArray<u8>): void {
+ if (!equalbytes(expected, actual, 32)) {
+ err('equalbytes', vector, `pass [${expected}]`, `fail [${actual}]`)
+ }
+}
+
+function xfail_equalbytes (vector: string, expected: StaticArray<u8>, actual: StaticArray<u8>): void {
+ if (equalbytes(expected, actual, 32)) {
+ err('equalbytes', vector, `fail [${expected}]`, `pass [${actual}]`)
+ }
+}
/**
- * equalbytes - checks masked bytes against the following test keys:
- * - random bytes
- * - all zeros
- * - all ones
+ * equalbytes must report "unequal" for every difference regardless of shape
+ * - `zeros`: lower boundary with every bit cleared
+ * - `ones`: upper boundary with every bit set
+ * - `spread`: all bytes distinct from each other and setting each bit to 0 or 1
*/
const zeros = new StaticArray<u8>(32).fill(0)
const ones = new StaticArray<u8>(32).fill(255)
-const random = new StaticArray<u8>(32)
+const spread = new StaticArray<u8>(32)
+// 37 is large enough prime to cover all bit positions as either 0 or 1
for (let i = 0; i < 32; i++) {
- random[i] = u8(Math.random() * 256)
+ spread[i] = u8(i * 37)
}
-const vectors = ['zeros', 'ones', 'random',]
-const expecteds = [zeros, ones, random,]
+const vectors = ['zeros', 'ones', 'spread',]
+const expecteds = [zeros, ones, spread,]
const actual = new StaticArray<u8>(32)
const vector = vectors[v]
const expected = expecteds[v]
memory.copy(changetype<usize>(actual), changetype<usize>(expected), 32)
- if (!equalbytes(actual, expected, 32)) {
- throw new Error(`equalbytes build error: ${vector} failed instead of passing (expected [${expected}], actual [${actual}])`)
- }
+ xpass_equalbytes('equal bytes', expected, actual)
+
for (let i = 0; i < 32; i++) {
for (let j = 1; j < 256; j++) {
- actual[i] ^= u8(j)
- if (equalbytes(actual, expected, 32)) {
- throw new Error(`equalbytes build error: ${vector} passed instead of failing (expected [${expected}], actual [${actual}])`)
+ const p = u8(j)
+ const q = u8(256 - j)
+
+ // check that any individual bit difference fails
+ actual[i] ^= p
+ xfail_equalbytes(vector, expected, actual)
+
+ // check that |= was not replaced by ^= or += due to a typo
+ // only necessary to check once per vector, for all bit positions
+ if (i === 0) {
+ actual[i + 1] ^= p
+ xfail_equalbytes(vector, expected, actual)
+ actual[i + 1] ^= p ^ q
+ xfail_equalbytes(vector, expected, actual)
+ actual[i + 1] = expected[i + 1]
}
+
actual[i] = expected[i]
}
}