def make_test(a, b): # Turn a[], b[] and the result into arrays of 64-bit words result = split64(a * b) a = split64(a) b = split64(b) # Pad the output vector with as many padding zeroes as needed # Computation does not depend on zero terms for _ in xrange(max(len(b), len(a)) - len(b)): b.append("0") for _ in xrange(max(len(b), len(a)) - len(a)): a.append("0") result_len = len(b) + len(a) for _ in xrange(result_len - len(result)): result.append("0") # Fill output buffer with values that must be overwritten t = ["0xCCCCCCCCCCCCCCCCULL"] * result_len print "" print "void test_%d() {" % counter.next() print " const uint64_t a[] = {" + ", ".join(a) + "};" print " const uint64_t b[] = {" + ", ".join(b) + "};" print " uint64_t t[] = {" + ", ".join(t) + ", 0xAAAAAAAAAAAAAAAAULL};" print " uint64_t scratchpad[%d];" % (3 * len(a)) print " const uint64_t expected_t[] = {" + ", ".join(result) + "};" print "" print " product(t, scratchpad, a, b, %d);" % len(a) print " assert(memcmp(t, expected_t, 8*%d) == 0);" % result_len #print ' printf("t[{0}]=0x%016lX\\n", t[{0}]);'.format(result_len) print " assert(t[%d] == 0xAAAAAAAAAAAAAAAAULL);" % result_len print "}" print ""
def make_test(secret): assert len(secret) == 16 clamped = bytearray(secret) for idx in 3, 7, 11, 15: clamped[idx] &= 15 for idx in 4, 8, 12: clamped[idx] &= 252 split = struct.unpack('<IIII', bytes(clamped)) r_out = [ "0x%08xUL" % x for x in split ] rr_out = [ "0x%08xUL" % ((x>>2)*5) for x in split ] print "" print "void test_%d() {" % counter.next() print " uint8_t secret[16] = {" + ",".join([str(ord(x)) for x in secret]) + "};" print " uint32_t r[5] = { 0 };" print " uint32_t rr[5] = { 0 };" print " const uint32_t expected_r[5] = {" + ", ".join(r_out) + "};" print " const uint32_t expected_rr[5] = {" + ", ".join(rr_out) + "};" print "" print " poly1305_load_r(r, rr, secret);" print " assert(memcmp(r, expected_r, sizeof(r)) == 0);" print " assert(memcmp(rr, expected_rr, sizeof(rr)) == 0);" print "}" print ""
def make_test(a, b): # Turn a[], b[] and the result into arrays of 64-bit words result = split64(a*b) a = split64(a) b = split64(b) # Pad the output vector with as many padding zeroes as needed # Computation does not depend on zero terms for _ in xrange(max(len(b), len(a)) - len(b)): b.append("0") for _ in xrange(max(len(b), len(a)) - len(a)): a.append("0") result_len = len(b) + len(a) for _ in xrange(result_len - len(result)): result.append("0") # Fill output buffer with values that must be overwritten t = [ "0xCCCCCCCCCCCCCCCCULL" ] * result_len print "" print "void test_%d() {" % counter.next() print " const uint64_t a[] = {" + ", ".join(a) + "};" print " const uint64_t b[] = {" + ", ".join(b) + "};" print " uint64_t t[] = {" + ", ".join(t) + ", 0xAAAAAAAAAAAAAAAAULL};" print " uint64_t scratchpad[%d];" % (3*len(a)) print " const uint64_t expected_t[] = {" + ", ".join(result) + "};" print "" print " product(t, scratchpad, a, b, %d);" % len(a) print " assert(memcmp(t, expected_t, 8*%d) == 0);" % result_len #print ' printf("t[{0}]=0x%016lX\\n", t[{0}]);'.format(result_len) print " assert(t[%d] == 0xAAAAAAAAAAAAAAAAULL);" % result_len print "}" print ""
def make_test(secret): assert len(secret) == 16 clamped = bytearray(secret) for idx in 3, 7, 11, 15: clamped[idx] &= 15 for idx in 4, 8, 12: clamped[idx] &= 252 split = struct.unpack('<IIII', clamped) r_out = ["0x%08xUL" % x for x in split] rr_out = ["0x%08xUL" % ((x >> 2) * 5) for x in split] print "" print "void test_%d() {" % counter.next() print " uint8_t secret[16] = {" + ",".join( [str(ord(x)) for x in secret]) + "};" print " uint32_t r[5] = { 0 };" print " uint32_t rr[5] = { 0 };" print " const uint32_t expected_r[5] = {" + ", ".join(r_out) + "};" print " const uint32_t expected_rr[5] = {" + ", ".join(rr_out) + "};" print "" print " poly1305_load_r(r, rr, secret);" print " assert(memcmp(r, expected_r, sizeof(r)) == 0);" print " assert(memcmp(rr, expected_rr, sizeof(rr)) == 0);" print "}" print ""
def make_test(a): # Turn a[] and the result into arrays of 64-bit words result = split64(a**2) a = split64(a) # Computation does not depend on zero terms result_len = 2 * len(a) # Pad the output vector with as many padding zeroes as needed for x in xrange(result_len - len(result)): result.append("0") # Fill output buffer with values that must be overwritten t = ["0xCCCCCCCCCCCCCCCCULL"] * result_len print "" print "void test_%d() {" % counter.next() print " const uint64_t a[] = {" + ", ".join(a) + "};" print " uint64_t t[] = {" + ", ".join(t) + ", 0xAAAAAAAAAAAAAAAAULL};" print " const uint64_t expected_t[] = {" + ", ".join(result) + "};" print " size_t result;" print "" print " result = square_w(t, a, %d);" % len(a) print " assert(memcmp(t, expected_t, 8*%d) == 0);" % result_len #print ' printf("t[{0}]=0x%016lX\\n", t[{0}]);'.format(result_len) print " assert(t[%d] == 0xAAAAAAAAAAAAAAAAULL);" % result_len print " assert(result == %d);" % result_len print "}" print ""
def make_test(value): result = value % (2**130 - 5) h_in = split32(value, 5) h_out = split32(result, 5) print "" print "void test_%d() {" % counter.next() print " uint32_t h[5] = {" + ", ".join(h_in) + "};" print " const uint32_t expected_h[5] = {" + ", ".join(h_out) + "};" print "" print " poly1305_reduce(h);" print " assert(memcmp(h, expected_h, sizeof(h)) == 0);" print "}" print ""
def make_test(term, secret): assert term < 2**(32*5) assert len(secret) == 16 # Several bits in the secret must be cleared clamped = bytearray(secret) for idx in 3, 7, 11, 15: clamped[idx] &= 15 for idx in 4, 8, 12: clamped[idx] &= 252 # Turn the secret into an integer r r = 0 for x in clamped[::-1]: r = (r * 256) + x # Work out what the results (2 or 3) should be p = 2**130 - 5 result = (term * r) % p all_results = [] while result < 2**131: all_results.append(split32(result, 5)) result += p n_results = len(all_results) # Split the term into 32-bit words h_split = split32(term, 5) print "" print "void test_%d() {" % counter.next() print " uint8_t secret[16] = {" + ",".join([str(ord(x)) for x in secret]) + "};" print " uint32_t r[4], rr[4];" print " uint32_t h[5] = {" + ",".join(h_split) + "};" print " int match;"; for x in range(n_results): y = ",".join(all_results[x]) print " uint32_t expected_h_%d[5] = { %s };" % (x+1, y) print "" print " poly1305_load_r(r, rr, secret);" print " poly1305_multiply(h, r, rr);" print " match = !0;" for x in range(n_results): print " match = match && memcmp(h, expected_h_%d, sizeof(h));" % (x+1) print " assert(match == 0);" print "}" print ""
def make_test(term1, term2): assert term1 < 2**(32*5) assert term2 < 2**(32*5) t1_split = split32(term1, 5) t2_split = split32(term2, 5) res_split = split32(term1 + term2, 5) print "" print "void test_%d() {" % counter.next() print " uint32_t h[5] = {" + ",".join(t1_split) + "};" print " uint32_t m[5] = {" + ",".join(t2_split) + "};" print " uint32_t w[5] = {" + ",".join(res_split) + "};" print " poly1305_accumulate(h, m);" print " assert(0 == memcmp(h, w, sizeof(h)));" print "}" print ""
def make_test(term1, term2): assert term1 < 2**(32 * 5) assert term2 < 2**(32 * 5) t1_split = split32(term1, 5) t2_split = split32(term2, 5) res_split = split32(term1 + term2, 5) print "" print "void test_%d() {" % counter.next() print " uint32_t h[5] = {" + ",".join(t1_split) + "};" print " uint32_t m[5] = {" + ",".join(t2_split) + "};" print " uint32_t w[5] = {" + ",".join(res_split) + "};" print " poly1305_accumulate(h, m);" print " assert(0 == memcmp(h, w, sizeof(h)));" print "}" print ""
def make_test(secret): assert len(secret) <= 16 padded = secret + b"\x01" + b"\x00" * (20 - len(secret) - 1) split = struct.unpack('<IIIII', padded) m_out = [ "0x%08xUL" % x for x in split ] print "" print "void test_%d() {" % counter.next() print " uint8_t secret[%d] = {" % len(secret), print ",".join([str(ord(x)) for x in secret]) + "};" print " uint32_t m[5] = { 0 };" print " const uint32_t expected_m[5] = {" + ", ".join(m_out) + "};" print "" print " poly1305_load_m(m, secret, %d);" % len(secret) print " assert(memcmp(m, expected_m, sizeof(m)) == 0);" print "}" print ""
def make_test(secret): assert len(secret) <= 16 padded = secret + b"\x01" + b"\x00" * (20 - len(secret) - 1) split = struct.unpack('<IIIII', padded) m_out = ["0x%08xUL" % x for x in split] print "" print "void test_%d() {" % counter.next() print " uint8_t secret[%d] = {" % len(secret), print ",".join([str(ord(x)) for x in secret]) + "};" print " uint32_t m[5] = { 0 };" print " const uint32_t expected_m[5] = {" + ", ".join(m_out) + "};" print "" print " poly1305_load_m(m, secret, %d);" % len(secret) print " assert(memcmp(m, expected_m, sizeof(m)) == 0);" print "}" print ""
def make_test(t, a, k): if k == -1: k = 0xFFFFFFFFFFFFFFFF assert (0 <= k < 0x10000000000000000) # What we expect the function to compute result = t + a * k # Turn a[] and t[] into arrays of 64-bit words a = split64(a) t_in = split64(t) result = split64(result) # Computation does not depend on zero terms result_len = max(len(result), 1 + len(a)) # Pad the output vector with as many padding zeroes as needed for x in xrange(result_len - len(t_in)): t_in.append("0") for x in xrange(result_len - len(result)): result.append("0") test_nr = counter.next() print "" print "void test_%d() {" % test_nr #print ' printf("Test #%d\\n");' % test_nr print " const uint64_t a[] = {" + ", ".join(a) + "};" print " uint64_t t[] = {" + ", ".join( t_in) + ", 0xAAAAAAAAAAAAAAAAULL};" print " const uint64_t expected_t[] = {" + ", ".join(result) + "};" print "" print " addmul(t, a, 0x%x, %d, %d);" % (k, len(a), result_len) print " assert(memcmp(t, expected_t, 8*%d) == 0);" % result_len print " assert(t[%d] == 0xAAAAAAAAAAAAAAAAULL);" % result_len print "}" print ""
def make_test(t, a, b0, b1): if b0 == -1: b0 = 0xFFFFFFFF if b1 == -1: b1 = 0xFFFFFFFF # What we expect the function to compute result = t + a * (b0 + (b1 << 64)) # Turn a[] and t[] into arrays of 64-bit words a = split64(a) t_in = split64(t) result = split64(result) # Computation does not depend on zero terms result_len = max(len(result), 2 + len(a)) # Pad the output vector with as many padding zeroes as needed for x in xrange(result_len - len(t_in)): t_in.append("0") for x in xrange(result_len - len(result)): result.append("0") print "" print "void test_%d() {" % counter.next() print " const uint64_t a[] = {" + ", ".join(a) + "};" print " uint64_t t[] = {" + ", ".join( t_in) + ", 0xAAAAAAAAAAAAAAAAULL};" print " uint64_t scratchpad[%d];" % (len(t_in) + len(a)) print " const uint64_t expected_t[] = {" + ", ".join(result) + "};" print "" print " addmul128(t, scratchpad, a, 0x%x, 0x%x, %d, %d);" % ( b0, b1, len(t_in), len(a)) print " assert(memcmp(t, expected_t, 8*%d) == 0);" % result_len print " assert(t[%d] == 0xAAAAAAAAAAAAAAAAULL);" % result_len print "}" print ""
def make_test(t, a, k): if k == -1: k = 0xFFFFFFFFFFFFFFFF assert(0 <= k < 0x10000000000000000) # What we expect the function to compute result = t + a*k # Turn a[] and t[] into arrays of 64-bit words a = split64(a) t_in = split64(t) result = split64(result) # Computation does not depend on zero terms result_len = max(len(result), 1 + len(a)) # Pad the output vector with as many padding zeroes as needed for x in xrange(result_len - len(t_in)): t_in.append("0") for x in xrange(result_len - len(result)): result.append("0") test_nr = counter.next() print "" print "void test_%d() {" % test_nr #print ' printf("Test #%d\\n");' % test_nr print " const uint64_t a[] = {" + ", ".join(a) + "};" print " uint64_t t[] = {" + ", ".join(t_in) + ", 0xAAAAAAAAAAAAAAAAULL};" print " const uint64_t expected_t[] = {" + ", ".join(result) + "};" print "" print " addmul(t, %d, a, %d, 0x%x);" % (result_len, len(a), k) print " assert(memcmp(t, expected_t, 8*%d) == 0);" % result_len print " assert(t[%d] == 0xAAAAAAAAAAAAAAAAULL);" % result_len print "}" print ""
def make_test(t, a, b0, b1): if b0 == -1: b0 = 0xFFFFFFFF if b1 == -1: b1 = 0xFFFFFFFF # What we expect the function to compute result = t + a*(b0 + (b1 << 64)) # Turn a[] and t[] into arrays of 64-bit words a = split64(a) t_in = split64(t) result = split64(result) # Computation does not depend on zero terms result_len = max(len(result), 2 + len(a)) # Pad the output vector with as many padding zeroes as needed for x in xrange(result_len - len(t_in)): t_in.append("0") for x in xrange(result_len - len(result)): result.append("0") print "" print "void test_%d() {" % counter.next() print " const uint64_t a[] = {" + ", ".join(a) + "};" print " uint64_t t[] = {" + ", ".join(t_in) + ", 0xAAAAAAAAAAAAAAAAULL};" print " uint64_t scratchpad[%d];" % (len(t_in) + len(a)) print " const uint64_t expected_t[] = {" + ", ".join(result) + "};" print "" print " addmul128(t, scratchpad, a, 0x%x, 0x%x, %d, %d);" % (b0, b1, len(t_in), len(a)) print " assert(memcmp(t, expected_t, 8*%d) == 0);" % result_len print " assert(t[%d] == 0xAAAAAAAAAAAAAAAAULL);" % result_len print "}" print ""
def make_test(a, b, modulus): assert (0 <= a < modulus) assert (0 <= b < modulus) assert (modulus & 1) R = 1 nw = 0 B = 1 << 64 while modulus >= R: R <<= 64 nw += 1 n0 = modulus & (B - 1) m0 = -inverse(n0, B) % B assert (0 < m0 < B) a_m = (a * R) % modulus b_m = (b * R) % modulus # What we expect the function to compute result_m = (a * b * R) % modulus # Turn data into arrays of 64-bit words a_m_s = split64(a_m) b_m_s = split64(b_m) modulus_s = split64(modulus) result_m_s = split64(result_m) # Everything must have nw words for ds in (a_m_s, b_m_s, modulus_s, result_m_s): ds += ["0"] * (nw - len(ds)) # Modulus also byte encoded, big endian modulus_b = [] while modulus > 0: modulus_b.insert(0, hex(modulus % 256)) modulus >>= 8 test_nr = counter.next() print "" print "void test_%d() {" % test_nr print " const uint64_t a[] = {" + ", ".join(a_m_s) + "};" print " const uint64_t b[] = {" + ", ".join(b_m_s) + "};" print " const uint64_t n[] = {" + ", ".join(modulus_s) + "};" print " const uint64_t expected[] = {" + ", ".join(result_m_s) + "};" print " uint64_t out[%d];" % (nw + 1) print " uint64_t scratch[%d];" % (3 * nw + 1) print "" print " memset(out, 0xAA, sizeof out);" print " mont_mult_internal(out, a, b, n, %dUL, scratch, %d);" % (m0, nw) print " assert(memcmp(out, expected, 8*%d) == 0);" % nw print " assert(out[%d] == 0xAAAAAAAAAAAAAAAAUL);" % nw print "}" print "" test_nr = counter.next() print "" print "void test_%d() {" % test_nr print " const uint64_t a[] = {" + ", ".join(a_m_s) + "};" print " const uint64_t b[] = {" + ", ".join(b_m_s) + "};" print " const uint8_t modulus[] = {" + ", ".join(modulus_b) + "};" print " const uint64_t expected[] = {" + ", ".join(result_m_s) + "};" print " uint64_t out[%d];" % (nw + 1) print " MontContext *ctx;" print " int res;" print " uint64_t scratch[%d];" % (3 * nw + 1) print "" print print " res = mont_context_init(&ctx, modulus, sizeof modulus);" print " assert(res == 0);" print " memset(out, 0xAA, sizeof out);" print " res = mont_mult(out, a, b, scratch, ctx);" print " assert(res == 0);" print " assert(out[%d] == 0xAAAAAAAAAAAAAAAAUL);" % nw print " assert(memcmp(out, expected, 8*%d) == 0);" % nw print " mont_context_free(ctx);" print "}" print ""