org.bouncycastle.crypto.test.NaccacheSternTest Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of bcprov-jdk15to18 Show documentation
Show all versions of bcprov-jdk15to18 Show documentation
The Bouncy Castle Crypto package is a Java implementation of cryptographic algorithms. This jar contains JCE provider and lightweight API for the Bouncy Castle Cryptography APIs for JDK 1.5 to JDK 1.8.
package org.bouncycastle.crypto.test;
import java.math.BigInteger;
import java.security.SecureRandom;
import java.util.Vector;
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
import org.bouncycastle.crypto.InvalidCipherTextException;
import org.bouncycastle.crypto.engines.NaccacheSternEngine;
import org.bouncycastle.crypto.generators.NaccacheSternKeyPairGenerator;
import org.bouncycastle.crypto.params.NaccacheSternKeyGenerationParameters;
import org.bouncycastle.crypto.params.NaccacheSternKeyParameters;
import org.bouncycastle.crypto.params.NaccacheSternPrivateKeyParameters;
import org.bouncycastle.util.encoders.Hex;
import org.bouncycastle.util.test.SimpleTest;
/**
* Test case for NaccacheStern cipher. For details on this cipher, please see
*
* https://www.gemplus.com/smart/rd/publications/pdf/NS98pkcs.pdf
*
* Performs the following tests:
*
* - Toy example from the NaccacheSternPaper
* - 768 bit test with text "Now is the time for all good men." (ripped from RSA test) and
* the same test with the first byte replaced by 0xFF
* - 1024 bit test analog to 768 bit test
*
*/
public class NaccacheSternTest
extends SimpleTest
{
static final boolean debug = false;
static final NaccacheSternEngine cryptEng = new NaccacheSternEngine();
static final NaccacheSternEngine decryptEng = new NaccacheSternEngine();
// Values from NaccacheStern paper
static final BigInteger a = BigInteger.valueOf(101);
static final BigInteger u1 = BigInteger.valueOf(3);
static final BigInteger u2 = BigInteger.valueOf(5);
static final BigInteger u3 = BigInteger.valueOf(7);
static final BigInteger b = BigInteger.valueOf(191);
static final BigInteger v1 = BigInteger.valueOf(11);
static final BigInteger v2 = BigInteger.valueOf(13);
static final BigInteger v3 = BigInteger.valueOf(17);
static final BigInteger ONE = BigInteger.valueOf(1);
static final BigInteger TWO = BigInteger.valueOf(2);
static final BigInteger sigma = u1.multiply(u2).multiply(u3).multiply(v1)
.multiply(v2).multiply(v3);
static final BigInteger p = TWO.multiply(a).multiply(u1).multiply(u2)
.multiply(u3).add(ONE);
static final BigInteger q = TWO.multiply(b).multiply(v1).multiply(v2)
.multiply(v3).add(ONE);
static final BigInteger n = p.multiply(q);
static final BigInteger phi_n = p.subtract(ONE).multiply(q.subtract(ONE));
static final BigInteger g = BigInteger.valueOf(131);
static final Vector smallPrimes = new Vector();
// static final BigInteger paperTest = BigInteger.valueOf(202);
static final String input = "4e6f77206973207468652074696d6520666f7220616c6c20676f6f64206d656e";
static final BigInteger paperTest = BigInteger.valueOf(202);
//
// to check that we handling byte extension by big number correctly.
//
static final String edgeInput = "ff6f77206973207468652074696d6520666f7220616c6c20676f6f64206d656e";
static
{
cryptEng.setDebug(debug);
decryptEng.setDebug(debug);
// First the Parameters from the NaccacheStern Paper
// (see https://www.gemplus.com/smart/rd/publications/pdf/NS98pkcs.pdf )
smallPrimes.addElement(u1);
smallPrimes.addElement(u2);
smallPrimes.addElement(u3);
smallPrimes.addElement(v1);
smallPrimes.addElement(v2);
smallPrimes.addElement(v3);
}
public String getName()
{
return "NaccacheStern";
}
public void performTest()
{
// Test with given key from NaccacheSternPaper (totally insecure)
NaccacheSternKeyParameters pubParameters = new NaccacheSternKeyParameters(false, g, n, sigma.bitLength());
NaccacheSternPrivateKeyParameters privParameters = new NaccacheSternPrivateKeyParameters(g, n, sigma.bitLength(), smallPrimes, phi_n);
AsymmetricCipherKeyPair pair = new AsymmetricCipherKeyPair(pubParameters, privParameters);
// Initialize Engines with KeyPair
if (debug)
{
System.out.println("initializing encryption engine");
}
cryptEng.init(true, pair.getPublic());
if (debug)
{
System.out.println("initializing decryption engine");
}
decryptEng.init(false, pair.getPrivate());
byte[] data = paperTest.toByteArray();
if (!new BigInteger(data).equals(new BigInteger(enDeCrypt(data))))
{
fail("failed NaccacheStern paper test");
}
//
// key generation test
//
//
// 768 Bit test
//
if (debug)
{
System.out.println();
System.out.println("768 Bit TEST");
}
// specify key generation parameters
NaccacheSternKeyGenerationParameters genParam
= new NaccacheSternKeyGenerationParameters(new SecureRandom(), 768, 8, 30, debug);
// Initialize Key generator and generate key pair
NaccacheSternKeyPairGenerator pGen = new NaccacheSternKeyPairGenerator();
pGen.init(genParam);
pair = pGen.generateKeyPair();
if (((NaccacheSternKeyParameters)pair.getPublic()).getModulus().bitLength() < 768)
{
System.out.println("FAILED: key size is <786 bit, exactly "
+ ((NaccacheSternKeyParameters)pair.getPublic()).getModulus().bitLength() + " bit");
fail("failed key generation (768) length test");
}
// Initialize Engines with KeyPair
if (debug)
{
System.out.println("initializing " + genParam.getStrength() + " bit encryption engine");
}
cryptEng.init(true, pair.getPublic());
if (debug)
{
System.out.println("initializing " + genParam.getStrength() + " bit decryption engine");
}
decryptEng.init(false, pair.getPrivate());
// Basic data input
data = Hex.decode(input);
if (!new BigInteger(1, data).equals(new BigInteger(1, enDeCrypt(data))))
{
fail("failed encryption decryption (" + genParam.getStrength() + ") basic test");
}
// Data starting with FF byte (would be interpreted as negative
// BigInteger)
data = Hex.decode(edgeInput);
if (!new BigInteger(1, data).equals(new BigInteger(1, enDeCrypt(data))))
{
fail("failed encryption decryption (" + genParam.getStrength() + ") edgeInput test");
}
//
// 1024 Bit Test
//
/*
if (debug)
{
System.out.println();
System.out.println("1024 Bit TEST");
}
// specify key generation parameters
genParam = new NaccacheSternKeyGenerationParameters(new SecureRandom(), 1024, 8, 40);
pGen.init(genParam);
pair = pGen.generateKeyPair();
if (((NaccacheSternKeyParameters)pair.getPublic()).getModulus().bitLength() < 1024)
{
if (debug)
{
System.out.println("FAILED: key size is <1024 bit, exactly "
+ ((NaccacheSternKeyParameters)pair.getPublic()).getModulus().bitLength() + " bit");
}
fail("failed key generation (1024) length test");
}
// Initialize Engines with KeyPair
if (debug)
{
System.out.println("initializing " + genParam.getStrength() + " bit encryption engine");
}
cryptEng.init(true, pair.getPublic());
if (debug)
{
System.out.println("initializing " + genParam.getStrength() + " bit decryption engine");
}
decryptEng.init(false, pair.getPrivate());
if (debug)
{
System.out.println("Data is " + new BigInteger(1, data));
}
// Basic data input
data = Hex.decode(input);
if (!new BigInteger(1, data).equals(new BigInteger(1, enDeCrypt(data))))
{
fail("failed encryption decryption (" + genParam.getStrength() + ") basic test");
}
// Data starting with FF byte (would be interpreted as negative
// BigInteger)
data = Hex.decode(edgeInput);
if (!new BigInteger(1, data).equals(new BigInteger(1, enDeCrypt(data))))
{
fail("failed encryption decryption (" + genParam.getStrength() + ") edgeInput test");
}
*/
// END OF TEST CASE
try
{
new NaccacheSternEngine().processBlock(new byte[]{ 1 }, 0, 1);
fail("failed initialisation check");
}
catch (IllegalStateException e)
{
// expected
}
catch (InvalidCipherTextException e)
{
fail("failed initialisation check");
}
if (debug)
{
System.out.println("All tests successful");
}
}
private byte[] enDeCrypt(byte[] input)
{
// create work array
byte[] data = new byte[input.length];
System.arraycopy(input, 0, data, 0, data.length);
// Perform encryption like in the paper from Naccache-Stern
if (debug)
{
System.out.println("encrypting data. Data representation\n"
// + "As String:.... " + new String(data) + "\n"
+ "As BigInteger: " + new BigInteger(1, data));
System.out.println("data length is " + data.length);
}
try
{
data = cryptEng.processData(data);
}
catch (InvalidCipherTextException e)
{
if (debug)
{
System.out.println("failed - exception " + e.toString() + "\n" + e.getMessage());
}
fail("failed - exception " + e.toString() + "\n" + e.getMessage());
}
if (debug)
{
System.out.println("enrypted data representation\n"
// + "As String:.... " + new String(data) + "\n"
+ "As BigInteger: " + new BigInteger(1, data));
System.out.println("data length is " + data.length);
}
try
{
data = decryptEng.processData(data);
}
catch (InvalidCipherTextException e)
{
if (debug)
{
System.out.println("failed - exception " + e.toString() + "\n" + e.getMessage());
}
fail("failed - exception " + e.toString() + "\n" + e.getMessage());
}
if (debug)
{
System.out.println("decrypted data representation\n"
// + "As String:.... " + new String(data) + "\n"
+ "As BigInteger: " + new BigInteger(1, data));
System.out.println("data length is " + data.length);
}
return data;
}
public static void main(String[] args)
{
runTest(new NaccacheSternTest());
}
}