blob: 2a3a3402429bcf74d44e2354ff9f3d48f2af5b23 [file] [log] [blame]
// Copyright 2017 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////
package com.google.crypto.tink.subtle;
import static com.google.crypto.tink.subtle.Poly1305.MAC_KEY_SIZE_IN_BYTES;
import static com.google.crypto.tink.subtle.Poly1305.MAC_TAG_SIZE_IN_BYTES;
import static org.junit.Assert.fail;
import com.google.common.truth.Truth;
import com.google.crypto.tink.TestUtil;
import java.nio.charset.Charset;
import java.security.GeneralSecurityException;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
/**
* Unit tests for {@link Poly1305}.
*/
@RunWith(JUnit4.class)
public class Poly1305Test {
private static final Charset UTF_8 = Charset.forName("UTF-8");
@Test
public void testPoly1305ComputeMacThrowsIllegalArgExpWhenKeyLenIsGreaterThan32() {
try {
Poly1305.computeMac(new byte[MAC_KEY_SIZE_IN_BYTES + 1], new byte[0]);
fail("Expected IllegalArgumentException.");
} catch (IllegalArgumentException e) {
Truth.assertThat(e).hasMessageThat().containsMatch("The key length in bytes must be 32.");
}
}
@Test
public void testPoly1305ComputeMacThrowsIllegalArgExpWhenKeyLenIsLessThan32() {
try {
Poly1305.computeMac(new byte[MAC_KEY_SIZE_IN_BYTES - 1], new byte[0]);
fail("Expected IllegalArgumentException.");
} catch (IllegalArgumentException e) {
Truth.assertThat(e).hasMessageThat().containsMatch("The key length in bytes must be 32.");
}
}
@Test
public void testPoly1305VerifyMacThrowsIllegalArgExpWhenKeyLenIsGreaterThan32()
throws GeneralSecurityException {
try {
Poly1305.verifyMac(new byte[MAC_KEY_SIZE_IN_BYTES + 1], new byte[0], new byte[0]);
fail("Expected IllegalArgumentException.");
} catch (IllegalArgumentException e) {
Truth.assertThat(e).hasMessageThat().containsMatch("The key length in bytes must be 32.");
}
}
@Test
public void testPoly1305VerifyMacThrowsIllegalArgExpWhenKeyLenIsLessThan32()
throws GeneralSecurityException {
try {
Poly1305.verifyMac(new byte[MAC_KEY_SIZE_IN_BYTES - 1], new byte[0], new byte[0]);
fail("Expected IllegalArgumentException.");
} catch (IllegalArgumentException e) {
Truth.assertThat(e).hasMessageThat().containsMatch("The key length in bytes must be 32.");
}
}
@Test
public void testRandomPoly1305Mac() throws GeneralSecurityException {
for (int i = 0; i < 1000; i++) {
byte[] in = Random.randBytes(new java.util.Random().nextInt(300));
byte[] key = Random.randBytes(MAC_KEY_SIZE_IN_BYTES);
byte[] mac = Poly1305.computeMac(key, in);
try {
Poly1305.verifyMac(key, in, mac);
} catch (Throwable e) {
String error = String.format(
"\n\nIteration: %d\nInput: %s\nKey: %s\nMac: %s\n",
i,
TestUtil.hexEncode(in),
TestUtil.hexEncode(key),
TestUtil.hexEncode(mac));
fail(error + e.getMessage());
}
}
}
@Test
public void testFailedVerification() throws GeneralSecurityException {
try {
byte[] key = new byte[MAC_KEY_SIZE_IN_BYTES];
key[0] = 1;
Poly1305.verifyMac(key, new byte[]{1}, new byte[MAC_TAG_SIZE_IN_BYTES]);
fail("Expected GeneralSecurityException.");
} catch (GeneralSecurityException e) {
Truth.assertThat(e).hasMessageThat().containsMatch("invalid MAC");
}
}
/**
* Tests against the test vectors in Section 2.5.2 of RFC 7539.
* https://tools.ietf.org/html/rfc7539#section-2.5.2
*/
@Test
public void testPoly1305() throws GeneralSecurityException {
byte[] key = TestUtil.hexDecode(""
+ "85d6be7857556d337f4452fe42d506a8"
+ "0103808afb0db2fd4abff6af4149f51b");
byte[] in = ("Cryptographic Forum Research Group").getBytes(UTF_8);
Truth.assertThat(Poly1305.computeMac(key, in)).isEqualTo(TestUtil.hexDecode(""
+ "a8061dc1305136c6c22b8baf0c0127a9"));
}
/**
* Tests against the test vector 1 in Appendix A.3 of RFC 7539.
* https://tools.ietf.org/html/rfc7539#appendix-A.3
*/
@Test
public void testPoly1305TestVector1() throws GeneralSecurityException {
byte[] key = TestUtil.hexDecode(""
+ "00000000000000000000000000000000"
+ "00000000000000000000000000000000");
byte[] in = TestUtil.hexDecode(""
+ "00000000000000000000000000000000"
+ "00000000000000000000000000000000"
+ "00000000000000000000000000000000"
+ "00000000000000000000000000000000");
Truth.assertThat(Poly1305.computeMac(key, in)).isEqualTo(TestUtil.hexDecode(""
+ "00000000000000000000000000000000"));
}
/**
* Tests against the test vector 2 in Appendix A.3 of RFC 7539.
* https://tools.ietf.org/html/rfc7539#appendix-A.3
*/
@Test
public void testPoly1305TestVector2() throws GeneralSecurityException {
byte[] key = TestUtil.hexDecode(""
+ "00000000000000000000000000000000"
+ "36e5f6b5c5e06070f0efca96227a863e");
byte[] in = (
"Any submission to the IETF intended by the Contributor for publication as all or "
+ "part of an IETF Internet-Draft or RFC and any statement made within the context "
+ "of an IETF activity is considered an \"IETF Contribution\". Such statements "
+ "include oral statements in IETF sessions, as well as written and electronic "
+ "communications made at any time or place, which are addressed to")
.getBytes(UTF_8);
Truth.assertThat(Poly1305.computeMac(key, in)).isEqualTo(TestUtil.hexDecode(""
+ "36e5f6b5c5e06070f0efca96227a863e"));
}
/**
* Tests against the test vector 3 in Appendix A.3 of RFC 7539.
* https://tools.ietf.org/html/rfc7539#appendix-A.3
*/
@Test
public void testPoly1305TestVector3() throws GeneralSecurityException {
byte[] key = TestUtil.hexDecode(""
+ "36e5f6b5c5e06070f0efca96227a863e"
+ "00000000000000000000000000000000");
byte[] in = (
"Any submission to the IETF intended by the Contributor for publication as all or "
+ "part of an IETF Internet-Draft or RFC and any statement made within the context "
+ "of an IETF activity is considered an \"IETF Contribution\". Such statements "
+ "include oral statements in IETF sessions, as well as written and electronic "
+ "communications made at any time or place, which are addressed to")
.getBytes(UTF_8);
Truth.assertThat(Poly1305.computeMac(key, in)).isEqualTo(TestUtil.hexDecode(""
+ "f3477e7cd95417af89a6b8794c310cf0"));
}
/**
* Tests against the test vector 4 in Appendix A.3 of RFC 7539.
* https://tools.ietf.org/html/rfc7539#appendix-A.3
*/
@Test
public void testPoly1305TestVector4() throws GeneralSecurityException {
byte[] key = TestUtil.hexDecode(""
+ "1c9240a5eb55d38af333888604f6b5f0"
+ "473917c1402b80099dca5cbc207075c0");
byte[] in = TestUtil.hexDecode(""
+ "2754776173206272696c6c69672c2061"
+ "6e642074686520736c6974687920746f"
+ "7665730a446964206779726520616e64"
+ "2067696d626c6520696e207468652077"
+ "6162653a0a416c6c206d696d73792077"
+ "6572652074686520626f726f676f7665"
+ "732c0a416e6420746865206d6f6d6520"
+ "7261746873206f757467726162652e");
Truth.assertThat(Poly1305.computeMac(key, in)).isEqualTo(TestUtil.hexDecode(""
+ "4541669a7eaaee61e708dc7cbcc5eb62"));
}
/**
* Tests against the test vector 5 in Appendix A.3 of RFC 7539.
* https://tools.ietf.org/html/rfc7539#appendix-A.3
*/
@Test
public void testPoly1305TestVector5() throws GeneralSecurityException {
byte[] key = TestUtil.hexDecode(""
+ "02000000000000000000000000000000"
+ "00000000000000000000000000000000");
byte[] in = TestUtil.hexDecode(""
+ "ffffffffffffffffffffffffffffffff");
Truth.assertThat(Poly1305.computeMac(key, in)).isEqualTo(TestUtil.hexDecode(""
+ "03000000000000000000000000000000"));
}
/**
* Tests against the test vector 6 in Appendix A.3 of RFC 7539.
* https://tools.ietf.org/html/rfc7539#appendix-A.3
*/
@Test
public void testPoly1305TestVector6() throws GeneralSecurityException {
byte[] key = TestUtil.hexDecode(""
+ "02000000000000000000000000000000"
+ "ffffffffffffffffffffffffffffffff");
byte[] in = TestUtil.hexDecode(""
+ "02000000000000000000000000000000");
Truth.assertThat(Poly1305.computeMac(key, in)).isEqualTo(TestUtil.hexDecode(""
+ "03000000000000000000000000000000"));
}
/**
* Tests against the test vector 7 in Appendix A.3 of RFC 7539.
* https://tools.ietf.org/html/rfc7539#appendix-A.3
*/
@Test
public void testPoly1305TestVector7() throws GeneralSecurityException {
byte[] key = TestUtil.hexDecode(""
+ "01000000000000000000000000000000"
+ "00000000000000000000000000000000");
byte[] in = TestUtil.hexDecode(""
+ "ffffffffffffffffffffffffffffffff"
+ "f0ffffffffffffffffffffffffffffff"
+ "11000000000000000000000000000000");
Truth.assertThat(Poly1305.computeMac(key, in)).isEqualTo(TestUtil.hexDecode(""
+ "05000000000000000000000000000000"));
}
/**
* Tests against the test vector 8 in Appendix A.3 of RFC 7539.
* https://tools.ietf.org/html/rfc7539#appendix-A.3
*/
@Test
public void testPoly1305TestVector8() throws GeneralSecurityException {
byte[] key = TestUtil.hexDecode(""
+ "01000000000000000000000000000000"
+ "00000000000000000000000000000000");
byte[] in = TestUtil.hexDecode(""
+ "ffffffffffffffffffffffffffffffff"
+ "fbfefefefefefefefefefefefefefefe"
+ "01010101010101010101010101010101");
Truth.assertThat(Poly1305.computeMac(key, in)).isEqualTo(TestUtil.hexDecode(""
+ "00000000000000000000000000000000"));
}
/**
* Tests against the test vector 9 in Appendix A.3 of RFC 7539.
* https://tools.ietf.org/html/rfc7539#appendix-A.3
*/
@Test
public void testPoly1305TestVector9() throws GeneralSecurityException {
byte[] key = TestUtil.hexDecode(""
+ "02000000000000000000000000000000"
+ "00000000000000000000000000000000");
byte[] in = TestUtil.hexDecode(""
+ "fdffffffffffffffffffffffffffffff");
Truth.assertThat(Poly1305.computeMac(key, in)).isEqualTo(TestUtil.hexDecode(""
+ "faffffffffffffffffffffffffffffff"));
}
/**
* Tests against the test vector 10 in Appendix A.3 of RFC 7539.
* https://tools.ietf.org/html/rfc7539#appendix-A.3
*/
@Test
public void testPoly1305TestVector10() throws GeneralSecurityException {
byte[] key = TestUtil.hexDecode(""
+ "01000000000000000400000000000000"
+ "00000000000000000000000000000000");
byte[] in = TestUtil.hexDecode(""
+ "e33594d7505e43b90000000000000000"
+ "3394d7505e4379cd0100000000000000"
+ "00000000000000000000000000000000"
+ "01000000000000000000000000000000");
Truth.assertThat(Poly1305.computeMac(key, in)).isEqualTo(TestUtil.hexDecode(""
+ "14000000000000005500000000000000"));
}
/**
* Tests against the test vector 11 in Appendix A.3 of RFC 7539.
* https://tools.ietf.org/html/rfc7539#appendix-A.3
*/
@Test
public void testPoly1305TestVector11() throws GeneralSecurityException {
byte[] key = TestUtil.hexDecode(""
+ "01000000000000000400000000000000"
+ "00000000000000000000000000000000");
byte[] in = TestUtil.hexDecode(""
+ "e33594d7505e43b90000000000000000"
+ "3394d7505e4379cd0100000000000000"
+ "00000000000000000000000000000000");
Truth.assertThat(Poly1305.computeMac(key, in)).isEqualTo(TestUtil.hexDecode(""
+ "13000000000000000000000000000000"));
}
}