/** * which Generates the p and g values from the given parameters, * returning the DHParameters object. * <p> * Note: can take a while...</p> */ public virtual DHParameters GenerateParameters() { // // find a safe prime p where p = 2*q + 1, where p and q are prime. // BigInteger[] safePrimes = DHParametersHelper.GenerateSafePrimes(size, certainty, random); BigInteger p = safePrimes[0]; BigInteger q = safePrimes[1]; BigInteger g; int qLength = size - 1; // // calculate the generator g - the advantage of using the 2q+1 // approach is that we know the prime factorisation of (p - 1)... // do { g = new BigInteger(qLength, random); } while (g.ModPow(BigInteger.Two, p).Equals(BigInteger.One) || g.ModPow(q, p).Equals(BigInteger.One)); return new DHParameters(p, g, q, 2); }
/// <summary> /// Constructor used by the pre-approved groups in JPakePrimeOrderGroups. /// These pre-approved groups can avoid the expensive checks. /// User-specified groups should not use this constructor. /// </summary> public JPakePrimeOrderGroup(BigInteger p, BigInteger q, BigInteger g, bool skipChecks) { JPakeUtilities.ValidateNotNull(p, "p"); JPakeUtilities.ValidateNotNull(q, "q"); JPakeUtilities.ValidateNotNull(g, "g"); if (!skipChecks) { if (!p.Subtract(JPakeUtilities.One).Mod(q).Equals(JPakeUtilities.Zero)) throw new ArgumentException("p-1 must be evenly divisible by q"); if (g.CompareTo(BigInteger.Two) == -1 || g.CompareTo(p.Subtract(JPakeUtilities.One)) == 1) throw new ArgumentException("g must be in [2, p-1]"); if (!g.ModPow(q, p).Equals(JPakeUtilities.One)) throw new ArgumentException("g^q mod p must equal 1"); // Note these checks do not guarantee that p and q are prime. // We just have reasonable certainty that they are prime. if (!p.IsProbablePrime(20)) throw new ArgumentException("p must be prime"); if (!q.IsProbablePrime(20)) throw new ArgumentException("q must be prime"); } this.p = p; this.q = q; this.g = g; }
internal BigInteger CalculatePublic( BigInteger p, BigInteger g, BigInteger x) { return g.ModPow(x, p); }
public BigInteger Encrypt(BigInteger m) { /* e = new BigInteger("3"); * m = new BigInteger("111111"); * n = new BigInteger("9173503");*/ Console.WriteLine("Encrypt message: " + m); return(m.ModPow(e, n)); }
/** * 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."); } return message.ModPow(key.X, dhParams.P).Multiply(pub.Y.ModPow(privateValue, dhParams.P)).Mod(dhParams.P); }
/// <summary> /// millerov agoritam /// </summary> /// <param name="a">točka</param> /// <param name="b">točka</param> /// <param name="m">red grupe</param> /// <param name="p">red polja, prim</param> /// <returns></returns> private static BigInteger Miller(FpPoint P, FpPoint Q, BigInteger m, BigInteger prim) { // Millerov algoritam string mBin = m.ToString(2); BigInteger t1 = new BigInteger("1", 10); BigInteger t2 = new BigInteger("1", 10); FpPoint V = P; for (int i = 0; i < m.BitLength; i++) { V = (FpPoint)V.Twice(); t1 = t1.ModPow(new BigInteger("2", 10), prim).Multiply(MLF(V, V, Q)); if (mBin[i] == '1') { t1 = t1.Multiply(MLF(V, P, Q)); V = (FpPoint)V.Add(P); } } return t1; }
private void processHandshake() { bool read; do { read = false; /* * We need the first 4 bytes, they contain type and length of * the message. */ if (handshakeQueue.Available >= 4) { byte[] beginning = new byte[4]; handshakeQueue.Read(beginning, 0, 4, 0); MemoryStream bis = new MemoryStream(beginning, false); short type = TlsUtilities.ReadUint8(bis); int len = TlsUtilities.ReadUint24(bis); /* * Check if we have enough bytes in the buffer to read * the full message. */ if (handshakeQueue.Available >= (len + 4)) { /* * Read the message. */ byte[] buf = new byte[len]; handshakeQueue.Read(buf, 0, len, 4); handshakeQueue.RemoveData(len + 4); /* * If it is not a finished message, update our hashes * we prepare for the finish message. */ if (type != HP_FINISHED) { rs.hash1.BlockUpdate(beginning, 0, 4); rs.hash2.BlockUpdate(beginning, 0, 4); rs.hash1.BlockUpdate(buf, 0, len); rs.hash2.BlockUpdate(buf, 0, len); } /* * Now, parse the message. */ MemoryStream inStr = new MemoryStream(buf, false); /* * Check the type. */ switch (type) { case HP_CERTIFICATE: switch (connection_state) { case CS_SERVER_HELLO_RECEIVED: /* * Parse the certificates. */ Certificate cert = Certificate.Parse(inStr); AssertEmpty(inStr); /* * Verify them. */ if (!this.verifyer.IsValid(cert.GetCerts())) { this.FailWithError(AL_fatal, AP_user_canceled); } /* * We only support RSA certificates. Lets hope * this is one. */ RsaPublicKeyStructure rsaKey = null; try { rsaKey = RsaPublicKeyStructure.GetInstance( cert.certs[0].TbsCertificate.SubjectPublicKeyInfo.GetPublicKey()); } catch (Exception) { /* * Sorry, we have to fail ;-( */ this.FailWithError(AL_fatal, AP_unsupported_certificate); } /* * Parse the servers public RSA key. */ this.serverRsaKey = new RsaKeyParameters( false, rsaKey.Modulus, rsaKey.PublicExponent); connection_state = CS_SERVER_CERTIFICATE_RECEIVED; read = true; break; default: this.FailWithError(AL_fatal, AP_unexpected_message); break; } break; case HP_FINISHED: switch (connection_state) { case CS_SERVER_CHANGE_CIPHER_SPEC_RECEIVED: /* * Read the checksum from the finished message, * it has always 12 bytes. */ byte[] receivedChecksum = new byte[12]; TlsUtilities.ReadFully(receivedChecksum, inStr); AssertEmpty(inStr); /* * Calculate our owne checksum. */ byte[] checksum = new byte[12]; byte[] md5andsha1 = new byte[16 + 20]; rs.hash2.DoFinal(md5andsha1, 0); TlsUtilities.PRF(this.ms, TlsUtilities.ToByteArray("server finished"), md5andsha1, checksum); /* * Compare both checksums. */ for (int i = 0; i < receivedChecksum.Length; i++) { if (receivedChecksum[i] != checksum[i]) { /* * Wrong checksum in the finished message. */ this.FailWithError(AL_fatal, AP_handshake_failure); } } connection_state = CS_DONE; /* * We are now ready to receive application data. */ this.appDataReady = true; read = true; break; default: this.FailWithError(AL_fatal, AP_unexpected_message); break; } break; case HP_SERVER_HELLO: switch (connection_state) { case CS_CLIENT_HELLO_SEND: /* * Read the server hello message */ TlsUtilities.CheckVersion(inStr, this); /* * Read the server random */ this.serverRandom = new byte[32]; TlsUtilities.ReadFully(this.serverRandom, inStr); /* * Currenty, we don't support session ids */ short sessionIdLength = TlsUtilities.ReadUint8(inStr); byte[] sessionId = new byte[sessionIdLength]; TlsUtilities.ReadFully(sessionId, inStr); /* * Find out which ciphersuite the server has * choosen. If we don't support this ciphersuite, * the TlsCipherSuiteManager will throw an * exception. */ this.choosenCipherSuite = TlsCipherSuiteManager.GetCipherSuite( TlsUtilities.ReadUint16(inStr), this); /* * We support only the null compression which * means no compression. */ short compressionMethod = TlsUtilities.ReadUint8(inStr); if (compressionMethod != 0) { this.FailWithError(TlsProtocolHandler.AL_fatal, TlsProtocolHandler.AP_illegal_parameter); } AssertEmpty(inStr); connection_state = CS_SERVER_HELLO_RECEIVED; read = true; break; default: this.FailWithError(AL_fatal, AP_unexpected_message); break; } break; case HP_SERVER_HELLO_DONE: switch (connection_state) { case CS_SERVER_CERTIFICATE_RECEIVED: case CS_SERVER_KEY_EXCHANGE_RECEIVED: // NB: Original code used case label fall-through if (connection_state == CS_SERVER_CERTIFICATE_RECEIVED) { /* * There was no server key exchange message, check * that we are doing RSA key exchange. */ if (this.choosenCipherSuite.KeyExchangeAlgorithm != TlsCipherSuite.KE_RSA) { this.FailWithError(AL_fatal, AP_unexpected_message); } } AssertEmpty(inStr); connection_state = CS_SERVER_HELLO_DONE_RECEIVED; /* * Send the client key exchange message, depending * on the key exchange we are using in our * ciphersuite. */ short ke = this.choosenCipherSuite.KeyExchangeAlgorithm; switch (ke) { case TlsCipherSuite.KE_RSA: /* * We are doing RSA key exchange. We will * choose a pre master secret and send it * rsa encrypted to the server. * * Prepare pre master secret. */ pms = new byte[48]; pms[0] = 3; pms[1] = 1; random.NextBytes(pms, 2, 46); /* * Encode the pms and send it to the server. * * Prepare an Pkcs1Encoding with good random * padding. */ RsaBlindedEngine rsa = new RsaBlindedEngine(); Pkcs1Encoding encoding = new Pkcs1Encoding(rsa); encoding.Init(true, new ParametersWithRandom(this.serverRsaKey, this.random)); byte[] encrypted = null; try { encrypted = encoding.ProcessBlock(pms, 0, pms.Length); } catch (InvalidCipherTextException) { /* * This should never happen, only during decryption. */ this.FailWithError(AL_fatal, AP_internal_error); } /* * Send the encrypted pms. */ MemoryStream bos = new MemoryStream(); TlsUtilities.WriteUint8(HP_CLIENT_KEY_EXCHANGE, bos); TlsUtilities.WriteUint24(encrypted.Length + 2, bos); TlsUtilities.WriteUint16(encrypted.Length, bos); bos.Write(encrypted, 0, encrypted.Length); byte[] message = bos.ToArray(); rs.WriteMessage((short)RL_HANDSHAKE, message, 0, message.Length); break; case TlsCipherSuite.KE_DHE_RSA: /* * Send the Client Key Exchange message for * DHE key exchange. */ byte[] YcByte = this.Yc.ToByteArray(); MemoryStream DHbos = new MemoryStream(); TlsUtilities.WriteUint8(HP_CLIENT_KEY_EXCHANGE, DHbos); TlsUtilities.WriteUint24(YcByte.Length + 2, DHbos); TlsUtilities.WriteUint16(YcByte.Length, DHbos); DHbos.Write(YcByte, 0, YcByte.Length); byte[] DHmessage = DHbos.ToArray(); rs.WriteMessage((short)RL_HANDSHAKE, DHmessage, 0, DHmessage.Length); break; default: /* * Proble during handshake, we don't know * how to thandle this key exchange method. */ this.FailWithError(AL_fatal, AP_unexpected_message); break; } connection_state = CS_CLIENT_KEY_EXCHANGE_SEND; /* * Now, we send change cipher state */ byte[] cmessage = new byte[1]; cmessage[0] = 1; rs.WriteMessage((short)RL_CHANGE_CIPHER_SPEC, cmessage, 0, cmessage.Length); connection_state = CS_CLIENT_CHANGE_CIPHER_SPEC_SEND; /* * Calculate the ms */ this.ms = new byte[48]; byte[] randBytes = new byte[clientRandom.Length + serverRandom.Length]; Array.Copy(clientRandom, 0, randBytes, 0, clientRandom.Length); Array.Copy(serverRandom, 0, randBytes, clientRandom.Length, serverRandom.Length); TlsUtilities.PRF(pms, TlsUtilities.ToByteArray("master secret"), randBytes, this.ms); /* * Initialize our cipher suite */ rs.writeSuite = this.choosenCipherSuite; rs.writeSuite.Init(this.ms, clientRandom, serverRandom); /* * Send our finished message. */ byte[] checksum = new byte[12]; byte[] md5andsha1 = new byte[16 + 20]; rs.hash1.DoFinal(md5andsha1, 0); TlsUtilities.PRF(this.ms, TlsUtilities.ToByteArray("client finished"), md5andsha1, checksum); MemoryStream bos2 = new MemoryStream(); TlsUtilities.WriteUint8(HP_FINISHED, bos2); TlsUtilities.WriteUint24(12, bos2); bos2.Write(checksum, 0, checksum.Length); byte[] message2 = bos2.ToArray(); rs.WriteMessage((short)RL_HANDSHAKE, message2, 0, message2.Length); this.connection_state = CS_CLIENT_FINISHED_SEND; read = true; break; default: this.FailWithError(AL_fatal, AP_handshake_failure); break; } break; case HP_SERVER_KEY_EXCHANGE: switch (connection_state) { case CS_SERVER_CERTIFICATE_RECEIVED: /* * Check that we are doing DHE key exchange */ if (this.choosenCipherSuite.KeyExchangeAlgorithm != TlsCipherSuite.KE_DHE_RSA) { this.FailWithError(AL_fatal, AP_unexpected_message); } /* * Parse the Structure */ int pLength = TlsUtilities.ReadUint16(inStr); byte[] pByte = new byte[pLength]; TlsUtilities.ReadFully(pByte, inStr); int gLength = TlsUtilities.ReadUint16(inStr); byte[] gByte = new byte[gLength]; TlsUtilities.ReadFully(gByte, inStr); int YsLength = TlsUtilities.ReadUint16(inStr); byte[] YsByte = new byte[YsLength]; TlsUtilities.ReadFully(YsByte, inStr); int sigLength = TlsUtilities.ReadUint16(inStr); byte[] sigByte = new byte[sigLength]; TlsUtilities.ReadFully(sigByte, inStr); this.AssertEmpty(inStr); /* * Verify the Signature. * * First, calculate the hash. */ CombinedHash sigDigest = new CombinedHash(); MemoryStream signedData = new MemoryStream(); TlsUtilities.WriteUint16(pLength, signedData); signedData.Write(pByte, 0, pByte.Length); TlsUtilities.WriteUint16(gLength, signedData); signedData.Write(gByte, 0, gByte.Length); TlsUtilities.WriteUint16(YsLength, signedData); signedData.Write(YsByte, 0, YsByte.Length); byte[] signed = signedData.ToArray(); sigDigest.BlockUpdate(this.clientRandom, 0, this.clientRandom.Length); sigDigest.BlockUpdate(this.serverRandom, 0, this.serverRandom.Length); sigDigest.BlockUpdate(signed, 0, signed.Length); byte[] hash = new byte[sigDigest.GetDigestSize()]; sigDigest.DoFinal(hash, 0); /* * Now, do the RSA operation */ RsaBlindedEngine rsa = new RsaBlindedEngine(); Pkcs1Encoding encoding = new Pkcs1Encoding(rsa); encoding.Init(false, this.serverRsaKey); /* * The data which was signed */ byte[] sigHash = null; try { sigHash = encoding.ProcessBlock(sigByte, 0, sigByte.Length); } catch (InvalidCipherTextException) { this.FailWithError(AL_fatal, AP_bad_certificate); } /* * Check if the data which was signed is equal to * the hash we calculated. */ if (sigHash.Length != hash.Length) { this.FailWithError(AL_fatal, AP_bad_certificate); } for (int i = 0; i < sigHash.Length; i++) { if (sigHash[i] != hash[i]) { this.FailWithError(AL_fatal, AP_bad_certificate); } } /* * OK, Signature was correct. * * Do the DH calculation. */ BigInteger p = new BigInteger(1, pByte); BigInteger g = new BigInteger(1, gByte); BigInteger Ys = new BigInteger(1, YsByte); BigInteger x = new BigInteger(p.BitLength - 1, this.random); Yc = g.ModPow(x, p); this.pms = (Ys.ModPow(x, p)).ToByteArray(); /* * Remove leading zero byte, if present. */ if (this.pms[0] == 0) { byte[] tmp = new byte[this.pms.Length - 1]; Array.Copy(this.pms, 1, tmp, 0, tmp.Length); this.pms = tmp; } this.connection_state = CS_SERVER_KEY_EXCHANGE_RECEIVED; read = true; break; default: this.FailWithError(AL_fatal, AP_unexpected_message); break; } break; case HP_HELLO_REQUEST: case HP_CLIENT_KEY_EXCHANGE: case HP_CERTIFICATE_REQUEST: case HP_CERTIFICATE_VERIFY: case HP_CLIENT_HELLO: default: // We do not support this! this.FailWithError(AL_fatal, AP_unexpected_message); break; } } } } while (read); }
/// <summary> /// Calculate a zero knowledge proof of x using Schnorr's signature. /// The returned array has two elements {g^v, r = v-x*h} for x. /// </summary> public static BigInteger[] CalculateZeroKnowledgeProof(BigInteger p, BigInteger q, BigInteger g, BigInteger gx, BigInteger x, string participantId, IDigest digest, SecureRandom random) { /* Generate a random v, and compute g^v */ BigInteger vMin = Zero; BigInteger vMax = q.Subtract(One); BigInteger v = BigIntegers.CreateRandomInRange(vMin, vMax, random); BigInteger gv = g.ModPow(v, p); BigInteger h = CalculateHashForZeroKnowledgeProof(g, gv, gx, participantId, digest); // h return new BigInteger[] { gv, v.Subtract(x.Multiply(h)).Mod(q) // r = v-x*h }; }
/// <summary> /// Calculate A as done in round 2. /// </summary> public static BigInteger CalculateA(BigInteger p, BigInteger q, BigInteger gA, BigInteger x2s) { // A = ga^(x*s) return gA.ModPow(x2s, p); }
// --- m => b public BigInteger BlindObject(byte[] message, BigInteger r) { BigInteger m = new BigInteger(message); BigInteger b = (r.ModPow(e, n).Multiply(m)).Mod(n); //Console.WriteLine("m: {0}\nr: {1}\ne: {2}\nn: {3}\nb: {4}", m, r, e, n, b); return b; }
internal bool RabinMillerTest( int certainty, Random random) { Debug.Assert(certainty > 0); Debug.Assert(BitLength > 2); Debug.Assert(TestBit(0)); // let n = 1 + d . 2^s BigInteger n = this; BigInteger nMinusOne = n.Subtract(One); int s = nMinusOne.GetLowestSetBit(); BigInteger r = nMinusOne.ShiftRight(s); Debug.Assert(s >= 1); do { // TODO Make a method for random BigIntegers in range 0 < x < n) // - Method can be optimized by only replacing examined bits at each trial BigInteger a; do { a = new BigInteger(n.BitLength, random); } while (a.CompareTo(One) <= 0 || a.CompareTo(nMinusOne) >= 0); BigInteger y = a.ModPow(r, n); if (!y.Equals(One)) { int j = 0; while (!y.Equals(nMinusOne)) { if (++j == s) return false; y = y.ModPow(Two, n); if (y.Equals(One)) return false; } } certainty -= 2; // composites pass for only 1/4 possible 'a' } while (certainty > 0); return true; }
/** * Process a single Block using the Naccache-Stern algorithm. * * @see org.bouncycastle.crypto.AsymmetricBlockCipher#ProcessBlock(byte[], * int, int) */ public byte[] ProcessBlock( byte[] inBytes, int inOff, int length) { if (key == null) throw new InvalidOperationException("NaccacheStern engine not initialised"); if (length > (GetInputBlockSize() + 1)) throw new DataLengthException("input too large for Naccache-Stern cipher.\n"); if (!forEncryption) { // At decryption make sure that we receive padded data blocks if (length < GetInputBlockSize()) { throw new InvalidCipherTextException("BlockLength does not match modulus for Naccache-Stern cipher.\n"); } } // transform input into BigInteger BigInteger input = new BigInteger(1, inBytes, inOff, length); if (debug) { System.Diagnostics.Debug.WriteLine("input as BigInteger: " + input); } byte[] output; if (forEncryption) { output = Encrypt(input); } else { IList plain = Platform.CreateArrayList(); NaccacheSternPrivateKeyParameters priv = (NaccacheSternPrivateKeyParameters)key; IList primes = priv.SmallPrimesList; // Get Chinese Remainders of CipherText for (int i = 0; i < primes.Count; i++) { BigInteger exp = input.ModPow(priv.PhiN.Divide((BigInteger)primes[i]), priv.Modulus); IList al = lookup[i]; if (lookup[i].Count != ((BigInteger)primes[i]).IntValue) { if (debug) { System.Diagnostics.Debug.WriteLine("Prime is " + primes[i] + ", lookup table has size " + al.Count); } throw new InvalidCipherTextException("Error in lookup Array for " + ((BigInteger)primes[i]).IntValue + ": Size mismatch. Expected ArrayList with length " + ((BigInteger)primes[i]).IntValue + " but found ArrayList of length " + lookup[i].Count); } int lookedup = al.IndexOf(exp); if (lookedup == -1) { if (debug) { System.Diagnostics.Debug.WriteLine("Actual prime is " + primes[i]); System.Diagnostics.Debug.WriteLine("Decrypted value is " + exp); System.Diagnostics.Debug.WriteLine("LookupList for " + primes[i] + " with size " + lookup[i].Count + " is: "); for (int j = 0; j < lookup[i].Count; j++) { System.Diagnostics.Debug.WriteLine(lookup[i][j]); } } throw new InvalidCipherTextException("Lookup failed"); } plain.Add(BigInteger.ValueOf(lookedup)); } BigInteger test = chineseRemainder(plain, primes); // Should not be used as an oracle, so reencrypt output to see // if it corresponds to input // this breaks probabilisic encryption, so disable it. Anyway, we do // use the first n primes for key generation, so it is pretty easy // to guess them. But as stated in the paper, this is not a security // breach. So we can just work with the correct sigma. // if (debug) { // System.Diagnostics.Debug.WriteLine("Decryption is " + test); // } // if ((key.G.ModPow(test, key.Modulus)).Equals(input)) { // output = test.ToByteArray(); // } else { // if(debug){ // System.Diagnostics.Debug.WriteLine("Engine seems to be used as an oracle, // returning null"); // } // output = null; // } output = test.ToByteArray(); } return output; }
// --- b => bs public BigInteger SignObject(BigInteger m) { BigInteger bs = m.ModPow(d, n); return bs; }
internal bool RabinMillerTest( int certainty, Random random) { Debug.Assert(certainty > 0); Debug.Assert(CompareTo(Two) > 0); Debug.Assert(TestBit(0)); // let n = 1 + d . 2^s BigInteger n = this; int bitLengthOfN = n.BitLength; BigInteger nMinusOne = n.Subtract(One); int k = nMinusOne.GetLowestSetBit(); BigInteger q = nMinusOne.ShiftRight(k); Debug.Assert(k >= 1); do { // TODO Make a method for random BigIntegers in range 0 < x < n) // - Method can be optimized by only replacing examined bits at each trial BigInteger x; do { x = new BigInteger(bitLengthOfN, random); } // NB: Spec says 0 < x < n, but 1 is trivial while (x.CompareTo(One) <= 0 || x.CompareTo(n) >= 0); BigInteger y = x.ModPow(q, n); if (!y.Equals(One)) { // y already = x.ModPow(d << 0, n) int r = 0; while (!y.Equals(nMinusOne)) { if (++r == k) return false; // y becomes x.ModPow(d << r, n) y = y.ModPow(Two, n); // TODO Confirm whether y.Equals(One) is worth testing here } } certainty -= 2; // composites pass for only 1/4 possible 'x' } while (certainty > 0); return true; }
// --- b => m public byte[] UnblindObject(BigInteger y, BigInteger r) { //BigInteger m = (r.ModPow(e.ModInverse(n), n).Multiply(y)).Mod(n); //BigInteger m = (y.Multiply(r.ModPow(e, n))).Mod(n); BigInteger m = (y.Multiply(r.ModPow(e.Negate(), n))).Mod(n); //Console.WriteLine("m: {0}\nr: {1}\ne: {2}\nn: {3}\ny: {4}", m, r, e, n, y); return m.ToByteArray(); }
private static BigInteger CalculatePublicKey(BigInteger p, BigInteger g, BigInteger x) { return g.ModPow(x, p); }
/** * 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); }
private void SetKey(BigInteger p, BigInteger q, BigInteger g, BigInteger x) { if (p == null) throw new ArgumentException("The DSA key parameter P cannot be null"); if (q == null) throw new ArgumentException("The DSA key parameter Q cannot be null"); if (g == null) throw new ArgumentException("The DSA key parameter G cannot be null"); if (x == null) throw new ArgumentException("The DSA key parameter X cannot be null"); _P = p; _Q = q; _G = g; _X = x; _Y = _G.ModPow(_X, _P); DsaParameters _dsa_param = new DsaParameters(_P, _Q, _G); _public_key_param = new DsaPublicKeyParameters(_Y, _dsa_param); _private_key_param = new DsaPrivateKeyParameters(_X, _dsa_param); SetPublicKeyEncodedMpi(); }
/** * 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 { byte[] in1 = new byte[length / 2]; byte[] in2 = new byte[length / 2]; Array.Copy(input, inOff, in1, 0, in1.Length); Array.Copy(input, inOff + in1.Length, in2, 0, in2.Length); BigInteger gamma = new BigInteger(1, in1); BigInteger phi = new BigInteger(1, in2); ElGamalPrivateKeyParameters priv = (ElGamalPrivateKeyParameters) key; BigInteger m = gamma.ModPow(p.Subtract(BigInteger.One).Subtract(priv.X), p).Multiply(phi).Mod(p); output = m.ToByteArrayUnsigned(); } else // encryption { byte[] block; if (inOff != 0 || length != input.Length) { block = new byte[length]; Array.Copy(input, inOff, block, 0, length); } else { block = input; } BigInteger tmp = new BigInteger(1, block); 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); byte[] out1 = gamma.ToByteArray(); byte[] out2 = phi.ToByteArray(); output = new byte[this.GetOutputBlockSize()]; int out1Start = out1[0] == 0 ? 1 : 0; Array.Copy(out1, out1Start, output, output.Length / 2 - (out1.Length - out1Start), out1.Length - out1Start); int out2Start = out2[0] == 0 ? 1 : 0; Array.Copy(out2, out2Start, output, output.Length - (out2.Length - out2Start), out2.Length - out2Start); } return output; }
/** * 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 virtual 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; }
/** * 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); }
public BigInteger Decrypt(BigInteger c) { /* d = new BigInteger("6111579");*/ return(c.ModPow(d, n)); }
/** * which Generates the p and g values from the given parameters, * returning the DsaParameters object. * <p> * Note: can take a while...</p> */ public DsaParameters GenerateParameters() { byte[] seed = new byte[20]; byte[] part1 = new byte[20]; byte[] part2 = new byte[20]; byte[] u = new byte[20]; Sha1Digest sha1 = new Sha1Digest(); int n = (size - 1) / 160; byte[] w = new byte[size / 8]; BigInteger q = null, p = null, g = null; int counter = 0; bool primesFound = false; while (!primesFound) { do { random.NextBytes(seed); sha1.BlockUpdate(seed, 0, seed.Length); sha1.DoFinal(part1, 0); Array.Copy(seed, 0, part2, 0, seed.Length); Add(part2, seed, 1); sha1.BlockUpdate(part2, 0, part2.Length); sha1.DoFinal(part2, 0); for (int i = 0; i != u.Length; i++) { u[i] = (byte)(part1[i] ^ part2[i]); } u[0] |= (byte)0x80; u[19] |= (byte)0x01; q = new BigInteger(1, u); } while (!q.IsProbablePrime(certainty)); counter = 0; int offset = 2; while (counter < 4096) { for (int k = 0; k < n; k++) { Add(part1, seed, offset + k); sha1.BlockUpdate(part1, 0, part1.Length); sha1.DoFinal(part1, 0); Array.Copy(part1, 0, w, w.Length - (k + 1) * part1.Length, part1.Length); } Add(part1, seed, offset + n); sha1.BlockUpdate(part1, 0, part1.Length); sha1.DoFinal(part1, 0); Array.Copy(part1, part1.Length - ((w.Length - (n) * part1.Length)), w, 0, w.Length - n * part1.Length); w[0] |= (byte)0x80; BigInteger x = new BigInteger(1, w); BigInteger c = x.Mod(q.ShiftLeft(1)); p = x.Subtract(c.Subtract(BigInteger.One)); if (p.TestBit(size - 1)) { if (p.IsProbablePrime(certainty)) { primesFound = true; break; } } counter += 1; offset += n + 1; } } // // calculate the generator g // BigInteger pMinusOneOverQ = p.Subtract(BigInteger.One).Divide(q); for (;;) { BigInteger h = new BigInteger(size, random); if (h.CompareTo(BigInteger.One) <= 0 || h.CompareTo(p.Subtract(BigInteger.One)) >= 0) { continue; } g = h.ModPow(pMinusOneOverQ, p); if (g.CompareTo(BigInteger.One) <= 0) { continue; } break; } return new DsaParameters(p, q, g, new DsaValidationParameters(seed, counter)); }
public void TestModPow() { try { two.ModPow(one, zero); Assert.Fail("expected ArithmeticException"); } catch (ArithmeticException) {} Assert.AreEqual(zero, zero.ModPow(zero, one)); Assert.AreEqual(one, zero.ModPow(zero, two)); Assert.AreEqual(zero, two.ModPow(one, one)); Assert.AreEqual(one, two.ModPow(zero, two)); for (int i = 0; i < 10; ++i) { BigInteger m = BigInteger.ProbablePrime(10 + i * 3, random); BigInteger x = new BigInteger(m.BitLength - 1, random); Assert.AreEqual(x, x.ModPow(m, m)); if (x.SignValue != 0) { Assert.AreEqual(zero, zero.ModPow(x, m)); Assert.AreEqual(one, x.ModPow(m.Subtract(one), m)); } BigInteger y = new BigInteger(m.BitLength - 1, random); BigInteger n = new BigInteger(m.BitLength - 1, random); BigInteger n3 = n.ModPow(three, m); BigInteger resX = n.ModPow(x, m); BigInteger resY = n.ModPow(y, m); BigInteger res = resX.Multiply(resY).Mod(m); BigInteger res3 = res.ModPow(three, m); Assert.AreEqual(res3, n3.ModPow(x.Add(y), m)); BigInteger a = x.Add(one); // Make sure it's not zero BigInteger b = y.Add(one); // Make sure it's not zero Assert.AreEqual(a.ModPow(b, m).ModInverse(m), a.ModPow(b.Negate(), m)); } }
private static bool ImplMRProbablePrimeToBase(BigInteger w, BigInteger wSubOne, BigInteger m, int a, BigInteger b) { BigInteger z = b.ModPow(m, w); if (z.Equals(One) || z.Equals(wSubOne)) return true; bool result = false; for (int j = 1; j < a; ++j) { z = z.ModPow(Two, w); if (z.Equals(wSubOne)) { result = true; break; } if (z.Equals(One)) return false; } return result; }
/// <summary> /// Validates the zero knowledge proof (generated by /// calculateZeroKnowledgeProof(BigInteger, BigInteger, BigInteger, BigInteger, BigInteger, string, Digest, SecureRandom) /// is correct. /// /// throws CryptoException if the zero knowledge proof is not correct /// </summary> public static void ValidateZeroKnowledgeProof(BigInteger p, BigInteger q, BigInteger g, BigInteger gx, BigInteger[] zeroKnowledgeProof, string participantId, IDigest digest) { /* sig={g^v,r} */ BigInteger gv = zeroKnowledgeProof[0]; BigInteger r = zeroKnowledgeProof[1]; BigInteger h = CalculateHashForZeroKnowledgeProof(g, gv, gx, participantId, digest); if (!(gx.CompareTo(Zero) == 1 && // g^x > 0 gx.CompareTo(p) == -1 && // g^x < p gx.ModPow(q, p).CompareTo(One) == 0 && // g^x^q mod q = 1 /* * Below, I took a straightforward way to compute g^r * g^x^h, * which needs 2 exp. Using a simultaneous computation technique * would only need 1 exp. */ g.ModPow(r, p).Multiply(gx.ModPow(h, p)).Mod(p).CompareTo(gv) == 0)) // g^v=g^r * g^x^h { throw new CryptoException("Zero-knowledge proof validation failed"); } }
/** * 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; } } } }
/// <summary> /// Calculates the keying material, which can be done after round 2 has completed. /// A session key must be derived from this key material using a secure key derivation function (KDF). /// The KDF used to derive the key is handled externally (i.e. not by JPAKEParticipant). /// /// KeyingMaterial = (B/g^{x2*x4*s})^x2 /// </summary> public static BigInteger CalculateKeyingMaterial(BigInteger p, BigInteger q, BigInteger gx4, BigInteger x2, BigInteger s, BigInteger B) { return gx4.ModPow(x2.Multiply(s).Negate().Mod(q), p).Multiply(B).ModPow(x2, p); }
private static 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; }
/// <summary> /// Calculate g^x mod p as done in round 1. /// </summary> public static BigInteger CalculateGx(BigInteger p, BigInteger g, BigInteger x) { return g.ModPow(x, p); }
public virtual 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); }
private bool VerifyZKProofA(byte hash_number, BigInteger r, BigInteger c, BigInteger d) { BigInteger _temp_2 = GENERATOR.ModPow(d, PRIME_MODULO); BigInteger _temp_3 = _session_object.G_3x.ModPow(c, PRIME_MODULO); BigInteger _temp_1 = _temp_2.Multiply(_temp_3).Mod(PRIME_MODULO); _temp_3 = _session_object.Qa_Qb.ModPow(d, PRIME_MODULO); _temp_2 = r.ModPow(c, PRIME_MODULO); _temp_2 = _temp_3.Multiply(_temp_2).Mod(PRIME_MODULO); BigInteger _computed_hashed_c = SMPHash(hash_number, _temp_1, _temp_2); return _computed_hashed_c.Equals(c); }