コード例 #1
0
        public virtual ECFieldElement HalfTrace()
        {
            int m = FieldSize;

            if ((m & 1) == 0)
            {
                throw new InvalidOperationException("Half-trace only defined for odd m");
            }

            //ECFieldElement ht = this;
            //for (int i = 1; i < m; i += 2)
            //{
            //    ht = ht.SquarePow(2).Add(this);
            //}

            int n  = (m + 1) >> 1;
            int k  = 31 - Integers.NumberOfLeadingZeros(n);
            int nk = 1;

            ECFieldElement ht = this;

            while (k > 0)
            {
                ht = ht.SquarePow(nk << 1).Add(ht);
                nk = n >> --k;
                if (0 != (nk & 1))
                {
                    ht = ht.SquarePow(2).Add(this);
                }
            }

            return(ht);
        }
コード例 #2
0
        public virtual int Trace()
        {
            int m = FieldSize;

            //ECFieldElement tr = this;
            //for (int i = 1; i < m; ++i)
            //{
            //    tr = tr.Square().Add(this);
            //}

            int k  = 31 - Integers.NumberOfLeadingZeros(m);
            int mk = 1;

            ECFieldElement tr = this;

            while (k > 0)
            {
                tr = tr.SquarePow(mk).Add(tr);
                mk = m >> --k;
                if (0 != (mk & 1))
                {
                    tr = tr.Square().Add(this);
                }
            }

            if (tr.IsZero)
            {
                return(0);
            }
            if (tr.IsOne)
            {
                return(1);
            }
            throw new InvalidOperationException("Internal error in trace calculation");
        }
コード例 #3
0
        /**
         * Encodes an int array whose elements are between 0 and <code>q</code>,
         * to a byte array leaving no gaps between bits.<br>
         * <code>q</code> must be a power of 2.
         *
         * @param a the input array
         * @param q the modulus
         * @return the encoded array
         */
        public static byte[] EncodeModQ(int[] a, int q)
        {
            int bitsPerCoeff = 31 - Integers.NumberOfLeadingZeros(q);
            int numBits      = a.Length * bitsPerCoeff;
            int numBytes     = (numBits + 7) / 8;

            byte[] data      = new byte[numBytes];
            int    bitIndex  = 0;
            int    byteIndex = 0;

            for (int i = 0; i < a.Length; i++)
            {
                for (int j = 0; j < bitsPerCoeff; j++)
                {
                    int currentBit = (a[i] >> j) & 1;
                    data[byteIndex] = (byte)(data[byteIndex] | currentBit << bitIndex);
                    if (bitIndex == 7)
                    {
                        bitIndex = 0;
                        byteIndex++;
                    }
                    else
                    {
                        bitIndex++;
                    }
                }
            }
            return(data);
        }
コード例 #4
0
        /**
         * Decodes data encoded with {@link #encodeModQ(int[], int)} back to an <code>int</code> array.<br>
         * <code>N</code> is the number of coefficients. <code>q</code> must be a power of <code>2</code>.<br>
         * Ignores any excess bytes.
         *
         * @param is an encoded ternary polynomial
         * @param N  number of coefficients
         * @param q
         * @return the decoded polynomial
         */
        public static int[] DecodeModQ(Stream stream, int N, int q)
        {
            int qBits = 31 - Integers.NumberOfLeadingZeros(q);
            int size  = (N * qBits + 7) / 8;

            byte[] arr = Util.ReadFullLength(stream, size);
            return(DecodeModQ(arr, N, q));
        }
コード例 #5
0
ファイル: Mod.cs プロジェクト: weexp/bc-csharp
        public static uint ModOddInverse(uint[] m, uint[] x, uint[] z)
        {
            int len32 = m.Length;

            Debug.Assert(len32 > 0);
            Debug.Assert((m[0] & 1) != 0);
            Debug.Assert(m[len32 - 1] != 0);

            int bits  = (len32 << 5) - Integers.NumberOfLeadingZeros((int)m[len32 - 1]);
            int len30 = (bits + 29) / 30;

            int[] t = new int[4];
            int[] D = new int[len30];
            int[] E = new int[len30];
            int[] F = new int[len30];
            int[] G = new int[len30];
            int[] M = new int[len30];

            E[0] = 1;
            Encode30(bits, x, 0, G, 0);
            Encode30(bits, m, 0, M, 0);
            Array.Copy(M, 0, F, 0, len30);

            int eta         = -1;
            int m0Inv32     = (int)Inverse32((uint)M[0]);
            int maxDivsteps = GetMaximumDivsteps(bits);

            for (int divSteps = 0; divSteps < maxDivsteps; divSteps += 30)
            {
                eta = Divsteps30(eta, F[0], G[0], t);
                UpdateDE30(len30, D, E, t, m0Inv32, M);
                UpdateFG30(len30, F, G, t);
            }

            int signF = F[len30 - 1] >> 31;

            /*
             * D is in the range (-2.M, M). First, conditionally add M if D is negative, to bring it
             * into the range (-M, M). Then normalize by conditionally negating (according to signF)
             * and/or then adding M, to bring it into the range [0, M).
             */
            int signD = D[len30 - 1] >> 31;

            signD = CAdd30(len30, signD, D, M);
            CNormalize30(len30, signF, D, M);

            Decode30(bits, D, 0, z, 0);
            Debug.Assert(0 != Nat.LessThan(len32, z, m));

            signF = CNegate30(len30, signF, F);
            Debug.Assert(0 == signF);

            return((uint)(EqualTo(len30, F, 1) & EqualToZero(len30, G)));
        }
コード例 #6
0
        public void TestNumberOfLeadingZeros()
        {
            for (int i = 0; i < 31; ++i)
            {
                Assert.AreEqual(i, Integers.NumberOfLeadingZeros((int)(0x80000000U >> i)));
                Assert.AreEqual(i, Integers.NumberOfLeadingZeros((int)(0xFFFFFFFFU >> i)));
            }

            Assert.AreEqual(31, Integers.NumberOfLeadingZeros(1));
            Assert.AreEqual(32, Integers.NumberOfLeadingZeros(0));
        }
コード例 #7
0
        public static uint ModOddInverse(uint[] m, uint[] x, uint[] z)
        {
            int len32 = m.Length;

            Debug.Assert(len32 > 0);
            Debug.Assert((m[0] & 1) != 0);
            Debug.Assert(m[len32 - 1] != 0);

            int bits      = (len32 << 5) - Integers.NumberOfLeadingZeros((int)m[len32 - 1]);
            int len30     = (bits + 29) / 30;
            int m0Inv30x4 = -(int)Inverse32(m[0]) << 2;

            int[] t = new int[4];
            int[] D = new int[len30];
            int[] E = new int[len30];
            int[] F = new int[len30];
            int[] G = new int[len30];
            int[] M = new int[len30];

            E[0] = 1;
            Encode30(bits, x, 0, G, 0);
            Encode30(bits, m, 0, M, 0);
            Array.Copy(M, 0, F, 0, len30);

            int eta         = -1;
            int maxDivsteps = GetMaximumDivsteps(bits);

            for (int divSteps = 0; divSteps < maxDivsteps; divSteps += 30)
            {
                eta = Divsteps30(eta, F[0], G[0], t);
                UpdateDE30(len30, D, E, t, m0Inv30x4, M);
                UpdateFG30(len30, F, G, t);
            }

            int signF = F[len30 - 1] >> 31;

            Debug.Assert(-1 == signF | 0 == signF);

            CNegate30(len30, signF, F);
            CNegate30(len30, signF, D);

            Decode30(bits, D, 0, z, 0);

            int signD = D[len30 - 1] >> 31;

            Debug.Assert(-1 == signD | 0 == signD);

            signD += (int)Nat.CAdd(len32, signD, z, m, z);
            Debug.Assert(0 == signD & 0 != Nat.LessThan(len32, z, m));

            return((uint)(EqualTo(len30, F, 1) & EqualToZero(len30, G)));
        }
コード例 #8
0
        /**
         * Decodes a byte array encoded with {@link #toBinary()} to a ploynomial.
         *
         * @param is         an input stream containing an encoded polynomial
         * @param N          number of coefficients including zeros
         * @param numOnes    number of coefficients equal to 1
         * @param numNegOnes number of coefficients equal to -1
         * @return the decoded polynomial
         * @throws IOException
         */
        public static SparseTernaryPolynomial FromBinary(Stream stream, int N, int numOnes, int numNegOnes)
        {
            int maxIndex     = 1 << BITS_PER_INDEX;
            int bitsPerIndex = 32 - Integers.NumberOfLeadingZeros(maxIndex - 1);

            int data1Len = (numOnes * bitsPerIndex + 7) / 8;

            byte[] data1 = Util.Util.ReadFullLength(stream, data1Len);
            int[]  ones  = ArrayEncoder.DecodeModQ(data1, numOnes, maxIndex);

            int data2Len = (numNegOnes * bitsPerIndex + 7) / 8;

            byte[] data2   = Util.Util.ReadFullLength(stream, data2Len);
            int[]  negOnes = ArrayEncoder.DecodeModQ(data2, numNegOnes, maxIndex);

            return(new SparseTernaryPolynomial(N, ones, negOnes));
        }
コード例 #9
0
        /**
         * Decodes a <code>byte</code> array encoded with {@link #encodeModQ(int[], int)} back to an <code>int</code> array.<br>
         * <code>N</code> is the number of coefficients. <code>q</code> must be a power of <code>2</code>.<br>
         * Ignores any excess bytes.
         *
         * @param data an encoded ternary polynomial
         * @param N    number of coefficients
         * @param q
         * @return an array containing <code>N</code> coefficients between <code>0</code> and <code>q-1</code>
         */
        public static int[] DecodeModQ(byte[] data, int N, int q)
        {
            int[] coeffs       = new int[N];
            int   bitsPerCoeff = 31 - Integers.NumberOfLeadingZeros(q);
            int   numBits      = N * bitsPerCoeff;
            int   coeffIndex   = 0;

            for (int bitIndex = 0; bitIndex < numBits; bitIndex++)
            {
                if (bitIndex > 0 && bitIndex % bitsPerCoeff == 0)
                {
                    coeffIndex++;
                }
                int bit = GetBit(data, bitIndex);
                coeffs[coeffIndex] += bit << (bitIndex % bitsPerCoeff);
            }
            return(coeffs);
        }
コード例 #10
0
        private void ImplAddSubtractMultiplyTwiceEncodingTest(ECCurve curve, ECPoint q, BigInteger n)
        {
            // Get point at infinity on the curve
            ECPoint infinity = curve.Infinity;

            ImplTestAddSubtract(q, infinity);
            ImplTestMultiply(q, n.BitLength);
            ImplTestMultiply(infinity, n.BitLength);

            int logSize = 32 - Integers.NumberOfLeadingZeros(curve.FieldSize - 1);
            int rounds  = System.Math.Max(2, System.Math.Min(10, 32 - 3 * logSize));

            ECPoint p = q;

            for (int i = 0; ;)
            {
                ImplTestEncoding(p);
                if (++i == rounds)
                {
                    break;
                }
                p = p.Twice();
            }
        }
コード例 #11
0
        public static bool ModOddInverseVar(uint[] m, uint[] x, uint[] z)
        {
            int len32 = m.Length;

            Debug.Assert(len32 > 0);
            Debug.Assert((m[0] & 1) != 0);
            Debug.Assert(m[len32 - 1] != 0);

            int bits      = (len32 << 5) - Integers.NumberOfLeadingZeros((int)m[len32 - 1]);
            int len30     = (bits + 29) / 30;
            int m0Inv30x4 = -(int)Inverse32(m[0]) << 2;

            int[] t = new int[4];
            int[] D = new int[len30];
            int[] E = new int[len30];
            int[] F = new int[len30];
            int[] G = new int[len30];
            int[] M = new int[len30];

            E[0] = 1;
            Encode30(bits, x, 0, G, 0);
            Encode30(bits, m, 0, M, 0);
            Array.Copy(M, 0, F, 0, len30);

            int clzG = Integers.NumberOfLeadingZeros(G[len30 - 1] | 1) - (len30 * 30 + 2 - bits);
            int eta = -1 - clzG;
            int lenDE = len30, lenFG = len30;
            int maxDivsteps = GetMaximumDivsteps(bits);

            int divsteps = 0;

            while (!IsZero(lenFG, G))
            {
                if (divsteps >= maxDivsteps)
                {
                    return(false);
                }

                divsteps += 30;

                eta = Divsteps30Var(eta, F[0], G[0], t);
                UpdateDE30(lenDE, D, E, t, m0Inv30x4, M);
                UpdateFG30(lenFG, F, G, t);

                int fn = F[lenFG - 1];
                int gn = G[lenFG - 1];

                int cond = (lenFG - 2) >> 31;
                cond |= fn ^ (fn >> 31);
                cond |= gn ^ (gn >> 31);

                if (cond == 0)
                {
                    F[lenFG - 2] |= fn << 30;
                    G[lenFG - 2] |= gn << 30;
                    --lenFG;
                }
            }

            int signF = F[lenFG - 1] >> 31;

            Debug.Assert(-1 == signF | 0 == signF);

            if (0 != signF)
            {
                Negate30(lenFG, F);
                Negate30(lenDE, D);
            }

            if (!IsOne(lenFG, F))
            {
                return(false);
            }

            Decode30(bits, D, 0, z, 0);

            int signD = D[lenDE - 1] >> 31;

            Debug.Assert(-1 == signD | 0 == signD);

            if (signD < 0)
            {
                signD += (int)Nat.AddTo(len32, m, z);
            }
            Debug.Assert(0 == signD && !Nat.Gte(len32, z, m));

            return(true);
        }
コード例 #12
0
        /**
         * Multiplies <code>this</code> by an integer <code>k</code> using the
         * Window NAF method.
         * @param k The integer by which <code>this</code> is multiplied.
         * @return A new <code>ECPoint</code> which equals <code>this</code>
         * multiplied by <code>k</code>.
         */
        protected override ECPoint MultiplyPositive(ECPoint p, BigInteger k)
        {
            int minWidth = WNafUtilities.GetWindowSize(k.BitLength);

            WNafPreCompInfo info = WNafUtilities.Precompute(p, minWidth, true);

            ECPoint[] preComp    = info.PreComp;
            ECPoint[] preCompNeg = info.PreCompNeg;
            int       width      = info.Width;

            int[] wnaf = WNafUtilities.GenerateCompactWindowNaf(width, k);

            ECPoint R = p.Curve.Infinity;

            int i = wnaf.Length;

            /*
             * NOTE: We try to optimize the first window using the precomputed points to substitute an
             * addition for 2 or more doublings.
             */
            if (i > 1)
            {
                int wi = wnaf[--i];
                int digit = wi >> 16, zeroes = wi & 0xFFFF;

                int       n     = System.Math.Abs(digit);
                ECPoint[] table = digit < 0 ? preCompNeg : preComp;

                // Optimization can only be used for values in the lower half of the table
                if ((n << 2) < (1 << width))
                {
                    int highest = 32 - Integers.NumberOfLeadingZeros(n);

                    // TODO Get addition/doubling cost ratio from curve and compare to 'scale' to see if worth substituting?
                    int scale   = width - highest;
                    int lowBits = n ^ (1 << (highest - 1));

                    int i1 = ((1 << (width - 1)) - 1);
                    int i2 = (lowBits << scale) + 1;
                    R = table[i1 >> 1].Add(table[i2 >> 1]);

                    zeroes -= scale;

                    //Console.WriteLine("Optimized: 2^" + scale + " * " + n + " = " + i1 + " + " + i2);
                }
                else
                {
                    R = table[n >> 1];
                }

                R = R.TimesPow2(zeroes);
            }

            while (i > 0)
            {
                int wi = wnaf[--i];
                int digit = wi >> 16, zeroes = wi & 0xFFFF;

                int       n     = System.Math.Abs(digit);
                ECPoint[] table = digit < 0 ? preCompNeg : preComp;
                ECPoint   r     = table[n >> 1];

                R = R.TwicePlus(r);
                R = R.TimesPow2(zeroes);
            }

            return(R);
        }
コード例 #13
0
ファイル: Mod.cs プロジェクト: weexp/bc-csharp
        public static bool ModOddInverseVar(uint[] m, uint[] x, uint[] z)
        {
            int len32 = m.Length;

            Debug.Assert(len32 > 0);
            Debug.Assert((m[0] & 1) != 0);
            Debug.Assert(m[len32 - 1] != 0);

            int bits  = (len32 << 5) - Integers.NumberOfLeadingZeros((int)m[len32 - 1]);
            int len30 = (bits + 29) / 30;

            int[] t = new int[4];
            int[] D = new int[len30];
            int[] E = new int[len30];
            int[] F = new int[len30];
            int[] G = new int[len30];
            int[] M = new int[len30];

            E[0] = 1;
            Encode30(bits, x, 0, G, 0);
            Encode30(bits, m, 0, M, 0);
            Array.Copy(M, 0, F, 0, len30);

            int clzG = Integers.NumberOfLeadingZeros(G[len30 - 1] | 1) - (len30 * 30 + 2 - bits);
            int eta = -1 - clzG;
            int lenDE = len30, lenFG = len30;
            int m0Inv32     = (int)Inverse32((uint)M[0]);
            int maxDivsteps = GetMaximumDivsteps(bits);

            int divsteps = 0;

            while (!IsZero(lenFG, G))
            {
                if (divsteps >= maxDivsteps)
                {
                    return(false);
                }

                divsteps += 30;

                eta = Divsteps30Var(eta, F[0], G[0], t);
                UpdateDE30(lenDE, D, E, t, m0Inv32, M);
                UpdateFG30(lenFG, F, G, t);

                int fn = F[lenFG - 1];
                int gn = G[lenFG - 1];

                int cond = (lenFG - 2) >> 31;
                cond |= fn ^ (fn >> 31);
                cond |= gn ^ (gn >> 31);

                if (cond == 0)
                {
                    F[lenFG - 2] |= fn << 30;
                    G[lenFG - 2] |= gn << 30;
                    --lenFG;
                }
            }

            int signF = F[lenFG - 1] >> 31;

            /*
             * D is in the range (-2.M, M). First, conditionally add M if D is negative, to bring it
             * into the range (-M, M). Then normalize by conditionally negating (according to signF)
             * and/or then adding M, to bring it into the range [0, M).
             */
            int signD = D[lenDE - 1] >> 31;

            if (signD < 0)
            {
                signD = Add30(lenDE, D, M);
            }
            if (signF < 0)
            {
                signD = Negate30(lenDE, D);
                signF = Negate30(lenFG, F);
            }
            Debug.Assert(0 == signF);

            if (!IsOne(lenFG, F))
            {
                return(false);
            }

            if (signD < 0)
            {
                signD = Add30(lenDE, D, M);
            }
            Debug.Assert(0 == signD);

            Decode30(bits, D, 0, z, 0);
            Debug.Assert(!Nat.Gte(len32, z, m));

            return(true);
        }