001: package org.bouncycastle.crypto.test;
002:
003: import org.bouncycastle.crypto.CipherParameters;
004: import org.bouncycastle.crypto.StreamCipher;
005: import org.bouncycastle.crypto.engines.Salsa20Engine;
006: import org.bouncycastle.crypto.params.KeyParameter;
007: import org.bouncycastle.crypto.params.ParametersWithIV;
008: import org.bouncycastle.util.encoders.Hex;
009: import org.bouncycastle.util.test.SimpleTest;
010:
011: /**
012: * Salsa20 Test
013: */
014: public class Salsa20Test extends SimpleTest {
015: byte[] zeroes = Hex.decode("00000000000000000000000000000000"
016: + "00000000000000000000000000000000"
017: + "00000000000000000000000000000000"
018: + "00000000000000000000000000000000");
019:
020: String set1v0_0 = "4DFA5E481DA23EA09A31022050859936"
021: + "DA52FCEE218005164F267CB65F5CFD7F"
022: + "2B4F97E0FF16924A52DF269515110A07"
023: + "F9E460BC65EF95DA58F740B7D1DBB0AA";
024:
025: String set1v0_192 = "DA9C1581F429E0A00F7D67E23B730676"
026: + "783B262E8EB43A25F55FB90B3E753AEF"
027: + "8C6713EC66C51881111593CCB3E8CB8F"
028: + "8DE124080501EEEB389C4BCB6977CF95";
029:
030: String set1v0_256 = "7D5789631EB4554400E1E025935DFA7B"
031: + "3E9039D61BDC58A8697D36815BF1985C"
032: + "EFDF7AE112E5BB81E37ECF0616CE7147"
033: + "FC08A93A367E08631F23C03B00A8DA2F";
034:
035: String set1v0_448 = "B375703739DACED4DD4059FD71C3C47F"
036: + "C2F9939670FAD4A46066ADCC6A564578"
037: + "3308B90FFB72BE04A6B147CBE38CC0C3"
038: + "B9267C296A92A7C69873F9F263BE9703";
039:
040: String set1v9_0 = "0471076057830FB99202291177FBFE5D"
041: + "38C888944DF8917CAB82788B91B53D1C"
042: + "FB06D07A304B18BB763F888A61BB6B75"
043: + "5CD58BEC9C4CFB7569CB91862E79C459";
044:
045: String set1v9_192 = "D1D7E97556426E6CFC21312AE3811425"
046: + "9E5A6FB10DACBD88E4354B0472556935"
047: + "2B6DA5ACAFACD5E266F9575C2ED8E6F2"
048: + "EFE4B4D36114C3A623DD49F4794F865B";
049:
050: String set1v9_256 = "AF06FAA82C73291231E1BD916A773DE1"
051: + "52FD2126C40A10C3A6EB40F22834B8CC"
052: + "68BD5C6DBD7FC1EC8F34165C517C0B63"
053: + "9DB0C60506D3606906B8463AA0D0EC2F";
054:
055: String set1v9_448 = "AB3216F1216379EFD5EC589510B8FD35"
056: + "014D0AA0B613040BAE63ECAB90A9AF79"
057: + "661F8DA2F853A5204B0F8E72E9D9EB4D"
058: + "BA5A4690E73A4D25F61EE7295215140C";
059:
060: String set6v0_0 = "F5FAD53F79F9DF58C4AEA0D0ED9A9601"
061: + "F278112CA7180D565B420A48019670EA"
062: + "F24CE493A86263F677B46ACE1924773D"
063: + "2BB25571E1AA8593758FC382B1280B71";
064:
065: String set6v0_65472 = "B70C50139C63332EF6E77AC54338A407"
066: + "9B82BEC9F9A403DFEA821B83F7860791"
067: + "650EF1B2489D0590B1DE772EEDA4E3BC"
068: + "D60FA7CE9CD623D9D2FD5758B8653E70";
069:
070: String set6v0_65536 = "81582C65D7562B80AEC2F1A673A9D01C"
071: + "9F892A23D4919F6AB47B9154E08E699B"
072: + "4117D7C666477B60F8391481682F5D95"
073: + "D96623DBC489D88DAA6956B9F0646B6E";
074:
075: String set6v1_0 = "3944F6DC9F85B128083879FDF190F7DE"
076: + "E4053A07BC09896D51D0690BD4DA4AC1"
077: + "062F1E47D3D0716F80A9B4D85E6D6085"
078: + "EE06947601C85F1A27A2F76E45A6AA87";
079:
080: String set6v1_65472 = "36E03B4B54B0B2E04D069E690082C8C5"
081: + "92DF56E633F5D8C7682A02A65ECD1371"
082: + "8CA4352AACCB0DA20ED6BBBA62E177F2"
083: + "10E3560E63BB822C4158CAA806A88C82";
084:
085: String set6v1_65536 = "1B779E7A917C8C26039FFB23CF0EF8E0"
086: + "8A1A13B43ACDD9402CF5DF38501098DF"
087: + "C945A6CC69A6A17367BC03431A86B3ED"
088: + "04B0245B56379BF997E25800AD837D7D";
089:
090: public String getName() {
091: return "Salsa20";
092: }
093:
094: public void performTest() {
095: salsa20Test1(new ParametersWithIV(new KeyParameter(Hex
096: .decode("80000000000000000000000000000000")), Hex
097: .decode("0000000000000000")), set1v0_0, set1v0_192,
098: set1v0_256, set1v0_448);
099: salsa20Test1(new ParametersWithIV(new KeyParameter(Hex
100: .decode("00400000000000000000000000000000")), Hex
101: .decode("0000000000000000")), set1v9_0, set1v9_192,
102: set1v9_256, set1v9_448);
103: salsa20Test2(
104: new ParametersWithIV(
105: new KeyParameter(
106: Hex
107: .decode("0053A6F94C9FF24598EB3E91E4378ADD3083D6297CCF2275C81B6EC11467BA0D")),
108: Hex.decode("0D74DB42A91077DE")), set6v0_0,
109: set6v0_65472, set6v0_65536);
110: salsa20Test2(
111: new ParametersWithIV(
112: new KeyParameter(
113: Hex
114: .decode("0558ABFE51A4F74A9DF04396E93C8FE23588DB2E81D4277ACD2073C6196CBF12")),
115: Hex.decode("167DE44BB21980E7")), set6v1_0,
116: set6v1_65472, set6v1_65536);
117: reinitBug();
118: }
119:
120: private void salsa20Test1(CipherParameters params, String v0,
121: String v192, String v256, String v448) {
122: StreamCipher salsa = new Salsa20Engine();
123: byte[] buf = new byte[64];
124:
125: salsa.init(true, params);
126:
127: for (int i = 0; i != 7; i++) {
128: salsa.processBytes(zeroes, 0, 64, buf, 0);
129: switch (i) {
130: case 0:
131: if (!areEqual(buf, Hex.decode(v0))) {
132: mismatch("v0", v0, buf);
133: }
134: break;
135: case 3:
136: if (!areEqual(buf, Hex.decode(v192))) {
137: mismatch("v192", v192, buf);
138: }
139: break;
140: case 4:
141: if (!areEqual(buf, Hex.decode(v256))) {
142: mismatch("v256", v256, buf);
143: }
144: break;
145: default:
146: // ignore
147: }
148: }
149:
150: for (int i = 0; i != 64; i++) {
151: buf[i] = salsa.returnByte(zeroes[i]);
152: }
153:
154: if (!areEqual(buf, Hex.decode(v448))) {
155: mismatch("v448", v448, buf);
156: }
157: }
158:
159: private void salsa20Test2(CipherParameters params, String v0,
160: String v65472, String v65536) {
161: StreamCipher salsa = new Salsa20Engine();
162: byte[] buf = new byte[64];
163:
164: salsa.init(true, params);
165:
166: for (int i = 0; i != 1025; i++) {
167: salsa.processBytes(zeroes, 0, 64, buf, 0);
168: switch (i) {
169: case 0:
170: if (!areEqual(buf, Hex.decode(v0))) {
171: mismatch("v0", v0, buf);
172: }
173: break;
174: case 1023:
175: if (!areEqual(buf, Hex.decode(v65472))) {
176: mismatch("v65472", v65472, buf);
177: }
178: break;
179: case 1024:
180: if (!areEqual(buf, Hex.decode(v65536))) {
181: mismatch("v65536", v65536, buf);
182: }
183: break;
184: default:
185: // ignore
186: }
187: }
188: }
189:
190: private void mismatch(String name, String expected, byte[] found) {
191: fail("mismatch on " + name, expected, new String(Hex
192: .encode(found)));
193: }
194:
195: private void reinitBug() {
196: KeyParameter key = new KeyParameter(Hex
197: .decode("80000000000000000000000000000000"));
198: ParametersWithIV parameters = new ParametersWithIV(key, Hex
199: .decode("0000000000000000"));
200:
201: StreamCipher salsa = new Salsa20Engine();
202:
203: salsa.init(true, parameters);
204:
205: try {
206: salsa.init(true, key);
207: fail("Salsa20 should throw exception if no IV in Init");
208: } catch (IllegalArgumentException e) {
209: }
210: }
211:
212: public static void main(String[] args) {
213: runTest(new Salsa20Test());
214: }
215: }
|