Exemplo n.º 1
0
    /*
     * Create a random non-infinity point by multiplying the
     * curve subgroup generator with a random non-zero integer
     * modulo the subgroup order. The multiplier is returned.
     */
    static byte[] MakeRandPoint(MutableECPoint P)
    {
        ECCurve curve = P.Curve;

        P.Set(curve.MakeGenerator());
        byte[] n = BigInt.RandIntNZ(curve.SubgroupOrder);
        if (P.MulSpecCT(n) == 0)
        {
            throw new Exception("Multiplication failed");
        }
        return(n);
    }
Exemplo n.º 2
0
    static void TestCurve(ECCurve curve, string[] kat)
    {
        Console.Write("Test {0}: ", curve.Name);

        // ====================================================

        /* obsolete -- DEBUG
         * Console.WriteLine();
         * ZInt p = ZInt.DecodeUnsignedBE(((ECCurvePrime)curve).mod);
         * ZInt a = ZInt.DecodeUnsignedBE(((ECCurvePrime)curve).a);
         * ZInt b = ZInt.DecodeUnsignedBE(((ECCurvePrime)curve).b);
         * Console.WriteLine("p  = {0}", p.ToHexString());
         * Console.WriteLine("a  = {0}", a.ToHexString());
         * Console.WriteLine("b  = {0}", b.ToHexString());
         * MutableECPoint F1 = curve.MakeGenerator();
         * byte[] enc = F1.Encode(false);
         * int flen = enc.Length >> 1;
         * for (int i = 0; i < enc.Length; i ++) {
         *      if (i == 1 || i == 1 + (enc.Length >> 1)) {
         *              Console.Write(" ");
         *      }
         *      Console.Write("{0:X2}", enc[i]);
         * }
         * Console.WriteLine();
         * byte[] X = new byte[flen];
         * byte[] Y = new byte[flen];
         * Array.Copy(enc, 1, X, 0, flen);
         * Array.Copy(enc, 1 + flen, Y, 0, flen);
         * ZInt x1 = ZInt.DecodeUnsignedBE(X);
         * ZInt y1 = ZInt.DecodeUnsignedBE(Y);
         * Console.WriteLine("X1 = {0}", x1.ToHexString());
         * Console.WriteLine("Y1 = {0}", y1.ToHexString());
         * MutableECPoint F2 = F1.Dup();
         * F2.DoubleCT();
         * MutableECPoint F3 = F2.Dup();
         * MutableECPoint F4 = F2.Dup();
         * enc = F2.Encode(false);
         * for (int i = 0; i < enc.Length; i ++) {
         *      if (i == 1 || i == 1 + (enc.Length >> 1)) {
         *              Console.Write(" ");
         *      }
         *      Console.Write("{0:X2}", enc[i]);
         * }
         * Console.WriteLine();
         * Array.Copy(enc, 1, X, 0, flen);
         * Array.Copy(enc, 1 + flen, Y, 0, flen);
         * ZInt x2 = ZInt.DecodeUnsignedBE(X);
         * ZInt y2 = ZInt.DecodeUnsignedBE(Y);
         * Console.WriteLine("X2 = {0}", x2.ToHexString());
         * Console.WriteLine("Y2 = {0}", y2.ToHexString());
         * if ((x1 * x1 * x1 + a * x1 + b - y1 * y1) % p != 0) {
         *      throw new Exception("Generator not on curve");
         * }
         * if ((x2 * x2 * x2 + a * x2 + b - y2 * y2) % p != 0) {
         *      throw new Exception("Double not on curve");
         * }
         *
         * if (F3.AddCT(F1) == 0) {
         *      throw new Exception("Addition failed");
         * }
         * MutableECPoint F5 = F3.Dup();
         * enc = F3.Encode(false);
         * for (int i = 0; i < enc.Length; i ++) {
         *      if (i == 1 || i == 1 + (enc.Length >> 1)) {
         *              Console.Write(" ");
         *      }
         *      Console.Write("{0:X2}", enc[i]);
         * }
         * Console.WriteLine();
         * Array.Copy(enc, 1, X, 0, flen);
         * Array.Copy(enc, 1 + flen, Y, 0, flen);
         * ZInt x3 = ZInt.DecodeUnsignedBE(X);
         * ZInt y3 = ZInt.DecodeUnsignedBE(Y);
         * Console.WriteLine("X3 = {0}", x3.ToHexString());
         * Console.WriteLine("Y3 = {0}", y3.ToHexString());
         * if ((x3 * x3 * x3 + a * x3 + b - y3 * y3) % p != 0) {
         *      throw new Exception("Triple not on curve");
         * }
         * ZInt l3 = ((p + y2 - y1)
         * ZInt.ModPow(p + x2 - x1, p - 2, p)) % p;
         * ZInt x3p = (l3 * l3 + p + p - x1 - x2) % p;
         * ZInt y3p = (l3 * (p + x1 - x3p) + p - y1) % p;
         * Console.WriteLine("X3p = {0}", x3p.ToHexString());
         * Console.WriteLine("Y3p = {0}", y3p.ToHexString());
         * Console.WriteLine("[X:{0}, Y:{1}]", x3 == x3p, y3 == y3p);
         *
         * if (F5.AddCT(F4) == 0) {
         *      throw new Exception("Addition failed");
         * }
         * enc = F5.Encode(false);
         * for (int i = 0; i < enc.Length; i ++) {
         *      if (i == 1 || i == 1 + (enc.Length >> 1)) {
         *              Console.Write(" ");
         *      }
         *      Console.Write("{0:X2}", enc[i]);
         * }
         * Console.WriteLine();
         * Array.Copy(enc, 1, X, 0, flen);
         * Array.Copy(enc, 1 + flen, Y, 0, flen);
         * ZInt x5 = ZInt.DecodeUnsignedBE(X);
         * ZInt y5 = ZInt.DecodeUnsignedBE(Y);
         * Console.WriteLine("X5 = {0}", x5.ToHexString());
         * Console.WriteLine("Y5 = {0}", y5.ToHexString());
         * if ((x5 * x5 * x5 + a * x5 + b - y5 * y5) % p != 0) {
         *      throw new Exception("Quintuple not on curve");
         * }
         * ZInt l5 = ((p + y3 - y2)
         * ZInt.ModPow(p + x3 - x2, p - 2, p)) % p;
         * ZInt x5p = (l5 * l5 + p + p - x2 - x3) % p;
         * ZInt y5p = (l5 * (p + x2 - x5p) + p - y2) % p;
         * Console.WriteLine("X5p = {0}", x5p.ToHexString());
         * Console.WriteLine("Y5p = {0}", y5p.ToHexString());
         * Console.WriteLine("[X:{0}, Y:{1}]", x5 == x5p, y5 == y5p);
         *
         * F1.Set(curve.MakeGenerator());
         * if (F1.MulSpecCT(new byte[] { 0x05 }) == 0) {
         *      throw new Exception("Multiplication failed");
         * }
         * enc = F1.Encode(false);
         * for (int i = 0; i < enc.Length; i ++) {
         *      if (i == 1 || i == 1 + (enc.Length >> 1)) {
         *              Console.Write(" ");
         *      }
         *      Console.Write("{0:X2}", enc[i]);
         * }
         * Console.WriteLine();
         * Array.Copy(enc, 1, X, 0, flen);
         * Array.Copy(enc, 1 + flen, Y, 0, flen);
         * ZInt x5t = ZInt.DecodeUnsignedBE(X);
         * ZInt y5t = ZInt.DecodeUnsignedBE(Y);
         * Console.WriteLine("X5t = {0}", x5t.ToHexString());
         * Console.WriteLine("Y5t = {0}", y5t.ToHexString());
         * if ((x5t * x5t * x5t + a * x5t + b - y5t * y5t) % p != 0) {
         *      throw new Exception("Quintuple not on curve (2)");
         * }
         * Console.WriteLine("[X:{0}, Y:{1}]", x5t == x5p, y5t == y5p);
         *
         * F1.Set(F5);
         * F2.SetZero();
         * if (F1.AddCT(F2) == 0) {
         *      throw new Exception("Addition failed (+0)");
         * }
         * enc = F1.Encode(false);
         * for (int i = 0; i < enc.Length; i ++) {
         *      if (i == 1 || i == 1 + (enc.Length >> 1)) {
         *              Console.Write(" ");
         *      }
         *      Console.Write("{0:X2}", enc[i]);
         * }
         * Console.WriteLine();
         * Array.Copy(enc, 1, X, 0, flen);
         * Array.Copy(enc, 1 + flen, Y, 0, flen);
         * ZInt x5q = ZInt.DecodeUnsignedBE(X);
         * ZInt y5q = ZInt.DecodeUnsignedBE(Y);
         * Console.WriteLine("X5q = {0}", x5q.ToHexString());
         * Console.WriteLine("Y5q = {0}", y5q.ToHexString());
         * Console.WriteLine("[X:{0}, Y:{1}]", x5q == x5p, y5q == y5p);
         *
         * F2.SetZero();
         * if (F2.AddCT(F1) == 0) {
         *      throw new Exception("Addition failed (0+)");
         * }
         * enc = F2.Encode(false);
         * for (int i = 0; i < enc.Length; i ++) {
         *      if (i == 1 || i == 1 + (enc.Length >> 1)) {
         *              Console.Write(" ");
         *      }
         *      Console.Write("{0:X2}", enc[i]);
         * }
         * Console.WriteLine();
         * Array.Copy(enc, 1, X, 0, flen);
         * Array.Copy(enc, 1 + flen, Y, 0, flen);
         * ZInt x5r = ZInt.DecodeUnsignedBE(X);
         * ZInt y5r = ZInt.DecodeUnsignedBE(Y);
         * Console.WriteLine("X5r = {0}", x5r.ToHexString());
         * Console.WriteLine("Y5r = {0}", y5r.ToHexString());
         * Console.WriteLine("[X:{0}, Y:{1}]", x5r == x5p, y5r == y5p);
         *
         * EC rG = EC.Make(p.ToBytesUnsignedBE(),
         *      a.ToBytesUnsignedBE(), b.ToBytesUnsignedBE());
         * rG.Set(x1.ToBytesUnsignedBE(), y1.ToBytesUnsignedBE());
         * for (int i = 1; i <= 30; i ++) {
         *      Console.Write(".");
         *      ZInt n = ZInt.MakeRand(i);
         *      byte[] nb = n.ToBytesUnsignedBE();
         *      F1 = curve.MakeGenerator();
         *      if (F1.MulSpecCT(nb) == 0) {
         *              throw new Exception("Multiplication error");
         *      }
         *      enc = F1.Encode(false);
         *      ZInt xp, yp;
         *      if (enc.Length == 1) {
         *              xp = 0;
         *              yp = 0;
         *      } else {
         *              Array.Copy(enc, 1, X, 0, flen);
         *              Array.Copy(enc, 1 + flen, Y, 0, flen);
         *              xp = ZInt.DecodeUnsignedBE(X);
         *              yp = ZInt.DecodeUnsignedBE(Y);
         *      }
         *      EC rH = rG.Dup();
         *      rH.Mul(nb);
         *      ZInt xh = ZInt.DecodeUnsignedBE(rH.X);
         *      ZInt yh = ZInt.DecodeUnsignedBE(rH.Y);
         *      if (xp != xh || yp != yh) {
         *              Console.WriteLine();
         *              Console.WriteLine("n = {0}", n);
         *              Console.WriteLine("xp = {0}", xp.ToHexString());
         *              Console.WriteLine("yp = {0}", yp.ToHexString());
         *              Console.WriteLine("xh = {0}", xh.ToHexString());
         *              Console.WriteLine("yh = {0}", yh.ToHexString());
         *              throw new Exception("Bad mult result");
         *      }
         * }
         * Console.WriteLine();
         */

        // ====================================================

        curve.CheckValid();
        MutableECPoint G = curve.MakeGenerator();

        if (G.IsInfinity)
        {
            throw new Exception("Generator is infinity");
        }
        MutableECPoint P = G.Dup();
        MutableECPoint Q = G.Dup();
        MutableECPoint R = G.Dup();
        MutableECPoint S = G.Dup();
        MutableECPoint T = G.Dup();

        for (int i = 0; i < 10; i++)
        {
            Console.Write(".");
            byte[] u, v, w;
            u = MakeRandPoint(P);
            do
            {
                v = MakeRandPoint(Q);
            } while (BigInt.Compare(u, v) == 0);
            // byte[] s = BigInt.Add(u, v);
            byte[] t;
            do
            {
                w = MakeRandPoint(R);
                t = BigInt.Add(v, w);
            } while (BigInt.Compare(u, w) == 0 ||
                     BigInt.Compare(v, w) == 0 ||
                     BigInt.Compare(u, t) == 0);
            if (P.Eq(Q) || P.Eq(R) || Q.Eq(R))
            {
                throw new Exception("Equal points");
            }
            S.Set(P);
            Add(S, Q);
            Add(S, R);
            T.Set(Q);
            Add(T, R);
            Add(T, P);
            if (!S.Eq(T) || !T.Eq(S))
            {
                throw new Exception("Associativity error");
            }
            S.Normalize();
            if (!S.Eq(T) || !T.Eq(S))
            {
                throw new Exception("Normalization error (1)");
            }
            T.Normalize();
            if (!S.Eq(T) || !T.Eq(S))
            {
                throw new Exception("Normalization error (2)");
            }

            byte[] enc1 = P.Encode(false);
            byte[] enc2 = P.Encode(true);
            byte[] enc3 = new byte[enc1.Length];
            Array.Copy(enc1, 1, enc3, 1, enc1.Length - 1);
            enc3[0] = (byte)(enc2[0] | 0x04);
            Q.Decode(enc1);
            if (!P.Eq(Q) || !Q.Eq(P))
            {
                throw new Exception("Encode/decode error 1");
            }
            Q.Decode(enc2);
            if (!P.Eq(Q) || !Q.Eq(P))
            {
                throw new Exception("Encode/decode error 2");
            }
            Q.Decode(enc3);
            if (!P.Eq(Q) || !Q.Eq(P))
            {
                throw new Exception("Encode/decode error 3");
            }
        }

        Console.Write(" ");
        for (int i = 0; i < kat.Length; i += 2)
        {
            P.Set(G);
            byte[] n = ToBin(kat[i]);
            if (P.MulSpecCT(n) == 0)
            {
                throw new Exception("Multiplication error");
            }
            byte[] er = ToBin(kat[i + 1]);
            if (!Eq(er, P.Encode(false)))
            {
                throw new Exception("KAT failed");
            }
            byte[] eg = curve.GetGenerator(false);
            byte[] ed = new byte[eg.Length];
            curve.Mul(eg, n, ed, false);
            if (!Eq(ed, er))
            {
                throw new Exception("KAT failed (API 2)");
            }
            Console.Write(".");
        }

        Console.WriteLine();
    }