package gnu.testlet.gnu.crypto.key.rsa; // ---------------------------------------------------------------------------- // $Id: TestOfRSAKeyGeneration.java,v 1.3 2005/10/06 04:24:20 rsdio Exp $ // // Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. // // This file is part of GNU Crypto. // // GNU Crypto is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2, or (at your option) // any later version. // // GNU Crypto is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; see the file COPYING. If not, write to the // // Free Software Foundation Inc., // 51 Franklin Street, Fifth Floor, // Boston, MA 02110-1301 // USA // // Linking this library statically or dynamically with other modules is // making a combined work based on this library. Thus, the terms and // conditions of the GNU General Public License cover the whole // combination. // // As a special exception, the copyright holders of this library give // you permission to link this library with independent modules to // produce an executable, regardless of the license terms of these // independent modules, and to copy and distribute the resulting // executable under terms of your choice, provided that you also meet, // for each linked independent module, the terms and conditions of the // license of that module. An independent module is a module which is // not derived from or based on this library. If you modify this // library, you may extend this exception to your version of the // library, but you are not obligated to do so. If you do not wish to // do so, delete this exception statement from your version. // ---------------------------------------------------------------------------- // Tags: GNU-CRYPTO import gnu.crypto.sig.rsa.RSA; import gnu.crypto.key.rsa.RSAKeyPairGenerator; import gnu.crypto.util.Prime; import gnu.testlet.TestHarness; import gnu.testlet.Testlet; import java.math.BigInteger; import java.security.KeyPair; import java.security.PrivateKey; import java.security.PublicKey; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPrivateCrtKey; import java.security.interfaces.RSAPublicKey; import java.util.HashMap; import java.util.Random; /** * <p>Conformance tests for the RSA key-pair generation implementation.</p> * * @version $Revision: 1.3 $ */ public class TestOfRSAKeyGeneration implements Testlet { // Constants and variables // ------------------------------------------------------------------------- private static final BigInteger ZERO = BigInteger.ZERO; private static final BigInteger ONE = BigInteger.ONE; private RSAKeyPairGenerator kpg = new RSAKeyPairGenerator(); private HashMap map = new HashMap(); // Constructor(s) // ------------------------------------------------------------------------- // default 0-arguments constructor // Class methods // ------------------------------------------------------------------------- // Instance methods // ------------------------------------------------------------------------- public void test(TestHarness harness) { testKeyPairGeneration(harness); testRSAParams(harness); testRSAPrimitives(harness); } public void testKeyPairGeneration(TestHarness harness) { harness.checkPoint("TestOfRSAKeyGeneration.testKeyPairGeneration"); try { setUp(); map.put(RSAKeyPairGenerator.MODULUS_LENGTH, new Integer(530)); try { kpg.setup(map); harness.fail("L should be >= 1024"); } catch (IllegalArgumentException x) { harness.check(true, "L should be >= 1024"); } map.put(RSAKeyPairGenerator.MODULUS_LENGTH, new Integer(1024)); kpg.setup(map); KeyPair kp = kpg.generate(); BigInteger n1 = ((RSAPublicKey) kp.getPublic()).getModulus(); BigInteger n2 = ((RSAPrivateKey) kp.getPrivate()).getModulus(); BigInteger p = ((RSAPrivateCrtKey) kp.getPrivate()).getPrimeP(); BigInteger q = ((RSAPrivateCrtKey) kp.getPrivate()).getPrimeQ(); harness.check(n1.equals(p.multiply(q)), "n1 == pq"); harness.check(n2.equals(p.multiply(q)), "n2 == pq"); } catch (Exception x) { harness.debug(x); harness.fail("TestOfRSAPSSSignature.testKeyPairGeneration"); } } public void testRSAParams(TestHarness harness) { harness.checkPoint("TestOfRSAKeyGeneration.testRSAParams"); try { setUp(); map.put(RSAKeyPairGenerator.MODULUS_LENGTH, new Integer(1024)); kpg.setup(map); KeyPair kp = kpg.generate(); BigInteger n1 = ((RSAPublicKey) kp.getPublic()).getModulus(); BigInteger e = ((RSAPublicKey) kp.getPublic()).getPublicExponent(); BigInteger n2 = ((RSAPrivateKey) kp.getPrivate()).getModulus(); BigInteger d = ((RSAPrivateKey) kp.getPrivate()).getPrivateExponent(); BigInteger p = ((RSAPrivateCrtKey) kp.getPrivate()).getPrimeP(); BigInteger q = ((RSAPrivateCrtKey) kp.getPrivate()).getPrimeQ(); BigInteger dP = ((RSAPrivateCrtKey) kp.getPrivate()).getPrimeExponentP(); BigInteger dQ = ((RSAPrivateCrtKey) kp.getPrivate()).getPrimeExponentQ(); BigInteger qInv = ((RSAPrivateCrtKey) kp.getPrivate()).getCrtCoefficient(); harness.check(n1.bitLength() == 1024, "n1 is a 1024-bit MPI"); harness.check(n2.bitLength() == 1024, "n2 is a 1024-bit MPI"); harness.check(n1.equals(n2), "n1 == n2"); // In a valid RSA private key with this representation, the two factors p // and q are the prime factors of the modulus n, harness.check(Prime.isProbablePrime(p), "p is prime"); harness.check(Prime.isProbablePrime(q), "q is prime"); harness.check(n1.equals(p.multiply(q)), "n == pq"); // dP and dQ are positive integers less than p and q respectively BigInteger p_minus_1 = p.subtract(ONE); BigInteger q_minus_1 = q.subtract(ONE); harness.check(ZERO.compareTo(dP) < 0 && dP.compareTo(p_minus_1) < 0, "0 < dP < p-1"); harness.check(ZERO.compareTo(dQ) < 0 && dQ.compareTo(q_minus_1) < 0, "0 < dQ < q-1"); // satisfying // e . dP = 1 (mod p?1); // e . dQ = 1 (mod q?1), harness.check(e.multiply(dP).mod(p_minus_1).equals(ONE), "e.dP == 1 (mod p-1)"); harness.check(e.multiply(dQ).mod(q_minus_1).equals(ONE), "e.dQ == 1 (mod q-1)"); // and the CRT coefficient qInv is a positive integer less than p // satisfying // q . qInv = 1 (mod p). harness.check(q.multiply(qInv).mod(p).equals(ONE), "q.qInv == 1 (mod p)"); BigInteger phi = p_minus_1.multiply(q_minus_1); harness.check(e.gcd(phi).equals(ONE), "gcd(e, phi) == 1"); harness.check(e.multiply(d).mod(phi).equals(ONE), "e.d == 1 (mod phi)"); } catch (Exception x) { harness.debug(x); harness.fail("TestOfRSAPSSSignature.testRSAParams"); } } public void testRSAPrimitives(TestHarness harness) { harness.checkPoint("TestOfRSAKeyGeneration.testRSAPrimitives"); try { setUp(); map.put(RSAKeyPairGenerator.MODULUS_LENGTH, new Integer(1024)); kpg.setup(map); KeyPair kp = kpg.generate(); PublicKey pubK = kp.getPublic(); PrivateKey privK = kp.getPrivate(); BigInteger n = ((RSAPublicKey) pubK).getModulus(); BigInteger m = ZERO; Random prng = new Random(System.currentTimeMillis()); while (m.equals(ZERO) || m.compareTo(n) >= 0) { m = new BigInteger(1024, prng); } BigInteger s = RSA.sign(privK, m); BigInteger cm = RSA.verify(pubK, s); harness.check(cm.equals(m)); } catch (Exception x) { harness.debug(x); harness.fail("TestOfRSAPSSSignature.testRSAPrimitives"); } } // helper methods ---------------------------------------------------------- private void setUp() { kpg = new RSAKeyPairGenerator(); map.clear(); } }