From 4e0ed53985ef4e9c03915f1790f319518fa09363 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Mon, 11 Mar 2013 01:19:24 +0100 Subject: [PATCH] more tests --- ecmult.h | 9 ++++--- group.h | 2 +- num_openssl.h | 7 +++++- tests.cpp | 65 +++++++++++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 74 insertions(+), 9 deletions(-) diff --git a/ecmult.h b/ecmult.h index 7fd22a55869..ca0c8900d90 100644 --- a/ecmult.h +++ b/ecmult.h @@ -8,7 +8,7 @@ #include "num.h" #define WINDOW_A 5 -#define WINDOW_G 15 +#define WINDOW_G 13 namespace secp256k1 { @@ -51,6 +51,7 @@ private: int used; void PushNAF(int num, int zeroes) { + assert(used < B+1); for (int i=0; i wpg128; ECMultConsts() { - printf("Precomputing G multiplies...\n"); const GroupElem &g = GetGroupConst().g; GroupElemJac g128j(g); for (int i=0; i<128; i++) @@ -120,7 +120,6 @@ public: GroupElem g128; g128.SetJac(g128j); wpg.Build(g); wpg128.Build(g128); - printf("Done precomputing\n"); } }; @@ -129,7 +128,7 @@ const ECMultConsts &GetECMultConsts() { return ecmult_consts; } -void ECMult(Context &ctx, GroupElemJac &out, const GroupElemJac &a, Number &an, Number &gn) { +void ECMult(Context &ctx, GroupElemJac &out, const GroupElemJac &a, const Number &an, const Number &gn) { Context ct(ctx); Number an1(ct), an2(ct); Number gn1(ct), gn2(ct); diff --git a/group.h b/group.h index 2ae90b3a746..0f39648c1a3 100644 --- a/group.h +++ b/group.h @@ -78,7 +78,7 @@ public: } /** Checks whether this is a non-infinite point on the curve */ - bool IsValid() { + bool IsValid() const { if (IsInfinity()) return false; // y^2 = x^3 + 7 diff --git a/num_openssl.h b/num_openssl.h index 0ce1a8fd77f..627a9fd5d49 100644 --- a/num_openssl.h +++ b/num_openssl.h @@ -74,7 +74,12 @@ public: BN_bn2bin(bn, bin + size - len); } void SetInt(int x) { - BN_set_word(bn, x); + if (x >= 0) { + BN_set_word(bn, x); + } else { + BN_set_word(bn, -x); + BN_set_negative(bn, 1); + } } void SetModInverse(Context &ctx, const Number &x, const Number &m) { BN_mod_inverse(bn, x.bn, m.bn, ctx); diff --git a/tests.cpp b/tests.cpp index 2eebbe45804..742b532448b 100644 --- a/tests.cpp +++ b/tests.cpp @@ -8,7 +8,7 @@ using namespace secp256k1; -void test_ecmult() { +void test_run_ecmult_chain() { Context ctx; // random starting point A (on the curve) FieldElem ax; ax.SetHex("8b30bbe9ae2a990696b22f670709dff3727fd8bc04d3362c6c7bf458e2846004"); @@ -47,8 +47,69 @@ void test_ecmult() { assert(res == res2); } +void test_point_times_order(const GroupElemJac &point) { + // either the point is not on the curve, or multiplying it by the order results in O + if (!point.IsValid()) + return; + + const GroupConstants &c = GetGroupConst(); + Context ctx; + Number zero(ctx); zero.SetInt(0); + GroupElemJac res; + ECMult(ctx, res, point, c.order, zero); // calc res = order * point + 0 * G; + assert(res.IsInfinity()); +} + +void test_run_point_times_order() { + Context ctx; + FieldElem x; x.SetHex("0000000000000000000000000000000000000000000000000000000000000002"); + for (int i=0; i<500; i++) { + GroupElemJac j; j.SetCompressed(x, true); + test_point_times_order(j); + x.SetSquare(x); + } +} + +void test_wnaf(const Number &number, int w) { + Context ctx; + Number x(ctx), two(ctx), t(ctx); + x.SetInt(0); + two.SetInt(2); + WNAF<1023> wnaf(ctx, number, w); + int zeroes = -1; + for (int i=wnaf.GetSize()-1; i>=0; i--) { + x.SetMult(ctx, x, two); + int v = wnaf.Get(i); + if (v) { + assert(zeroes == -1 || zeroes >= w-1); // check that distance between non-zero elements is at least w-1 + zeroes=0; + assert((v & 1) == 1); // check non-zero elements are odd + assert(v <= (1 << (w-1)) - 1); // check range below + assert(v >= -(1 << (w-1)) - 1); // check range above + } else { + assert(zeroes != -1); // check that no unnecessary zero padding exists + zeroes++; + } + t.SetInt(v); + x.SetAdd(ctx, x, t); + } + assert(x.Compare(number) == 0); // check that wnaf represents number +} + +void test_run_wnaf() { + Context ctx; + Number range(ctx), min(ctx), n(ctx); + range.SetHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"); + min = range; min.Shift1(); min.Negate(); + for (int i=0; i<100; i++) { + n.SetPseudoRand(range); n.SetAdd(ctx,n,min); + test_wnaf(n, 4+(i%10)); + } +} int main(void) { - test_ecmult(); + test_run_wnaf(); + test_run_point_times_order(); + test_run_ecmult_chain(); return 0; }