private static int[] PointPrecompute(PointAffine p, int count)
        {
            Debug.Assert(count > 0);

            PointExt q = PointCopy(p);
            PointExt d = PointCopy(q);

            PointAdd(q, d);

            int[] table = X25519Field.CreateTable(count * 4);
            int   off   = 0;

            int i = 0;

            for (;;)
            {
                X25519Field.Copy(q.x, 0, table, off); off += X25519Field.Size;
                X25519Field.Copy(q.y, 0, table, off); off += X25519Field.Size;
                X25519Field.Copy(q.z, 0, table, off); off += X25519Field.Size;
                X25519Field.Copy(q.t, 0, table, off); off += X25519Field.Size;

                if (++i == count)
                {
                    break;
                }

                PointAdd(d, q);
            }

            return(table);
        }
        private static void ScalarMultOrderVar(PointAffine p, PointAccum r)
        {
            int width = 5;

            sbyte[] ws_p = GetWnafVar(L, width);

            PointExt[] tp = PointPrecomputeVar(PointCopy(p), 1 << (width - 2));

            PointSetNeutral(r);

            for (int bit = 252; ;)
            {
                int wp = ws_p[bit];
                if (wp != 0)
                {
                    int sign  = wp >> 31;
                    int index = (wp ^ sign) >> 1;

                    PointAddVar((sign != 0), tp[index], r);
                }

                if (--bit < 0)
                {
                    break;
                }

                PointDouble(r);
            }
        }
        public static bool ValidatePublicKeyFull(byte[] pk, int pkOff)
        {
            PointAffine p = new PointAffine();

            if (!DecodePointVar(pk, pkOff, false, p))
            {
                return(false);
            }

            F.Normalize(p.x);
            F.Normalize(p.y);

            if (IsNeutralElementVar(p.x, p.y))
            {
                return(false);
            }

            PointAccum r = new PointAccum();

            ScalarMultOrderVar(p, r);

            F.Normalize(r.x);
            F.Normalize(r.y);
            F.Normalize(r.z);

            return(IsNeutralElementVar(r.x, r.y, r.z));
        }
Пример #4
0
        public static EllipticCurveEdwards GenerateCurve12(BigInteger n, out BigInteger x, out BigInteger y)// Z/12Z
        {
            var         E = new EllipticCurveWeierstrass(-12, 0, n);
            PointAffine P;
            BigInteger  d;

            while (true)
            {
                P = new PointAffine(6, -12, E);
                BigInteger k = new Random().Next() % n;
                P = k * P;
                if ((P.x == 0 && P.y == 0) || (P.x == -2 && BigInteger.Abs(P.y) == 4) || (P.x == 6 && BigInteger.Abs(P.y) == 12))
                {
                    continue;
                }

                BigInteger temp = (1024 * P.x * P.x * P.y * P.y) % n;
                BigInteger inv  = Algorithms.Invert(temp, n);
                if (temp * inv % n != 1)
                {
                    continue;
                }
                temp = (-BigInteger.ModPow(P.x - 2, 3, n) * BigInteger.ModPow(P.x + 6, 3, n) * (P.x * P.x - 12 * P.x - 12)) % n;
                if (temp < 0)
                {
                    temp += n;
                }
                d = (temp * inv) % n;

                temp = ((P.x - 2) * (P.x + 6) * (P.x * P.x + 12 * P.x - 12)) % n;
                if (temp < 0)
                {
                    temp += n;
                }
                inv = Algorithms.Invert(temp, n);
                if (temp * inv % n != 1)
                {
                    continue;
                }
                x = (8 * P.y * (P.x * P.x + 12) * inv) % n;

                temp = ((P.x - 2) * (P.x + 6) * (P.x * P.x - 12)) % n;
                if (temp < 0)
                {
                    temp += n;
                }
                inv = Algorithms.Invert(temp, n);
                if (temp * inv % n != 1)
                {
                    continue;
                }
                y = (-4 * P.x * (P.x * P.x - 12 * P.x - 12) * inv) % n;

                break;
            }

            return(new EllipticCurveEdwards(1, d, n));
        }
        private static PointExt PointCopy(PointAffine p)
        {
            PointExt r = new PointExt();

            F.Copy(p.x, 0, r.x, 0);
            F.Copy(p.y, 0, r.y, 0);
            PointExtendXY(r);
            return(r);
        }
Пример #6
0
        private static bool ImplVerify(byte[] sig, int sigOff, byte[] pk, int pkOff, byte[] ctx, byte phflag, byte[] m,
                                       int mOff, int mLen)
        {
            if (!CheckContextVar(ctx, phflag))
            {
                throw new ArgumentException("ctx");
            }

            byte[] R = Arrays.CopyOfRange(sig, sigOff, sigOff + PointBytes);
            byte[] S = Arrays.CopyOfRange(sig, sigOff + PointBytes, sigOff + SignatureSize);

            if (!CheckPointVar(R))
            {
                return(false);
            }

            if (!CheckScalarVar(S))
            {
                return(false);
            }

            PointAffine pA = new PointAffine();

            if (!DecodePointVar(pk, pkOff, true, pA))
            {
                return(false);
            }

            IDigest d = CreateDigest();

            byte[] h = new byte[d.GetDigestSize()];

            Dom2(d, phflag, ctx);
            d.BlockUpdate(R, 0, PointBytes);
            d.BlockUpdate(pk, pkOff, PointBytes);
            d.BlockUpdate(m, mOff, mLen);
            d.DoFinal(h, 0);

            byte[] k = ReduceScalar(h);

            uint[] nS = new uint[ScalarUints];
            DecodeScalar(S, 0, nS);

            uint[] nA = new uint[ScalarUints];
            DecodeScalar(k, 0, nA);

            PointAccum pR = new PointAccum();

            ScalarMultStrausVar(nS, nA, pA, pR);

            byte[] check = new byte[PointBytes];
            return(0 != EncodePoint(pR, check, 0) && Arrays.AreEqual(check, R));
        }
        private static void ScalarMult(byte[] k, PointAffine p, PointAccum r)
        {
            uint[] n = new uint[ScalarUints];
            DecodeScalar(k, 0, n);

            Debug.Assert(0U == (n[0] & 7));
            Debug.Assert(1U == n[ScalarUints - 1] >> 30);

            Nat.ShiftDownBits(ScalarUints, n, 3, 1U);

            // Recode the scalar into signed-digit form
            {
                uint c1 = Nat.CAdd(ScalarUints, ~(int)n[0] & 1, n, L, n);   Debug.Assert(c1 == 0U);
                uint c2 = Nat.ShiftDownBit(ScalarUints, n, 0U);             Debug.Assert(c2 == (1U << 31));
            }

            Debug.Assert(1U == n[ScalarUints - 1] >> 28);

            int[]    table = PointPrecompute(p, 8);
            PointExt q     = new PointExt();

            // Replace first 4 doublings (2^4 * P) with 1 addition (P + 15 * P)
            PointCopy(p, r);
            PointLookup(table, 7, q);
            PointAdd(q, r);

            int w = 62;

            for (;;)
            {
                PointLookup(n, w, table, q);
                PointAdd(q, r);

                PointDouble(r);
                PointDouble(r);
                PointDouble(r);

                if (--w < 0)
                {
                    break;
                }

                PointDouble(r);
            }
        }
        private static void ScalarMultStrausVar(uint[] nb, uint[] np, PointAffine p, PointAccum r)
        {
            Precompute();

            int width = 5;

            sbyte[] ws_b = GetWnafVar(nb, WnafWidthBase);
            sbyte[] ws_p = GetWnafVar(np, width);

            PointExt[] tp = PointPrecomputeVar(PointCopy(p), 1 << (width - 2));

            PointSetNeutral(r);

            for (int bit = 252;;)
            {
                int wb = ws_b[bit];
                if (wb != 0)
                {
                    int sign  = wb >> 31;
                    int index = (wb ^ sign) >> 1;

                    PointAddVar((sign != 0), precompBaseTable[index], r);
                }

                int wp = ws_p[bit];
                if (wp != 0)
                {
                    int sign  = wp >> 31;
                    int index = (wp ^ sign) >> 1;

                    PointAddVar((sign != 0), tp[index], r);
                }

                if (--bit < 0)
                {
                    break;
                }

                PointDouble(r);
            }
        }
        private static bool DecodePointVar(byte[] p, int pOff, bool negate, PointAffine r)
        {
            byte[] py = Copy(p, pOff, PointBytes);
            if (!CheckPointVar(py))
            {
                return(false);
            }

            int x_0 = (py[PointBytes - 1] & 0x80) >> 7;

            py[PointBytes - 1] &= 0x7F;

            F.Decode(py, 0, r.y);

            int[] u = F.Create();
            int[] v = F.Create();

            F.Sqr(r.y, u);
            F.Mul(C_d, u, v);
            F.SubOne(u);
            F.AddOne(v);

            if (!F.SqrtRatioVar(u, v, r.x))
            {
                return(false);
            }

            F.Normalize(r.x);
            if (x_0 == 1 && F.IsZeroVar(r.x))
            {
                return(false);
            }

            if (negate ^ (x_0 != (r.x[0] & 1)))
            {
                F.Negate(r.x, r.x);
            }

            return(true);
        }
Пример #10
0
 private static void PointCopy(PointAffine p, PointAccum r)
 {
     F.Copy(p.x, 0, r.x, 0);
     F.Copy(p.y, 0, r.y, 0);
     PointExtendXY(r);
 }
Пример #11
0
        public static bool ValidatePublicKeyPartial(byte[] pk, int pkOff)
        {
            PointAffine p = new PointAffine();

            return(DecodePointVar(pk, pkOff, false, p));
        }
Пример #12
0
        public static EllipticCurveEdwards GenerateCurve2x8(BigInteger n, out BigInteger x, out BigInteger y)// Z/2Z x Z/8Z
        {
            var         E = new EllipticCurveWeierstrass(-8, -32, n);
            PointAffine P;
            BigInteger  d;

            while (true)
            {
                P = new PointAffine(12, 40, E);
                BigInteger k = new Random().Next() % n;
                P = k * P;

                BigInteger temp = (P.x - 9) % n;
                if (temp < 0)
                {
                    temp += n;
                }
                BigInteger inv = Algorithms.Invert(temp, n);
                if (temp * inv % n != 1)
                {
                    continue;
                }
                temp = ((P.y + 25) * inv + 1) % n;
                if (temp < 0)
                {
                    temp += n;
                }
                BigInteger a = Algorithms.Invert(temp, n);
                if (temp * a % n != 1)
                {
                    continue;
                }

                temp = (8 * a * a - 1) % n;
                if (temp < 0)
                {
                    temp += n;
                }
                inv = Algorithms.Invert(temp, n);
                if (temp * inv % n != 1)
                {
                    continue;
                }
                BigInteger b = (2 * a * (4 * a + 1) * inv) % n;

                temp = BigInteger.ModPow(2 * b - 1, 4, n);
                if (temp < 0)
                {
                    temp += n;
                }
                inv = Algorithms.Invert(temp, n);
                if (temp * inv % n != 1)
                {
                    continue;
                }
                d = ((2 * (2 * b - 1) * (2 * b - 1) - 1) * inv) % n;

                temp = (6 * b - 5) % n;
                if (temp < 0)
                {
                    temp += n;
                }
                inv = Algorithms.Invert(temp, n);
                if (temp * inv % n != 1)
                {
                    continue;
                }
                x = ((2 * b - 1) * (4 * b - 3) * inv) % n;

                temp = ((P.y + 3 * P.x - 2) * (P.y + P.x + 16)) % n;
                if (temp < 0)
                {
                    temp += n;
                }
                inv = Algorithms.Invert(temp, n);
                if (temp * inv % n != 1)
                {
                    continue;
                }
                y = ((2 * b - 1) * (P.y * P.y + 50 * P.y - 2 * P.x * P.x * P.x + 27 * P.x * P.x - 104) * inv) % n;
                break;
            }

            return(new EllipticCurveEdwards(1, d, n));
        }