/* * Extra checks: * -- modulus is prime * -- subgroup order is prime * -- generator indeed generates subgroup */ public override void CheckValid() { /* * Check that the modulus is prime. */ if (!BigInt.IsPrime(mod)) { throw new CryptoException( "Invalid curve: modulus is not prime"); } /* * Check that the subgroup order is prime. */ if (!BigInt.IsPrime(SubgroupOrder)) { throw new CryptoException( "Invalid curve: subgroup order is not prime"); } /* * Check that the G point is indeed a generator of the * subgroup. Note that since it has explicit coordinates, * it cannot be the point at infinity; it suffices to * verify that, when multiplied by the subgroup order, * it yields infinity. */ MutableECPointPrime G = new MutableECPointPrime(this); G.Set(gx, gy, false); if (G.MulSpecCT(SubgroupOrder) == 0 || !G.IsInfinity) { throw new CryptoException( "Invalid curve: generator does not match" + " subgroup order"); } /* * TODO: check cofactor. * * If the cofactor is small, then we can simply compute * the complete curve order by multiplying the cofactor * with the subgroup order, and see whether it is in the * proper range with regards to the field cardinal (by * using Hasse's theorem). However, if the cofactor is * larger than the subgroup order, then detecting a * wrong cofactor value is a bit more complex. We could * generate a few random points and multiply them by * the computed order, but this may be expensive. */ }
/* * CheckValid() will verify that the prime factors are indeed * prime, and that all other values are correct. */ public void CheckValid() { /* * Factors ought to be prime. */ if (!BigInt.IsPrime(p) || !BigInt.IsPrime(q)) { throw new CryptoException("Invalid RSA private key" + " (non-prime factor)"); } /* * FIXME: Verify that: * dp = d mod p-1 * e*dp = 1 mod p-1 * dq = d mod q-1 * e*dq = 1 mod q-1 * (This is not easy with existing code because p-1 and q-1 * are even, but ModInt tolerates only odd moduli.) * * CheckExp(p, d, dp, e); * CheckExp(q, d, dq, e); */ /* * Verify that: * q*iq = 1 mod p */ ModInt x = new ModInt(p); ModInt y = x.Dup(); x.DecodeReduce(q); x.ToMonty(); y.Decode(iq); x.MontyMul(y); if (!x.IsOne) { throw new CryptoException("Invalid RSA private key" + " (wrong CRT coefficient)"); } }