Exemplo n.º 1
0
        private bool CheckKey(DSA_Secret_Key dskKey)
        {
            // - p, q, g, x, y > 0
            if (dskKey.p <= 0 || dskKey.q <= 0 || dskKey.g <= 0 ||
                dskKey.y <= 0 || dskKey.x <= 0)
            {
                return(false);
            }

            // - p is odd, q is odd
            if (dskKey.p % 2 == 0 || dskKey.q % 2 == 0)
            {
                return(false);
            }


            // - 2^159 < q < 2^160
            if (dskKey.q.bitCount() < 159)
            {
                return(false);
            }

            // - 1 < g < p
            if (dskKey.g >= dskKey.p || dskKey.g <= 1)
            {
                return(false);
            }

            // - 1 < y < p
            if (dskKey.y >= dskKey.p || dskKey.y <= 1)
            {
                return(false);
            }

            // - x < q
            if (dskKey.x >= dskKey.q)
            {
                return(false);
            }

            // - g^q mod p = 1
            if (dskKey.g.modPow(dskKey.q, dskKey.p) != 1)
            {
                return(false);
            }

            // - g^x mod p = y
            if (dskKey.g.modPow(dskKey.x, dskKey.p) != dskKey.y)
            {
                return(false);
            }

            return(true);
        }
Exemplo n.º 2
0
        private BigInteger[,] ParseSecretKey(DSA_Secret_Key dskKey)
        {
            BigInteger[,] biReturn = new BigInteger[2, 4];

            biReturn[0, 0] = dskKey.p;
            biReturn[0, 1] = dskKey.q;
            biReturn[0, 2] = dskKey.g;
            biReturn[0, 3] = dskKey.y;
            biReturn[1, 0] = dskKey.x;

            return(biReturn);
        }
Exemplo n.º 3
0
        // this part is quite fast
        private DSA_Secret_Key GenerateKeyPair(DSA_Secret_Key dskKey)
        {
            dskKey.x = new BigInteger();
            do
            {
                // size of x (private key) isn't affected by the keysize (512-1024)
                dskKey.x = BigInteger.genRandom(160);
                BigInteger xx = new BigInteger();
            } while ((dskKey.x == 0) || (dskKey.x >= dskKey.q));

            // calculate the public key y = g^x % p
            dskKey.y = dskKey.g.modPow(dskKey.x, dskKey.p);

            return(dskKey);
        }
Exemplo n.º 4
0
        private DSA_Secret_Key ParseSecretKey(SecretKeyPacket skpKey, string strPassphrase)
        {
            DSA_Secret_Key dskKey = new DSA_Secret_Key();

            dskKey.p = skpKey.PublicKey.KeyMaterial[0];
            dskKey.q = skpKey.PublicKey.KeyMaterial[1];
            dskKey.g = skpKey.PublicKey.KeyMaterial[2];
            dskKey.y = skpKey.PublicKey.KeyMaterial[3];

            BigInteger[] biSecretKeyMaterial = skpKey.GetDecryptedKeyMaterial(strPassphrase);

            dskKey.x = biSecretKeyMaterial[0];

            return(dskKey);
        }
Exemplo n.º 5
0
        /// <summary>
        /// Creates a new DES secret key and returns it as a
        /// 2 dimensional array of biginteger. return[0] holds
        /// the public values of the key and return[1] all the
        /// secret values.
        /// </summary>
        /// <remarks>
        /// Creates a new DSA secret key and returns it as a
        /// 2 dimensional array of biginteger. return[0] holds
        /// the public values of the key and return[1] all the
        /// secret values.<br></br>
        /// The order of the public components is p, q, g, y
        /// The order of the secret components is x.
        /// </remarks>
        /// <param name="nbits">The size of the key in bits.</param>
        /// <returns> a new DSA secret key and returns it as a
        /// 2 dimensional array of biginteger. return[0] holds
        /// the public values of the key and return[1] all the
        /// secret values.<br></br>
        /// The order of the public components is p, q, g, y
        /// The order of the secret components is x.</returns>
        public override BigInteger[][] Generate(int keyLength)
        {
            DSA_Secret_Key dskKey = new DSA_Secret_Key();

            dskKey = GenerateParams(keyLength);
            dskKey = GenerateKeyPair(dskKey);

            biGeneratedKey = new BigInteger[2][];

            biGeneratedKey[0]    = new BigInteger[4];
            biGeneratedKey[0][0] = dskKey.p;
            biGeneratedKey[0][1] = dskKey.q;
            biGeneratedKey[0][2] = dskKey.g;
            biGeneratedKey[0][3] = dskKey.y;

            biGeneratedKey[1]    = new BigInteger[1];
            biGeneratedKey[1][0] = dskKey.x;

            return(biGeneratedKey);
        }
Exemplo n.º 6
0
        /// <summary>
        /// Secret key operation. Signs biHash with the keydata
        /// in the given secret key packet.
        /// </summary>
        /// <param name="biHash">The hash value of a message that is about to
        /// be signed</param>
        /// <param name="skpKey">The secret key packet with the key
        /// material for the signature</param>
        /// <param name="strPassphrase">The passphrase for the
        /// keymaterial</param>
        /// <returns>The signed hash as array of biginteger. Only return[0]
        /// contains a value: the signed hash.</returns>
        /// <remarks>No remarks</remarks>
        public override BigInteger[] Sign(BigInteger biHash, SecretKeyPacket skpKey, string strPassphase)
        {
            DSA_Secret_Key dskKey = new DSA_Secret_Key();

            dskKey = ParseSecretKey(skpKey, strPassphase);

            //check if the key has been mangled with
            if (!CheckKey(dskKey))
            {
                throw(new Exception("This key does not fullfill the requirements of a valid DSA key. Please check if someone messed with your keys!"));
            }

            //if (biHash == null)
            //	throw new ArgumentNullException();

            // (a) Select a random secret integer k; 0 < k < q.
            BigInteger k = new BigInteger();

            k = BigInteger.genRandom(160);
            while (k >= dskKey.q)
            {
                k = BigInteger.genRandom(160);
            }

            // (b) Compute r = ( k mod p) mod q
            BigInteger r = (dskKey.g.modPow(k, dskKey.p)) % dskKey.q;
            // (c) Compute k -1 mod q (e.g., using Algorithm 2.142).
            // (d) Compute s = k -1 fh(m) +arg mod q.
            BigInteger s = (k.modInverse(dskKey.q) * (biHash + dskKey.x * r)) % dskKey.q;

            BigInteger[] biReturn = new BigInteger[2];

            biReturn[0] = r;
            biReturn[1] = s;
            return(biReturn);
        }
Exemplo n.º 7
0
        private DSA_Secret_Key ParseSecretKey(SecretKeyPacket skpKey, string strPassphrase)
        {
            DSA_Secret_Key dskKey = new DSA_Secret_Key();

            dskKey.p = skpKey.PublicKey.KeyMaterial[0];
            dskKey.q = skpKey.PublicKey.KeyMaterial[1];
            dskKey.g = skpKey.PublicKey.KeyMaterial[2];
            dskKey.y = skpKey.PublicKey.KeyMaterial[3];

            BigInteger[] biSecretKeyMaterial = skpKey.GetDecryptedKeyMaterial(strPassphrase);

            dskKey.x = biSecretKeyMaterial[0];

            return dskKey;
        }
Exemplo n.º 8
0
        private BigInteger[,] ParseSecretKey(DSA_Secret_Key dskKey)
        {
            BigInteger[,] biReturn = new BigInteger[2,4];

            biReturn[0,0] = dskKey.p;
            biReturn[0,1] = dskKey.q;
            biReturn[0,2] = dskKey.g;
            biReturn[0,3] = dskKey.y;
            biReturn[1,0] = dskKey.x;

            return biReturn;
        }
Exemplo n.º 9
0
        private DSA_Secret_Key GenerateParams(int keyLength)
        {
            byte[] seed = new byte[20];
            byte[] part1 = new byte[20];
            byte[] part2 = new byte[20];
            byte[] u = new byte[20];
            RandomNumberGenerator rng = RandomNumberGenerator.Create();

            BigInteger p = new BigInteger();	    // prime
            BigInteger q = new BigInteger();	    // group order
            BigInteger g;	    // group generator
            DSA_Secret_Key dskKey = new DSA_Secret_Key();

            SHA1 sha = SHA1.Create();

            int n = (keyLength - 1) / 160;
            byte[] w = new byte [keyLength / 8];
            bool primesFound = false;

            while (!primesFound) {
                do {
                    rng.GetBytes(seed);
                    part1 = sha.ComputeHash(seed);
                    Array.Copy(seed, 0, part2, 0, seed.Length);

                    add(part2, seed, 1);

                    part2 = sha.ComputeHash(part2);

                    for (int i = 0; i != u.Length; i++)
                        u[i] = (byte)(part1[i] ^ part2[i]);

                    // first bit must be set (to respect key length)
                    u[0] |= (byte)0x80;
                    // last bit must be set (prime are all odds - except 2)
                    u[19] |= (byte)0x01;

                    q = new BigInteger(u);
                } while (!q.isProbablePrime());

                int counter = 0;
                int offset = 2;
                while (counter < 4096) {
                    for (int k = 0; k < n; k++) {
                        add(part1, seed, offset + k);
                        part1 = sha.ComputeHash(part1);
                        Array.Copy(part1, 0, w, w.Length - (k + 1) * part1.Length, part1.Length);
                    }

                    add(part1, seed, offset + n);
                    part1 = sha.ComputeHash(part1);
                    Array.Copy(part1, part1.Length - ((w.Length - (n) * part1.Length)), w, 0, w.Length - n * part1.Length);

                    w[0] |= (byte)0x80;
                    BigInteger xx = new BigInteger (w);

                    BigInteger c = xx % (q * 2);

                    p = xx - (c - 1);

                    if (p.testBit((uint)(keyLength - 1))) {
                        if (p.isProbablePrime()) {
                            primesFound = true;
                            break;
                        }
                    }

                    counter += 1;
                    offset += n + 1;
                }

            }

            // calculate the generator g
            BigInteger pMinusOneOverQ = (p - 1) / q;
            for (;;) {
                BigInteger h = new BigInteger();
                h = BigInteger.genRandom(keyLength);
                if ((h <= 1) || (h >= (p - 1)))
                    continue;

                g = h.modPow(pMinusOneOverQ, p);
                if (g <= 1)
                    continue;
                break;
            }

            dskKey.p = p;
            dskKey.q = q;
            dskKey.g = g;

            return dskKey;
        }
Exemplo n.º 10
0
        // this part is quite fast
        private DSA_Secret_Key GenerateKeyPair(DSA_Secret_Key dskKey)
        {
            dskKey.x = new BigInteger();
            do {
                // size of x (private key) isn't affected by the keysize (512-1024)
                dskKey.x = BigInteger.genRandom(160);
                BigInteger xx = new BigInteger();
            } while ((dskKey.x == 0) || (dskKey.x >= dskKey.q));

            // calculate the public key y = g^x % p
            dskKey.y = dskKey.g.modPow(dskKey.x, dskKey.p);

            return dskKey;
        }
Exemplo n.º 11
0
        private bool CheckKey(DSA_Secret_Key dskKey)
        {
            // - p, q, g, x, y > 0
            if (dskKey.p <= 0 || dskKey.q <= 0 || dskKey.g <= 0 ||
                dskKey.y <= 0 || dskKey.x <= 0) {
                return false;
            }

            // - p is odd, q is odd
            if (dskKey.p % 2 == 0 || dskKey.q % 2 == 0)
                return false;

            // - 2^159 < q < 2^160
            if (dskKey.q.bitCount() < 159)
                return false;

            // - 1 < g < p
            if (dskKey.g >= dskKey.p || dskKey.g <= 1)
                return false;

            // - 1 < y < p
            if (dskKey.y >= dskKey.p || dskKey.y <= 1)
                return false;

            // - x < q
            if (dskKey.x >= dskKey.q)
                return false;

            // - g^q mod p = 1
            if (dskKey.g.modPow(dskKey.q, dskKey.p) != 1)
                return false;

            // - g^x mod p = y
            if (dskKey.g.modPow(dskKey.x, dskKey.p) != dskKey.y)
                return false;

            return true;
        }
Exemplo n.º 12
0
        /// <summary>
        /// Secret key operation. Signs biHash with the keydata
        /// in the given secret key packet.
        /// </summary>
        /// <param name="biHash">The hash value of a message that is about to
        /// be signed</param>
        /// <param name="skpKey">The secret key packet with the key
        /// material for the signature</param>
        /// <param name="strPassphrase">The passphrase for the 
        /// keymaterial</param>
        /// <returns>The signed hash as array of biginteger. Only return[0]
        /// contains a value: the signed hash.</returns>
        /// <remarks>No remarks</remarks>
        public override BigInteger[] Sign(BigInteger biHash, SecretKeyPacket skpKey, string strPassphase)
        {
            DSA_Secret_Key dskKey = new DSA_Secret_Key();

            dskKey = ParseSecretKey(skpKey, strPassphase);

            //check if the key has been mangled with
            if (!CheckKey(dskKey))
                throw(new Exception("This key does not fullfill the requirements of a valid DSA key. Please check if someone messed with your keys!"));

            //if (biHash == null)
            //	throw new ArgumentNullException();

            // (a) Select a random secret integer k; 0 < k < q.
            BigInteger k = new BigInteger();
            k = BigInteger.genRandom(160);
            while (k >= dskKey.q)
                k = BigInteger.genRandom(160);

            // (b) Compute r = ( k mod p) mod q
            BigInteger r = (dskKey.g.modPow (k, dskKey.p)) % dskKey.q;
            // (c) Compute k -1 mod q (e.g., using Algorithm 2.142).
            // (d) Compute s = k -1 fh(m) +arg mod q.
            BigInteger s = (k.modInverse (dskKey.q) * (biHash + dskKey.x * r)) % dskKey.q;

            BigInteger[] biReturn = new BigInteger[2];

            biReturn[0] = r;
            biReturn[1] = s;
            return biReturn;
        }
Exemplo n.º 13
0
        /// <summary>
        /// Creates a new DES secret key and returns it as a
        /// 2 dimensional array of biginteger. return[0] holds
        /// the public values of the key and return[1] all the
        /// secret values.
        /// </summary>
        /// <remarks>
        /// Creates a new DSA secret key and returns it as a
        /// 2 dimensional array of biginteger. return[0] holds
        /// the public values of the key and return[1] all the
        /// secret values.<br></br>
        /// The order of the public components is p, q, g, y
        /// The order of the secret components is x.
        /// </remarks>
        /// <param name="nbits">The size of the key in bits.</param>
        /// <returns> a new DSA secret key and returns it as a
        /// 2 dimensional array of biginteger. return[0] holds
        /// the public values of the key and return[1] all the
        /// secret values.<br></br>
        /// The order of the public components is p, q, g, y
        /// The order of the secret components is x.</returns>
        public override BigInteger[][] Generate(int keyLength)
        {
            DSA_Secret_Key dskKey = new DSA_Secret_Key();
            dskKey = GenerateParams(keyLength);
            dskKey = GenerateKeyPair(dskKey);

            biGeneratedKey = new BigInteger[2][];

            biGeneratedKey[0] = new BigInteger[4];
            biGeneratedKey[0][0] = dskKey.p;
            biGeneratedKey[0][1] = dskKey.q;
            biGeneratedKey[0][2] = dskKey.g;
            biGeneratedKey[0][3] = dskKey.y;

            biGeneratedKey[1] = new BigInteger[1];
            biGeneratedKey[1][0] = dskKey.x;

            return biGeneratedKey;
        }
Exemplo n.º 14
0
        private DSA_Secret_Key GenerateParams(int keyLength)
        {
            byte[] seed  = new byte[20];
            byte[] part1 = new byte[20];
            byte[] part2 = new byte[20];
            byte[] u     = new byte[20];
            RandomNumberGenerator rng = RandomNumberGenerator.Create();

            BigInteger     p = new BigInteger(); // prime
            BigInteger     q = new BigInteger(); // group order
            BigInteger     g;                    // group generator
            DSA_Secret_Key dskKey = new DSA_Secret_Key();

            SHA1 sha = SHA1.Create();

            int n = (keyLength - 1) / 160;

            byte[] w           = new byte [keyLength / 8];
            bool   primesFound = false;

            while (!primesFound)
            {
                do
                {
                    rng.GetBytes(seed);
                    part1 = sha.ComputeHash(seed);
                    Array.Copy(seed, 0, part2, 0, seed.Length);

                    add(part2, seed, 1);

                    part2 = sha.ComputeHash(part2);

                    for (int i = 0; i != u.Length; i++)
                    {
                        u[i] = (byte)(part1[i] ^ part2[i]);
                    }

                    // first bit must be set (to respect key length)
                    u[0] |= (byte)0x80;
                    // last bit must be set (prime are all odds - except 2)
                    u[19] |= (byte)0x01;

                    q = new BigInteger(u);
                } while (!q.isProbablePrime());

                int counter = 0;
                int offset  = 2;
                while (counter < 4096)
                {
                    for (int k = 0; k < n; k++)
                    {
                        add(part1, seed, offset + k);
                        part1 = sha.ComputeHash(part1);
                        Array.Copy(part1, 0, w, w.Length - (k + 1) * part1.Length, part1.Length);
                    }

                    add(part1, seed, offset + n);
                    part1 = sha.ComputeHash(part1);
                    Array.Copy(part1, part1.Length - ((w.Length - (n) * part1.Length)), w, 0, w.Length - n * part1.Length);

                    w[0] |= (byte)0x80;
                    BigInteger xx = new BigInteger(w);

                    BigInteger c = xx % (q * 2);

                    p = xx - (c - 1);

                    if (p.testBit((uint)(keyLength - 1)))
                    {
                        if (p.isProbablePrime())
                        {
                            primesFound = true;
                            break;
                        }
                    }

                    counter += 1;
                    offset  += n + 1;
                }
            }

            // calculate the generator g
            BigInteger pMinusOneOverQ = (p - 1) / q;

            for (;;)
            {
                BigInteger h = new BigInteger();
                h = BigInteger.genRandom(keyLength);
                if ((h <= 1) || (h >= (p - 1)))
                {
                    continue;
                }

                g = h.modPow(pMinusOneOverQ, p);
                if (g <= 1)
                {
                    continue;
                }
                break;
            }

            dskKey.p = p;
            dskKey.q = q;
            dskKey.g = g;

            return(dskKey);
        }