Пример #1
0
 /*
  * Given a value X in sx, this method computes X^3+aX+b into sd.
  * 'sx' is unmodified. 'st' is modified (it receives a*X).
  * The sx, sd and st instances MUST be distinct.
  */
 internal void RebuildY2(ModInt sx, ModInt sd, ModInt st)
 {
     sd.Set(sx);
     sd.ToMonty();
     st.Set(sd);
     sd.MontySquare();
     sd.MontyMul(sx);
     st.MontyMul(ma);
     sd.Add(st);
     sd.Add(mb);
 }
Пример #2
0
        public static byte[] SignRaw(ECPrivateKey sk, IDigest rfc6979Hash,
                                     byte[] hash, int hashOff, int hashLen)
        {
            ECCurve curve = sk.Curve;

            byte[]  q  = curve.SubgroupOrder;
            RFC6979 rf = new RFC6979(rfc6979Hash, q, sk.X,
                                     hash, hashOff, hashLen, rfc6979Hash != null);
            ModInt mh = rf.GetHashMod();
            ModInt mx = mh.Dup();

            mx.Decode(sk.X);

            /*
             * Compute DSA signature. We use a loop to enumerate
             * candidates for k until a proper one is found (it
             * is VERY improbable that we may have to loop).
             */
            ModInt mr = mh.Dup();
            ModInt ms = mh.Dup();
            ModInt mk = mh.Dup();

            byte[] k = new byte[q.Length];
            for (;;)
            {
                rf.NextK(k);
                MutableECPoint G = curve.MakeGenerator();
                if (G.MulSpecCT(k) == 0)
                {
                    /*
                     * We may get an error here only if the
                     * curve is invalid (generator does not
                     * produce the expected subgroup).
                     */
                    throw new CryptoException(
                              "Invalid EC private key / curve");
                }
                mr.DecodeReduce(G.X);
                if (mr.IsZero)
                {
                    continue;
                }
                ms.Set(mx);
                ms.ToMonty();
                ms.MontyMul(mr);
                ms.Add(mh);
                mk.Decode(k);
                mk.Invert();
                ms.ToMonty();
                ms.MontyMul(mk);

                byte[] sig = new byte[q.Length << 1];
                mr.Encode(sig, 0, q.Length);
                ms.Encode(sig, q.Length, q.Length);
                return(sig);
            }
        }
Пример #3
0
        internal override void DoubleCT()
        {
            ToJacobian();

            /*
             * Formulas are:
             *   S = 4*X*Y^2
             *   M = 3*X^2 + a*Z^4
             *   X' = M^2 - 2*S
             *   Y' = M*(S - X') - 8*Y^4
             *   Z' = 2*Y*Z
             *
             * These formulas also happen to work properly (with our
             * chosen representation) when the source point has
             * order 2 (Y = 0 implies Z' = 0) and when the source
             * point is already the point at infinity (Z = 0 implies
             * Z' = 0).
             *
             * When a = -3, the value of M can be computed with the
             * more efficient formula:
             *   M = 3*(X+Z^2)*(X-Z^2)
             */

            /*
             * Compute M in t1.
             */
            if (curve.aIsM3)
            {
                /*
                 * Set t1 = Z^2.
                 */
                mt1.Set(mz);
                mt1.MontySquare();

                /*
                 * Set t2 = X-Z^2 and then t1 = X+Z^2.
                 */
                mt2.Set(mx);
                mt2.Sub(mt1);
                mt1.Add(mx);

                /*
                 * Set t1 = 3*(X+Z^2)*(X-Z^2).
                 */
                mt1.MontyMul(mt2);
                mt2.Set(mt1);
                mt1.Add(mt2);
                mt1.Add(mt2);
            }
            else
            {
                /*
                 * Set t1 = 3*X^2.
                 */
                mt1.Set(mx);
                mt1.MontySquare();
                mt2.Set(mt1);
                mt1.Add(mt2);
                mt1.Add(mt2);

                /*
                 * Set t2 = a*Z^4.
                 */
                mt2.Set(mz);
                mt2.MontySquare();
                mt2.MontySquare();
                mt2.MontyMul(curve.ma);

                /*
                 * Set t1 = 3*X^2 + a*Z^4.
                 */
                mt1.Add(mt2);
            }

            /*
             * Compute S = 4*X*Y^2 in t2. We also save 2*Y^2 in mt3.
             */
            mt2.Set(my);
            mt2.MontySquare();
            mt2.Add(mt2);
            mt3.Set(mt2);
            mt2.Add(mt2);
            mt2.MontyMul(mx);

            /*
             * Compute X' = M^2 - 2*S.
             */
            mx.Set(mt1);
            mx.MontySquare();
            mx.Sub(mt2);
            mx.Sub(mt2);

            /*
             * Compute Z' = 2*Y*Z.
             */
            mz.MontyMul(my);
            mz.Add(mz);

            /*
             * Compute Y' = M*(S - X') - 8*Y^4. We already have
             * 4*Y^2 in t3.
             */
            mt2.Sub(mx);
            mt2.MontyMul(mt1);
            mt3.MontySquare();
            mt3.Add(mt3);
            my.Set(mt2);
            my.Sub(mt3);
        }
Пример #4
0
        internal override uint MulSpecCT(byte[] n)
        {
            /*
             * Copy scalar into a temporary array (u[]) for
             * normalisation to 32 bytes and clamping.
             */
            if (n.Length > 32)
            {
                return(0);
            }
            Array.Copy(n, 0, u, 32 - n.Length, n.Length);
            for (int i = 0; i < 32 - n.Length; i++)
            {
                u[i] = 0;
            }
            u[31] &= 0xF8;
            u[0]  &= 0x7F;
            u[0]  |= 0x40;

            x1.Set(x);
            x1.ToMonty();
            x2.SetMonty(0xFFFFFFFF);
            z2.Set(0);
            x3.Set(x1);
            z3.Set(x2);
            uint   swap = 0;
            ModInt ma24 = ((ECCurve25519)EC.Curve25519).ma24;

            for (int t = 254; t >= 0; t--)
            {
                uint kt = (uint)-((u[31 - (t >> 3)] >> (t & 7)) & 1);
                swap ^= kt;
                x2.CondSwap(x3, swap);
                z2.CondSwap(z3, swap);
                swap = kt;

                a.Set(x2);
                a.Add(z2);
                aa.Set(a);
                aa.MontySquare();
                b.Set(x2);
                b.Sub(z2);
                bb.Set(b);
                bb.MontySquare();
                e.Set(aa);
                e.Sub(bb);
                c.Set(x3);
                c.Add(z3);
                d.Set(x3);
                d.Sub(z3);
                d.MontyMul(a);
                c.MontyMul(b);
                x3.Set(d);
                x3.Add(c);
                x3.MontySquare();
                z3.Set(d);
                z3.Sub(c);
                z3.MontySquare();
                z3.MontyMul(x1);
                x2.Set(aa);
                x2.MontyMul(bb);
                z2.Set(e);
                z2.MontyMul(ma24);
                z2.Add(aa);
                z2.MontyMul(e);
            }
            x2.CondSwap(x3, swap);
            z2.CondSwap(z3, swap);

            /*
             * We need to restore z2 to normal representation before
             * inversion. Then the final Montgomery multiplication
             * will cancel out with x2, which is still in Montgomery
             * representation.
             */
            z2.FromMonty();
            z2.Invert();
            x2.MontyMul(z2);

            /*
             * x2 now contains the result.
             */
            x.Set(x2);
            return(0xFFFFFFFF);
        }
Пример #5
0
        public static void DoPrivate(RSAPrivateKey sk,
                                     byte[] x, int off, int len)
        {
            /*
             * Check that the source array has the proper length
             * (identical to the length of the modulus).
             */
            if (len != sk.N.Length)
            {
                throw new CryptoException(
                          "Invalid source length for RSA private");
            }

            /*
             * Reduce the source value to the proper range.
             */
            ModInt mx = new ModInt(sk.N);

            mx.DecodeReduce(x, off, len);

            /*
             * Compute m1 = x^dp mod p.
             */
            ModInt m1 = new ModInt(sk.P);

            m1.Set(mx);
            m1.Pow(sk.DP);

            /*
             * Compute m2 = x^dq mod q.
             */
            ModInt m2 = new ModInt(sk.Q);

            m2.Set(mx);
            m2.Pow(sk.DQ);

            /*
             * Compute h = (m1 - m2) / q mod p.
             * (Result goes in m1.)
             */
            ModInt m3 = m1.Dup();

            m3.Set(m2);
            m1.Sub(m3);
            m3.Decode(sk.IQ);
            m1.ToMonty();
            m1.MontyMul(m3);

            /*
             * Compute m_2 + q*h. This works on plain integers, but
             * we have efficient and constant-time code for modular
             * integers, so we will do it modulo n.
             */
            m3 = mx;
            m3.Set(m1);
            m1 = m3.Dup();
            m1.Decode(sk.Q);
            m1.ToMonty();
            m3.MontyMul(m1);
            m1.Set(m2);
            m3.Add(m1);

            /*
             * Write result back in x[].
             */
            m3.Encode(x, off, len);
        }
Пример #6
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;
        }