protected KeyParameter initRecordMAC(ChaChaEngine cipher, boolean forEncryption, long seqNo) { byte[] nonce = new byte[8]; TlsUtils.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' System.arraycopy(firstBlock, 0, firstBlock, 32, 16); KeyParameter macKey = new KeyParameter(firstBlock, 16, 32); Poly1305KeyGenerator.clamp(macKey.getKey()); return macKey; }
private void setKey(byte[] key, byte[] nonce) { if (nonce.length != BLOCK_SIZE) { throw new IllegalArgumentException("Poly1305 requires a 128 bit IV."); } Poly1305KeyGenerator.checkKey(key); // Expand private integer r for (int i = 0; i < BLOCK_SIZE; i++) { r[i] = key[BLOCK_SIZE + i] & 0xFF; } r[BLOCK_SIZE] = 0; // Calculate encrypted nonce final byte[] cipherKey = new byte[BLOCK_SIZE]; System.arraycopy(key, 0, cipherKey, 0, cipherKey.length); cipher.init(true, new KeyParameter(cipherKey)); cipher.processBlock(nonce, 0, this.encryptedNonce, 0); }
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 KeyParameter initRecordMAC(ChaChaEngine cipher) { byte[] firstBlock = new byte[64]; cipher.processBytes(firstBlock, 0, firstBlock.length, firstBlock, 0); // NOTE: The BC implementation puts 'r' after 'k' System.arraycopy(firstBlock, 0, firstBlock, 32, 16); KeyParameter macKey = new KeyParameter(firstBlock, 16, 32); Poly1305KeyGenerator.clamp(macKey.getKey()); return macKey; }
private void setKey(final byte[] key, final byte[] nonce) { if (nonce.length != BLOCK_SIZE) { throw new IllegalArgumentException("Poly1305 requires a 128 bit IV."); } Poly1305KeyGenerator.checkKey(key); // Extract r portion of key int t0 = Pack.littleEndianToInt(key, BLOCK_SIZE + 0); int t1 = Pack.littleEndianToInt(key, BLOCK_SIZE + 4); int t2 = Pack.littleEndianToInt(key, BLOCK_SIZE + 8); int t3 = Pack.littleEndianToInt(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; // Compute encrypted nonce final byte[] cipherKey = new byte[BLOCK_SIZE]; System.arraycopy(key, 0, cipherKey, 0, cipherKey.length); cipher.init(true, new KeyParameter(cipherKey)); cipher.processBlock(nonce, 0, cipherKey, 0); k0 = Pack.littleEndianToInt(cipherKey, 0); k1 = Pack.littleEndianToInt(cipherKey, 4); k2 = Pack.littleEndianToInt(cipherKey, 8); k3 = Pack.littleEndianToInt(cipherKey, 12); }
/** * Computes the MAC of the specified length for the given share with the given key. * * @param data the data to create the MAC for * @param key the key to use for computing the MAC * @return the message authentication code (tag or MAC) for this share * @throws InvalidKeyException thrown if an InvalidKeyException occurred */ @Override public byte[] computeMAC(byte[] data, byte[] key) throws InvalidKeyException { byte[] result = new byte[mac.getMacSize()]; Poly1305KeyGenerator.clamp(key); mac.init(new KeyParameter(key)); mac.update(data, 0, data.length); mac.doFinal(result, 0); return result; }
/** * Verifies the given MAC.<br> * (recomputes the tag from share and key and compares it with the given tag) * * @param data the data to verify the MAC for * @param tag the tag to verify * @param key the key to use for verification * @return true if verification was successful (the tags matched); false otherwise */ @Override public boolean verifyMAC(byte[] data, byte[] tag, byte[] key) { boolean valid = false; Poly1305KeyGenerator.clamp(key); try { byte[] newTag = computeMAC(data, key); // compute tag for the given parameters valid = Arrays.equals(tag, newTag); // compare with original tag } catch (InvalidKeyException e) { } return valid; }
private void setKey(final byte[] key, final byte[] nonce) { if (cipher != null && (nonce == null || nonce.length != BLOCK_SIZE)) { throw new IllegalArgumentException("Poly1305 requires a 128 bit IV."); } Poly1305KeyGenerator.checkKey(key); // Extract r portion of key int t0 = Pack.littleEndianToInt(key, BLOCK_SIZE + 0); int t1 = Pack.littleEndianToInt(key, BLOCK_SIZE + 4); int t2 = Pack.littleEndianToInt(key, BLOCK_SIZE + 8); int t3 = Pack.littleEndianToInt(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; final 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.littleEndianToInt(kBytes, 0); k1 = Pack.littleEndianToInt(kBytes, 4); k2 = Pack.littleEndianToInt(kBytes, 8); k3 = Pack.littleEndianToInt(kBytes, 12); }
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[] out = new byte[16]; int c = 0; final Mac 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.update(m, 0, len); mac.doFinal(out, 0); // if (c == 678) // { // TestCase tc = CASES[0]; // // if (!Arrays.areEqual(tc.key, kr)) // { // System.err.println("Key bad"); // System.err.println(new String(Hex.encode(tc.key))); // System.err.println(new String(Hex.encode(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, new String(Hex.encode(m, 0, len))); // System.out.printf("[%d] K: %s\n", c, new String(Hex.encodje(kr))); // System.out.printf("[%d] N: %s\n", c, new String(Hex.encode(n))); // System.out.printf("[%d] M: ", c); // } // System.out.printf("%d/%s\n", c, new String(Hex.encode(out))); if (len >= MAXLEN) break; n[0] ^= loop; for (int i = 0; i < 16; ++i) n[i] ^= out[i]; if (len % 2 != 0) for (int i = 0; i < 16; ++i) kr[i] ^= out[i]; if (len % 3 != 0) for (int i = 0; i < 16; ++i) kr[i + 16] ^= out[i]; Poly1305KeyGenerator.clamp(kr); m[len++] ^= out[0]; } } // Output after 13 loops as generated by poly1305 ref if (c != 13013 || !Arrays.areEqual(out, Hex.decode("c96f60a23701a5b0fd2016f58cbe4f7e"))) { fail("Sequential Poly1305 " + c, "c96f60a23701a5b0fd2016f58cbe4f7e", new String(Hex.encode(out))); } }
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[] out = new byte[16]; // Generate baseline Mac poly = new Poly1305(new AESFastEngine()); poly.init(new ParametersWithIV(new KeyParameter(k), new byte[16])); poly.update(m, 0, m.length); poly.doFinal(check, 0); // Check reset after doFinal poly.update(m, 0, m.length); poly.doFinal(out, 0); if (!Arrays.areEqual(check, out)) { fail("Mac not reset after doFinal"); } // Check reset poly.update((byte)1); poly.update((byte)2); poly.reset(); poly.update(m, 0, m.length); poly.doFinal(out, 0); if (!Arrays.areEqual(check, out)) { 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.update(m, 0, m.length); poly.doFinal(out, 0); if (!Arrays.areEqual(check, out)) { fail("Mac not reset after doFinal"); } }
public Poly1305KeyGen() { super("Poly1305-RC6", 256, new Poly1305KeyGenerator()); }
public Poly1305KeyGen() { super("Poly1305-SEED", 256, new Poly1305KeyGenerator()); }
public Poly1305KeyGen() { super("Poly1305-Twofish", 256, new Poly1305KeyGenerator()); }
public Poly1305KeyGen() { super("Poly1305-SM4", 256, new Poly1305KeyGenerator()); }
public Poly1305KeyGen() { super("Poly1305-Noekeon", 256, new Poly1305KeyGenerator()); }
public Poly1305KeyGen() { super("Poly1305-Camellia", 256, new Poly1305KeyGenerator()); }
public Poly1305KeyGen() { super("Poly1305-CAST6", 256, new Poly1305KeyGenerator()); }
public Poly1305KeyGen() { super("Poly1305-AES", 256, new Poly1305KeyGenerator()); }
public Poly1305KeyGen() { super("Poly1305-Serpent", 256, new Poly1305KeyGenerator()); }