1 // Copyright 2023 Google LLC 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 // 15 //////////////////////////////////////////////////////////////////////////////// 16 17 package com.google.crypto.tink.aead; 18 19 import static com.google.common.truth.Truth.assertThat; 20 import static org.junit.Assert.assertThrows; 21 22 import com.google.crypto.tink.InsecureSecretKeyAccess; 23 import com.google.crypto.tink.internal.KeyTester; 24 import com.google.crypto.tink.util.Bytes; 25 import com.google.crypto.tink.util.SecretBytes; 26 import java.security.GeneralSecurityException; 27 import org.junit.Test; 28 import org.junit.runner.RunWith; 29 import org.junit.runners.JUnit4; 30 31 @RunWith(JUnit4.class) 32 public final class XChaCha20Poly1305KeyTest { 33 @Test buildNoPrefixVariantAndGetProperties()34 public void buildNoPrefixVariantAndGetProperties() throws Exception { 35 SecretBytes keyBytes = SecretBytes.randomBytes(32); 36 XChaCha20Poly1305Key key = XChaCha20Poly1305Key.create(keyBytes); 37 assertThat(key.getParameters()).isEqualTo(XChaCha20Poly1305Parameters.create()); 38 assertThat(key.getKeyBytes()).isEqualTo(keyBytes); 39 assertThat(key.getOutputPrefix()).isEqualTo(Bytes.copyFrom(new byte[] {})); 40 assertThat(key.getIdRequirementOrNull()).isNull(); 41 } 42 43 @Test buildNoPrefixVariantExplicitAndGetProperties()44 public void buildNoPrefixVariantExplicitAndGetProperties() throws Exception { 45 SecretBytes keyBytes = SecretBytes.randomBytes(32); 46 XChaCha20Poly1305Key key = 47 XChaCha20Poly1305Key.create(XChaCha20Poly1305Parameters.Variant.NO_PREFIX, keyBytes, null); 48 assertThat(key.getParameters()).isEqualTo(XChaCha20Poly1305Parameters.create()); 49 assertThat(key.getKeyBytes()).isEqualTo(keyBytes); 50 assertThat(key.getOutputPrefix()).isEqualTo(Bytes.copyFrom(new byte[] {})); 51 assertThat(key.getIdRequirementOrNull()).isNull(); 52 } 53 54 @Test buildTinkVariantAndGetProperties()55 public void buildTinkVariantAndGetProperties() throws Exception { 56 SecretBytes keyBytes = SecretBytes.randomBytes(32); 57 XChaCha20Poly1305Key key = 58 XChaCha20Poly1305Key.create(XChaCha20Poly1305Parameters.Variant.TINK, keyBytes, 0x0708090a); 59 assertThat(key.getParameters()) 60 .isEqualTo(XChaCha20Poly1305Parameters.create(XChaCha20Poly1305Parameters.Variant.TINK)); 61 assertThat(key.getKeyBytes()).isEqualTo(keyBytes); 62 assertThat(key.getOutputPrefix()) 63 .isEqualTo(Bytes.copyFrom(new byte[] {0x01, 0x07, 0x08, 0x09, 0x0a})); 64 assertThat(key.getIdRequirementOrNull()).isEqualTo(0x708090a); 65 } 66 67 @Test buildCrunchyVariantAndGetProperties()68 public void buildCrunchyVariantAndGetProperties() throws Exception { 69 SecretBytes keyBytes = SecretBytes.randomBytes(32); 70 XChaCha20Poly1305Key key = 71 XChaCha20Poly1305Key.create( 72 XChaCha20Poly1305Parameters.Variant.CRUNCHY, keyBytes, 0x0708090a); 73 assertThat(key.getParameters()) 74 .isEqualTo(XChaCha20Poly1305Parameters.create(XChaCha20Poly1305Parameters.Variant.CRUNCHY)); 75 assertThat(key.getKeyBytes()).isEqualTo(keyBytes); 76 assertThat(key.getOutputPrefix()) 77 .isEqualTo(Bytes.copyFrom(new byte[] {0x00, 0x07, 0x08, 0x09, 0x0a})); 78 assertThat(key.getIdRequirementOrNull()).isEqualTo(0x708090a); 79 } 80 81 @Test wrongIdRequirement_throws()82 public void wrongIdRequirement_throws() throws Exception { 83 SecretBytes keyBytes = SecretBytes.randomBytes(32); 84 assertThrows( 85 GeneralSecurityException.class, 86 () -> 87 XChaCha20Poly1305Key.create( 88 XChaCha20Poly1305Parameters.Variant.NO_PREFIX, keyBytes, 1115)); 89 assertThrows( 90 GeneralSecurityException.class, 91 () -> 92 XChaCha20Poly1305Key.create( 93 XChaCha20Poly1305Parameters.Variant.CRUNCHY, keyBytes, null)); 94 assertThrows( 95 GeneralSecurityException.class, 96 () -> 97 XChaCha20Poly1305Key.create(XChaCha20Poly1305Parameters.Variant.TINK, keyBytes, null)); 98 } 99 100 @Test testEqualities()101 public void testEqualities() throws Exception { 102 SecretBytes keyBytes = SecretBytes.randomBytes(32); 103 SecretBytes keyBytesCopy = 104 SecretBytes.copyFrom( 105 keyBytes.toByteArray(InsecureSecretKeyAccess.get()), InsecureSecretKeyAccess.get()); 106 SecretBytes keyBytesDiff = SecretBytes.randomBytes(32); 107 108 new KeyTester() 109 .addEqualityGroup( 110 "No prefix, keyBytes", 111 XChaCha20Poly1305Key.create( 112 XChaCha20Poly1305Parameters.Variant.NO_PREFIX, keyBytes, null), 113 XChaCha20Poly1305Key.create(keyBytes), 114 XChaCha20Poly1305Key.create( 115 XChaCha20Poly1305Parameters.Variant.NO_PREFIX, keyBytesCopy, null)) 116 .addEqualityGroup( 117 "No prefix, different key bytes", 118 XChaCha20Poly1305Key.create( 119 XChaCha20Poly1305Parameters.Variant.NO_PREFIX, keyBytesDiff, null)) 120 .addEqualityGroup( 121 "Tink with key id 1907, keyBytes32", 122 XChaCha20Poly1305Key.create(XChaCha20Poly1305Parameters.Variant.TINK, keyBytes, 1907), 123 XChaCha20Poly1305Key.create( 124 XChaCha20Poly1305Parameters.Variant.TINK, keyBytesCopy, 1907)) 125 .addEqualityGroup( 126 "Tink with key id 1908, keyBytes32", 127 XChaCha20Poly1305Key.create(XChaCha20Poly1305Parameters.Variant.TINK, keyBytes, 1908)) 128 .addEqualityGroup( 129 "Crunchy with key id 1907, keyBytes32", 130 XChaCha20Poly1305Key.create( 131 XChaCha20Poly1305Parameters.Variant.CRUNCHY, keyBytes, 1907)) 132 .doTests(); 133 } 134 } 135