private void CheckTestCase( ChaCha20Poly1305 encCipher, ChaCha20Poly1305 decCipher, string testName, byte[] SA, byte[] P, byte[] C, byte[] T) { byte[] enc = new byte[encCipher.GetOutputSize(P.Length)]; if (SA != null) { encCipher.ProcessAadBytes(SA, 0, SA.Length); } int len = encCipher.ProcessBytes(P, 0, P.Length, enc, 0); len += encCipher.DoFinal(enc, len); if (enc.Length != len) { Fail("encryption reported incorrect length: " + testName); } byte[] mac = encCipher.GetMac(); byte[] data = new byte[P.Length]; Array.Copy(enc, 0, data, 0, data.Length); byte[] tail = new byte[enc.Length - P.Length]; Array.Copy(enc, P.Length, tail, 0, tail.Length); if (!AreEqual(C, data)) { Fail("incorrect encrypt in: " + testName); } if (!AreEqual(T, mac)) { Fail("getMac() returned wrong mac in: " + testName); } if (!AreEqual(T, tail)) { Fail("stream contained wrong mac in: " + testName); } byte[] dec = new byte[decCipher.GetOutputSize(enc.Length)]; if (SA != null) { decCipher.ProcessAadBytes(SA, 0, SA.Length); } len = decCipher.ProcessBytes(enc, 0, enc.Length, dec, 0); len += decCipher.DoFinal(dec, len); mac = decCipher.GetMac(); data = new byte[C.Length]; Array.Copy(dec, 0, data, 0, data.Length); if (!AreEqual(P, data)) { Fail("incorrect decrypt in: " + testName); } }
private void RandomTest(SecureRandom random) { int kLength = 32; byte[] K = new byte[kLength]; random.NextBytes(K); int pHead = random.Next(256); int pLength = random.Next(65536); int pTail = random.Next(256); byte[] P = new byte[pHead + pLength + pTail]; random.NextBytes(P); int aLength = random.Next(256); byte[] A = new byte[aLength]; random.NextBytes(A); int saLength = random.Next(256); byte[] SA = new byte[saLength]; random.NextBytes(SA); int nonceLength = 12; byte[] nonce = new byte[nonceLength]; random.NextBytes(nonce); AeadParameters parameters = new AeadParameters(new KeyParameter(K), 16 * 8, nonce, A); ChaCha20Poly1305 cipher = InitCipher(true, parameters); int ctLength = cipher.GetOutputSize(pLength); byte[] C = new byte[saLength + ctLength]; Array.Copy(SA, 0, C, 0, saLength); int split = NextInt(random, saLength + 1); cipher.ProcessAadBytes(C, 0, split); cipher.ProcessAadBytes(C, split, saLength - split); int predicted = cipher.GetUpdateOutputSize(pLength); int len = cipher.ProcessBytes(P, pHead, pLength, C, saLength); if (predicted != len) { Fail("encryption reported incorrect update length in randomised test"); } len += cipher.DoFinal(C, saLength + len); if (ctLength != len) { Fail("encryption reported incorrect length in randomised test"); } byte[] encT = cipher.GetMac(); byte[] tail = new byte[ctLength - pLength]; Array.Copy(C, saLength + pLength, tail, 0, tail.Length); if (!AreEqual(encT, tail)) { Fail("stream contained wrong mac in randomised test"); } cipher.Init(false, parameters); int decPHead = random.Next(256); int decPLength = cipher.GetOutputSize(ctLength); int decPTail = random.Next(256); byte[] decP = new byte[decPHead + decPLength + decPTail]; split = NextInt(random, saLength + 1); cipher.ProcessAadBytes(C, 0, split); cipher.ProcessAadBytes(C, split, saLength - split); predicted = cipher.GetUpdateOutputSize(ctLength); len = cipher.ProcessBytes(C, saLength, ctLength, decP, decPHead); if (predicted != len) { Fail("decryption reported incorrect update length in randomised test"); } len += cipher.DoFinal(decP, decPHead + len); if (!AreEqual(P, pHead, pHead + pLength, decP, decPHead, decPHead + decPLength)) { Fail("incorrect decrypt in randomised test"); } byte[] decT = cipher.GetMac(); if (!AreEqual(encT, decT)) { Fail("decryption produced different mac from encryption"); } // // key reuse test // cipher.Init(false, AeadTestUtilities.ReuseKey(parameters)); decPHead = random.Next(256); decPLength = cipher.GetOutputSize(ctLength); decPTail = random.Next(256); decP = new byte[decPHead + decPLength + decPTail]; split = NextInt(random, saLength + 1); cipher.ProcessAadBytes(C, 0, split); cipher.ProcessAadBytes(C, split, saLength - split); len = cipher.ProcessBytes(C, saLength, ctLength, decP, decPHead); len += cipher.DoFinal(decP, decPHead + len); if (!AreEqual(P, pHead, pHead + pLength, decP, decPHead, decPHead + decPLength)) { Fail("incorrect decrypt in randomised test"); } decT = cipher.GetMac(); if (!AreEqual(encT, decT)) { Fail("decryption produced different mac from encryption"); } }