/// <summary> /// Check is the key is valid see RFC 2631, Section 2.1.5, http://www.ietf.org/rfc/rfc2631.txt /// </summary> public static bool IsValidPublicKey(Org.BouncyCastle.Math.BigInteger y, Org.BouncyCastle.Math.BigInteger p, Org.BouncyCastle.Math.BigInteger q) { Org.BouncyCastle.Math.BigInteger bn; // y must lie in [2,p-1] // check y < 2 then failed bn = new Org.BouncyCastle.Math.BigInteger("2"); if (y.CompareTo(bn) < 0) { LibRTMPLogger.Log(LibRTMPLogLevel.Warning, "[CDR.LibRTMP.RTMPHelper.IsValidPublicKey] DH public key must be at least 2"); return false; } // y must lie in [2,p-1] bn = new Org.BouncyCastle.Math.BigInteger(p.ToString()); bn = bn.Subtract(new Org.BouncyCastle.Math.BigInteger("1")); if (y.CompareTo(bn) > 0) { LibRTMPLogger.Log(LibRTMPLogLevel.Warning, "[CDR.LibRTMP.RTMPHelper.IsValidPublicKey] DH public key must be at most p-2"); return false; } // Verify with Sophie-Germain prime // // This is a nice test to make sure the public key position is calculated // correctly. This test will fail in about 50% of the cases if applied to // random data. bn = y.ModPow(q, p); if (bn.CompareTo(new Org.BouncyCastle.Math.BigInteger("1")) != 0) { LibRTMPLogger.Log(LibRTMPLogLevel.Warning, "[CDR.LibRTMP.RTMPHelper.IsValidPublicKey] DH public key does not fulfill y^q mod p = 1"); return false; } return true; }