Пример #1
0
        /*
         * Create a new random prime with a specific length (in bits). The
         * returned prime will have its two top bits set, _and_ its two
         * least significant bits set as well. The size parameter must be
         * greater than or equal to 9 (that is, the unsigned encoding of
         * the prime will need at least two bytes).
         */
        public static byte[] RandPrime(int size)
        {
            if (size < 9)
            {
                throw new CryptoException(
                          "Invalid size for prime generation");
            }
            int len = (size + 7) >> 3;

            byte[] buf = new byte[len];
            int    hm1 = 0xFFFF >> ((len << 3) - size);
            int    hm2 = 0xC000 >> ((len << 3) - size);

            for (;;)
            {
                RNG.GetBytes(buf);
                buf[len - 1] |= (byte)0x03;
                int x = (buf[0] << 8) | buf[1];
                x     &= hm1;
                x     |= hm2;
                buf[0] = (byte)(x >> 8);
                buf[1] = (byte)x;
                if (IsPrime(buf))
                {
                    return(buf);
                }
            }
        }
Пример #2
0
        static byte[] RandInt(byte[] max, bool notZero)
        {
            int mlen = BitLength(max);

            if (mlen == 0 || (notZero && mlen == 1))
            {
                throw new CryptoException(
                          "Null maximum for random generation");
            }
            byte[] x  = new byte[(mlen + 7) >> 3];
            byte   hm = (byte)(0xFF >> ((8 - mlen) & 7));

            for (;;)
            {
                RNG.GetBytes(x);
                x[0] &= hm;
                if (notZero && IsZero(x))
                {
                    continue;
                }
                if (CompareCT(x, max) >= 0)
                {
                    continue;
                }
                return(x);
            }
        }
Пример #3
0
 public override byte[] MakeRandomSecret()
 {
     /*
      * For Curve25519, we simply generate a random 32-byte
      * array, to which we apply the "clamping" that will
      * be done for point multiplication anyway.
      */
     byte[] x = new byte[32];
     RNG.GetBytes(x);
     x[0]  &= 0x7F;
     x[0]  |= 0x40;
     x[31] &= 0xF8;
     return(x);
 }
Пример #4
0
        internal RFC6979(IDigest h, byte[] q, byte[] x,
                         byte[] hv, int hvOff, int hvLen, bool deterministic)
        {
            if (h == null)
            {
                h = new SHA256();
            }
            else
            {
                h = h.Dup();
                h.Reset();
            }
            drbg = new HMAC_DRBG(h);
            mh   = new ModInt(q);
            qlen = mh.ModBitLength;
            int qolen = (qlen + 7) >> 3;

            this.q = new byte[qolen];
            Array.Copy(q, q.Length - qolen, this.q, 0, qolen);
            int hlen = hvLen << 3;

            if (hlen > qlen)
            {
                byte[] htmp = new byte[hvLen];
                Array.Copy(hv, hvOff, htmp, 0, hv.Length);
                BigInt.RShift(htmp, hlen - qlen);
                hv    = htmp;
                hvOff = 0;
            }
            mh.DecodeReduce(hv, hvOff, hvLen);
            ModInt mx = mh.Dup();

            mx.Decode(x);

            byte[] seed = new byte[(qolen << 1) + (deterministic ? 0 : 32)];
            mx.Encode(seed, 0, qolen);
            mh.Encode(seed, qolen, qolen);
            if (!deterministic)
            {
                RNG.GetBytes(seed, qolen << 1,
                             seed.Length - (qolen << 1));
            }
            drbg.SetSeed(seed);
        }
Пример #5
0
        /* obsolete
         * public override uint Mul(byte[] G, byte[] x, byte[] D, bool compressed)
         * {
         *      MutableECPointPrime P = new MutableECPointPrime(this);
         *      uint good = P.DecodeCT(G);
         *      good &= ~P.IsInfinityCT;
         *      good &= P.MulSpecCT(x);
         *      good &= P.Encode(D, compressed);
         *      return good;
         * }
         *
         * public override uint MulAdd(byte[] A, byte[] x, byte[] B, byte[] y,
         *      byte[] D, bool compressed)
         * {
         *      MutableECPointPrime P = new MutableECPointPrime(this);
         *      MutableECPointPrime Q = new MutableECPointPrime(this);
         *
         *      uint good = P.DecodeCT(A);
         *      good &= Q.DecodeCT(B);
         *      good &= ~P.IsInfinityCT & ~Q.IsInfinityCT;
         *
         *      good &= P.MulSpecCT(x);
         *      good &= Q.MulSpecCT(y);
         *      good &= ~P.IsInfinityCT & ~Q.IsInfinityCT;
         *
         *      uint z = P.AddCT(Q);
         *      Q.DoubleCT();
         *      P.Set(Q, ~z);
         *
         *      good &= P.Encode(D, compressed);
         *      return good;
         * }
         */

        public override byte[] MakeRandomSecret()
        {
            /*
             * We force the top bits to 0 to guarantee that the value
             * is less than the subgroup order; and we force the
             * least significant bit to 0 so that the value is not null.
             * This is good enough for ECDH.
             */
            byte[] q    = SubgroupOrder;
            byte[] x    = new byte[q.Length];
            int    mask = 0xFF;

            while (mask >= q[0])
            {
                mask >>= 1;
            }
            RNG.GetBytes(x);
            x[0]            &= (byte)mask;
            x[x.Length - 1] |= (byte)0x01;
            return(x);
        }
Пример #6
0
        /*
         * Test an integer for primality. This function runs up to 50
         * Miller-Rabin rounds, which is a lot of overkill but ensures
         * that non-primes will be reliably detected (with overwhelming
         * probability) even with maliciously crafted inputs. "Normal"
         * non-primes will be detected most of the time at the first
         * iteration.
         *
         * This function is not constant-time.
         */
        public static bool IsPrime(byte[] x)
        {
            x = NormalizeBE(x);

            /*
             * Handle easy cases:
             *   0 is not prime
             *   small primes (one byte) are known in a constant bit-field
             *   even numbers (larger than one byte) are non-primes
             */
            if (x.Length == 0)
            {
                return(false);
            }
            if (x.Length == 1)
            {
                return(IsSmallPrime(x[0]));
            }
            if ((x[x.Length - 1] & 0x01) == 0)
            {
                return(false);
            }

            /*
             * Perform some trial divisions by small primes.
             */
            for (int sp = 3; sp < 256; sp += 2)
            {
                if (!IsSmallPrime(sp))
                {
                    continue;
                }
                int z = 0;
                foreach (byte b in x)
                {
                    z = ((z << 8) + b) % sp;
                }
                if (z == 0)
                {
                    return(false);
                }
            }

            /*
             * Run some Miller-Rabin rounds. We use as basis random
             * integers that are one byte smaller than the modulus.
             */
            ModInt xm1 = new ModInt(x);
            ModInt y   = xm1.Dup();

            y.Set(1);
            xm1.Sub(y);
            byte[] e = xm1.Encode();
            ModInt a = new ModInt(x);

            byte[] buf = new byte[x.Length - 1];
            for (int i = 0; i < 50; i++)
            {
                RNG.GetBytes(buf);
                a.Decode(buf);
                a.Pow(e);
                if (!a.IsOne)
                {
                    return(false);
                }
            }
            return(true);
        }