/// <summary> /// Generate a key. /// </summary> /// <returns>A Poly1305 key.</returns> public Key GenerateKey() { Poly1305KeyGenerator cipherKeyGenerator = new Poly1305KeyGenerator(); cipherKeyGenerator.Init(new Internal.KeyGenerationParameters(random, keySizeInBits)); return(new Key(cipherKeyGenerator.GenerateKey())); }
public TestCase(string key, string nonce, string message, string expectedMac) { this.key = Hex.Decode(key); // nacl test case keys are not pre-Clamped Poly1305KeyGenerator.Clamp(this.key); this.nonce = (nonce == null) ? null : Hex.Decode(nonce); this.message = Hex.Decode(message); this.expectedMac = Hex.Decode(expectedMac); }
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"); } }
protected virtual KeyParameter InitRecordMac(ChaChaEngine cipher, bool forEncryption, long seqNo) { byte[] array = new byte[8]; TlsUtilities.WriteUint64(seqNo, array, 0); cipher.Init(forEncryption, new ParametersWithIV(null, array)); byte[] array2 = new byte[64]; cipher.ProcessBytes(array2, 0, array2.Length, array2, 0); Array.Copy(array2, 0, array2, 32, 16); KeyParameter keyParameter = new KeyParameter(array2, 16, 32); Poly1305KeyGenerator.Clamp(keyParameter.GetKey()); return(keyParameter); }
protected virtual KeyParameter GenerateRecordMacKey(IStreamCipher cipher) { byte[] firstBlock = new byte[64]; cipher.ProcessBytes(firstBlock, 0, firstBlock.Length, firstBlock, 0); // NOTE: The BC implementation puts 'r' after 'k' Array.Copy(firstBlock, 0, firstBlock, 32, 16); Poly1305KeyGenerator.Clamp(firstBlock, 16); KeyParameter macKey = new KeyParameter(firstBlock, 16, 32); Arrays.Fill(firstBlock, (byte)0); return(macKey); }
protected virtual KeyParameter InitRecordMac(ChaChaEngine cipher, bool forEncryption, long seqNo) { byte[] nonce = new byte[8]; TlsUtilities.WriteUint64(seqNo, nonce, 0); cipher.Init(forEncryption, new ParametersWithIV(null, nonce)); byte[] firstBlock = new byte[64]; cipher.ProcessBytes(firstBlock, 0, firstBlock.Length, firstBlock, 0); // NOTE: The BC implementation puts 'r' after 'k' Array.Copy(firstBlock, 0, firstBlock, 32, 16); KeyParameter macKey = new KeyParameter(firstBlock, 16, 32); Poly1305KeyGenerator.Clamp(macKey.GetKey()); return(macKey); }
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 SetKey(byte[] key, byte[] nonce) { if (cipher != null && (nonce == null || nonce.Length != BLOCK_SIZE)) { throw new ArgumentException("Poly1305 requires a 128 bit IV."); } Poly1305KeyGenerator.CheckKey(key); // Extract r portion of key uint t0 = Pack.LE_To_UInt32(key, BLOCK_SIZE + 0); uint t1 = Pack.LE_To_UInt32(key, BLOCK_SIZE + 4); uint t2 = Pack.LE_To_UInt32(key, BLOCK_SIZE + 8); uint t3 = Pack.LE_To_UInt32(key, BLOCK_SIZE + 12); r0 = t0 & 0x3ffffff; t0 >>= 26; t0 |= t1 << 6; r1 = t0 & 0x3ffff03; t1 >>= 20; t1 |= t2 << 12; r2 = t1 & 0x3ffc0ff; t2 >>= 14; t2 |= t3 << 18; r3 = t2 & 0x3f03fff; t3 >>= 8; r4 = t3 & 0x00fffff; // Precompute multipliers s1 = r1 * 5; s2 = r2 * 5; s3 = r3 * 5; s4 = r4 * 5; byte[] kBytes; if (cipher == null) { kBytes = key; } else { // Compute encrypted nonce kBytes = new byte[BLOCK_SIZE]; cipher.Init(true, new KeyParameter(key, 0, BLOCK_SIZE)); cipher.ProcessBlock(nonce, 0, kBytes, 0); } k0 = Pack.LE_To_UInt32(kBytes, 0); k1 = Pack.LE_To_UInt32(kBytes, 4); k2 = Pack.LE_To_UInt32(kBytes, 8); k3 = Pack.LE_To_UInt32(kBytes, 12); }
private void SetKey(byte[] key, byte[] nonce) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) if (cipher != null && (nonce == null || nonce.Length != 16)) { throw new ArgumentException("Poly1305 requires a 128 bit IV."); } Poly1305KeyGenerator.CheckKey(key); uint num = Pack.LE_To_UInt32(key, 16); uint num2 = Pack.LE_To_UInt32(key, 20); uint num3 = Pack.LE_To_UInt32(key, 24); uint num4 = Pack.LE_To_UInt32(key, 28); r0 = num & 0x3FFFFFFu; num >>= 26; num |= num2 << 6; r1 = num & 0x3FFFF03u; num2 >>= 20; num2 |= num3 << 12; r2 = num2 & 0x3FFC0FFu; num3 >>= 14; num3 |= num4 << 18; r3 = num3 & 0x3F03FFFu; num4 >>= 8; r4 = num4 & 0xFFFFFu; s1 = r1 * 5; s2 = r2 * 5; s3 = r3 * 5; s4 = r4 * 5; byte[] array; if (cipher == null) { array = key; } else { array = new byte[16]; cipher.Init(forEncryption: true, new KeyParameter(key, 0, 16)); cipher.ProcessBlock(nonce, 0, array, 0); } k0 = Pack.LE_To_UInt32(array, 0); k1 = Pack.LE_To_UInt32(array, 4); k2 = Pack.LE_To_UInt32(array, 8); k3 = Pack.LE_To_UInt32(array, 12); }
private void SetKey(byte[] key, byte[] nonce) { if (this.cipher != null && (nonce == null || nonce.Length != 16)) { throw new ArgumentException("Poly1305 requires a 128 bit IV."); } Poly1305KeyGenerator.CheckKey(key); uint num = Pack.LE_To_UInt32(key, 16); uint num2 = Pack.LE_To_UInt32(key, 20); uint num3 = Pack.LE_To_UInt32(key, 24); uint num4 = Pack.LE_To_UInt32(key, 28); this.r0 = (num & 67108863u); num >>= 26; num |= num2 << 6; this.r1 = (num & 67108611u); num2 >>= 20; num2 |= num3 << 12; this.r2 = (num2 & 67092735u); num3 >>= 14; num3 |= num4 << 18; this.r3 = (num3 & 66076671u); num4 >>= 8; this.r4 = (num4 & 1048575u); this.s1 = this.r1 * 5u; this.s2 = this.r2 * 5u; this.s3 = this.r3 * 5u; this.s4 = this.r4 * 5u; byte[] array; if (this.cipher == null) { array = key; } else { array = new byte[16]; this.cipher.Init(true, new KeyParameter(key, 0, 16)); this.cipher.ProcessBlock(nonce, 0, array, 0); } this.k0 = Pack.LE_To_UInt32(array, 0); this.k1 = Pack.LE_To_UInt32(array, 4); this.k2 = Pack.LE_To_UInt32(array, 8); this.k3 = Pack.LE_To_UInt32(array, 12); }
private void testKeyGenerator() { CipherKeyGenerator gen = new Poly1305KeyGenerator(); gen.Init(new KeyGenerationParameters(new SecureRandom(), 256)); byte[] k = gen.GenerateKey(); if (k.Length != 32) { Fail("Poly1305 key should be 256 bits."); } try { Poly1305KeyGenerator.CheckKey(k); } catch (ArgumentException) { Fail("Poly1305 key should be Clamped on generation."); } byte[] k2 = new byte[k.Length]; Array.Copy(k, 0, k2, 0, k2.Length); Poly1305KeyGenerator.Clamp(k); if (!Arrays.AreEqual(k, k2)) { Fail("Poly1305 key should be Clamped on generation."); } /* * try * { * k2[19] = (byte)0xff; * Poly1305KeyGenerator.CheckKey(k2); * Fail("UnClamped key should fail check."); * } * catch (ArgumentException) * { * // Expected * } */ }
private KeyParameter InitRecordMAC(ChaChaEngine cipher) { byte[] zeroes = StringToByteArray( "00000000000000000000000000000000" + "00000000000000000000000000000000" + "00000000000000000000000000000000" + "00000000000000000000000000000000"); byte[] firstBlock = new byte[64]; cipher.ProcessBytes(zeroes, 0, firstBlock.Length, firstBlock, 0); Console.WriteLine("ChaCha OutBytes"); Console.WriteLine(ByteArrayToString(firstBlock)); // NOTE: The BC implementation puts 'r' after 'k' //Array.Copy(firstBlock, 0, firstBlock, 32, 16); //KeyParameter macKey = new KeyParameter(firstBlock, 16, 32); //Poly1305KeyGenerator.clamp(macKey.getKey()); // 8th January, 2018 21:05 // // The above code is from the github HAP-Java implementation. The problem was that the clamp() operator // wasn't having any effect! I'm guessing it's because the getKey() returns a new instance each time. // To work around this, I create a buffer, clamp it and then create a KeyParameter with the new byte[] // How the f**k I spotted this I'll never know. // KeyParameter macKey = new KeyParameter(firstBlock, 0, 32); var key = macKey.GetKey(); //Console.WriteLine(ByteArrayToString(key)); Poly1305KeyGenerator.Clamp(key); //Console.WriteLine(ByteArrayToString(key)); Poly1305KeyGenerator.CheckKey(key); return(new KeyParameter(key)); }
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)); } }