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(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(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 range(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() {" % next(counter)) print(" const uint64_t a[] = {" + ", ".join(a) + "};") 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(" square(t, scratchpad, 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("}") print("")
def make_test_max(): v = ["0x%08X" % (2**26 - 1)] * 10 modulus = 2**255 - 19 base = [0, 26, 51, 77, 102, 128, 153, 179, 204, 230] n = 0 for i in range(10): n += (2**26 - 1) * (2**(base[i])) n %= modulus x2_out, z2_out, x3_out, z3_out = ref(n, n, n, n, n) # Output words = split64(x2_out) x2outx = words + ["0"] * (4 - len(words)) words = split64(z2_out) z2outx = words + ["0"] * (4 - len(words)) words = split64(x3_out) x3outx = words + ["0"] * (4 - len(words)) words = split64(z3_out) z3outx = words + ["0"] * (4 - len(words)) print("") print("void test_%d() {" % next(counter)) print(" uint32_t x2[10] = { " + ",".join(v) + " };") print(" uint32_t z2[10] = { " + ",".join(v) + " };") print(" uint32_t x3[10] = { " + ",".join(v) + " };") print(" uint32_t z3[10] = { " + ",".join(v) + " };") print(" uint32_t xp[10] = { " + ",".join(v) + " };") print(" const uint64_t x2_out_ref[4] = {" + ", ".join(x2outx) + "};") print(" const uint64_t z2_out_ref[4] = {" + ", ".join(z2outx) + "};") print(" const uint64_t x3_out_ref[4] = {" + ", ".join(x3outx) + "};") print(" const uint64_t z3_out_ref[4] = {" + ", ".join(z3outx) + "};") print(" uint64_t x2_out[4] = { 0 };") print(" uint64_t z2_out[4] = { 0 };") print(" uint64_t x3_out[4] = { 0 };") print(" uint64_t z3_out[4] = { 0 };") print("") print(" ladder_step(x2, z2, x3, z3, xp);") print(" convert_le25p5_to_le64(x2_out, x2);") print(" convert_le25p5_to_le64(z2_out, z2);") print(" convert_le25p5_to_le64(x3_out, x3);") print(" convert_le25p5_to_le64(z3_out, z3);") print(" reduce_25519_le64(x2_out);") print(" reduce_25519_le64(z2_out);") print(" reduce_25519_le64(x3_out);") print(" reduce_25519_le64(z3_out);") print("") print(" assert(0 == memcmp(x2_out, x2_out_ref, sizeof x2_out));") print(" assert(0 == memcmp(z2_out, z2_out_ref, sizeof z2_out));") print(" assert(0 == memcmp(x3_out, x3_out_ref, sizeof x3_out));") print(" assert(0 == memcmp(z3_out, z3_out_ref, sizeof z3_out));") 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 range(result_len - len(t_in)): t_in.append("0") for x in range(result_len - len(result)): result.append("0") test_nr = next(counter) 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 range(result_len - len(t_in)): t_in.append("0") for x in range(result_len - len(result)): result.append("0") print("") print("void test_%d() {" % next(counter)) 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 ""
def make_test(x2, z2, x3, z3, xp): x2_out, z2_out, x3_out, z3_out = ref(x2, z2, x3, z3, xp) # Input words = split64(x2) x2x = words + ["0"] * (4 - len(words)) words = split64(z2) z2x = words + ["0"] * (4 - len(words)) words = split64(x3) x3x = words + ["0"] * (4 - len(words)) words = split64(z3) z3x = words + ["0"] * (4 - len(words)) words = split64(xp) xpx = words + ["0"] * (4 - len(words)) # Output words = split64(x2_out) x2outx = words + ["0"] * (4 - len(words)) words = split64(z2_out) z2outx = words + ["0"] * (4 - len(words)) words = split64(x3_out) x3outx = words + ["0"] * (4 - len(words)) words = split64(z3_out) z3outx = words + ["0"] * (4 - len(words)) print("") print("void test_%d() {" % next(counter)) print(" const uint64_t x2_in[4] = {" + ", ".join(x2x) + "};") print(" const uint64_t z2_in[4] = {" + ", ".join(z2x) + "};") print(" const uint64_t x3_in[4] = {" + ", ".join(x3x) + "};") print(" const uint64_t z3_in[4] = {" + ", ".join(z3x) + "};") print(" const uint64_t xp_in[4] = {" + ", ".join(xpx) + "};") print(" const uint64_t x2_out_ref[4] = {" + ", ".join(x2outx) + "};") print(" const uint64_t z2_out_ref[4] = {" + ", ".join(z2outx) + "};") print(" const uint64_t x3_out_ref[4] = {" + ", ".join(x3outx) + "};") print(" const uint64_t z3_out_ref[4] = {" + ", ".join(z3outx) + "};") print(" uint32_t x2[10] = { 0 };") print(" uint32_t z2[10] = { 0 };") print(" uint32_t x3[10] = { 0 };") print(" uint32_t z3[10] = { 0 };") print(" uint32_t xp[10] = { 0 };") print(" uint64_t x2_out[4] = { 0 };") print(" uint64_t z2_out[4] = { 0 };") print(" uint64_t x3_out[4] = { 0 };") print(" uint64_t z3_out[4] = { 0 };") print("") print(" convert_le64_to_le25p5(x2, x2_in);") print(" convert_le64_to_le25p5(z2, z2_in);") print(" convert_le64_to_le25p5(x3, x3_in);") print(" convert_le64_to_le25p5(z3, z3_in);") print(" convert_le64_to_le25p5(xp, xp_in);") print(" ladder_step(x2, z2, x3, z3, xp);") print(" convert_le25p5_to_le64(x2_out, x2);") print(" convert_le25p5_to_le64(z2_out, z2);") print(" convert_le25p5_to_le64(x3_out, x3);") print(" convert_le25p5_to_le64(z3_out, z3);") print(" reduce_25519_le64(x2_out);") print(" reduce_25519_le64(z2_out);") print(" reduce_25519_le64(x3_out);") print(" reduce_25519_le64(z3_out);") print("") print(" assert(0 == memcmp(x2_out, x2_out_ref, sizeof x2_out));") print(" assert(0 == memcmp(z2_out, z2_out_ref, sizeof z2_out));") print(" assert(0 == memcmp(x3_out, x3_out_ref, sizeof x3_out));") print(" assert(0 == memcmp(z3_out, z3_out_ref, sizeof z3_out));") print("}")
def make_test(f, g): assert (len(f) == 10) assert (len(g) == 10) for i in range(10): assert (f[i] < 2**27) assert (g[i] < 2**27) fx = ["0x%08X" % x for x in f] gx = ["0x%08X" % x for x in g] max26 = hex(2**26 - 1) max25 = hex(2**25 - 1) modulus = 2**255 - 19 base = [0, 26, 51, 77, 102, 128, 153, 179, 204, 230] fv = 0 gv = 0 for i in range(10): fv += f[i] * (2**(base[i])) gv += g[i] * (2**(base[i])) canonical = (fv * gv) % modulus results = [canonical, canonical + modulus] if canonical < 38: results.append(canonical + modulus * 2) # Turn results[] into arrays of 64-bit words results_hex = [] for result in results: words = split64(result) words = words + ["0"] * (4 - len(words)) results_hex.append(words) print("") print("void test_%d() {" % next(counter)) print(" const uint32_t f[10] = {" + ", ".join(fx) + "};") print(" const uint32_t g[10] = {" + ", ".join(gx) + "};") print(" uint32_t out[10];") print(" uint64_t out64[4];") print(" uint64_t exp[%d][4] = {" % len(results)) print(" { " + ",".join(results_hex[0]) + " },") print(" { " + ",".join(results_hex[1]) + " }") if len(results_hex) == 3: print(" ,{ " + ",".join(results_hex[2]) + " }") print(" };") print(" unsigned match;") print("") print(" mul_25519(out, f, g);") print(" assert(out[0] <= " + max26 + ");") print(" assert(out[1] <= " + max25 + ");") print(" assert(out[2] <= " + max26 + ");") print(" assert(out[3] <= " + max25 + ");") print(" assert(out[4] <= " + max26 + ");") print(" assert(out[5] <= " + max25 + ");") print(" assert(out[6] <= " + max26 + ");") print(" assert(out[7] <= " + max25 + ");") print(" assert(out[8] <= " + max26 + ");") print(" assert(out[9] <= " + max26 + ");") print(" convert_le25p5_to_le64(out64, out);") print(" match = 0;") print(" match |= !memcmp(exp[0], out64, 32);") print(" match |= !memcmp(exp[1], out64, 32);") if len(results_hex) == 3: print(" match |= !memcmp(exp[2], out64, 32);") print(" assert(match);") print("}")