Esempio n. 1
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);
        }
Esempio n. 2
0
        private static void ScalarMult(ReadOnlySpan <byte> k, int kOff, ReadOnlySpan <byte> u, int uOff, Span <byte> r, int rOff)
        {
            Span <uint> n = stackalloc uint[8];

            DecodeScalar(k, kOff, n);

            Span <int> x1 = stackalloc int[X25519Field.Size];

            X25519Field.Decode(u, uOff, x1);
            Span <int> x2 = stackalloc int[X25519Field.Size];

            X25519Field.Copy(x1, 0, x2, 0);
            Span <int> z2 = stackalloc int[X25519Field.Size];

            z2[0] = 1;
            Span <int> x3 = stackalloc int[X25519Field.Size];

            x3[0] = 1;
            Span <int> z3 = stackalloc int[X25519Field.Size];

            Span <int> t1 = stackalloc int[X25519Field.Size];
            Span <int> t2 = stackalloc int[X25519Field.Size];

            int bit = 254, swap = 1;

            do
            {
                X25519Field.Apm(x3, z3, t1, x3);
                X25519Field.Apm(x2, z2, z3, x2);
                X25519Field.Mul(t1, x2, t1);
                X25519Field.Mul(x3, z3, x3);
                X25519Field.Sqr(z3, z3);
                X25519Field.Sqr(x2, x2);

                X25519Field.Sub(z3, x2, t2);
                X25519Field.Mul(t2, C_A24, z2);
                X25519Field.Add(z2, x2, z2);
                X25519Field.Mul(z2, t2, z2);
                X25519Field.Mul(x2, z3, x2);

                X25519Field.Apm(t1, x3, x3, z3);
                X25519Field.Sqr(x3, x3);
                X25519Field.Sqr(z3, z3);
                X25519Field.Mul(z3, x1, z3);

                --bit;

                int word = bit >> 5, shift = bit & 0x1F;
                int kt = (int)(n[word] >> shift) & 1;
                swap ^= kt;
                X25519Field.CSwap(swap, x2, x3);
                X25519Field.CSwap(swap, z2, z3);
                swap = kt;
            }while (bit >= 3);

            for (int i = 0; i < 3; ++i)
            {
                PointDouble(x2, z2);
            }

            X25519Field.Inv(z2, z2);
            X25519Field.Mul(x2, z2, x2);

            X25519Field.Normalize(x2);
            X25519Field.Encode(x2, r, rOff);
        }