示例#1
0
            internal ZMod(byte[] bmod, int off, int len)
            {
                bitLen = BigInt.BitLength(bmod, off, len);
                if (bitLen <= 1 || (bmod[off + len - 1] & 1) == 0)
                {
                    throw new CryptoException("invalid modulus");
                }
                int n = (bitLen + 30) / 31;

                val = new uint[n];
                DecodeBE(bmod, off, len, val);
                uint x = val[0];
                uint y = 2 - x;

                y  *= 2 - y * x;
                y  *= 2 - y * x;
                y  *= 2 - y * x;
                y  *= 2 - y * x;
                n0i = (1 + ~y) & 0x7FFFFFFF;

                /*
                 * Compute the Rx[] values.
                 */
                int zk = 0;

                while ((n >> zk) != 0)
                {
                    zk++;
                }
                R        = new uint[n];
                R[n - 1] = 1;
                for (int i = 0; i < 31; i++)
                {
                    ModMul2(R, val);
                }
                Rx    = new uint[zk][];
                Rx[0] = new uint[n];
                Array.Copy(R, 0, Rx[0], 0, n);
                for (int i = 0; i < 31; i++)
                {
                    ModMul2(Rx[0], val);
                }
                for (int k = 1; k < zk; k++)
                {
                    Rx[k] = new uint[n];
                    MontyMul(Rx[k - 1], Rx[k - 1], Rx[k], val, n0i);
                }

                /*
                 * Compute R2 by multiplying the relevant Rx[]
                 * values.
                 */
                R2 = null;
                uint[] tt = new uint[n];
                for (int k = 0; k < zk; k++)
                {
                    if (((n >> k) & 1) == 0)
                    {
                        continue;
                    }
                    if (R2 == null)
                    {
                        R2 = new uint[n];
                        Array.Copy(Rx[k], 0, R2, 0, n);
                    }
                    else
                    {
                        MontyMul(Rx[k], R2, tt, val, n0i);
                        Array.Copy(tt, 0, R2, 0, n);
                    }
                }

                /*
                 * Compute N-2; used as an exponent for modular
                 * inversion. Since modulus N is odd and greater
                 * than 1, N-2 is necessarily positive.
                 */
                vm2 = new byte[(bitLen + 7) >> 3];
                int cc = 2;

                for (int i = 0; i < vm2.Length; i++)
                {
                    int b = bmod[off + len - 1 - i];
                    b -= cc;
                    vm2[vm2.Length - 1 - i] = (byte)b;
                    cc = (b >> 8) & 1;
                }
            }
示例#2
0
        /*
         * Checks enforced by the constructor:
         * -- modulus is odd and at least 80-bit long
         * -- subgroup order is odd and at least 30-bit long
         * -- parameters a[] and b[] are lower than modulus
         * -- coordinates gx and gy are lower than modulus
         * -- coordinates gx and gy match curve equation
         */
        internal ECCurvePrime(string name, byte[] mod, byte[] a, byte[] b,
                              byte[] gx, byte[] gy, byte[] subgroupOrder, byte[] cofactor)
            : base(subgroupOrder, cofactor)
        {
            this.mod = mod = BigInt.NormalizeBE(mod);
            int modLen = BigInt.BitLength(mod);

            if (modLen < 80)
            {
                throw new CryptoException(
                          "Invalid curve: modulus is too small");
            }
            if ((mod[mod.Length - 1] & 0x01) == 0)
            {
                throw new CryptoException(
                          "Invalid curve: modulus is even");
            }
            int sgLen = BigInt.BitLength(subgroupOrder);

            if (sgLen < 30)
            {
                throw new CryptoException(
                          "Invalid curve: subgroup is too small");
            }
            if ((subgroupOrder[subgroupOrder.Length - 1] & 0x01) == 0)
            {
                throw new CryptoException(
                          "Invalid curve: subgroup order is even");
            }

            mp    = new ModInt(mod);
            flen  = (modLen + 7) >> 3;
            pMod4 = mod[mod.Length - 1] & 3;

            this.a = a = BigInt.NormalizeBE(a);
            this.b = b = BigInt.NormalizeBE(b);
            if (BigInt.CompareCT(a, mod) >= 0 ||
                BigInt.CompareCT(b, mod) >= 0)
            {
                throw new CryptoException(
                          "Invalid curve: out-of-range parameter");
            }
            ma = mp.Dup();
            ma.Decode(a);
            ma.Add(3);
            aIsM3 = ma.IsZero;
            ma.Sub(3);
            mb = mp.Dup();
            mb.Decode(b);

            this.gx = gx = BigInt.NormalizeBE(gx);
            this.gy = gy = BigInt.NormalizeBE(gy);
            if (BigInt.CompareCT(gx, mod) >= 0 ||
                BigInt.CompareCT(gy, mod) >= 0)
            {
                throw new CryptoException(
                          "Invalid curve: out-of-range coordinates");
            }
            MutableECPointPrime G = new MutableECPointPrime(this);

            G.Set(gx, gy, true);

            hashCode = (int)(BigInt.HashInt(mod)
                             ^ BigInt.HashInt(a) ^ BigInt.HashInt(b)
                             ^ BigInt.HashInt(gx) ^ BigInt.HashInt(gy));

            if (name == null)
            {
                name = string.Format("generic prime {0}/{1}",
                                     modLen, sgLen);
            }
            this.name = name;
        }