コード例 #1
0
        private static void PointAdd(PointExt p, PointAccum r)
        {
            int[] a = F.Create();
            int[] b = F.Create();
            int[] c = F.Create();
            int[] d = F.Create();
            int[] e = r.u;
            int[] f = F.Create();
            int[] g = F.Create();
            int[] h = r.v;

            F.Apm(r.y, r.x, b, a);
            F.Apm(p.y, p.x, d, c);
            F.Mul(a, c, a);
            F.Mul(b, d, b);
            F.Mul(r.u, r.v, c);
            F.Mul(c, p.t, c);
            F.Mul(c, C_d2, c);
            F.Mul(r.z, p.z, d);
            F.Add(d, d, d);
            F.Apm(b, a, h, e);
            F.Apm(d, c, g, f);
            F.Carry(g);
            F.Mul(e, f, r.x);
            F.Mul(g, h, r.y);
            F.Mul(f, g, r.z);
        }
コード例 #2
0
        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));
        }
コード例 #3
0
        private static void ScalarMultBaseEncoded(byte[] k, byte[] r, int rOff)
        {
            PointAccum p = new PointAccum();

            ScalarMultBase(k, p);
            EncodePoint(p, r, rOff);
        }
コード例 #4
0
        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);
            }
        }
コード例 #5
0
 private static void PointSetNeutral(PointAccum p)
 {
     X25519Field.Zero(p.x);
     X25519Field.One(p.y);
     X25519Field.One(p.z);
     X25519Field.Zero(p.u);
     X25519Field.One(p.v);
 }
コード例 #6
0
 private static void PointSetNeutral(PointAccum p)
 {
     F.Zero(p.x);
     F.One(p.y);
     F.One(p.z);
     F.Zero(p.u);
     F.One(p.v);
 }
コード例 #7
0
        private static PointExt PointCopy(PointAccum p)
        {
            PointExt r = new PointExt();

            X25519Field.Copy(p.x, 0, r.x, 0);
            X25519Field.Copy(p.y, 0, r.y, 0);
            X25519Field.Copy(p.z, 0, r.z, 0);
            X25519Field.Mul(p.u, p.v, r.t);
            return(r);
        }
コード例 #8
0
        private static void ScalarMultBaseEncoded(byte[] k, byte[] r, int rOff)
        {
            PointAccum p = new PointAccum();

            ScalarMultBase(k, p);
            if (0 == EncodePoint(p, r, rOff))
            {
                throw new InvalidOperationException();
            }
        }
コード例 #9
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);
            }

            PointExt pA = new PointExt();

            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();

            ScalarMultStraussVar(nS, nA, pA, pR);

            byte[] check = new byte[PointBytes];
            EncodePoint(pR, check, 0);

            return(Arrays.AreEqual(check, R));
        }
コード例 #10
0
        internal static void ScalarMultBaseYZ(byte[] k, int kOff, int[] y, int[] z)
        {
            byte[] n = new byte[ScalarBytes];
            PruneScalar(k, kOff, n);

            PointAccum p = new PointAccum();

            ScalarMultBase(n, p);
            X25519Field.Copy(p.y, 0, y, 0);
            X25519Field.Copy(p.z, 0, z, 0);
        }
コード例 #11
0
        private static void ScalarMultBase(byte[] k, PointAccum r)
        {
            Precompute();

            PointSetNeutral(r);

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

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

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

            PointPrecomp p = new PointPrecomp();

            int cOff = (PrecompSpacing - 1) * PrecompTeeth;

            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;

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

                    PointLookup(b, abs, p);

                    X25519Field.CSwap(sign, p.ypx_h, p.ymx_h);
                    X25519Field.CNegate(sign, p.xyd);

                    PointAddPrecomp(p, r);
                }

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

                PointDouble(r);
            }
        }
コード例 #12
0
        private static void EncodePoint(PointAccum p, byte[] r, int rOff)
        {
            int[] x = X25519Field.Create();
            int[] y = X25519Field.Create();

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

            X25519Field.Encode(y, r, rOff);
            r[rOff + PointBytes - 1] |= (byte)((x[0] & 1) << 7);
        }
コード例 #13
0
        private static void ScalarMultStraussVar(uint[] nb, uint[] np, PointExt p, PointAccum r)
        {
            Precompute();

            int width = 5;

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

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

            PointSetNeutral(r);

            int bit = 255;

            while (bit > 0 && ((byte)ws_b[bit] | (byte)ws_p[bit]) == 0)
            {
                --bit;
            }

            for (; ;)
            {
                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);
            }
        }
コード例 #14
0
ファイル: Ed25519.cs プロジェクト: 894880010/MP
        public static bool Verify(byte[] sig, int sigOff, byte[] pk, int pkOff, byte[] m, int mOff, int mLen)
        {
            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);
            }

            PointExt pA = new PointExt();

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

            Sha512Digest d = new Sha512Digest();

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

            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();

            ScalarMultStraussVar(nS, nA, pA, pR);

            byte[] check = new byte[PointBytes];
            EncodePoint(pR, check, 0);

            return(Arrays.AreEqual(check, R));
        }
コード例 #15
0
        internal static void ScalarMultBaseYZ(byte[] k, int kOff, int[] y, int[] z)
        {
            byte[] n = new byte[ScalarBytes];
            PruneScalar(k, kOff, n);

            PointAccum p = new PointAccum();

            ScalarMultBase(n, p);

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

            X25519Field.Copy(p.y, 0, y, 0);
            X25519Field.Copy(p.z, 0, z, 0);
        }
コード例 #16
0
        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);
            }
        }
コード例 #17
0
        private static int EncodePoint(PointAccum p, byte[] r, int rOff)
        {
            int[] x = F.Create();
            int[] y = F.Create();

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

            int result = CheckPoint(x, y);

            F.Encode(y, r, rOff);
            r[rOff + PointBytes - 1] |= (byte)((x[0] & 1) << 7);

            return(result);
        }
コード例 #18
0
        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);
            }
        }
コード例 #19
0
        private static void PointAddPrecomp(PointPrecomp p, PointAccum r)
        {
            int[] a = F.Create();
            int[] b = F.Create();
            int[] c = F.Create();
            int[] e = r.u;
            int[] f = F.Create();
            int[] g = F.Create();
            int[] h = r.v;

            F.Apm(r.y, r.x, b, a);
            F.Mul(a, p.ymx_h, a);
            F.Mul(b, p.ypx_h, b);
            F.Mul(r.u, r.v, c);
            F.Mul(c, p.xyd, c);
            F.Apm(b, a, h, e);
            F.Apm(r.z, c, g, f);
            F.Carry(g);
            F.Mul(e, f, r.x);
            F.Mul(g, h, r.y);
            F.Mul(f, g, r.z);
        }
コード例 #20
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);
        }
コード例 #21
0
        private static void PointAddVar(bool negate, PointExt p, PointAccum r)
        {
            int[] a = F.Create();
            int[] b = F.Create();
            int[] c = F.Create();
            int[] d = F.Create();
            int[] e = r.u;
            int[] f = F.Create();
            int[] g = F.Create();
            int[] h = r.v;

            int[] nc, nd, nf, ng;
            if (negate)
            {
                nc = d; nd = c; nf = g; ng = f;
            }
            else
            {
                nc = c; nd = d; nf = f; ng = g;
            }

            F.Apm(r.y, r.x, b, a);
            F.Apm(p.y, p.x, nd, nc);
            F.Mul(a, c, a);
            F.Mul(b, d, b);
            F.Mul(r.u, r.v, c);
            F.Mul(c, p.t, c);
            F.Mul(c, C_d2, c);
            F.Mul(r.z, p.z, d);
            F.Add(d, d, d);
            F.Apm(b, a, h, e);
            F.Apm(d, c, ng, nf);
            F.Carry(ng);
            F.Mul(e, f, r.x);
            F.Mul(g, h, r.y);
            F.Mul(f, g, r.z);
        }
コード例 #22
0
        private static void PointAddVar(bool negate, PointExt p, PointAccum r)
        {
            int[] A = X25519Field.Create();
            int[] B = X25519Field.Create();
            int[] C = X25519Field.Create();
            int[] D = X25519Field.Create();
            int[] E = r.u;
            int[] F = X25519Field.Create();
            int[] G = X25519Field.Create();
            int[] H = r.v;

            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(r.y, r.x, B, A);
            X25519Field.Apm(p.y, p.x, d, c);
            X25519Field.Mul(A, C, A);
            X25519Field.Mul(B, D, B);
            X25519Field.Mul(r.u, r.v, C);
            X25519Field.Mul(C, p.t, C);
            X25519Field.Mul(C, C_d2, C);
            X25519Field.Mul(r.z, p.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);
        }
コード例 #23
0
        private static void PointDouble(PointAccum r)
        {
            int[] a = F.Create();
            int[] b = F.Create();
            int[] c = F.Create();
            int[] e = r.u;
            int[] f = F.Create();
            int[] g = F.Create();
            int[] h = r.v;

            F.Sqr(r.x, a);
            F.Sqr(r.y, b);
            F.Sqr(r.z, c);
            F.Add(c, c, c);
            F.Apm(a, b, h, g);
            F.Add(r.x, r.y, e);
            F.Sqr(e, e);
            F.Sub(h, e, e);
            F.Add(c, g, f);
            F.Carry(f);
            F.Mul(e, f, r.x);
            F.Mul(g, h, r.y);
            F.Mul(f, g, r.z);
        }
コード例 #24
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);
        }
コード例 #25
0
 private static void PointExtendXY(PointAccum p)
 {
     F.One(p.z);
     F.Copy(p.x, 0, p.u, 0);
     F.Copy(p.y, 0, p.v, 0);
 }
コード例 #26
0
ファイル: Ed25519.cs プロジェクト: gendalf90/Datagrammer.Quic
        private static void Precompute()
        {
            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());
                    }
                }

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

                    int[] x = new int[X25519Field.Size];
                    int[] y = new int[X25519Field.Size];

                    X25519Field.Add(q.z, q.z, x);
                    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.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;
                }
            }
        }
コード例 #27
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);
 }
コード例 #28
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);
            }
        }
コード例 #29
0
 private static void PointExtendXY(PointAccum p)
 {
     X25519Field.One(p.z);
     X25519Field.Copy(p.x, 0, p.u, 0);
     X25519Field.Copy(p.y, 0, p.v, 0);
 }
コード例 #30
0
        public static void Precompute()
        {
            lock (precompLock)
            {
                if (precompBase != null)
                {
                    return;
                }

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

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

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

                precompBase = F.CreateTable(PrecompBlocks * PrecompPoints * 3);

                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);

                    int[] cs = F.CreateTable(PrecompPoints);

                    // TODO[ed25519] A single batch inversion across all blocks?
                    {
                        int[] u = F.Create();
                        F.Copy(points[0].z, 0, u, 0);
                        F.Copy(u, 0, cs, 0);

                        int i = 0;
                        while (++i < PrecompPoints)
                        {
                            F.Mul(u, points[i].z, u);
                            F.Copy(u, 0, cs, i * F.Size);
                        }

                        F.Add(u, u, u);
                        F.InvVar(u, u);
                        --i;

                        int[] t = F.Create();

                        while (i > 0)
                        {
                            int j = i--;
                            F.Copy(cs, i * F.Size, t, 0);
                            F.Mul(t, u, t);
                            F.Copy(t, 0, cs, j * F.Size);
                            F.Mul(u, points[j].z, u);
                        }

                        F.Copy(u, 0, cs, 0);
                    }

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

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

                        //F.Add(q.z, q.z, x);
                        //F.InvVar(x, y);
                        F.Copy(cs, i * F.Size, y, 0);

                        F.Mul(q.x, y, x);
                        F.Mul(q.y, y, y);

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

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

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

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