Пример #1
0
        public static void InvAllVar(Fe[] r, Fe[] a, int len)
        {
            if (len < 1)
            {
                return;
            }
            for (int index = 0; index < len; ++index)
            {
                r[index] = a[index].Clone();
            }
            int index1 = 0;

            while (++index1 < len)
            {
                Field.Mul(r[index1], r[index1 - 1], a[index1]);
            }
            Fe  fe = new Fe();
            int index2;

            Field.InvVar(fe, r[index2 = index1 - 1]);
            while (index2 > 0)
            {
                int index3 = index2--;
                Field.Mul(r[index3], r[index2], fe);
                Field.Mul(fe, fe, a[index3]);
            }
            r[0] = fe.Clone();
        }
Пример #2
0
        /** Compare two field elements. Requires both inputs to be normalized */
        //static int secp256k1_fe_cmp_var(const secp256k1_fe* a, const secp256k1_fe* b);

        /** Set a field element equal to 32-byte big endian value. If successful, the resulting field element is normalized. */
        //static int SetB32(secp256k1_fe* r, const unsigned char* a);

        /** Convert a field element to a 32-byte big endian value. Requires the input to be normalized */
        //static void GetB32(unsigned char* r, const secp256k1_fe* a);

        /** Set a field element equal to the additive inverse of another. Takes a maximum magnitude of the input
         *  as an argument. The magnitude of the output is one higher. */
        //static void Negate(secp256k1_fe* r, const secp256k1_fe* a, int m);

        /** Multiplies the passed field element with a small integer constant. Multiplies the magnitude by that
         *  small integer. */
        //static void MulInt(secp256k1_fe* r, int a);

        /** Adds a field element to another. The result has the sum of the inputs' magnitudes as magnitude. */
        //static void Add(secp256k1_fe* r, const secp256k1_fe* a);

        /** Sets a field element to be the product of two others. Requires the inputs' magnitudes to be at most 8.
         *  The output magnitude is 1 (but not guaranteed to be normalized). */
        //static void Mul(secp256k1_fe* r, const secp256k1_fe* a, const secp256k1_fe* SECP256K1_RESTRICT b);

        /** Sets a field element to be the square of another. Requires the input's magnitude to be at most 8.
         *  The output magnitude is 1 (but not guaranteed to be normalized). */
        //static void Sqr(secp256k1_fe* r, const secp256k1_fe* a);

        /// <summary>
        /// If a has a square root, it is computed in r and 1 is returned. If a does not have a square root, the root of its negation is computed and 0 is returned. The input's magnitude can be at most 8. The output magnitude is 1 (but not guaranteed to be normalized). The result in r will always be a square itself.
        /// </summary>
        /// <param name="r"></param>
        /// <param name="a"></param>
        /// <returns></returns>
        public static bool Sqrt(Fe r, 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)).
             */
            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 Fe();
            Sqr(x2, a);
            Mul(x2, x2, a);

            x3 = new Fe();
            Sqr(x3, x2);
            Mul(x3, x3, a);

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

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

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

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

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

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

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

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

            x223 = x220.Clone();
            for (j = 0; j < 3; j++)
            {
                Sqr(x223, x223);
            }
            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++)
            {
                Sqr(t1, t1);
            }
            Mul(t1, t1, x22);
            for (j = 0; j < 6; j++)
            {
                Sqr(t1, t1);
            }
            Mul(t1, t1, x2);
            Sqr(t1, t1);
            Sqr(r, t1);

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

            Sqr(t1, r);
            return(Equal(t1, a));
        }
Пример #3
0
        /** Checks whether a field element is a quadratic residue. */
        //        static int secp256k1_fe_is_quad_var(const secp256k1_fe* a)
        //        {
        //# ifndef USE_NUM_NONE
        //            unsigned char b[32];
        //            secp256k1_num n;
        //            secp256k1_num m;
        //        /* secp256k1 field prime, value p defined in "Standards for Efficient Cryptography" (SEC2) 2.7.1. */
        //        static const unsigned char prime[32] = {
        //            0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
        //            0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
        //            0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
        //            0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFC,0x2F
        //        };

        //    secp256k1_fe c = *a;
        //    NormalizeVar(c);
        //    GetB32(b, c);
        //    secp256k1_num_set_bin(n, b, 32);
        //    secp256k1_num_set_bin(m, prime, 32);
        //    return secp256k1_num_jacobi(n, m) >= 0;
        //#else
        //    secp256k1_fe r;
        //    return Sqrt(r, a);
        //#endif
        //}

        /// <summary>
        /// Sets a field element to be the (modular) inverse of another. Requires the input's magnitude to be at most 8. The output magnitude is 1 (but not guaranteed to be normalized).
        /// </summary>
        /// <param name="r"></param>
        /// <param name="a"></param>
        /// <returns></returns>
        public static void Inv(Fe r, Fe a)
        {
            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 Fe();
            Sqr(x2, a);
            Mul(x2, x2, a);

            x3 = new Fe();
            Sqr(x3, x2);
            Mul(x3, x3, a);

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

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

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

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

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

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

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

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

            x223 = x220.Clone();
            for (j = 0; j < 3; j++)
            {
                Sqr(x223, x223);
            }
            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++)
            {
                Sqr(t1, t1);
            }
            Mul(t1, t1, x22);
            for (j = 0; j < 5; j++)
            {
                Sqr(t1, t1);
            }
            Mul(t1, t1, a);
            for (j = 0; j < 3; j++)
            {
                Sqr(t1, t1);
            }
            Mul(t1, t1, x2);
            for (j = 0; j < 2; j++)
            {
                Sqr(t1, t1);
            }
            Mul(r, a, t1);
        }
Пример #4
0
        public static bool Sqrt(Fe r, Fe a)
        {
            Fe fe1 = new Fe();

            Field.Sqr(fe1, a);
            Field.Mul(fe1, fe1, a);
            Fe fe2 = new Fe();

            Field.Sqr(fe2, fe1);
            Field.Mul(fe2, fe2, a);
            Fe fe3 = fe2.Clone();

            for (int index = 0; index < 3; ++index)
            {
                Field.Sqr(fe3, fe3);
            }
            Field.Mul(fe3, fe3, fe2);
            Fe fe4 = fe3.Clone();

            for (int index = 0; index < 3; ++index)
            {
                Field.Sqr(fe4, fe4);
            }
            Field.Mul(fe4, fe4, fe2);
            Fe fe5 = fe4.Clone();

            for (int index = 0; index < 2; ++index)
            {
                Field.Sqr(fe5, fe5);
            }
            Field.Mul(fe5, fe5, fe1);
            Fe fe6 = fe5.Clone();

            for (int index = 0; index < 11; ++index)
            {
                Field.Sqr(fe6, fe6);
            }
            Field.Mul(fe6, fe6, fe5);
            Fe fe7 = fe6.Clone();

            for (int index = 0; index < 22; ++index)
            {
                Field.Sqr(fe7, fe7);
            }
            Field.Mul(fe7, fe7, fe6);
            Fe fe8 = fe7.Clone();

            for (int index = 0; index < 44; ++index)
            {
                Field.Sqr(fe8, fe8);
            }
            Field.Mul(fe8, fe8, fe7);
            Fe fe9 = fe8.Clone();

            for (int index = 0; index < 88; ++index)
            {
                Field.Sqr(fe9, fe9);
            }
            Field.Mul(fe9, fe9, fe8);
            Fe fe10 = fe9.Clone();

            for (int index = 0; index < 44; ++index)
            {
                Field.Sqr(fe10, fe10);
            }
            Field.Mul(fe10, fe10, fe7);
            Fe fe11 = fe10.Clone();

            for (int index = 0; index < 3; ++index)
            {
                Field.Sqr(fe11, fe11);
            }
            Field.Mul(fe11, fe11, fe2);
            Fe fe12 = fe11.Clone();

            for (int index = 0; index < 23; ++index)
            {
                Field.Sqr(fe12, fe12);
            }
            Field.Mul(fe12, fe12, fe6);
            for (int index = 0; index < 6; ++index)
            {
                Field.Sqr(fe12, fe12);
            }
            Field.Mul(fe12, fe12, fe1);
            Field.Sqr(fe12, fe12);
            Field.Sqr(r, fe12);
            Field.Sqr(fe12, r);
            return(Field.Equal(fe12, a));
        }
Пример #5
0
 public GeJ Clone()
 {
     return(new GeJ(X?.Clone(), Y?.Clone(), Z?.Clone()));
 }
Пример #6
0
        public static void Inv(Fe r, Fe a)
        {
            var fe1 = new Fe();

            Field.Sqr(fe1, a);
            Field.Mul(fe1, fe1, a);
            var fe2 = new Fe();

            Field.Sqr(fe2, fe1);
            Field.Mul(fe2, fe2, a);
            var fe3 = fe2.Clone();

            for (var index = 0; index < 3; ++index)
            {
                Field.Sqr(fe3, fe3);
            }
            Field.Mul(fe3, fe3, fe2);
            var fe4 = fe3.Clone();

            for (var index = 0; index < 3; ++index)
            {
                Field.Sqr(fe4, fe4);
            }
            Field.Mul(fe4, fe4, fe2);
            var fe5 = fe4.Clone();

            for (var index = 0; index < 2; ++index)
            {
                Field.Sqr(fe5, fe5);
            }
            Field.Mul(fe5, fe5, fe1);
            var fe6 = fe5.Clone();

            for (var index = 0; index < 11; ++index)
            {
                Field.Sqr(fe6, fe6);
            }
            Field.Mul(fe6, fe6, fe5);
            var fe7 = fe6.Clone();

            for (var index = 0; index < 22; ++index)
            {
                Field.Sqr(fe7, fe7);
            }
            Field.Mul(fe7, fe7, fe6);
            var fe8 = fe7.Clone();

            for (var index = 0; index < 44; ++index)
            {
                Field.Sqr(fe8, fe8);
            }
            Field.Mul(fe8, fe8, fe7);
            var fe9 = fe8.Clone();

            for (var index = 0; index < 88; ++index)
            {
                Field.Sqr(fe9, fe9);
            }
            Field.Mul(fe9, fe9, fe8);
            var fe10 = fe9.Clone();

            for (var index = 0; index < 44; ++index)
            {
                Field.Sqr(fe10, fe10);
            }
            Field.Mul(fe10, fe10, fe7);
            var fe11 = fe10.Clone();

            for (var index = 0; index < 3; ++index)
            {
                Field.Sqr(fe11, fe11);
            }
            Field.Mul(fe11, fe11, fe2);
            var fe12 = fe11.Clone();

            for (var index = 0; index < 23; ++index)
            {
                Field.Sqr(fe12, fe12);
            }
            Field.Mul(fe12, fe12, fe6);
            for (var index = 0; index < 5; ++index)
            {
                Field.Sqr(fe12, fe12);
            }
            Field.Mul(fe12, fe12, a);
            for (var index = 0; index < 3; ++index)
            {
                Field.Sqr(fe12, fe12);
            }
            Field.Mul(fe12, fe12, fe1);
            for (var index = 0; index < 2; ++index)
            {
                Field.Sqr(fe12, fe12);
            }
            Field.Mul(r, a, fe12);
        }