Пример #1
0
        private static void PointAddVar(bool negate, PointExt p, PointExt q, PointExt r)
        {
            int[] A = new int[X25519Field.Size];
            int[] B = new int[X25519Field.Size];
            int[] C = new int[X25519Field.Size];
            int[] D = new int[X25519Field.Size];
            int[] E = new int[X25519Field.Size];
            int[] F = new int[X25519Field.Size];
            int[] G = new int[X25519Field.Size];
            int[] H = new int[X25519Field.Size];

            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);
        }
Пример #2
0
        private static void PointDouble(PointAccum r)
        {
            int[] A = new int[X25519Field.Size];
            int[] B = new int[X25519Field.Size];
            int[] C = new int[X25519Field.Size];
            int[] E = r.u;
            int[] F = new int[X25519Field.Size];
            int[] G = new int[X25519Field.Size];
            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);
        }
Пример #3
0
        private static void ScalarMultBase(Span <byte> k, Span <int> y, Span <int> z)
        {
            Span <int> rx = stackalloc int[X25519Field.Size];
            Span <int> ry = stackalloc int[X25519Field.Size];
            Span <int> rz = stackalloc int[X25519Field.Size];
            Span <int> ru = stackalloc int[X25519Field.Size];
            Span <int> rv = stackalloc int[X25519Field.Size];

            X25519Field.Zero(rx);
            X25519Field.One(ry);
            X25519Field.One(rz);
            X25519Field.Zero(ru);
            X25519Field.One(rv);

            Span <uint> n = stackalloc uint[ScalarUints];

            DecodeScalar(k, 0, n);

            {
                uint c1 = CAdd(ScalarUints, ~(int)n[0] & 1, n, L, n);
                uint c2 = ShiftDownBit(ScalarUints, n, 1U);

                for (int i = 0; i < ScalarUints; ++i)
                {
                    n[i] = Shuffle2(n[i]);
                }
            }

            Span <int> pypx_h = stackalloc int[X25519Field.Size];
            Span <int> pymx_h = stackalloc int[X25519Field.Size];
            Span <int> pxyd   = stackalloc int[X25519Field.Size];

            int cOff = (PrecompSpacing - 1) * PrecompTeeth;

            Span <int> A = stackalloc int[X25519Field.Size];
            Span <int> B = stackalloc int[X25519Field.Size];
            Span <int> C = stackalloc int[X25519Field.Size];
            Span <int> E = stackalloc int[X25519Field.Size];
            Span <int> F = stackalloc int[X25519Field.Size];
            Span <int> G = stackalloc int[X25519Field.Size];
            Span <int> H = stackalloc int[X25519Field.Size];

            Span <int> pdA = stackalloc int[X25519Field.Size];
            Span <int> pdB = stackalloc int[X25519Field.Size];
            Span <int> pdC = stackalloc int[X25519Field.Size];
            Span <int> pdE = stackalloc int[X25519Field.Size];
            Span <int> pdF = stackalloc int[X25519Field.Size];
            Span <int> pdG = stackalloc int[X25519Field.Size];
            Span <int> pdH = stackalloc int[X25519Field.Size];

            for (; ;)
            {
                for (int b = 0; b < PrecompBlocks; ++b)
                {
                    uint w    = n[b] >> cOff;
                    int  sign = (int)(w >> (PrecompTeeth - 1)) & 1;
                    int  abs  = ((int)w ^ -sign) & PrecompMask;

                    int off = b * PrecompPoints * 3 * X25519Field.Size;

                    for (int i = 0; i < PrecompPoints; ++i)
                    {
                        int cond = ((i ^ abs) - 1) >> 31;
                        X25519Field.CMov(cond, precompBase, off, pypx_h, 0); off += X25519Field.Size;
                        X25519Field.CMov(cond, precompBase, off, pymx_h, 0); off += X25519Field.Size;
                        X25519Field.CMov(cond, precompBase, off, pxyd, 0); off   += X25519Field.Size;
                    }

                    X25519Field.CSwap(sign, pypx_h, pymx_h);
                    X25519Field.CNegate(sign, pxyd);

                    A.Clear();
                    B.Clear();
                    C.Clear();
                    E = ru;
                    F.Clear();
                    G.Clear();
                    H = rv;

                    X25519Field.Apm(ry, rx, B, A);
                    X25519Field.Mul(A, pymx_h, A);
                    X25519Field.Mul(B, pypx_h, B);
                    X25519Field.Mul(ru, rv, C);
                    X25519Field.Mul(C, pxyd, C);
                    X25519Field.Apm(B, A, H, E);
                    X25519Field.Apm(rz, C, G, F);
                    X25519Field.Carry(G);
                    X25519Field.Mul(E, F, rx);
                    X25519Field.Mul(G, H, ry);
                    X25519Field.Mul(F, G, rz);
                }

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

                pdA.Clear();
                pdB.Clear();
                pdC.Clear();
                pdE = ru;
                pdF.Clear();
                pdG.Clear();
                pdH = rv;

                X25519Field.Sqr(rx, pdA);
                X25519Field.Sqr(ry, pdB);
                X25519Field.Sqr(rz, pdC);
                X25519Field.Add(pdC, pdC, pdC);
                X25519Field.Apm(pdA, pdB, pdH, pdG);
                X25519Field.Add(rx, ry, pdE);
                X25519Field.Sqr(pdE, pdE);
                X25519Field.Sub(pdH, pdE, pdE);
                X25519Field.Add(pdC, pdG, pdF);
                X25519Field.Carry(pdF);
                X25519Field.Mul(pdE, pdF, rx);
                X25519Field.Mul(pdG, pdH, ry);
                X25519Field.Mul(pdF, pdG, rz);
            }

            if (0 == CheckPoint(rx, ry, rz))
            {
                throw new InvalidOperationException();
            }

            X25519Field.Copy(ry, 0, y, 0);
            X25519Field.Copy(rz, 0, z, 0);
        }