1 // Copyright 2017 Google Inc. 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.subtle; 18 19 import static com.google.common.truth.Truth.assertThat; 20 import static org.junit.Assert.assertEquals; 21 import static org.junit.Assert.assertThrows; 22 23 import java.nio.ByteBuffer; 24 import org.junit.Test; 25 import org.junit.runner.RunWith; 26 import org.junit.runners.JUnit4; 27 28 /** Tests for Bytes */ 29 @RunWith(JUnit4.class) 30 public class BytesTest { 31 32 // Some test arrays for the XOR operations. 33 static final byte[] EMPTY = {}; 34 static final byte[] ONE_ONE = {1}; 35 static final byte[] TWO_ONES = {1, 1}; 36 static final byte[] THREE_ONES = {1, 1, 1}; 37 static final byte[] THREE_ZEROES = {0, 0, 0}; 38 static final byte[] TWO_FF = {(byte) 0xFF, (byte) 0xFF}; 39 40 @Test xorTwoArgsBasicTest()41 public void xorTwoArgsBasicTest() { 42 byte[] shouldBeZeroes = Bytes.xor(TWO_ONES, TWO_ONES); 43 assertEquals(0, shouldBeZeroes[0]); 44 assertEquals(0, shouldBeZeroes[1]); 45 } 46 47 @Test xorTwoArgsSizeMismatchA()48 public void xorTwoArgsSizeMismatchA() { 49 assertThrows(IllegalArgumentException.class, () -> Bytes.xor(THREE_ZEROES, TWO_ONES)); 50 } 51 52 @Test xorTwoArgsSizeMismatchB()53 public void xorTwoArgsSizeMismatchB() { 54 assertThrows(IllegalArgumentException.class, () -> Bytes.xor(TWO_ONES, THREE_ZEROES)); 55 } 56 57 @Test xorThreeArgsBasicTest()58 public void xorThreeArgsBasicTest() { 59 byte[] shouldBeZeroes = Bytes.xor(TWO_ONES, 0, TWO_ONES, 0, 2); 60 assertEquals(0, shouldBeZeroes[0]); 61 assertEquals(0, shouldBeZeroes[1]); 62 assertEquals(2, shouldBeZeroes.length); 63 } 64 65 @Test xorThreeArgsDifferentSizes()66 public void xorThreeArgsDifferentSizes() { 67 byte[] shouldBeOne = Bytes.xor(THREE_ZEROES, 1, TWO_ONES, 0, 1); 68 assertEquals(1, shouldBeOne[0]); 69 assertEquals(1, shouldBeOne.length); 70 } 71 72 @Test xorThreeArgsTooLong()73 public void xorThreeArgsTooLong() { 74 assertThrows(IllegalArgumentException.class, () -> Bytes.xor(THREE_ZEROES, 0, TWO_ONES, 0, 3)); 75 } 76 77 @Test xorThreeArgsTooLongOffsets()78 public void xorThreeArgsTooLongOffsets() { 79 assertThrows(IllegalArgumentException.class, () -> Bytes.xor(THREE_ZEROES, 3, TWO_ONES, 1, 1)); 80 } 81 82 @Test xorThreeArgsSizeMismatchB()83 public void xorThreeArgsSizeMismatchB() { 84 assertThrows(IllegalArgumentException.class, () -> Bytes.xor(TWO_ONES, THREE_ZEROES)); 85 } 86 87 @Test xorEndBasicTest()88 public void xorEndBasicTest() { 89 byte[] r = Bytes.xorEnd(THREE_ONES, TWO_FF); 90 assertEquals(1, r[0]); 91 assertEquals((byte) 0xFE, r[1]); 92 assertEquals((byte) 0xFE, r[2]); 93 assertEquals(3, r.length); 94 } 95 96 @Test xorEndSizeMismatch()97 public void xorEndSizeMismatch() { 98 assertThrows(IllegalArgumentException.class, () -> Bytes.xorEnd(TWO_ONES, THREE_ZEROES)); 99 } 100 101 @Test xorByteBufferNegativeLength()102 public void xorByteBufferNegativeLength() { 103 ByteBuffer output = ByteBuffer.allocate(10); 104 ByteBuffer x = ByteBuffer.allocate(10); 105 ByteBuffer y = ByteBuffer.allocate(10); 106 assertThrows(IllegalArgumentException.class, () -> Bytes.xor(output, x, y, -1)); 107 } 108 109 @Test xorByteBufferLengthLargerThanOutput()110 public void xorByteBufferLengthLargerThanOutput() { 111 ByteBuffer output = ByteBuffer.allocate(9); 112 ByteBuffer x = ByteBuffer.allocate(10); 113 ByteBuffer y = ByteBuffer.allocate(10); 114 assertThrows(IllegalArgumentException.class, () -> Bytes.xor(output, x, y, 10)); 115 } 116 117 @Test xorByteBufferLengthLargerThanFirstInput()118 public void xorByteBufferLengthLargerThanFirstInput() { 119 ByteBuffer output = ByteBuffer.allocate(10); 120 ByteBuffer x = ByteBuffer.allocate(9); 121 ByteBuffer y = ByteBuffer.allocate(10); 122 assertThrows(IllegalArgumentException.class, () -> Bytes.xor(output, x, y, 10)); 123 } 124 125 @Test xorByteBufferLengthLargerThanSecondInput()126 public void xorByteBufferLengthLargerThanSecondInput() { 127 ByteBuffer output = ByteBuffer.allocate(10); 128 ByteBuffer x = ByteBuffer.allocate(10); 129 ByteBuffer y = ByteBuffer.allocate(9); 130 assertThrows(IllegalArgumentException.class, () -> Bytes.xor(output, x, y, 10)); 131 } 132 133 @Test xorByteBufferBasic()134 public void xorByteBufferBasic() { 135 ByteBuffer output = ByteBuffer.allocate(10); 136 ByteBuffer x = ByteBuffer.allocate(10); 137 ByteBuffer y = ByteBuffer.allocate(10); 138 for (int i = 0; i < 10; i++) { 139 x.put((byte) i); 140 y.put((byte) (i + 1)); 141 } 142 x.flip(); 143 y.flip(); 144 Bytes.xor(output, x, y, 10); 145 for (int i = 0; i < 10; i++) { 146 assertEquals(output.get(i), i ^ (i + 1)); 147 } 148 } 149 150 @Test intToByteArray_works()151 public void intToByteArray_works() { 152 assertThat(Bytes.intToByteArray(0, 0)).isEqualTo(new byte[] {}); 153 assertThat(Bytes.intToByteArray(1, 42)).isEqualTo(new byte[] {(byte) 42}); 154 assertThat(Bytes.intToByteArray(2, 0x0102)).isEqualTo(new byte[] {(byte) 02, (byte) 0x01}); 155 156 assertThat(Bytes.intToByteArray(1, 0xdd)).isEqualTo(new byte[] {(byte) 0xdd}); 157 assertThat(Bytes.intToByteArray(2, 0xccdd)).isEqualTo(new byte[] {(byte) 0xdd, (byte) 0xcc}); 158 assertThat(Bytes.intToByteArray(3, 0xbbccdd)) 159 .isEqualTo(new byte[] {(byte) 0xdd, (byte) 0xcc, (byte) 0xbb}); 160 assertThat(Bytes.intToByteArray(4, 0x0abbccdd)) 161 .isEqualTo(new byte[] {(byte) 0xdd, (byte) 0xcc, (byte) 0xbb, (byte) 0x0a}); 162 assertThat(Bytes.intToByteArray(4, Integer.MAX_VALUE)) 163 .isEqualTo(new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x7f}); 164 } 165 166 @Test intToByteArray_failsWithInvalidCapacity()167 public void intToByteArray_failsWithInvalidCapacity() { 168 assertThrows(IllegalArgumentException.class, () -> Bytes.intToByteArray(5, 42)); 169 assertThrows(IllegalArgumentException.class, () -> Bytes.intToByteArray(-1, 42)); 170 } 171 172 @Test intToByteArray_valueTooLong_fails()173 public void intToByteArray_valueTooLong_fails() { 174 assertThrows(IllegalArgumentException.class, () -> Bytes.intToByteArray(0, 1)); 175 assertThrows(IllegalArgumentException.class, () -> Bytes.intToByteArray(0, -1)); 176 assertThrows(IllegalArgumentException.class, () -> Bytes.intToByteArray(1, 256)); 177 assertThrows(IllegalArgumentException.class, () -> Bytes.intToByteArray(1, -1)); 178 assertThrows(IllegalArgumentException.class, () -> Bytes.intToByteArray(2, 256 * 256)); 179 assertThrows(IllegalArgumentException.class, () -> Bytes.intToByteArray(2, -1)); 180 assertThrows(IllegalArgumentException.class, () -> Bytes.intToByteArray(3, 256 * 256 * 256)); 181 assertThrows(IllegalArgumentException.class, () -> Bytes.intToByteArray(3, -1)); 182 assertThrows(IllegalArgumentException.class, () -> Bytes.intToByteArray(4, -1)); 183 assertThrows(IllegalArgumentException.class, () -> Bytes.intToByteArray(4, Integer.MIN_VALUE)); 184 } 185 186 @Test intToByteArrayToInt_works()187 public void intToByteArrayToInt_works() { 188 assertThat(Bytes.byteArrayToInt(Bytes.intToByteArray(0, 0))).isEqualTo(0); 189 assertThat(Bytes.byteArrayToInt(Bytes.intToByteArray(1, 42))).isEqualTo(42); 190 assertThat(Bytes.byteArrayToInt(Bytes.intToByteArray(2, 0x0102))).isEqualTo(0x0102); 191 assertThat(Bytes.byteArrayToInt(Bytes.intToByteArray(4, 0x0abbccdd))).isEqualTo(0x0abbccdd); 192 assertThat(Bytes.byteArrayToInt(Bytes.intToByteArray(4, Integer.MAX_VALUE))) 193 .isEqualTo(Integer.MAX_VALUE); 194 } 195 196 @Test byteArrayToInt_works()197 public void byteArrayToInt_works() { 198 assertThat(Bytes.byteArrayToInt(new byte[] {})).isEqualTo(0); 199 assertThat(Bytes.byteArrayToInt(new byte[] {(byte) 1})).isEqualTo(1); 200 assertThat(Bytes.byteArrayToInt(new byte[] {(byte) 0x02, (byte) 0x01})).isEqualTo(0x0102); 201 assertThat(Bytes.byteArrayToInt(new byte[] {(byte) 0x02, (byte) 0x01}, /* length= */ 2)) 202 .isEqualTo(0x0102); 203 assertThat( 204 Bytes.byteArrayToInt( 205 new byte[] {(byte) 0x02, (byte) 0x01}, /* offset= */ 0, /* length= */ 2)) 206 .isEqualTo(0x0102); 207 assertThat( 208 Bytes.byteArrayToInt( 209 new byte[] {(byte) 0x02, (byte) 0x01}, /* offset= */ 1, /* length= */ 1)) 210 .isEqualTo(0x01); 211 assertThat(Bytes.byteArrayToInt(new byte[] {(byte) 0x02, (byte) 0x01}, /* length= */ 1)) 212 .isEqualTo(0x02); 213 assertThat( 214 Bytes.byteArrayToInt( 215 new byte[] {(byte) 0x05, (byte) 0x04, (byte) 0x03, (byte) 0x02, (byte) 0x01}, 216 /* offset= */ 2, 217 /* length= */ 1)) 218 .isEqualTo(3); 219 } 220 221 @Test byteArrayToInt_failsWithInvalidLength()222 public void byteArrayToInt_failsWithInvalidLength() { 223 assertThrows( 224 IllegalArgumentException.class, 225 () -> 226 Bytes.byteArrayToInt( 227 new byte[] {(byte) 0x02, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x01})); 228 assertThrows( 229 IllegalArgumentException.class, () -> Bytes.byteArrayToInt(new byte[] {(byte) 0x01}, -1)); 230 } 231 232 @Test byteArrayToInt_outOfBounds_fails()233 public void byteArrayToInt_outOfBounds_fails() { 234 assertThrows( 235 IllegalArgumentException.class, 236 () -> Bytes.byteArrayToInt(new byte[] {(byte) 0x05, (byte) 0x04}, /* length= */ 3)); 237 assertThrows( 238 IllegalArgumentException.class, 239 () -> 240 Bytes.byteArrayToInt( 241 new byte[] {(byte) 0x05, (byte) 0x04}, /* offset= */ 1, /* length= */ 2)); 242 assertThrows( 243 IllegalArgumentException.class, 244 () -> 245 Bytes.byteArrayToInt( 246 new byte[] {(byte) 0x05, (byte) 0x04}, /* offset= */ -1, /* length= */ 1)); 247 } 248 } 249