示例#1
0
        public static void secp256k1_ecmult_context_build(EcMultContext ctx, EventHandler <Callback> cb)
        {
            if (ctx.PreG != null)
            {
                return;
            }


            GeJ gj = new GeJ();

            /* get the generator */
            Group.secp256k1_gej_set_ge(gj, Group.Secp256K1GeConstG);

#if USE_ENDOMORPHISM
            var WINDOW_G = 15;
#else
            var WINDOW_G = 16;
#endif
            var tblsize = (1 << ((WINDOW_G)-2));
            ctx.PreG = new GeStorage[tblsize];
            for (int i = 0; i < tblsize; i++)
            {
                ctx.PreG[i] = new GeStorage();
            }
            /* precompute the tables with odd multiples */
            secp256k1_ecmult_odd_multiples_table_storage_var(tblsize, ctx.PreG, gj, cb);

#if USE_ENDOMORPHISM
            {
                secp256k1_gej g_128j;
                int           i;

                ctx.pre_g_128 = (secp256k1_ge_storage(*)[])checked_malloc(cb, sizeof((*ctx.pre_g_128)[0]) * ECMULT_TABLE_SIZE(WINDOW_G));
示例#2
0
 public static void secp256k1_gej_set_ge(GeJ r, Ge a)
 {
     r.Infinity = a.Infinity;
     r.X        = a.X.Clone();
     r.Y        = a.Y.Clone();
     Field.SetInt(r.Z, 1U);
 }
        public static void ContextBuild(EcmultGenContext ctx, EventHandler <Callback> cb)
        {
            Ge[] r1   = new Ge[1024];
            GeJ  r2   = new GeJ();
            GeJ  geJ1 = new GeJ();

            if (ctx.Prec != null)
            {
                return;
            }
            ctx.PrecInit();
            Group.secp256k1_gej_set_ge(r2, Group.Secp256K1GeConstG);
            byte[] bytes = Encoding.UTF8.GetBytes("The scalar for this x is unknown");
            Fe     fe    = new Fe();
            Ge     ge    = new Ge();

            Field.SetB32(fe, bytes);
            Group.secp256k1_ge_set_xo_var(ge, fe, false);
            Group.secp256k1_gej_set_ge(geJ1, ge);
            Group.secp256k1_gej_add_ge_var(geJ1, geJ1, Group.Secp256K1GeConstG, (Fe)null);
            GeJ[] a = new GeJ[1024];
            for (int index = 0; index < a.Length; ++index)
            {
                a[index] = new GeJ();
            }
            GeJ geJ2 = r2.Clone();
            GeJ geJ3 = geJ1.Clone();

            for (int index1 = 0; index1 < 64; ++index1)
            {
                a[index1 * 16] = geJ3.Clone();
                for (int index2 = 1; index2 < 16; ++index2)
                {
                    Group.secp256k1_gej_add_var(a[index1 * 16 + index2], a[index1 * 16 + index2 - 1], geJ2, (Fe)null);
                }
                for (int index2 = 0; index2 < 4; ++index2)
                {
                    Group.secp256k1_gej_double_var(geJ2, geJ2, (Fe)null);
                }
                Group.secp256k1_gej_double_var(geJ3, geJ3, (Fe)null);
                if (index1 == 62)
                {
                    Group.secp256k1_gej_neg(geJ3, geJ3);
                    Group.secp256k1_gej_add_var(geJ3, geJ3, geJ1, (Fe)null);
                }
            }
            for (int index = 0; index < r1.Length; ++index)
            {
                r1[index] = new Ge();
            }
            Group.secp256k1_ge_set_all_gej_var(r1, a, 1024, cb);
            for (int index1 = 0; index1 < 64; ++index1)
            {
                for (int index2 = 0; index2 < 16; ++index2)
                {
                    Group.ToStorage(ctx.Prec[index1][index2], r1[index1 * 16 + index2]);
                }
            }
            EcMultGen.Blind(ctx, (byte[])null);
        }
示例#4
0
 public static void secp256k1_gej_clear(GeJ r)
 {
     r.Infinity = false;
     Field.Clear(r.X);
     Field.Clear(r.Y);
     Field.Clear(r.Z);
 }
示例#5
0
 public static void secp256k1_gej_neg(GeJ r, GeJ a)
 {
     r.Infinity = a.Infinity;
     r.X        = a.X.Clone();
     r.Y        = a.Y.Clone();
     r.Z        = a.Z.Clone();
     Field.NormalizeWeak(r.Y);
     Field.Negate(r.Y, r.Y, 1U);
 }
示例#6
0
        public static void secp256k1_gej_rescale(GeJ r, Fe s)
        {
            Fe fe = new Fe();

            Field.Sqr(fe, s);
            Field.Mul(r.X, r.X, fe);
            Field.Mul(r.Y, r.Y, fe);
            Field.Mul(r.Y, r.Y, s);
            Field.Mul(r.Z, r.Z, s);
        }
示例#7
0
        public static void secp256k1_ge_set_gej_zinv(Ge r, GeJ a, Fe zi)
        {
            Fe fe1 = new Fe();
            Fe fe2 = new Fe();

            Field.Sqr(fe1, zi);
            Field.Mul(fe2, fe1, zi);
            Field.Mul(r.X, a.X, fe1);
            Field.Mul(r.Y, a.Y, fe2);
            r.Infinity = a.Infinity;
        }
示例#8
0
        public static void SetGeJ(Ge r, GeJ a)
        {
            Fe fe1 = new Fe();
            Fe fe2 = new Fe();

            r.Infinity = a.Infinity;
            Field.Inv(a.Z, a.Z);
            Field.Sqr(fe1, a.Z);
            Field.Mul(fe2, a.Z, fe1);
            Field.Mul(a.X, a.X, fe1);
            Field.Mul(a.Y, a.Y, fe2);
            Field.SetInt(a.Z, 1U);
            r.X = a.X.Clone();
            r.Y = a.Y.Clone();
        }
示例#9
0
        public static bool EcPubKeyCreate(Context ctx, PubKey pubkey, byte[] seckey)
        {
            GeJ    r      = new GeJ();
            Ge     ge     = new Ge();
            Scalar scalar = new Scalar();
            int    num    = !Scalar.SetB32(scalar, seckey) & !Scalar.IsZero(scalar) ? 1 : 0;

            if (num != 0)
            {
                EcMultGen.secp256k1_ecmult_gen(ctx.EcMultGenCtx, out r, scalar);
                Group.SetGeJ(ge, r);
                Secp256K1T.SavePubKey(pubkey, ge);
            }
            Scalar.Clear(scalar);
            return(num != 0);
        }
示例#10
0
 public static void secp256k1_gej_double_var(GeJ r, GeJ a, Fe rzr)
 {
     r.Infinity = a.Infinity;
     if (r.Infinity)
     {
         if (rzr == null)
         {
             return;
         }
         Field.SetInt(rzr, 1U);
     }
     else
     {
         if (rzr != null)
         {
             rzr = a.Y.Clone();
             Field.NormalizeWeak(rzr);
             Field.MulInt(rzr, 2U);
         }
         Field.Mul(r.Z, a.Z, a.Y);
         Field.MulInt(r.Z, 2U);
         Fe fe1 = new Fe();
         Field.Sqr(fe1, a.X);
         Field.MulInt(fe1, 3U);
         Fe fe2 = new Fe();
         Field.Sqr(fe2, fe1);
         Fe fe3 = new Fe();
         Field.Sqr(fe3, a.Y);
         Field.MulInt(fe3, 2U);
         Fe fe4 = new Fe();
         Field.Sqr(fe4, fe3);
         Field.MulInt(fe4, 2U);
         Field.Mul(fe3, fe3, a.X);
         r.X = fe3.Clone();
         Field.MulInt(r.X, 4U);
         Field.Negate(r.X, r.X, 4U);
         Field.Add(r.X, fe2);
         Field.Negate(fe2, fe2, 1U);
         Field.MulInt(fe3, 6U);
         Field.Add(fe3, fe2);
         Field.Mul(r.Y, fe1, fe3);
         Field.Negate(fe2, fe4, 2U);
         Field.Add(r.Y, fe2);
     }
 }
示例#11
0
        public static bool EcPubKeyCreate(Context ctx, PubKey pubkey, byte[] seckey)
        {
            GeJ pj  = new GeJ();
            Ge  p   = new Ge();
            var sec = new Scalar();

            var overflow = Scalar.SetB32(sec, seckey);
            var ret      = !overflow & !Scalar.IsZero(sec);

            if (ret)
            {
                EcMultGen.secp256k1_ecmult_gen(ctx.EcMultGenCtx, out pj, sec);
                Group.SetGeJ(p, pj);
                SavePubKey(pubkey, p);
            }
            Scalar.Clear(sec);
            return(ret);
        }
示例#12
0
        public static void secp256k1_ecmult_context_build(EcMultContext ctx, EventHandler <Callback> cb)
        {
            if (ctx.PreG != null)
            {
                return;
            }
            GeJ geJ = new GeJ();

            Group.secp256k1_gej_set_ge(geJ, Group.Secp256K1GeConstG);
            int n = 1 << 16 - 2;

            ctx.PreG = new GeStorage[n];
            for (int index = 0; index < n; ++index)
            {
                ctx.PreG[index] = new GeStorage();
            }
            EcMult.secp256k1_ecmult_odd_multiples_table_storage_var(n, ctx.PreG, geJ, cb);
        }
示例#13
0
 public static void secp256k1_ecmult_odd_multiples_table_storage_var(int n, GeStorage[] pre, GeJ a, EventHandler <Callback> cb)
 {
     GeJ[] geJArray = new GeJ[n];
     Ge[]  r        = new Ge[n];
     Fe[]  zr       = new Fe[n];
     for (int index = 0; index < n; ++index)
     {
         geJArray[index] = new GeJ();
         r[index]        = new Ge();
         zr[index]       = new Fe();
     }
     EcMult.secp256k1_ecmult_odd_multiples_table(n, geJArray, zr, a);
     Group.secp256k1_ge_set_table_gej_var(r, geJArray, zr, n);
     for (int index = 0; index < n; ++index)
     {
         Group.ToStorage(pre[index], r[index]);
     }
 }
示例#14
0
        ///** Fill a table 'pre' with precomputed odd multiples of a.
        // *
        // *  There are two versions of this function:
        // *  - secp256k1_ecmult_odd_multiples_table_globalz_windowa which brings its
        // *    resulting point set to a single constant Z denominator, stores the X and Y
        // *    coordinates as ge_storage points in pre, and stores the global Z in rz.
        // *    It only operates on tables sized for WINDOW_A wnaf multiples.
        // *  - secp256k1_ecmult_odd_multiples_table_storage_var, which converts its
        // *    resulting point set to actually affine points, and stores those in pre.
        // *    It operates on tables of any size, but uses heap-allocated temporaries.
        // *
        // *  To compute a*P + b*G, we compute a table for P using the first function,
        // *  and for G using the second (which requires an inverse, but it only needs to
        // *  happen once).
        // */
        //static void secp256k1_ecmult_odd_multiples_table_globalz_windowa(secp256k1_ge* pre, secp256k1_fe* globalz, const secp256k1_gej* a)
        //{
        //    secp256k1_gej prej[ECMULT_TABLE_SIZE(WINDOW_A)];
        //    secp256k1_fe zr[ECMULT_TABLE_SIZE(WINDOW_A)];

        //    /* Compute the odd multiples in Jacobian form. */
        //    secp256k1_ecmult_odd_multiples_table(ECMULT_TABLE_SIZE(WINDOW_A), prej, zr, a);
        //    /* Bring them to the same Z denominator. */
        //    secp256k1_ge_globalz_set_table_gej(ECMULT_TABLE_SIZE(WINDOW_A), pre, globalz, prej, zr);
        //}

        public static void secp256k1_ecmult_odd_multiples_table_storage_var(int n, GeStorage[] pre, GeJ a, EventHandler <Callback> cb)
        {
            GeJ[] prej = new GeJ[n];
            Ge[]  prea = new Ge[n];
            Fe[]  zr   = new Fe[n];
            for (int i = 0; i < n; i++)
            {
                prej[i] = new GeJ();
                prea[i] = new Ge();
                zr[i]   = new Fe();
            }

            /* Compute the odd multiples in Jacobian form. */
            secp256k1_ecmult_odd_multiples_table(n, prej, zr, a);
            /* Convert them in batch to affine coordinates. */
            Group.secp256k1_ge_set_table_gej_var(prea, prej, zr, n);
            /* Convert them to compact storage form. */
            for (var i = 0; i < n; i++)
            {
                Group.ToStorage(pre[i], prea[i]);
            }
        }
示例#15
0
        //        //    /** Double multiply: R = na*A + ng*G */
        //        //    static void secp256k1_ecmult(const secp256k1_ecmult_context* ctx, secp256k1_gej* r, const secp256k1_gej* a, const secp256k1_scalar* na, const secp256k1_scalar* ng);

        //#if defined(EXHAUSTIVE_TEST_ORDER)
        ///* We need to lower these values for exhaustive tests because
        // * the tables cannot have infinities in them (this breaks the
        // * affine-isomorphism stuff which tracks z-ratios) */
        //#if EXHAUSTIVE_TEST_ORDER > 128
        //#define WINDOW_A 5
        //#define WINDOW_G 8
        //#elif EXHAUSTIVE_TEST_ORDER > 8
        //#define WINDOW_A 4
        //#define WINDOW_G 4
        //#else
        //#define WINDOW_A 2
        //#define WINDOW_G 2
        //#endif
        //#else
        //        /* optimal for 128-bit and 256-bit exponents. */
        //#define WINDOW_A 5
        //        /** larger numbers may result in slightly better performance, at the cost of
        //            exponentially larger precomputed tables. */
        //# ifdef USE_ENDOMORPHISM
        //        /** Two tables for window size 15: 1.375 MiB. */
        //#define WINDOW_G 15
        //#else
        //        /** One table for window size 16: 1.375 MiB. */
        //#define WINDOW_G 16
        //#endif
        //#endif

        /** The number of entries a table with precomputed multiples needs to have. */
        //#define ECMULT_TABLE_SIZE(w) (1 << ((w)-2))



        /// <summary>
        /// Fill a table 'prej' with precomputed odd multiples of a. Prej will contain
        /// the values [1*a,3*a,...,(2*n-1)*a], so it space for n values. zr[0] will
        /// contain prej[0].z / a.z. The other zr[i] values = prej[i].z / prej[i-1].z.
        /// Prej's Z values are undefined, except for the last value.
        /// </summary>
        /// <param name="n"></param>
        /// <param name="prej"></param>
        /// <param name="zr"></param>
        /// <param name="a"></param>
        static void secp256k1_ecmult_odd_multiples_table(int n, GeJ[] prej, Fe[] zr, GeJ a)
        {
            Debug.Assert(!a.Infinity);

            GeJ d = new GeJ();

            Group.secp256k1_gej_double_var(d, a, null);

            /*
             * Perform the additions on an isomorphism where 'd' is affine: drop the z coordinate
             * of 'd', and scale the 1P starting value's x/y coordinates without changing its z.
             */
            Ge dGe = new Ge();

            dGe.X        = d.X.Clone();
            dGe.Y        = d.Y.Clone();
            dGe.Infinity = false;


            Ge aGe = new Ge();

            Group.secp256k1_ge_set_gej_zinv(aGe, a, d.Z);
            prej[0].X        = aGe.X.Clone();
            prej[0].Y        = aGe.Y.Clone();
            prej[0].Z        = a.Z.Clone();
            prej[0].Infinity = false;

            zr[0] = d.Z.Clone();
            for (var i = 1; i < n; i++)
            {
                Group.secp256k1_gej_add_ge_var(prej[i], prej[i - 1], dGe, zr[i]);
            }

            /*
             * Each point in 'prej' has a z coordinate too small by a factor of 'd.z'. Only
             * the final point's z coordinate is actually used though, so just update that.
             */
            Field.Mul(prej[n - 1].Z, prej[n - 1].Z, d.Z);
        }
示例#16
0
        public static void secp256k1_ecmult_gen(EcmultGenContext ctx, out GeJ r, Scalar gn)
        {
            Ge        ge        = new Ge();
            GeStorage geStorage = new GeStorage();

            r = ctx.Initial.Clone();
            Scalar r1 = new Scalar();

            Scalar.Add(r1, gn, ctx.Blind);
            ge.Infinity = false;
            for (int index1 = 0; index1 < 64; ++index1)
            {
                uint bits = r1.GetBits(index1 * 4, 4);
                for (int index2 = 0; index2 < 16; ++index2)
                {
                    Group.StorageCmov(geStorage, ctx.Prec[index1][index2], (long)index2 == (long)bits);
                }
                Group.FromStorage(ge, geStorage);
                Group.GeJAddGe(r, r, ge);
            }
            Group.secp256k1_ge_clear(ge);
            Scalar.Clear(r1);
        }
示例#17
0
        private static void secp256k1_ecmult_odd_multiples_table(int n, GeJ[] prej, Fe[] zr, GeJ a)
        {
            GeJ r1 = new GeJ();

            Group.secp256k1_gej_double_var(r1, a, (Fe)null);
            Ge b = new Ge();

            b.X        = r1.X.Clone();
            b.Y        = r1.Y.Clone();
            b.Infinity = false;
            Ge r2 = new Ge();

            Group.secp256k1_ge_set_gej_zinv(r2, a, r1.Z);
            prej[0].X        = r2.X.Clone();
            prej[0].Y        = r2.Y.Clone();
            prej[0].Z        = a.Z.Clone();
            prej[0].Infinity = false;
            zr[0]            = r1.Z.Clone();
            for (int index = 1; index < n; ++index)
            {
                Group.secp256k1_gej_add_ge_var(prej[index], prej[index - 1], b, zr[index]);
            }
            Field.Mul(prej[n - 1].Z, prej[n - 1].Z, r1.Z);
        }
示例#18
0
        ///** Check whether a group element is valid (i.e., on the curve). */
        //        static int secp256k1_ge_is_valid_var(const secp256k1_ge* a);

        //        static void secp256k1_ge_neg(secp256k1_ge* r, const secp256k1_ge* a);

        ///** Bring a batch inputs given in jacobian coordinates (with known z-ratios) to
        // *  the same global z "denominator". zr must contain the known z-ratios such
        // *  that mul(a[i].z, zr[i+1]) == a[i+1].z. zr[0] is ignored. The x and y
        // *  coordinates of the result are stored in r, the common z coordinate is
        // *  stored in globalz. */
        //        static void secp256k1_ge_globalz_set_table_gej(size_t len, secp256k1_ge* r, secp256k1_fe* globalz, const secp256k1_gej* a, const secp256k1_fe* zr);

        ///** Set a group element (jacobian) equal to the point at infinity. */
        //        static void secp256k1_gej_set_infinity(secp256k1_gej* r);


        ///** Compare the X coordinate of a group element (jacobian). */
        //        static int secp256k1_gej_eq_x_var(const secp256k1_fe* x, const secp256k1_gej* a);

        ///** Check whether a group element is the point at infinity. */
        //        static int secp256k1_gej_is_infinity(const secp256k1_gej* a);

        ///** Check whether a group element's y coordinate is a quadratic residue. */
        //        static int secp256k1_gej_has_quad_y_var(const secp256k1_gej* a);

        ///** Set r equal to the double of a. If rzr is not-null, r.z = a.z * *rzr (where infinity means an implicit z = 0).
        // * a may not be zero. Constant time. */
        //        static void secp256k1_gej_double_nonzero(secp256k1_gej* r, const secp256k1_gej* a, secp256k1_fe* rzr);


        /// <summary>
        /// Set r equal to the sum of a and b (with b given in affine coordinates, and not infinity).
        /// </summary>
        /// <param name="r"></param>
        /// <param name="a"></param>
        /// <param name="b"></param>
        public static void GeJAddGe(GeJ r, GeJ a, Ge b)
        {
示例#19
0
 public static void secp256k1_gej_add_ge_var(GeJ r, GeJ a, Ge b, Fe rzr)
 {
     if (a.Infinity)
     {
         Group.secp256k1_gej_set_ge(r, b);
     }
     else if (b.Infinity)
     {
         if (rzr != null)
         {
             Field.SetInt(rzr, 1U);
         }
         r = a.Clone();
     }
     else
     {
         r.Infinity = false;
         Fe fe1 = new Fe();
         Field.Sqr(fe1, a.Z);
         Fe fe2 = a.X.Clone();
         Field.NormalizeWeak(fe2);
         Fe fe3 = new Fe();
         Field.Mul(fe3, b.X, fe1);
         Fe fe4 = a.Y.Clone();
         Field.NormalizeWeak(fe4);
         Fe fe5 = new Fe();
         Field.Mul(fe5, b.Y, fe1);
         Field.Mul(fe5, fe5, a.Z);
         Fe fe6 = new Fe();
         Field.Negate(fe6, fe2, 1U);
         Field.Add(fe6, fe3);
         Fe fe7 = new Fe();
         Field.Negate(fe7, fe4, 1U);
         Field.Add(fe7, fe5);
         if (Field.NormalizesToZeroVar(fe6))
         {
             if (Field.NormalizesToZeroVar(fe7))
             {
                 Group.secp256k1_gej_double_var(r, a, rzr);
             }
             else
             {
                 if (rzr != null)
                 {
                     Field.SetInt(rzr, 0U);
                 }
                 r.Infinity = true;
             }
         }
         else
         {
             Fe fe8 = new Fe();
             Field.Sqr(fe8, fe7);
             Fe fe9 = new Fe();
             Field.Sqr(fe9, fe6);
             Fe fe10 = new Fe();
             Field.Mul(fe10, fe6, fe9);
             if (rzr != null)
             {
                 rzr = fe6.Clone();
             }
             Field.Mul(r.Z, a.Z, fe6);
             Fe fe11 = new Fe();
             Field.Mul(fe11, fe2, fe9);
             r.X = fe11.Clone();
             Field.MulInt(r.X, 2U);
             Field.Add(r.X, fe10);
             Field.Negate(r.X, r.X, 3U);
             Field.Add(r.X, fe8);
             Field.Negate(r.Y, r.X, 5U);
             Field.Add(r.Y, fe11);
             Field.Mul(r.Y, r.Y, fe7);
             Field.Mul(fe10, fe10, fe4);
             Field.Negate(fe10, fe10, 1U);
             Field.Add(r.Y, fe10);
         }
     }
 }
示例#20
0
        public static void GeJAddGe(GeJ r, GeJ a, Ge b)
        {
            uint[] arr = new uint[10];
            arr[0] = 1U;
            Fe a1 = new Fe(arr);

            if (b.Infinity)
            {
                throw new ArithmeticException();
            }
            Fe fe1 = new Fe();

            Field.Sqr(fe1, a.Z);
            Fe fe2 = a.X.Clone();

            Field.NormalizeWeak(fe2);
            Fe fe3 = new Fe();

            Field.Mul(fe3, b.X, fe1);
            Fe r1 = a.Y.Clone();

            Field.NormalizeWeak(r1);
            Fe fe4 = new Fe();

            Field.Mul(fe4, b.Y, fe1);
            Field.Mul(fe4, fe4, a.Z);
            Fe fe5 = fe2.Clone();

            Field.Add(fe5, fe3);
            Fe fe6 = r1.Clone();

            Field.Add(fe6, fe4);
            Fe fe7 = new Fe();

            Field.Sqr(fe7, fe5);
            Fe fe8 = new Fe();

            Field.Negate(fe8, fe3, 1U);
            Fe fe9 = new Fe();

            Field.Mul(fe9, fe2, fe8);
            Field.Add(fe7, fe9);
            bool flag1 = Field.NormalizesToZero(fe6) && Field.NormalizesToZero(fe7);
            Fe   fe10  = r1.Clone();

            Field.MulInt(fe10, 2U);
            Field.Add(fe8, fe2);
            Field.Cmov(fe10, fe7, !flag1);
            Field.Cmov(fe8, fe6, !flag1);
            Fe fe11 = new Fe();

            Field.Sqr(fe11, fe8);
            Fe fe12 = new Fe();

            Field.Mul(fe12, fe11, fe5);
            Field.Sqr(fe11, fe11);
            Field.Cmov(fe11, fe6, flag1);
            Field.Sqr(fe5, fe10);
            Field.Mul(r.Z, a.Z, fe8);
            bool flag2 = !a.Infinity && Field.NormalizesToZero(r.Z);

            Field.MulInt(r.Z, 2U);
            Field.Negate(fe12, fe12, 1U);
            Field.Add(fe5, fe12);
            Field.NormalizeWeak(fe5);
            r.X = fe5.Clone();
            Field.MulInt(fe5, 2U);
            Field.Add(fe5, fe12);
            Field.Mul(fe5, fe5, fe10);
            Field.Add(fe5, fe11);
            Field.Negate(r.Y, fe5, 3U);
            Field.NormalizeWeak(r.Y);
            Field.MulInt(r.X, 4U);
            Field.MulInt(r.Y, 4U);
            Field.Cmov(r.X, b.X, a.Infinity);
            Field.Cmov(r.Y, b.Y, a.Infinity);
            Field.Cmov(r.Z, a1, a.Infinity);
            r.Infinity = flag2;
        }
示例#21
0
        public static void ContextBuild(EcmultGenContext ctx, EventHandler <Callback> cb)
        {
#if !USE_ECMULT_STATIC_PRECOMPUTATION
            Ge[] prec = new Ge[1024];
            GeJ  gj = new GeJ();
            GeJ  numsGej = new GeJ();
            int  i, j;
#endif

            if (ctx.Prec != null)
            {
                return;
            }
#if !USE_ECMULT_STATIC_PRECOMPUTATION
            ctx.PrecInit();

            /* get the generator */
            Group.secp256k1_gej_set_ge(gj, Group.Secp256K1GeConstG);

            /* Construct a group element with no known corresponding scalar (nothing up my sleeve). */
            {
                var numsB32 = Encoding.UTF8.GetBytes("The scalar for this x is unknown");
                Fe  numsX   = new Fe();
                Ge  numsGe  = new Ge();
                var r       = Field.SetB32(numsX, numsB32);
                //(void)r;
                Util.VERIFY_CHECK(r);
                r = Group.secp256k1_ge_set_xo_var(numsGe, numsX, false);
                //(void)r;
                Util.VERIFY_CHECK(r);
                Group.secp256k1_gej_set_ge(numsGej, numsGe);
                /* Add G to make the bits in x uniformly distributed. */
                Group.secp256k1_gej_add_ge_var(numsGej, numsGej, Group.Secp256K1GeConstG, null);
            }

            /* compute prec. */
            {
                GeJ[] precj = new GeJ[1024]; /* Jacobian versions of prec. */
                for (int k = 0; k < precj.Length; k++)
                {
                    precj[k] = new GeJ();
                }
                GeJ gbase;
                GeJ numsbase;
                gbase    = gj.Clone();      /* 16^j * G */
                numsbase = numsGej.Clone(); /* 2^j * nums. */
                for (j = 0; j < 64; j++)
                {
                    /* Set precj[j*16 .. j*16+15] to (numsbase, numsbase + gbase, ..., numsbase + 15*gbase). */
                    precj[j * 16] = numsbase.Clone();
                    for (i = 1; i < 16; i++)
                    {
                        Group.secp256k1_gej_add_var(precj[j * 16 + i], precj[j * 16 + i - 1], gbase, null);
                    }
                    /* Multiply gbase by 16. */
                    for (i = 0; i < 4; i++)
                    {
                        Group.secp256k1_gej_double_var(gbase, gbase, null);
                    }
                    /* Multiply numbase by 2. */
                    Group.secp256k1_gej_double_var(numsbase, numsbase, null);
                    if (j == 62)
                    {
                        /* In the last iteration, numsbase is (1 - 2^j) * nums instead. */
                        Group.secp256k1_gej_neg(numsbase, numsbase);
                        Group.secp256k1_gej_add_var(numsbase, numsbase, numsGej, null);
                    }
                }
                for (int k = 0; k < prec.Length; k++)
                {
                    prec[k] = new Ge();
                }
                Group.secp256k1_ge_set_all_gej_var(prec, precj, 1024, cb);
            }
            for (j = 0; j < 64; j++)
            {
                for (i = 0; i < 16; i++)
                {
                    Group.ToStorage(ctx.Prec[j][i], prec[j * 16 + i]);
                }
            }
#else
            (void)cb;
            ctx.prec = (secp256k1_ge_storage(*)[64][16])secp256k1_ecmult_static_context;