Пример #1
0
        private static void PointAddPrecomp(PointPrecomp p, PointAccum r)
        {
            int[] A = X25519Field.Create();
            int[] B = X25519Field.Create();
            int[] C = X25519Field.Create();
            int[] E = r.u;
            int[] F = X25519Field.Create();
            int[] G = X25519Field.Create();
            int[] H = r.v;

            X25519Field.Apm(r.y, r.x, B, A);
            X25519Field.Mul(A, p.ymx_h, A);
            X25519Field.Mul(B, p.ypx_h, B);
            X25519Field.Mul(r.u, r.v, C);
            X25519Field.Mul(C, p.xyd, C);
            X25519Field.Apm(B, A, H, E);
            X25519Field.Apm(r.z, C, G, F);
            X25519Field.Carry(G);
            X25519Field.Mul(E, F, r.x);
            X25519Field.Mul(G, H, r.y);
            X25519Field.Mul(F, G, r.z);
        }
Пример #2
0
        private static void PointAddVar(bool negate, PointExt p, PointExt q, PointExt r)
        {
            int[] A = X25519Field.Create();
            int[] B = X25519Field.Create();
            int[] C = X25519Field.Create();
            int[] D = X25519Field.Create();
            int[] E = X25519Field.Create();
            int[] F = X25519Field.Create();
            int[] G = X25519Field.Create();
            int[] H = X25519Field.Create();

            int[] c, d, f, g;
            if (negate)
            {
                c = D; d = C; f = G; g = F;
            }
            else
            {
                c = C; d = D; f = F; g = G;
            }

            X25519Field.Apm(p.y, p.x, B, A);
            X25519Field.Apm(q.y, q.x, d, c);
            X25519Field.Mul(A, C, A);
            X25519Field.Mul(B, D, B);
            X25519Field.Mul(p.t, q.t, C);
            X25519Field.Mul(C, C_d2, C);
            X25519Field.Mul(p.z, q.z, D);
            X25519Field.Add(D, D, D);
            X25519Field.Apm(B, A, H, E);
            X25519Field.Apm(D, C, g, f);
            X25519Field.Carry(g);
            X25519Field.Mul(E, F, r.x);
            X25519Field.Mul(G, H, r.y);
            X25519Field.Mul(F, G, r.z);
            X25519Field.Mul(E, H, r.t);
        }
Пример #3
0
        private static void PointDouble(PointAccum r)
        {
            int[] A = X25519Field.Create();
            int[] B = X25519Field.Create();
            int[] C = X25519Field.Create();
            int[] E = r.u;
            int[] F = X25519Field.Create();
            int[] G = X25519Field.Create();
            int[] H = r.v;

            X25519Field.Sqr(r.x, A);
            X25519Field.Sqr(r.y, B);
            X25519Field.Sqr(r.z, C);
            X25519Field.Add(C, C, C);
            X25519Field.Apm(A, B, H, G);
            X25519Field.Add(r.x, r.y, E);
            X25519Field.Sqr(E, E);
            X25519Field.Sub(H, E, E);
            X25519Field.Add(C, G, F);
            X25519Field.Carry(F);
            X25519Field.Mul(E, F, r.x);
            X25519Field.Mul(G, H, r.y);
            X25519Field.Mul(F, G, r.z);
        }
Пример #4
0
        public static void Precompute()
        {
            lock (precompLock)
            {
                if (precompBase != null)
                {
                    return;
                }

                // Precomputed table for the base point in verification ladder
                {
                    PointExt b = new PointExt();
                    X25519Field.Copy(B_x, 0, b.x, 0);
                    X25519Field.Copy(B_y, 0, b.y, 0);
                    PointExtendXY(b);

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

                PointAccum p = new PointAccum();
                X25519Field.Copy(B_x, 0, p.x, 0);
                X25519Field.Copy(B_y, 0, p.y, 0);
                PointExtendXY(p);

                precompBase = new int[PrecompBlocks * PrecompPoints * 3 * X25519Field.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)
                    {
                        PointExt q = PointCopy(p);
                        PointAddVar(true, sum, q, 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)
                        {
                            PointAddVar(false, points[k - size], ds[t], points[k] = new PointExt());
                        }
                    }

                    Debug.Assert(k == PrecompPoints);

                    for (int i = 0; i < PrecompPoints; ++i)
                    {
                        PointExt q = points[i];

                        int[] x = X25519Field.Create();
                        int[] y = X25519Field.Create();

                        X25519Field.Add(q.z, q.z, x);
                        // TODO[ed25519] Batch inversion
                        X25519Field.Inv(x, y);
                        X25519Field.Mul(q.x, y, x);
                        X25519Field.Mul(q.y, y, y);

                        PointPrecomp r = new PointPrecomp();
                        X25519Field.Apm(y, x, r.ypx_h, r.ymx_h);
                        X25519Field.Mul(x, y, r.xyd);
                        X25519Field.Mul(r.xyd, C_d4, r.xyd);

                        X25519Field.Normalize(r.ypx_h);
                        X25519Field.Normalize(r.ymx_h);
                        //X25519Field.Normalize(r.xyd);

                        X25519Field.Copy(r.ypx_h, 0, precompBase, off); off += X25519Field.Size;
                        X25519Field.Copy(r.ymx_h, 0, precompBase, off); off += X25519Field.Size;
                        X25519Field.Copy(r.xyd, 0, precompBase, off); off   += X25519Field.Size;
                    }
                }

                Debug.Assert(off == precompBase.Length);
            }
        }