Esempio n. 1
0
        private static void PointDouble(PointExt r)
        {
            uint[] B = X448Field.Create();
            uint[] C = X448Field.Create();
            uint[] D = X448Field.Create();
            uint[] E = X448Field.Create();
            uint[] H = X448Field.Create();
            uint[] J = X448Field.Create();

            X448Field.Add(r.x, r.y, B);
            X448Field.Sqr(B, B);
            X448Field.Sqr(r.x, C);
            X448Field.Sqr(r.y, D);
            X448Field.Add(C, D, E);
            X448Field.Carry(E);
            X448Field.Sqr(r.z, H);
            X448Field.Add(H, H, H);
            X448Field.Carry(H);
            X448Field.Sub(E, H, J);
            X448Field.Sub(B, E, B);
            X448Field.Sub(C, D, C);
            X448Field.Mul(B, J, r.x);
            X448Field.Mul(E, C, r.y);
            X448Field.Mul(E, J, r.z);
        }
Esempio n. 2
0
        private static uint[] PointPrecompute(PointExt p, int count)
        {
            Debug.Assert(count > 0);

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

            PointDouble(d);

            uint[] table = X448Field.CreateTable(count * 3);
            int    off   = 0;

            int i = 0;

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

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

                PointAdd(d, q);
            }

            return(table);
        }
Esempio n. 3
0
        private static void PointAddPrecomp(PointPrecomp p, PointExt r)
        {
            uint[] B = X448Field.Create();
            uint[] C = X448Field.Create();
            uint[] D = X448Field.Create();
            uint[] E = X448Field.Create();
            uint[] F = X448Field.Create();
            uint[] G = X448Field.Create();
            uint[] H = X448Field.Create();

            X448Field.Sqr(r.z, B);
            X448Field.Mul(p.x, r.x, C);
            X448Field.Mul(p.y, r.y, D);
            X448Field.Mul(C, D, E);
            X448Field.Mul(E, -C_d, E);
            //X448Field.Apm(B, E, F, G);
            X448Field.Add(B, E, F);
            X448Field.Sub(B, E, G);
            X448Field.Add(p.x, p.y, B);
            X448Field.Add(r.x, r.y, E);
            X448Field.Mul(B, E, H);
            //X448Field.Apm(D, C, B, E);
            X448Field.Add(D, C, B);
            X448Field.Sub(D, C, E);
            X448Field.Carry(B);
            X448Field.Sub(H, B, H);
            X448Field.Mul(H, r.z, H);
            X448Field.Mul(E, r.z, E);
            X448Field.Mul(F, H, r.x);
            X448Field.Mul(E, G, r.y);
            X448Field.Mul(F, G, r.z);
        }
Esempio n. 4
0
        private static PointExt PointCopy(PointExt p)
        {
            PointExt r = new PointExt();

            X448Field.Copy(p.x, 0, r.x, 0);
            X448Field.Copy(p.y, 0, r.y, 0);
            X448Field.Copy(p.z, 0, r.z, 0);
            return(r);
        }
Esempio n. 5
0
        private static void ScalarMultBase(byte[] k, PointExt r)
        {
            Precompute();

            PointSetNeutral(r);

            uint[] n = new uint[ScalarUints + 1];
            DecodeScalar(k, 0, n);

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

            PointPrecomp p = new PointPrecomp();

            int cOff = PrecompSpacing - 1;

            for (;;)
            {
                int tPos = cOff;

                for (int b = 0; b < PrecompBlocks; ++b)
                {
                    uint w = 0;
                    for (int t = 0; t < PrecompTeeth; ++t)
                    {
                        uint tBit = n[tPos >> 5] >> (tPos & 0x1F);
                        w    &= ~(1U << t);
                        w    ^= (tBit << t);
                        tPos += PrecompSpacing;
                    }

                    int sign = (int)(w >> (PrecompTeeth - 1)) & 1;
                    int abs  = ((int)w ^ -sign) & PrecompMask;

                    Debug.Assert(sign == 0 || sign == 1);
                    Debug.Assert(0 <= abs && abs < PrecompPoints);

                    PointLookup(b, abs, p);

                    X448Field.CNegate(sign, p.x);

                    PointAddPrecomp(p, r);
                }

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

                PointDouble(r);
            }
        }
Esempio n. 6
0
        internal static void ScalarMultBaseXY(byte[] k, int kOff, uint[] x, uint[] y)
        {
            byte[] n = new byte[ScalarBytes];
            PruneScalar(k, kOff, n);

            PointExt p = new PointExt();

            ScalarMultBase(n, p);
            X448Field.Copy(p.x, 0, x, 0);
            X448Field.Copy(p.y, 0, y, 0);
        }
Esempio n. 7
0
        private static void PointLookup(int block, int index, PointPrecomp p)
        {
            Debug.Assert(0 <= block && block < PrecompBlocks);
            Debug.Assert(0 <= index && index < PrecompPoints);

            int off = block * PrecompPoints * 2 * X448Field.Size;

            for (int i = 0; i < PrecompPoints; ++i)
            {
                int cond = ((i ^ index) - 1) >> 31;
                X448Field.CMov(cond, precompBase, off, p.x, 0);     off += X448Field.Size;
                X448Field.CMov(cond, precompBase, off, p.y, 0);     off += X448Field.Size;
            }
        }
Esempio n. 8
0
        private static void EncodePoint(PointExt p, byte[] r, int rOff)
        {
            uint[] x = X448Field.Create();
            uint[] y = X448Field.Create();

            X448Field.Inv(p.z, y);
            X448Field.Mul(p.x, y, x);
            X448Field.Mul(p.y, y, y);
            X448Field.Normalize(x);
            X448Field.Normalize(y);

            X448Field.Encode(y, r, rOff);
            r[rOff + PointBytes - 1] = (byte)((x[0] & 1) << 7);
        }
Esempio n. 9
0
        private static int CheckPoint(uint[] x, uint[] y)
        {
            uint[] t = X448Field.Create();
            uint[] u = X448Field.Create();
            uint[] v = X448Field.Create();

            X448Field.Sqr(x, u);
            X448Field.Sqr(y, v);
            X448Field.Mul(u, v, t);
            X448Field.Add(u, v, u);
            X448Field.Mul(t, -C_d, t);
            X448Field.SubOne(t);
            X448Field.Add(t, u, t);
            X448Field.Normalize(t);

            return(X448Field.IsZero(t));
        }
Esempio n. 10
0
        internal static void ScalarMultBaseXY(byte[] k, int kOff, uint[] x, uint[] y)
        {
            byte[] n = new byte[ScalarBytes];
            PruneScalar(k, kOff, n);

            PointExt p = new PointExt();

            ScalarMultBase(n, p);

            if (0 == CheckPoint(p.x, p.y, p.z))
            {
                throw new InvalidOperationException();
            }

            X448Field.Copy(p.x, 0, x, 0);
            X448Field.Copy(p.y, 0, y, 0);
        }
Esempio n. 11
0
        private static void PointAddVar(bool negate, PointExt p, PointExt r)
        {
            uint[] A = X448Field.Create();
            uint[] B = X448Field.Create();
            uint[] C = X448Field.Create();
            uint[] D = X448Field.Create();
            uint[] E = X448Field.Create();
            uint[] F = X448Field.Create();
            uint[] G = X448Field.Create();
            uint[] H = X448Field.Create();

            uint[] b, e, f, g;
            if (negate)
            {
                b = E; e = B; f = G; g = F;
                X448Field.Sub(p.y, p.x, H);
            }
            else
            {
                b = B; e = E; f = F; g = G;
                X448Field.Add(p.y, p.x, H);
            }

            X448Field.Mul(p.z, r.z, A);
            X448Field.Sqr(A, B);
            X448Field.Mul(p.x, r.x, C);
            X448Field.Mul(p.y, r.y, D);
            X448Field.Mul(C, D, E);
            X448Field.Mul(E, -C_d, E);
            //X448Field.Apm(B, E, F, G);
            X448Field.Add(B, E, f);
            X448Field.Sub(B, E, g);
            X448Field.Add(r.x, r.y, E);
            X448Field.Mul(H, E, H);
            //X448Field.Apm(D, C, B, E);
            X448Field.Add(D, C, b);
            X448Field.Sub(D, C, e);
            X448Field.Carry(b);
            X448Field.Sub(H, B, H);
            X448Field.Mul(H, A, H);
            X448Field.Mul(E, A, E);
            X448Field.Mul(F, H, r.x);
            X448Field.Mul(E, G, r.y);
            X448Field.Mul(F, G, r.z);
        }
Esempio n. 12
0
        private static bool DecodePointVar(byte[] p, int pOff, bool negate, PointExt r)
        {
            byte[] py = Arrays.CopyOfRange(p, pOff, pOff + PointBytes);
            if (!CheckPointVar(py))
            {
                return(false);
            }

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

            py[PointBytes - 1] &= 0x7F;

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

            uint[] u = X448Field.Create();
            uint[] v = X448Field.Create();

            X448Field.Sqr(r.y, u);
            X448Field.Mul(u, (uint)-C_d, v);
            X448Field.Negate(u, u);
            X448Field.AddOne(u);
            X448Field.AddOne(v);

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

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

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

            PointExtendXY(r);
            return(true);
        }
Esempio n. 13
0
        public static void Precompute()
        {
            lock (precompLock)
            {
                if (precompBase != null)
                {
                    return;
                }

                PointExt p = new PointExt();
                X448Field.Copy(B_x, 0, p.x, 0);
                X448Field.Copy(B_y, 0, p.y, 0);
                PointExtendXY(p);

                precompBaseTable = PointPrecompVar(p, 1 << (WnafWidthBase - 2));

                precompBase = new uint[PrecompBlocks * PrecompPoints * 2 * X448Field.Size];

                int off = 0;
                for (int b = 0; b < PrecompBlocks; ++b)
                {
                    PointExt[] ds = new PointExt[PrecompTeeth];

                    PointExt sum = new PointExt();
                    PointSetNeutral(sum);

                    for (int t = 0; t < PrecompTeeth; ++t)
                    {
                        PointAddVar(true, p, sum);
                        PointDouble(p);

                        ds[t] = PointCopy(p);

                        if (b + t != PrecompBlocks + PrecompTeeth - 2)
                        {
                            for (int s = 1; s < PrecompSpacing; ++s)
                            {
                                PointDouble(p);
                            }
                        }
                    }

                    PointExt[] points = new PointExt[PrecompPoints];
                    int        k      = 0;
                    points[k++] = sum;

                    for (int t = 0; t < (PrecompTeeth - 1); ++t)
                    {
                        int size = 1 << t;
                        for (int j = 0; j < size; ++j, ++k)
                        {
                            points[k] = PointCopy(points[k - size]);
                            PointAddVar(false, ds[t], points[k]);
                        }
                    }

                    Debug.Assert(k == PrecompPoints);

                    for (int i = 0; i < PrecompPoints; ++i)
                    {
                        PointExt q = points[i];
                        // TODO[ed448] Batch inversion
                        X448Field.Inv(q.z, q.z);
                        X448Field.Mul(q.x, q.z, q.x);
                        X448Field.Mul(q.y, q.z, q.y);

                        //X448Field.Normalize(q.x);
                        //X448Field.Normalize(q.y);

                        X448Field.Copy(q.x, 0, precompBase, off); off += X448Field.Size;
                        X448Field.Copy(q.y, 0, precompBase, off); off += X448Field.Size;
                    }
                }

                Debug.Assert(off == precompBase.Length);
            }
        }
Esempio n. 14
0
 private static void PointSetNeutral(PointExt p)
 {
     X448Field.Zero(p.x);
     X448Field.One(p.y);
     X448Field.One(p.z);
 }
Esempio n. 15
0
 private static void PointExtendXY(PointExt p)
 {
     X448Field.One(p.z);
 }