package org.bouncycastle.crypto.test;
import org.bouncycastle.crypto.InvalidCipherTextException;
import org.bouncycastle.crypto.engines.SerpentEngine;
import org.bouncycastle.crypto.modes.CBCBlockCipher;
import org.bouncycastle.crypto.modes.EAXBlockCipher;
import org.bouncycastle.crypto.paddings.PKCS7Padding;
import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher;
import org.bouncycastle.crypto.params.AEADParameters;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.crypto.params.ParametersWithIV;
import org.bouncycastle.util.Arrays;
import org.bouncycastle.util.Strings;
import org.bouncycastle.util.encoders.Hex;
import org.bouncycastle.util.test.SimpleTest;
public class SerpentTest
extends CipherTest
{
static SimpleTest[] tests =
{
new BlockCipherVectorTest(0, new SerpentEngine(),
new KeyParameter(Hex.decode("00000000000000000000000000000000")),
"00000000000000000000000000000000", "3620b17ae6a993d09618b8768266bae9"),
new BlockCipherVectorTest(1, new SerpentEngine(),
new KeyParameter(Hex.decode("80000000000000000000000000000000")),
"00000000000000000000000000000000", "264E5481EFF42A4606ABDA06C0BFDA3D"),
new BlockCipherVectorTest(2, new SerpentEngine(),
new KeyParameter(Hex.decode("D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9")),
"D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9", "20EA07F19C8E93FDA30F6B822AD5D486"),
new BlockCipherVectorTest(3, new SerpentEngine(),
new KeyParameter(Hex.decode("000000000000000000000000000000000000000000008000")),
"00000000000000000000000000000000", "40520018C4AC2BBA285AEEB9BCB58755"),
new BlockCipherVectorTest(4, new SerpentEngine(),
new KeyParameter(Hex.decode("0000000000000000000000000000000000000000000000000000000000000000")),
"00000000000000000000000000000001", "AD86DE83231C3203A86AE33B721EAA9F"),
new BlockCipherVectorTest(5, new SerpentEngine(),
new KeyParameter(Hex.decode("000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F")),
"3DA46FFA6F4D6F30CD258333E5A61369", "00112233445566778899AABBCCDDEEFF"),
new BlockCipherVectorTest(6, new SerpentEngine(),
new KeyParameter(Hex.decode("2BD6459F82C5B300952C49104881FF482BD6459F82C5B300952C49104881FF48")),
"677C8DFAA08071743FD2B415D1B28AF2", "EA024714AD5C4D84EA024714AD5C4D84"),
new BlockCipherVectorTest(7, new SerpentEngine(),
new KeyParameter(Hex.decode("000102030405060708090A0B0C0D0E0F1011121314151617")),
"4528CACCB954D450655E8CFD71CBFAC7", "00112233445566778899AABBCCDDEEFF"),
new BlockCipherVectorTest(8, new SerpentEngine(),
new KeyParameter(Hex.decode("2BD6459F82C5B300952C49104881FF482BD6459F82C5B300")),
"E0208BE278E21420C4B1B9747788A954", "EA024714AD5C4D84EA024714AD5C4D84"),
new BlockCipherVectorTest(9, new SerpentEngine(),
new KeyParameter(Hex.decode("000102030405060708090A0B0C0D0E0F")),
"33B3DC87EDDD9B0F6A1F407D14919365", "00112233445566778899AABBCCDDEEFF"),
new BlockCipherVectorTest(10, new SerpentEngine(),
new KeyParameter(Hex.decode("2BD6459F82C5B300952C49104881FF48")),
"BEB6C069393822D3BE73FF30525EC43E", "EA024714AD5C4D84EA024714AD5C4D84"),
new BlockCipherMonteCarloTest(20, 100, new SerpentEngine(),
new KeyParameter(Hex.decode("F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3")),
"F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3", "8FD0E58DB7A54B929FCA6A12F96F20AF"),
new BlockCipherMonteCarloTest(21, 100, new SerpentEngine(),
new KeyParameter(Hex.decode("0004000000000000000000000000000000000000000000000000000000000000")),
"00000000000000000000000000000000", "E7B681E8871FD05FEAE5FB64DA891EA2"),
new BlockCipherMonteCarloTest(22, 100, new SerpentEngine(),
new KeyParameter(Hex.decode("0000000020000000000000000000000000000000000000000000000000000000")),
"00000000000000000000000000000000", "C5545D516EEC73BFA3622A8194F95620"),
new BlockCipherMonteCarloTest(23, 100, new SerpentEngine(),
new KeyParameter(Hex.decode("0000000000000000000000000000000000000000000000000000000002000000")),
"00000000000000000000000000000000", "11FF5C9BE006F82C98BD4FAC1A19920E"),
new BlockCipherMonteCarloTest(24, 100, new SerpentEngine(),
new KeyParameter(Hex.decode("0000000000000000000000000000000000000000000000000000000000000000")),
"00000000000000000000000000010000", "47CA1CA404B6481CAD4C21C8A0415A0E"),
new BlockCipherMonteCarloTest(25, 100, new SerpentEngine(),
new KeyParameter(Hex.decode("0000000000000000000000000000000000000000000000000000000000000000")),
"00000000000000008000000000000000", "A0A2D5B07E27D539CA5BEE9DE1EAB3E6")
};
SerpentTest()
{
super(tests, new SerpentEngine(), new KeyParameter(new byte[32]));
}
public void performTest()
throws Exception
{
super.performTest();
doCbc(Hex.decode("BE4295539F6BD1752FD0A80229EF8847"), Hex.decode("00963F59224794D5AD4252094358FBC3"), Strings.toByteArray("CBC Mode Test"), Hex.decode("CF2CF2547E02F6D34D97246E8042ED89"));
doEax(Hex.decode("7494A57648FB420043BFBFC5639EB82D"), Hex.decode("6DF94638B83E01458F3E30C9A1D6AF1C"), Strings.toByteArray("EAX Mode Test"), new byte[0], 128, Hex.decode("96C521F32DC5E9BBC369DDE4914CB13B710EEBBAB7D706D3ABE06A99DC"));
}
private void doEax(byte[] key, byte[] iv, byte[] pt, byte[] aad, int tagLength, byte[] expected)
throws InvalidCipherTextException
{
EAXBlockCipher c = new EAXBlockCipher(new SerpentEngine());
c.init(true, new AEADParameters(new KeyParameter(key), tagLength, iv, aad));
byte[] out = new byte[expected.length];
int len = c.processBytes(pt, 0, pt.length, out, 0);
c.doFinal(out, len);
if (!Arrays.areEqual(expected, out))
{
fail("EAX test failed");
}
}
private void doCbc(byte[] key, byte[] iv, byte[] pt, byte[] expected)
throws Exception
{
PaddedBufferedBlockCipher c = new PaddedBufferedBlockCipher(new CBCBlockCipher(new SerpentEngine()), new PKCS7Padding());
byte[] ct = new byte[expected.length];
c.init(true, new ParametersWithIV(new KeyParameter(key), iv));
int l = c.processBytes(pt, 0, pt.length, ct, 0);
c.doFinal(ct, l);
if (!Arrays.areEqual(expected, ct))
{
fail("CBC test failed");
}
}
public String getName()
{
return "Serpent";
}
public static void main(
String[] args)
{
runTest(new SerpentTest());
}
}