public Init ( ICipherParameters parameters ) : void | ||
parameters | ICipherParameters | a {@link ParametersWithIV} containing a 128 bit nonce and a {@link KeyParameter} with /// a 256 bit key complying to the {@link Poly1305KeyGenerator Poly1305 key format}. |
리턴 | void |
public byte[] Decrypt(byte[] cipher, byte[] key, byte[] iv, byte[] aad = null, byte[] associated = null) { if (key.Length * 8 != this.KeySize) { throw new InvalidOperationException($"the given key has invalid size {key.Length * 8}, expect {this.KeySize}"); } if (iv.Length != 12) { throw new InvalidOperationException($"chacha20 requires 96 bits IV, got {iv.Length * 8}"); } if (cipher.Length <= 16) { throw new ArgumentException($"incorrect argument [cipher] size"); } // split cipher and mac var cipherText = cipher.Take(cipher.Length - 16).ToArray(); var macText = cipher.Skip(cipher.Length - 16).ToArray(); var engine = new Engines.ChaCha7539Engine(); engine.Init(false, new Parameters.ParametersWithIV(new Parameters.KeyParameter(key), iv)); // calculate mac key var mackeyBlock = new byte[64]; engine.ProcessBytes(mackeyBlock, 0, mackeyBlock.Length, mackeyBlock, 0); var mackey = mackeyBlock.Take(32).ToArray(); // calculate mac var poly = new Macs.Poly1305(); poly.Init(new Parameters.KeyParameter(mackey)); PolyUpdateMacText(poly, aad); PolyUpdateMacText(poly, cipherText); PolyUpdateMacLength(poly, aad.Length); PolyUpdateMacLength(poly, cipherText.Length); var myMac = PolyDoFinal(poly); if (!Utils.BytesEqual(myMac, macText)) { throw new ArgumentException("bad record mac"); } // decrypt var plain = new byte[cipherText.Length]; engine.ProcessBytes(cipherText, 0, cipherText.Length, plain, 0); return(plain); }
public byte[] Encrypt(byte[] plain, byte[] key, byte[] iv, byte[] aad = null, byte[] associated = null) { if (key.Length * 8 != this.KeySize) { throw new InvalidOperationException($"the given key has invalid size {key.Length * 8}, expect {this.KeySize}"); } if (iv.Length != 12) { throw new InvalidOperationException($"chacha20 requires 96 bits IV, got {iv.Length * 8}"); } var engine = new Engines.ChaCha7539Engine(); engine.Init(true, new Parameters.ParametersWithIV(new Parameters.KeyParameter(key), iv)); // calculate mac key var mackeyBlock = new byte[64]; engine.ProcessBytes(mackeyBlock, 0, mackeyBlock.Length, mackeyBlock, 0); var mackey = mackeyBlock.Take(32).ToArray(); // encrypt var cipher = new byte[plain.Length]; engine.ProcessBytes(plain, 0, plain.Length, cipher, 0); // calculate mac var poly = new Macs.Poly1305(); poly.Init(new Parameters.KeyParameter(mackey)); PolyUpdateMacText(poly, aad); PolyUpdateMacText(poly, cipher); PolyUpdateMacLength(poly, aad.Length); PolyUpdateMacLength(poly, cipher.Length); var myMac = PolyDoFinal(poly); var cipherBlock = new byte[cipher.Length + myMac.Length]; Buffer.BlockCopy(cipher, 0, cipherBlock, 0, cipher.Length); Buffer.BlockCopy(myMac, 0, cipherBlock, cipher.Length, myMac.Length); return(cipherBlock); }
protected virtual byte[] CalculateRecordMac(KeyParameter macKey, byte[] additionalData, byte[] buf, int off, int len) { IMac mac = new Poly1305(); mac.Init(macKey); UpdateRecordMacText(mac, additionalData, 0, additionalData.Length); UpdateRecordMacText(mac, buf, off, len); UpdateRecordMacLength(mac, additionalData.Length); UpdateRecordMacLength(mac, len); return MacUtilities.DoFinal(mac); }
private void testInit() { CipherKeyGenerator gen = new Poly1305KeyGenerator(); gen.Init(new KeyGenerationParameters(new SecureRandom(), 256)); byte[] k = gen.GenerateKey(); IMac poly = new Poly1305(new AesFastEngine()); poly.Init(new ParametersWithIV(new KeyParameter(k), new byte[16])); try { poly.Init(new ParametersWithIV(new KeyParameter(k), new byte[15])); Fail("16 byte nonce required"); } catch (ArgumentException) { // Expected } try { byte[] k2 = new byte[k.Length - 1]; Array.Copy(k, 0, k2, 0, k2.Length); poly.Init(new ParametersWithIV(new KeyParameter(k2), new byte[16])); Fail("32 byte key required"); } catch (ArgumentException) { // Expected } try { k[19] = (byte)0xFF; poly.Init(new ParametersWithIV(new KeyParameter(k), new byte[16])); Fail("UnClamped key should not be accepted."); } catch (ArgumentException) { // Expected } }
private void testReset() { CipherKeyGenerator gen = new Poly1305KeyGenerator(); gen.Init(new KeyGenerationParameters(new SecureRandom(), 256)); byte[] k = gen.GenerateKey(); byte[] m = new byte[10000]; byte[] check = new byte[16]; byte[] output = new byte[16]; // Generate baseline IMac poly = new Poly1305(new AesFastEngine()); poly.Init(new ParametersWithIV(new KeyParameter(k), new byte[16])); poly.BlockUpdate(m, 0, m.Length); poly.DoFinal(check, 0); // Check reset after doFinal poly.BlockUpdate(m, 0, m.Length); poly.DoFinal(output, 0); if (!Arrays.AreEqual(check, output)) { Fail("Mac not reset after doFinal"); } // Check reset poly.Update((byte)1); poly.Update((byte)2); poly.Reset(); poly.BlockUpdate(m, 0, m.Length); poly.DoFinal(output, 0); if (!Arrays.AreEqual(check, output)) { Fail("Mac not reset after doFinal"); } // Check init resets poly.Update((byte)1); poly.Update((byte)2); poly.Init(new ParametersWithIV(new KeyParameter(k), new byte[16])); poly.BlockUpdate(m, 0, m.Length); poly.DoFinal(output, 0); if (!Arrays.AreEqual(check, output)) { Fail("Mac not reset after doFinal"); } }
private void testSequential() { // Sequential test, adapted from test-poly1305aes int len; byte[] kr = new byte[32]; byte[] m = new byte[MAXLEN]; byte[] n = new byte[16]; byte[] output = new byte[16]; int c = 0; IMac mac = new Poly1305(new AesFastEngine()); for (int loop = 0; loop < 13; loop++) { len = 0; for (;;) { c++; mac.Init(new ParametersWithIV(new KeyParameter(kr), n)); mac.BlockUpdate(m, 0, len); mac.DoFinal(output, 0); // if (c == 678) // { // TestCase tc = CASES[0]; // // if (!Arrays.AreEqual(tc.key, kr)) // { // System.err.println("Key bad"); // System.err.println(Hex.ToHexString(tc.key))); // System.err.println(Hex.ToHexString(kr))); // System.exit(1); // } // if (!Arrays.AreEqual(tc.nonce, n)) // { // System.err.println("Nonce bad"); // System.exit(1); // } // System.out.printf("[%d] m: %s\n", c, Hex.ToHexString(m, 0, len))); // System.out.printf("[%d] K: %s\n", c, new string(Hex.encodje(kr))); // System.out.printf("[%d] N: %s\n", c, Hex.ToHexString(n))); // System.out.printf("[%d] M: ", c); // } // System.out.printf("%d/%s\n", c, Hex.ToHexString(out))); if (len >= MAXLEN) break; n[0] = (byte)(n[0] ^ loop); for (int i = 0; i < 16; ++i) n[i] ^= output[i]; if (len % 2 != 0) for (int i = 0; i < 16; ++i) kr[i] ^= output[i]; if (len % 3 != 0) for (int i = 0; i < 16; ++i) kr[i + 16] ^= output[i]; Poly1305KeyGenerator.Clamp(kr); m[len++] ^= output[0]; } } // Output after 13 loops as generated by poly1305 ref if (c != 13013 || !Arrays.AreEqual(output, Hex.Decode("c96f60a23701a5b0fd2016f58cbe4f7e"))) { Fail("Sequential Poly1305 " + c, "c96f60a23701a5b0fd2016f58cbe4f7e", Hex.ToHexString(output)); } }
private void testCase(int i) { byte[] output = new byte[16]; TestCase tc = CASES[i]; IMac mac; if (tc.nonce == null) { // Raw Poly1305 test - don't do any transform on AES key part mac = new Poly1305(new KeyEngine(16)); mac.Init(new ParametersWithIV(new KeyParameter(tc.key), new byte[16])); } else { mac = new Poly1305(new AesFastEngine()); mac.Init(new ParametersWithIV(new KeyParameter(tc.key), tc.nonce)); } mac.BlockUpdate(tc.message, 0, tc.message.Length); mac.DoFinal(output, 0); if (!Arrays.AreEqual(output, tc.expectedMac)) { Fail("Mismatched output " + i, Hex.ToHexString(tc.expectedMac), Hex.ToHexString(output)); } }
private void CheckVector(byte[] keyMaterial, byte[] input, byte[] tag) { Poly1305 poly1305 = new Poly1305(); poly1305.Init(new KeyParameter(keyMaterial)); poly1305.BlockUpdate(input, 0, input.Length); byte[] mac = new byte[poly1305.GetMacSize()]; poly1305.DoFinal(mac, 0); if (!Arrays.AreEqual(tag, mac)) { Fail("rfc7539", Hex.ToHexString(tag), Hex.ToHexString(mac)); } }