Beispiel #1
0
        //#if defined HAVE_CONFIG_H
        //# include "libsecp256k1-config.h"
        //#endif

        //# include "util.h"

        //#if defined(USE_FIELD_10X26)
        //# include "field_10x26_impl.h"
        //#elif defined(USE_FIELD_5X52)
        //# include "field_5x52_impl.h"
        //#else
        //#error "Please select field implementation"
        //#endif

        public static bool secp256k1_fe_equal(secp256k1_fe a, secp256k1_fe b)
        {
            secp256k1_fe na = new secp256k1_fe();

            secp256k1_fe_negate(na, a, 1);
            secp256k1_fe_add(na, b);
            return(secp256k1_fe_normalizes_to_zero(na));
        }
Beispiel #2
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, secp256k1_ge_storage[] pre, secp256k1_gej a, EventHandler <secp256k1_callback> cb)
        {
            secp256k1_gej[] prej = new secp256k1_gej[n];
            secp256k1_ge[]  prea = new secp256k1_ge[n];
            secp256k1_fe[]  zr   = new secp256k1_fe[n];
            for (int i = 0; i < n; i++)
            {
                prej[i] = new secp256k1_gej();
                prea[i] = new secp256k1_ge();
                zr[i]   = new secp256k1_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.secp256k1_ge_to_storage(pre[i], prea[i]);
            }
        }
        public static void secp256k1_ecmult_gen_context_build(secp256k1_ecmult_gen_context ctx, EventHandler <secp256k1_callback> cb)
        {
#if !USE_ECMULT_STATIC_PRECOMPUTATION
            secp256k1_ge[] prec = new secp256k1_ge[1024];
            secp256k1_gej  gj = new secp256k1_gej();
            secp256k1_gej  nums_gej = new secp256k1_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.secp256k1_ge_const_g);

            /* Construct a group element with no known corresponding scalar (nothing up my sleeve). */
            {
                var          nums_b32 = Encoding.UTF8.GetBytes("The scalar for this x is unknown");
                secp256k1_fe nums_x   = new secp256k1_fe();
                secp256k1_ge nums_ge  = new secp256k1_ge();
                var          r        = Field.secp256k1_fe_set_b32(nums_x, nums_b32);
                //(void)r;
                Util.VERIFY_CHECK(r);
                r = Group.secp256k1_ge_set_xo_var(nums_ge, nums_x, false);
                //(void)r;
                Util.VERIFY_CHECK(r);
                Group.secp256k1_gej_set_ge(nums_gej, nums_ge);
                /* Add G to make the bits in x uniformly distributed. */
                Group.secp256k1_gej_add_ge_var(nums_gej, nums_gej, Group.secp256k1_ge_const_g, null);
            }

            /* compute prec. */
            {
                secp256k1_gej[] precj = new secp256k1_gej[1024]; /* Jacobian versions of prec. */
                for (int k = 0; k < precj.Length; k++)
                {
                    precj[k] = new secp256k1_gej();
                }
                secp256k1_gej gbase;
                secp256k1_gej numsbase;
                gbase    = gj.Clone();       /* 16^j * G */
                numsbase = nums_gej.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, nums_gej, null);
                    }
                }
                for (int k = 0; k < prec.Length; k++)
                {
                    prec[k] = new secp256k1_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.secp256k1_ge_to_storage(ctx.prec[j][i], prec[j * 16 + i]);
                }
            }
#else
            (void)cb;
            ctx.prec = (secp256k1_ge_storage(*)[64][16])secp256k1_ecmult_static_context;
Beispiel #4
0
        //        SECP256K1_INLINE static int secp256k1_fe_equal_var(const secp256k1_fe* a, const secp256k1_fe* b)
        //        {
        //            secp256k1_fe na;
        //            secp256k1_fe_negate(na, a, 1);
        //            secp256k1_fe_add(na, b);
        //            return secp256k1_fe_normalizes_to_zero_var(na);
        //        }

        public static bool secp256k1_fe_sqrt(secp256k1_fe r, secp256k1_fe a)
        {
            /** Given that p is congruent to 3 mod 4, we can compute the square root of
             *  a mod p as the (p+1)/4'th power of a.
             *
             *  As (p+1)/4 is an even number, it will have the same result for a and for
             *  (-a). Only one of these two numbers actually has a square root however,
             *  so we test at the end by squaring and comparing to the input.
             *  Also because (p+1)/4 is an even number, the computed square root is
             *  itself always a square (a ** ((p+1)/4) is the square of a ** ((p+1)/8)).
             */
            secp256k1_fe x2, x3, x6, x9, x11, x22, x44, x88, x176, x220, x223, t1;
            int          j;

            /** The binary representation of (p + 1)/4 has 3 blocks of 1s, with lengths in
             *  { 2, 22, 223 }. Use an addition chain to calculate 2^n - 1 for each block:
             *  1, [2], 3, 6, 9, 11, [22], 44, 88, 176, 220, [223]
             */
            x2 = new secp256k1_fe();
            secp256k1_fe_sqr(x2, a);
            secp256k1_fe_mul(x2, x2, a);

            x3 = new secp256k1_fe();
            secp256k1_fe_sqr(x3, x2);
            secp256k1_fe_mul(x3, x3, a);

            x6 = x3.Clone();
            for (j = 0; j < 3; j++)
            {
                secp256k1_fe_sqr(x6, x6);
            }
            secp256k1_fe_mul(x6, x6, x3);

            x9 = x6.Clone();
            for (j = 0; j < 3; j++)
            {
                secp256k1_fe_sqr(x9, x9);
            }
            secp256k1_fe_mul(x9, x9, x3);

            x11 = x9.Clone();
            for (j = 0; j < 2; j++)
            {
                secp256k1_fe_sqr(x11, x11);
            }
            secp256k1_fe_mul(x11, x11, x2);

            x22 = x11.Clone();
            for (j = 0; j < 11; j++)
            {
                secp256k1_fe_sqr(x22, x22);
            }
            secp256k1_fe_mul(x22, x22, x11);

            x44 = x22.Clone();
            for (j = 0; j < 22; j++)
            {
                secp256k1_fe_sqr(x44, x44);
            }
            secp256k1_fe_mul(x44, x44, x22);

            x88 = x44.Clone();
            for (j = 0; j < 44; j++)
            {
                secp256k1_fe_sqr(x88, x88);
            }
            secp256k1_fe_mul(x88, x88, x44);

            x176 = x88.Clone();
            for (j = 0; j < 88; j++)
            {
                secp256k1_fe_sqr(x176, x176);
            }
            secp256k1_fe_mul(x176, x176, x88);

            x220 = x176.Clone();
            for (j = 0; j < 44; j++)
            {
                secp256k1_fe_sqr(x220, x220);
            }
            secp256k1_fe_mul(x220, x220, x44);

            x223 = x220.Clone();
            for (j = 0; j < 3; j++)
            {
                secp256k1_fe_sqr(x223, x223);
            }
            secp256k1_fe_mul(x223, x223, x3);

            /* The final result is then assembled using a sliding window over the blocks. */

            t1 = x223.Clone();
            for (j = 0; j < 23; j++)
            {
                secp256k1_fe_sqr(t1, t1);
            }
            secp256k1_fe_mul(t1, t1, x22);
            for (j = 0; j < 6; j++)
            {
                secp256k1_fe_sqr(t1, t1);
            }
            secp256k1_fe_mul(t1, t1, x2);
            secp256k1_fe_sqr(t1, t1);
            secp256k1_fe_sqr(r, t1);

            /* Check that a square root was actually calculated */

            secp256k1_fe_sqr(t1, r);
            return(secp256k1_fe_equal(t1, a));
        }
Beispiel #5
0
        public static void secp256k1_fe_inv_var(secp256k1_fe r, secp256k1_fe a)
        {
#if USE_FIELD_INV_BUILTIN
            secp256k1_fe_inv(r, a);
#elif USE_FIELD_INV_NUM
            secp256k1_num             n, m;
Beispiel #6
0
        public static void secp256k1_fe_inv(secp256k1_fe r, secp256k1_fe a)
        {
            secp256k1_fe x2, x3, x6, x9, x11, x22, x44, x88, x176, x220, x223, t1;
            int          j;

            /** The binary representation of (p - 2) has 5 blocks of 1s, with lengths in
             *  { 1, 2, 22, 223 }. Use an addition chain to calculate 2^n - 1 for each block:
             *  [1], [2], 3, 6, 9, 11, [22], 44, 88, 176, 220, [223]
             */
            x2 = new secp256k1_fe();
            secp256k1_fe_sqr(x2, a);
            secp256k1_fe_mul(x2, x2, a);

            x3 = new secp256k1_fe();
            secp256k1_fe_sqr(x3, x2);
            secp256k1_fe_mul(x3, x3, a);

            x6 = x3.Clone();
            for (j = 0; j < 3; j++)
            {
                secp256k1_fe_sqr(x6, x6);
            }
            secp256k1_fe_mul(x6, x6, x3);

            x9 = x6.Clone();
            for (j = 0; j < 3; j++)
            {
                secp256k1_fe_sqr(x9, x9);
            }
            secp256k1_fe_mul(x9, x9, x3);

            x11 = x9.Clone();
            for (j = 0; j < 2; j++)
            {
                secp256k1_fe_sqr(x11, x11);
            }
            secp256k1_fe_mul(x11, x11, x2);

            x22 = x11.Clone();
            for (j = 0; j < 11; j++)
            {
                secp256k1_fe_sqr(x22, x22);
            }
            secp256k1_fe_mul(x22, x22, x11);

            x44 = x22.Clone();
            for (j = 0; j < 22; j++)
            {
                secp256k1_fe_sqr(x44, x44);
            }
            secp256k1_fe_mul(x44, x44, x22);

            x88 = x44.Clone();
            for (j = 0; j < 44; j++)
            {
                secp256k1_fe_sqr(x88, x88);
            }
            secp256k1_fe_mul(x88, x88, x44);

            x176 = x88.Clone();
            for (j = 0; j < 88; j++)
            {
                secp256k1_fe_sqr(x176, x176);
            }
            secp256k1_fe_mul(x176, x176, x88);

            x220 = x176.Clone();
            for (j = 0; j < 44; j++)
            {
                secp256k1_fe_sqr(x220, x220);
            }
            secp256k1_fe_mul(x220, x220, x44);

            x223 = x220.Clone();
            for (j = 0; j < 3; j++)
            {
                secp256k1_fe_sqr(x223, x223);
            }
            secp256k1_fe_mul(x223, x223, x3);

            /* The final result is then assembled using a sliding window over the blocks. */

            t1 = x223.Clone();
            for (j = 0; j < 23; j++)
            {
                secp256k1_fe_sqr(t1, t1);
            }
            secp256k1_fe_mul(t1, t1, x22);
            for (j = 0; j < 5; j++)
            {
                secp256k1_fe_sqr(t1, t1);
            }
            secp256k1_fe_mul(t1, t1, a);
            for (j = 0; j < 3; j++)
            {
                secp256k1_fe_sqr(t1, t1);
            }
            secp256k1_fe_mul(t1, t1, x2);
            for (j = 0; j < 2; j++)
            {
                secp256k1_fe_sqr(t1, t1);
            }
            secp256k1_fe_mul(r, a, t1);
        }