Ejemplo n.º 1
0
		public BigInteger ProcessBlock(
			BigInteger input)
		{
			if (key is RsaPrivateCrtKeyParameters)
			{
				//
				// we have the extra factors, use the Chinese Remainder Theorem - the author
				// wishes to express his thanks to Dirk Bonekaemper at rtsffm.com for
				// advice regarding the expression of this.
				//
				RsaPrivateCrtKeyParameters crtKey = (RsaPrivateCrtKeyParameters)key;

				BigInteger p = crtKey.P;;
				BigInteger q = crtKey.Q;
				BigInteger dP = crtKey.DP;
				BigInteger dQ = crtKey.DQ;
				BigInteger qInv = crtKey.QInv;

				BigInteger mP, mQ, h, m;

				// mP = ((input Mod p) ^ dP)) Mod p
				mP = (input.Remainder(p)).ModPow(dP, p);

				// mQ = ((input Mod q) ^ dQ)) Mod q
				mQ = (input.Remainder(q)).ModPow(dQ, q);

				// h = qInv * (mP - mQ) Mod p
				h = mP.Subtract(mQ);
				h = h.Multiply(qInv);
				h = h.Mod(p);               // Mod (in Java) returns the positive residual

				// m = h * q + mQ
				m = h.Multiply(q);
				m = m.Add(mQ);

				return m;
			}

			return input.ModPow(key.Exponent, key.Modulus);
		}
Ejemplo n.º 2
0
		/**
		 * return true if the value r and s represent a Gost3410 signature for
		 * the passed in message for standard Gost3410 the message should be a
		 * Gost3411 hash of the real message to be verified.
		 */
		public bool VerifySignature(
			byte[]		message,
			BigInteger	r,
			BigInteger	s)
		{
			byte[] mRev = new byte[message.Length]; // conversion is little-endian
			for (int i = 0; i != mRev.Length; i++)
			{
				mRev[i] = message[mRev.Length - 1 - i];
			}

			BigInteger m = new BigInteger(1, mRev);
			Gost3410Parameters parameters = key.Parameters;

			if (r.SignValue < 0 || parameters.Q.CompareTo(r) <= 0)
			{
				return false;
			}

			if (s.SignValue < 0 || parameters.Q.CompareTo(s) <= 0)
			{
				return false;
			}

			BigInteger v = m.ModPow(parameters.Q.Subtract(BigInteger.Two), parameters.Q);

			BigInteger z1 = s.Multiply(v).Mod(parameters.Q);
			BigInteger z2 = (parameters.Q.Subtract(r)).Multiply(v).Mod(parameters.Q);

			z1 = parameters.A.ModPow(z1, parameters.P);
			z2 = ((Gost3410PublicKeyParameters)key).Y.ModPow(z2, parameters.P);

			BigInteger u = z1.Multiply(z2).Mod(parameters.P).Mod(parameters.Q);

			return u.Equals(r);
		}
Ejemplo n.º 3
0
		/**
		 * given a message from a given party and the corresponding public key
		 * calculate the next message in the agreement sequence. In this case
		 * this will represent the shared secret.
		 */
		public BigInteger CalculateAgreement(
			DHPublicKeyParameters	pub,
			BigInteger				message)
		{
			if (pub == null)
				throw new ArgumentNullException("pub");
			if (message == null)
				throw new ArgumentNullException("message");

			if (!pub.Parameters.Equals(dhParams))
			{
				throw new ArgumentException("Diffie-Hellman public key has wrong parameters.");
			}

			BigInteger p = dhParams.P;

			return message.ModPow(key.X, p).Multiply(pub.Y.ModPow(privateValue, p)).Mod(p);
		}
		/**
		 * Procedure C
		 * procedure generates the a value from the given p,q,
		 * returning the a value.
		 */
		private BigInteger procedure_C(BigInteger p, BigInteger q)
		{
			BigInteger pSub1 = p.Subtract(BigInteger.One);
			BigInteger pSub1Divq = pSub1.Divide(q);

			for(;;)
			{
				BigInteger d = new BigInteger(p.BitLength, init_random);

				// 1 < d < p-1
				if (d.CompareTo(BigInteger.One) > 0 && d.CompareTo(pSub1) < 0)
				{
					BigInteger a = d.ModPow(pSub1Divq, p);

					if (a.CompareTo(BigInteger.One) != 0)
					{
						return a;
					}
				}
			}
		}
Ejemplo n.º 5
0
		/**
		* Process a single block using the basic ElGamal algorithm.
		*
		* @param in the input array.
		* @param inOff the offset into the input buffer where the data starts.
		* @param length the length of the data to be processed.
		* @return the result of the ElGamal process.
		* @exception DataLengthException the input block is too large.
		*/
		public byte[] ProcessBlock(
			byte[]	input,
			int		inOff,
			int		length)
		{
			if (key == null)
				throw new InvalidOperationException("ElGamal engine not initialised");

			int maxLength = forEncryption
				?	(bitSize - 1 + 7) / 8
				:	GetInputBlockSize();

			if (length > maxLength)
				throw new DataLengthException("input too large for ElGamal cipher.\n");

			BigInteger p = key.Parameters.P;

			byte[] output;
			if (key is ElGamalPrivateKeyParameters) // decryption
			{
				int halfLength = length / 2;
				BigInteger gamma = new BigInteger(1, input, inOff, halfLength);
				BigInteger phi = new BigInteger(1, input, inOff + halfLength, halfLength);

				ElGamalPrivateKeyParameters priv = (ElGamalPrivateKeyParameters) key;

				// a shortcut, which generally relies on p being prime amongst other things.
				// if a problem with this shows up, check the p and g values!
				BigInteger m = gamma.ModPow(p.Subtract(BigInteger.One).Subtract(priv.X), p).Multiply(phi).Mod(p);

				output = m.ToByteArrayUnsigned();
			}
			else // encryption
			{
				BigInteger tmp = new BigInteger(1, input, inOff, length);

				if (tmp.BitLength >= p.BitLength)
					throw new DataLengthException("input too large for ElGamal cipher.\n");


				ElGamalPublicKeyParameters pub = (ElGamalPublicKeyParameters) key;

				BigInteger pSub2 = p.Subtract(BigInteger.Two);

				// TODO In theory, a series of 'k', 'g.ModPow(k, p)' and 'y.ModPow(k, p)' can be pre-calculated
				BigInteger k;
				do
				{
					k = new BigInteger(p.BitLength, random);
				}
				while (k.SignValue == 0 || k.CompareTo(pSub2) > 0);

				BigInteger g = key.Parameters.G;
				BigInteger gamma = g.ModPow(k, p);
				BigInteger phi = tmp.Multiply(pub.Y.ModPow(k, p)).Mod(p);

				output = new byte[this.GetOutputBlockSize()];

				// TODO Add methods to allow writing BigInteger to existing byte array?
				byte[] out1 = gamma.ToByteArrayUnsigned();
				byte[] out2 = phi.ToByteArrayUnsigned();
				out1.CopyTo(output, output.Length / 2 - out1.Length);
				out2.CopyTo(output, output.Length - out2.Length);
			}

			return output;
		}
Ejemplo n.º 6
0
 private static BigInteger CalculatePublicKey(BigInteger p, BigInteger g, BigInteger x)
 {
     return g.ModPow(x, p);
 }
Ejemplo n.º 7
0
        protected virtual BigInteger CalculateGenerator_FIPS186_3_Verifiable(IDigest d, BigInteger p, BigInteger q,
            byte[] seed, int index)
        {
            // A.2.3 Verifiable Canonical Generation of the Generator g
            BigInteger e = p.Subtract(BigInteger.One).Divide(q);
            byte[] ggen = Hex.Decode("6767656E");

            // 7. U = domain_parameter_seed || "ggen" || index || count.
            byte[] U = new byte[seed.Length + ggen.Length + 1 + 2];
            Array.Copy(seed, 0, U, 0, seed.Length);
            Array.Copy(ggen, 0, U, seed.Length, ggen.Length);
            U[U.Length - 3] = (byte)index; 

            byte[] w = new byte[d.GetDigestSize()];
            for (int count = 1; count < (1 << 16); ++count)
            {
                Inc(U);
                Hash(d, U, w);
                BigInteger W = new BigInteger(1, w);
                BigInteger g = W.ModPow(e, p);

                if (g.CompareTo(BigInteger.Two) >= 0)
                    return g;
            }

            return null;
        }
Ejemplo n.º 8
0
		/**
		 * Set the private key.
		 *
		 * @param p   key parameter: field modulus
		 * @param q   key parameter: subgroup order
		 * @param g   key parameter: generator
		 * @param x   private key
		 */
		public void setPrivateKey(BigInteger p, BigInteger q,
				BigInteger g, BigInteger x)
		{
			/*
			 * Perform some basic sanity checks.  We do not
			 * check primality of p or q because that would
			 * be too expensive.
			 *
			 * We reject keys where q is longer than 999 bits,
			 * because it would complicate signature encoding.
			 * Normal DSA keys do not have a q longer than 256
			 * bits anyway.
			 */
			if(p == null || q == null || g == null || x == null
					|| p.SignValue <= 0 || q.SignValue <= 0
					|| g.SignValue <= 0 || x.SignValue <= 0
					|| x.CompareTo(q) >= 0 || q.CompareTo(p) >= 0
					|| q.BitLength > 999
					|| g.CompareTo(p) >= 0 || g.BitLength == 1
					|| g.ModPow(q, p).BitLength != 1)
			{
				throw new InvalidOperationException(
						"invalid DSA private key");
			}
			this.p = p;
			this.q = q;
			this.g = g;
			this.x = x;
			qlen = q.BitLength;
			if(q.SignValue <= 0 || qlen < 8)
			{
				throw new InvalidOperationException(
						"bad group order: " + q);

			}
			rolen = (qlen + 7) >> 3;
			rlen = rolen * 8;

			/*
			 * Convert the private exponent (x) into a sequence
			 * of octets.
			 */
			bx = int2octets(x);
		}