Example #1
0
        /// <summary>
        /// Secret key operation. Decrypts biCipher with the keydata
        /// in the given secret key packet.
        /// </summary>
        /// <param name="biCipher">The ciphertext that is about to
        /// be decrypted</param>
        /// <param name="skpKey">The secret key packet with the key
        /// material for the decryption</param>
        /// <param name="strPassphrase">The passphrase for the 
        /// keymaterial</param>
        /// <returns>The decrypted ciphertext.</returns>
        /// <remarks>No remarks.</remarks>
        public override BigInteger Decrypt(BigInteger[] biCipher, SecretKeyPacket skpKey, string strPassphrase)
        {
            RSA_Secret_Key skey = new RSA_Secret_Key();

            skey = ParseSecretKey(skpKey, strPassphrase);

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

            if ((skey.d == 0) || (skey.n == 0))
                throw new System.ArgumentException("This is not a valid secret key");

            BigInteger biPlain = biCipher[0].modPow(skey.d, skey.n);

            return biPlain;
        }
Example #2
0
        /// <summary>
        /// Secret key operation. Decrypts biCipher with the keydata
        /// in the given secret key packet.
        /// </summary>
        /// <param name="biInput">The ciphertext that is about to
        /// be decrypted</param>
        /// <param name="skpKey">The secret key packet with the key
        /// material for the decryption</param>
        /// <param name="strPassphrase">The passphrase for the 
        /// keymaterial</param>
        /// <returns>The decrypted ciphertext.</returns>
        /// <remarks>No remarks.</remarks>
        public override BigInteger Decrypt(BigInteger[] biInput, SecretKeyPacket skpKey, string strPassphrase)
        {
            BigInteger[] biKeyMaterial = skpKey.GetDecryptedKeyMaterial(strPassphrase);
            EG_Secret_Key eskKey = new EG_Secret_Key();
            eskKey.x = biKeyMaterial[0];
            eskKey.p = skpKey.PublicKey.KeyMaterial[0];
            eskKey.g = skpKey.PublicKey.KeyMaterial[1];
            eskKey.y = skpKey.PublicKey.KeyMaterial[2];

            if (biInput.Length != 2)
                throw new ArgumentException("biInput is not an ElGamal encrypted Packet");

            BigInteger B = biInput[0];
            BigInteger c = biInput[1];

            BigInteger z = B.modPow(eskKey.x, eskKey.p).modInverse(eskKey.p);

            BigInteger output = (z * c) % eskKey.p;

            return output;
        }
Example #3
0
 /// <summary>
 /// Decryption is not supported for DSA. If you call this function,
 /// an Exception will be thrown.
 /// </summary>
 /// <remarks>
 /// Decryption is not supported for DSA. If you call this function,
 /// an Exception will be thrown.
 /// </remarks>
 public override BigInteger Decrypt(BigInteger[] biCipher, SecretKeyPacket spkKey, string strPassphrase)
 {
     throw(new Exception("The DSA cipher cannot be used for encryption/decryption"));
 }
Example #4
0
        private BigInteger[] ParsePublicKey(DSA_Public_Key dpkKey)
        {
            BigInteger[] biReturn = new BigInteger[4];

            biReturn[0] = dpkKey.p;
            biReturn[1] = dpkKey.q;
            biReturn[2] = dpkKey.g;
            biReturn[3] = dpkKey.y;

            return biReturn;
        }
Example #5
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;
        }
Example #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;
        }
        /// <summary>
        /// Verifies the data given as parameter with the given public key.
        /// </summary>
        /// <remarks>
        /// <para>The function calculates a message digest over the given signature
        /// data and verifies the digest with the digest stored in the
        /// signature packet.</para>
        /// <para>The results of the verify operation are directly stored
        /// in the SignatureStatus property of this class.</para>
        /// </remarks>
        /// <param name="bSignedData">The data that is to be verified.</param>
        /// <param name="pkpKey">The key that is to verify the signature</param>
        public void Verify(byte[] bSignedData, PublicKeyPacket pkpKey)
        {
            System.Security.Cryptography.HashAlgorithm haVerifyer;
            AsymmetricCipher acVerifyer;

            switch (this.HashAlgorithm) {
                case HashAlgorithms.MD5:
                    haVerifyer = System.Security.Cryptography.MD5.Create();
                    break;
                case HashAlgorithms.SHA1:
                    haVerifyer = System.Security.Cryptography.SHA1.Create();
                    break;
                default:
                    throw(new System.Exception("Currently only MD5 and SHA1 are implemented as hash algorithms!"));
            }

            switch (this.SignatureAlgorithm) {
                case AsymAlgorithms.DSA:
                    acVerifyer = new SharpPrivacy.SharpPrivacyLib.Cipher.DSA();
                    break;
                case AsymAlgorithms.RSA_Encrypt_Sign:
                case AsymAlgorithms.RSA_Sign_Only:
                    acVerifyer = new SharpPrivacy.SharpPrivacyLib.Cipher.RSA();
                    break;
                default:
                    throw(new System.Exception("Currently only DSA and RSA are implemented as signature algorithms!"));
            }

            byte[] bSignature = new byte[0];
            int iCounter = 0;
            if (this.Version <= SignaturePacketVersionNumbers.v3) {
                bSignature = new byte[5];

                bSignature[iCounter++] = (byte)this.SignatureType;
                long lTime = (dtTimeCreated.Ticks - new DateTime(1970, 1, 1).Ticks)/10000000;
                bSignature[iCounter++] = (byte)((lTime >> 24) & 0xFF);
                bSignature[iCounter++] = (byte)((lTime >> 16) & 0xFF);
                bSignature[iCounter++] = (byte)((lTime >> 8) & 0xFF);
                bSignature[iCounter++] = (byte)(lTime & 0xFF);
            } else {
                //Hashed Subpackets Length
                int lHashedSubPacketLength = 0;
                for (int i=0; i<this.HashedSubPackets.Length; i++) {
                    lHashedSubPacketLength += this.HashedSubPackets[i].Generate().Length;
                }

                bSignature = new byte[lHashedSubPacketLength + 12];
                bSignature[iCounter++] = 4; // Version
                bSignature[iCounter++] = (byte)this.SignatureType;
                bSignature[iCounter++] = (byte)this.SignatureAlgorithm;
                bSignature[iCounter++] = (byte)this.HashAlgorithm;

                //Hashed Subpackets
                bSignature[iCounter++] = (byte)((lHashedSubPacketLength >> 8) & 0xFF);
                bSignature[iCounter++] = (byte)(lHashedSubPacketLength & 0xFF);
                for (int i=0; i<this.HashedSubPackets.Length; i++) {
                    byte[] bSubPacket = this.HashedSubPackets[i].Generate();
                    Array.Copy(bSubPacket, 0, bSignature, iCounter, bSubPacket.Length);
                    iCounter += bSubPacket.Length;
                }

                //Final Trailer of 6 bytes
                bSignature[iCounter++] = 0x04;
                bSignature[iCounter++] = 0xFF;
                bSignature[iCounter++] = (byte)(((lHashedSubPacketLength+6) >> 24) & 0xFF);
                bSignature[iCounter++] = (byte)(((lHashedSubPacketLength+6) >> 16) & 0xFF);
                bSignature[iCounter++] = (byte)(((lHashedSubPacketLength+6) >> 8) & 0xFF);
                bSignature[iCounter++] = (byte)((lHashedSubPacketLength+6) & 0xFF);

            }

            byte[] bData = new byte[bSignedData.Length + bSignature.Length];
            Array.Copy(bSignedData, bData, bSignedData.Length);
            Array.Copy(bSignature, 0, bData, bSignedData.Length, bSignature.Length);

            byte[] bHash = haVerifyer.ComputeHash(bData);
            BigInteger biHash = new BigInteger(bHash);

            //PKCS1 Encode the hash
            if (this.SignatureAlgorithm != AsymAlgorithms.DSA) {

                // We encode the MD in this way:
                //  0  A PAD(n bytes)   0  ASN(asnlen bytes)  MD(len bytes)
                // PAD consists of FF bytes.
                byte[] bASN = new byte[0];

                switch (this.HashAlgorithm) {
                    case HashAlgorithms.MD5:
                        bASN = new byte[] {0x30, 0x20, 0x30, 0x0C, 0x06, 0x08,
                                           0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D,
                                           0x02, 0x05, 0x05, 0x00, 0x04, 0x10};
                        break;
                    case HashAlgorithms.SHA1:
                        bASN = new byte[] {0x30, 0x21, 0x30, 0x09, 0x06, 0x05,
                                           0x2b, 0x0E, 0x03, 0x02, 0x1A, 0x05,
                                           0x00, 0x04, 0x14};
                        break;
                }

                int iFrameSize = (pkpKey.KeyMaterial[0].bitCount() + 7) / 8;
                byte[] bFrame = new byte[iFrameSize];
                int iASNCounter = 0;

                bFrame[iASNCounter++] = 0;
                bFrame[iASNCounter++] = 1;
                int iFFLength = iFrameSize - bHash.Length - bASN.Length - 3;
                for (int i=0; i<iFFLength; i++) {
                    bFrame[iASNCounter++] = 0xFF;
                }
                bFrame[iASNCounter++] = 0;
                Array.Copy(bASN, 0, bFrame, iASNCounter, bASN.Length);
                iASNCounter += bASN.Length;
                Array.Copy(bHash, 0, bFrame, iASNCounter, bHash.Length);
                biHash = new BigInteger(bFrame);
            }

            if (acVerifyer.Verify(this.Signature, biHash, pkpKey)) {
                ssSignatureStatus = SignatureStatusTypes.Valid;
            } else {
                ssSignatureStatus = SignatureStatusTypes.Invalid;
            }
        }
Example #8
0
			private unsafe BigInteger OddPow (uint b, BigInteger exp) {
				exp.Normalize ();
				uint [] wkspace = new uint [mod.length << 1 + 1];
				
				BigInteger resultNum = Montgomery.ToMont ((BigInteger)b, this.mod);
				resultNum = new BigInteger (resultNum, mod.length << 1 +1);
				
				uint mPrime = Montgomery.Inverse (mod.data [0]);
				
				uint pos = (uint)exp.bitCount () - 2;
				
				//
				// We know that the first itr will make the val b
				//
				
				do {
					//
					// r = r ^ 2 % m
					//
					Kernel.SquarePositive (resultNum, ref wkspace);
					resultNum = Montgomery.Reduce (resultNum, mod, mPrime);
					
					if (exp.testBit (pos)) {
						
						//
						// r = r * b % m
						//
						
						// TODO: Is Unsafe really speeding things up?
						fixed (uint* u = resultNum.data) {
							
							uint i = 0;
							ulong mc = 0;
							
							do {
								mc += (ulong)u [i] * (ulong)b;
								u [i] = (uint)mc;
								mc >>= 32;
							} while (++i < resultNum.length);
							
							if (resultNum.length < mod.length) {
								if (mc != 0) {
									u [i] = (uint)mc;
									resultNum.length++;
									while (resultNum >= mod)
										Kernel.MinusEq (resultNum, mod);
								}
							} else if (mc != 0) {
								
								//
								// First, we estimate the quotient by dividing
								// the first part of each of the numbers. Then
								// we correct this, if necessary, with a subtraction.
								//
								
								uint cc = (uint)mc;
								
								// We would rather have this estimate overshoot,
								// so we add one to the divisor
								uint divEstimate = (uint) ((((ulong)cc << 32) | (ulong) u [i -1]) /
									(mod.data [mod.length-1] + 1));
									
								uint t;
								
								i = 0;
								mc = 0;
								do {
									mc += (ulong)mod.data [i] * (ulong)divEstimate;
									t = u [i];
									u [i] -= (uint)mc;
									mc >>= 32;
									if (u [i] > t) mc++;
									i++;
								} while (i < resultNum.length);
								cc -= (uint)mc;
								
								if (cc != 0) {
									
									uint sc = 0, j = 0;
									uint [] s = mod.data;
									do {
										uint a = s [j];
										if (((a += sc) < sc) | ((u [j] -= a) > ~a)) sc = 1;
										else sc = 0;
										j++;
									} while (j < resultNum.length);
									cc -= sc;
								}
								while (resultNum >= mod)
									Kernel.MinusEq (resultNum, mod);
							} else {
								while (resultNum >= mod)
									Kernel.MinusEq (resultNum, mod);
							}
						}
					}
				} while (pos-- > 0);
				
				resultNum = Montgomery.Reduce (resultNum, mod, mPrime);
				return resultNum;
				
			}
Example #9
0
		public BigInteger modPow (BigInteger exp, BigInteger n) {
			ModulusRing mr = new ModulusRing (n);
			return mr.Pow (this, exp);
		}
Example #10
0
		public BigInteger modInverse (BigInteger mod) {
			return Kernel.modInverse (this, mod);
		}
Example #11
0
		public BigInteger gcd (BigInteger bi) {
			return Kernel.gcd (this, bi);
		}
Example #12
0
		public string ToString (uint radix, string charSet) {
			if (charSet.Length < radix)
				throw new ArgumentException ("charSet length less than radix", "charSet");
			if (radix == 1)
				throw new ArgumentException ("There is no such thing as radix one notation", "radix");

			if (this == 0) return "0";
			if (this == 1) return "1";

			string result = "";

			BigInteger a = new BigInteger (this);

			while (a != 0) {
				uint rem = Kernel.SingleByteDivideInPlace (a, radix);
				result = charSet [ (int)rem] + result;
			}

			return result;
		}
Example #13
0
		public Sign Compare (BigInteger bi) {
			return Kernel.Compare (this, bi);
		}
Example #14
0
		/// <summary>
		/// Generates a new, random BigInteger of the specified length.
		/// </summary>
		/// <param name="bits">The number of bits for the new number.</param>
		/// <param name="rng">A random number generator to use to obtain the bits.</param>
		/// <returns>A random number of the specified length.</returns>
		public static BigInteger genRandom (int bits, System.Security.Cryptography.RandomNumberGenerator rng) {
			int dwords = bits >> 5;
			int remBits = bits & 0x1F;

			if (remBits != 0)
				dwords++;

			BigInteger ret = new BigInteger (Sign.Positive, (uint)dwords + 1);
			byte [] random = new byte [dwords << 2];

			rng.GetBytes (random);
			Buffer.BlockCopy (random, 0, ret.data, 0, (int)dwords << 2);

			if (remBits != 0) {
				uint mask = (uint)(0x01 << (remBits-1));
				ret.data [dwords-1] |= mask;

				mask = (uint)(0xFFFFFFFF >> (32 - remBits));
				ret.data [dwords-1] &= mask;
			}
			else
				ret.data [dwords-1] |= 0x80000000;

			ret.Normalize ();
			return ret;
		}
Example #15
0
		public static BigInteger operator * (BigInteger bi1, BigInteger bi2) {
			if (bi1 == 0 || bi2 == 0) return 0;

			//
			// Validate pointers
			//
			if (bi1.data.Length < bi1.length) throw new IndexOutOfRangeException ("bi1 out of range");
			if (bi2.data.Length < bi2.length) throw new IndexOutOfRangeException ("bi2 out of range");

			BigInteger ret = new BigInteger (Sign.Positive, bi1.length + bi2.length);

			Kernel.Multiply (bi1.data, 0, bi1.length, bi2.data, 0, bi2.length, ret.data, 0);

			ret.Normalize ();
			return ret;
		}
Example #16
0
			private BigInteger OddPow (BigInteger b, BigInteger exp) {
				BigInteger resultNum = new BigInteger (Montgomery.ToMont (1, mod), mod.length << 1);
				BigInteger tempNum = new BigInteger (Montgomery.ToMont (b, mod), mod.length << 1);  // ensures (tempNum * tempNum) < b^ (2k)
				uint mPrime = Montgomery.Inverse (mod.data [0]);
				uint totalBits = (uint)exp.bitCount ();
				
				uint [] wkspace = new uint [mod.length << 1];
				
				// perform squaring and multiply exponentiation
				for (uint pos = 0; pos < totalBits; pos++) {
					if (exp.testBit (pos)) {
						
						Array.Clear (wkspace, 0, wkspace.Length);
						Kernel.Multiply (resultNum.data, 0, resultNum.length, tempNum.data, 0, tempNum.length, wkspace, 0);
						resultNum.length += tempNum.length;
						uint [] t = wkspace;
						wkspace = resultNum.data;
						resultNum.data = t;
						
						Montgomery.Reduce (resultNum, mod, mPrime);
					}
					
					Kernel.SquarePositive (tempNum, ref wkspace);
					Montgomery.Reduce (tempNum, mod, mPrime);
				}
				
				Montgomery.Reduce (resultNum, mod, mPrime);
				return resultNum;
			}
Example #17
0
			// TODO: Make tests for this, not really needed b/c prime stuff
			// checks it, but still would be nice
			public BigInteger Pow (uint b, BigInteger exp) {
				if (b != 2) {
					if ((mod.data [0] & 1) == 1) return OddPow (b, exp);
					else return EvenPow (b, exp);
				} else {
					if ((mod.data [0] & 1) == 1) return OddModTwoPow (exp);
					else return EvenModTwoPow (exp);
				}
			}
Example #18
0
		/// <summary>
		/// Generates the smallest prime >= bi
		/// </summary>
		/// <param name="bi">A BigInteger</param>
		/// <returns>The smallest prime >= bi. More mathematically, if bi is prime: bi, else Prime [PrimePi [bi] + 1].</returns>
		public static BigInteger NextHightestPrime (BigInteger bi) {
			NextPrimeFinder npf = new NextPrimeFinder ();
			return npf.GenerateNewPrime (0, bi);
		}
Example #19
0
        /// <summary>
        /// Signes the data given as parameter with the given secret key.
        /// The given password has to fit the given key.
        /// </summary>
        /// <remarks>
        /// <para>The function calculates a message digest over the given signature
        /// data and signes the digest with the given key.</para>
        /// <para>The results of the signature operation are directly stored
        /// in the Signature property of this class.</para>
        /// </remarks>
        /// <param name="bSignedData">The data that is to be signed.</param>
        /// <param name="skpKey">The key that is to sign the data</param>
        /// <param name="strPassphrase">The passphrase that is neccessary to
        /// decrypt the given key.</param>
        public void Sign(byte[] bSignedData, SecretKeyPacket skpKey, string strPassphrase)
        {
            System.Security.Cryptography.HashAlgorithm haSigner;
            AsymmetricCipher acSigner;

            this.SignatureAlgorithm = skpKey.PublicKey.Algorithm;

            switch (this.HashAlgorithm) {
                case HashAlgorithms.MD5:
                    haSigner = System.Security.Cryptography.MD5.Create();
                    break;
                case HashAlgorithms.SHA1:
                    haSigner = System.Security.Cryptography.SHA1.Create();
                    break;
                default:
                    throw(new System.Exception("Currently only MD5 and SHA1 are implemented as hash algorithms!"));
            }

            switch (this.SignatureAlgorithm) {
                case AsymAlgorithms.DSA:
                    acSigner = new SharpPrivacy.SharpPrivacyLib.Cipher.DSA();
                    break;
                case AsymAlgorithms.RSA_Encrypt_Sign:
                case AsymAlgorithms.RSA_Sign_Only:
                    acSigner = new SharpPrivacy.SharpPrivacyLib.Cipher.RSA();
                    break;
                default:
                    throw(new System.Exception("Currently only DSA and RSA are implemented as signature algorithms!"));
            }

            byte[] bSignature = new byte[0];
            int iCounter = 0;
            if (this.Version <= SignaturePacketVersionNumbers.v3) {
                bSignature = new byte[5];

                bSignature[iCounter++] = (byte)this.SignatureType;
                long lTime = (dtTimeCreated.Ticks - new DateTime(1970, 1, 1).Ticks)/10000000;
                bSignature[iCounter++] = (byte)((lTime >> 24) & 0xFF);
                bSignature[iCounter++] = (byte)((lTime >> 16) & 0xFF);
                bSignature[iCounter++] = (byte)((lTime >> 8) & 0xFF);
                bSignature[iCounter++] = (byte)(lTime & 0xFF);
            } else {

                // Add Issuer KeyID Subpacket if it's not there.
                try {
                    ulong lTestForKeyID = this.KeyID;
                } catch (Exception) {
                    SignatureSubPacket sspIssuerKeyID = new SignatureSubPacket();
                    sspIssuerKeyID.Type = SignatureSubPacketTypes.IssuerKeyID;
                    sspIssuerKeyID.KeyID = this.lKeyID;
                    this.AddSubPacket(sspIssuerKeyID, true);
                }

                // Add TimeCreated Subpacket if it's not there.
                try {
                    this.FindSignatureCreationTime();
                } catch (Exception) {
                    SignatureSubPacket sspCreationTime = new SignatureSubPacket();
                    sspCreationTime.Type = SignatureSubPacketTypes.SignatureCreationTime;
                    sspCreationTime.TimeCreated = DateTime.Now;
                    this.AddSubPacket(sspCreationTime, true);
                }

                //Hashed Subpackets Length
                int lHashedSubPacketLength = 0;
                for (int i=0; i<this.HashedSubPackets.Length; i++) {
                    lHashedSubPacketLength += this.HashedSubPackets[i].Generate().Length;
                }

                bSignature = new byte[lHashedSubPacketLength + 12];
                bSignature[iCounter++] = 4; // Version
                bSignature[iCounter++] = (byte)this.SignatureType;
                bSignature[iCounter++] = (byte)this.SignatureAlgorithm;
                bSignature[iCounter++] = (byte)this.HashAlgorithm;

                //Hashed
                bSignature[iCounter++] = (byte)((lHashedSubPacketLength >> 8) & 0xFF);
                bSignature[iCounter++] = (byte)(lHashedSubPacketLength & 0xFF);
                for (int i=0; i<this.HashedSubPackets.Length; i++) {
                    byte[] bSubPacket = this.HashedSubPackets[i].Generate();
                    Array.Copy(bSubPacket, 0, bSignature, iCounter, bSubPacket.Length);
                    iCounter += bSubPacket.Length;
                }

                //Final Trailer of 6 bytes
                bSignature[iCounter++] = 0x04;
                bSignature[iCounter++] = 0xFF;
                bSignature[iCounter++] = (byte)(((lHashedSubPacketLength+6) >> 24) & 0xFF);
                bSignature[iCounter++] = (byte)(((lHashedSubPacketLength+6) >> 16) & 0xFF);
                bSignature[iCounter++] = (byte)(((lHashedSubPacketLength+6) >> 8) & 0xFF);
                bSignature[iCounter++] = (byte)((lHashedSubPacketLength+6) & 0xFF);
            }

            byte[] bData = new byte[bSignedData.Length + bSignature.Length];
            Array.Copy(bSignedData, bData, bSignedData.Length);
            Array.Copy(bSignature, 0, bData, bSignedData.Length, bSignature.Length);

            byte[] bHash = haSigner.ComputeHash(bData);
            BigInteger biHash = new BigInteger(bHash);

            //PKCS1 Encode the hash
            if (this.SignatureAlgorithm != AsymAlgorithms.DSA) {

                // We encode the MD in this way:
                //  0  A PAD(n bytes)   0  ASN(asnlen bytes)  MD(len bytes)
                // PAD consists of FF bytes.
                byte[] bASN = new byte[0];

                switch (this.HashAlgorithm) {
                    case HashAlgorithms.MD5:
                        bASN = new byte[] {0x30, 0x20, 0x30, 0x0C, 0x06, 0x08,
                                           0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D,
                                           0x02, 0x05, 0x05, 0x00, 0x04, 0x10};
                        break;
                    case HashAlgorithms.SHA1:
                        bASN = new byte[] {0x30, 0x21, 0x30, 0x09, 0x06, 0x05,
                                           0x2b, 0x0E, 0x03, 0x02, 0x1A, 0x05,
                                           0x00, 0x04, 0x14};
                        break;
                }

                int iFrameSize = (skpKey.PublicKey.KeyMaterial[0].bitCount() + 7) / 8;
                byte[] bFrame = new byte[iFrameSize];
                int iASNCounter = 0;

                bFrame[iASNCounter++] = 0;
                bFrame[iASNCounter++] = 1;
                int iFFLength = iFrameSize - bHash.Length - bASN.Length - 3;
                for (int i=0; i<iFFLength; i++)
                    bFrame[iASNCounter++] = 0xFF;

                bFrame[iASNCounter++] = 0;
                Array.Copy(bASN, 0, bFrame, iASNCounter, bASN.Length);
                iASNCounter += bASN.Length;
                Array.Copy(bHash, 0, bFrame, iASNCounter, bHash.Length);
                biHash = new BigInteger(bFrame);
            }

            sSignedHash16Bit = (ushort)((bHash[0] << 8) + bHash[1]);
            biSignature = acSigner.Sign(biHash, skpKey, strPassphrase);
            this.bIsUpdated = true;
        }
Example #20
0
			public ModulusRing (BigInteger mod) {
				this.mod = mod;
				
				// calculate constant = b^ (2k) / m
				uint i = mod.length << 1;
				
				constant = new BigInteger (Sign.Positive, i + 1);
				constant.data [i] = 0x00000001;
				
				constant = constant / mod;
			}
Example #21
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;
        }
Example #22
0
			public void BarrettReduction (BigInteger x) {
				BigInteger n = mod;
				uint k = n.length,
					kPlusOne = k+1,
					kMinusOne = k-1;
				
				// x < mod, so nothing to do.
				if (x.length < k) return;
				
				BigInteger q3;
				
				//
				// Validate pointers
				//
				if (x.data.Length < x.length) throw new IndexOutOfRangeException ("x out of range");
				
				// q1 = x / b^ (k-1)
				// q2 = q1 * constant
				// q3 = q2 / b^ (k+1), Needs to be accessed with an offset of kPlusOne
				
				// TODO: We should the method in HAC p 604 to do this (14.45)
				q3 = new BigInteger (Sign.Positive, x.length - kMinusOne + constant.length);
				Kernel.Multiply (x.data, kMinusOne, x.length - kMinusOne, constant.data, 0, constant.length, q3.data, 0);
				
				// r1 = x mod b^ (k+1)
				// i.e. keep the lowest (k+1) words
				
				uint lengthToCopy = (x.length > kPlusOne) ? kPlusOne : x.length;
				
				x.length = lengthToCopy;
				x.Normalize ();
				
				// r2 = (q3 * n) mod b^ (k+1)
				// partial multiplication of q3 and n
				
				BigInteger r2 = new BigInteger (Sign.Positive, kPlusOne);
				Kernel.MultiplyMod2p32pmod (q3.data, (int)kPlusOne, (int)q3.length - (int)kPlusOne, n.data, 0, (int)n.length, r2.data, 0, (int)kPlusOne);
				
				r2.Normalize ();
				
				if (r2 < x) {
					Kernel.MinusEq (x, r2);
				} else {
					BigInteger val = new BigInteger (Sign.Positive, kPlusOne + 1);
					val.data [kPlusOne] = 0x00000001;
					
					Kernel.MinusEq (val, r2);
					Kernel.PlusEq (x, val);
				}
				
				while (x >= n)
					Kernel.MinusEq (x, n);
			}
Example #23
0
        /// <summary>
        /// Public key operation. Verifies biSignature with the keydata
        /// in the given public key packet and returns true if the signature
        /// is valid.
        /// </summary>
        /// <param name="biSignature">The signature that is about to
        /// be verified</param>
        /// <param name="biHash">The hash value of the signed message.</param>
        /// <param name="pkpKey">The public key packet with the key
        /// material for the verification.</param>
        /// <returns>True if the signature is valid, otherwise 
        /// false</returns>
        /// <remarks>No remarks</remarks>
        public override bool Verify(BigInteger[] biSignature, BigInteger biHash, PublicKeyPacket pkpKey)
        {
            if (biSignature == null)
                throw new ArgumentNullException("rgbSignature");

            DSA_Public_Key dpkKey = new DSA_Public_Key();
            dpkKey = ParsePublicKey(pkpKey);

            try {
                BigInteger m = biHash;
                BigInteger r = biSignature[0];
                BigInteger s = biSignature[1];

                if ((r < 0) || (dpkKey.q <= r))
                    return false;

                if ((s < 0) || (dpkKey.q <= s))
                    return false;

                BigInteger w = s.modInverse(dpkKey.q);
                BigInteger u1 = m * w % dpkKey.q;
                BigInteger u2 = r * w % dpkKey.q;

                u1 = dpkKey.g.modPow(u1, dpkKey.p);
                u2 = dpkKey.y.modPow(u2, dpkKey.p);

                BigInteger v = ((u1 * u2 % dpkKey.p) % dpkKey.q);
                return (v == r);
            } catch {
                throw new CryptographicException();
            }
        }
Example #24
0
			public BigInteger Multiply (BigInteger a, BigInteger b) {
				if (a == 0 || b == 0) return 0;
				
				if (a.length >= mod.length << 1)
					a %= mod;
				
				if (b.length >= mod.length << 1)
					b %= mod;
				
				if (a.length >= mod.length)
					BarrettReduction (a);
				
				if (b.length >= mod.length)
					BarrettReduction (b);
				
				BigInteger ret = new BigInteger (a * b);
				BarrettReduction (ret);
				
				return ret;
			}
Example #25
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;
        }
Example #26
0
			public BigInteger Difference (BigInteger a, BigInteger b) {
				Sign cmp = Kernel.Compare (a, b);
				BigInteger diff;
				
				switch (cmp) {
					case Sign.Zero:
						return 0;
					case Sign.Positive:
						diff = a - b; break;
					case Sign.Negative:
						diff = b - a; break;
					default:
						throw new Exception ();
				}
				
				if (diff >= mod) {
					if (diff.length >= mod.length << 1)
						diff %= mod;
					else
						BarrettReduction (diff);
				}
				if (cmp == Sign.Negative)
					diff = mod - diff;
				return diff;
			}
Example #27
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;
        }
Example #28
0
			public BigInteger Pow (BigInteger b, BigInteger exp) {
				if ((mod.data [0] & 1) == 1) return OddPow (b, exp);
				else return EvenPow (b, exp);
			}
Example #29
0
 /// <summary>
 /// Encryption is not supported for DSA. If you call this function,
 /// an Exception will be thrown.
 /// </summary>
 /// <remarks>
 /// Encryption is not supported for DSA. If you call this function,
 /// an Exception will be thrown.
 /// </remarks>
 public override BigInteger[] Encrypt(BigInteger biPlain, PublicKeyPacket pkpKey)
 {
     throw(new Exception("The DSA cipher cannot be used for encryption"));
 }
Example #30
0
			public BigInteger EvenPow (BigInteger b, BigInteger exp) {
				BigInteger resultNum = new BigInteger ((BigInteger)1, mod.length << 1);
				BigInteger tempNum = new BigInteger (b % mod, mod.length << 1);  // ensures (tempNum * tempNum) < b^ (2k)
				
				uint totalBits = (uint)exp.bitCount ();
				
				uint [] wkspace = new uint [mod.length << 1];
				
				// perform squaring and multiply exponentiation
				for (uint pos = 0; pos < totalBits; pos++) {
					if (exp.testBit (pos)) {
						
						Array.Clear (wkspace, 0, wkspace.Length);
						Kernel.Multiply (resultNum.data, 0, resultNum.length, tempNum.data, 0, tempNum.length, wkspace, 0);
						resultNum.length += tempNum.length;
						uint [] t = wkspace;
						wkspace = resultNum.data;
						resultNum.data = t;
						
						BarrettReduction (resultNum);
					}
					
					Kernel.SquarePositive (tempNum, ref wkspace);
					BarrettReduction (tempNum);
					
					if (tempNum == 1) {
						return resultNum;
					}
				}
				
				return resultNum;
			}