示例#1
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.InvVar(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);
            }
        }