1 // Copyright 2022 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.util; 18 19 import com.google.crypto.tink.SecretKeyAccess; 20 import com.google.errorprone.annotations.Immutable; 21 import java.math.BigInteger; 22 import java.security.MessageDigest; 23 24 /** A class storing a secret BigInteger, protecting the value via {@link SecretKeyAccess}. */ 25 @Immutable 26 public final class SecretBigInteger { 27 private final BigInteger value; 28 SecretBigInteger(BigInteger value)29 private SecretBigInteger(BigInteger value) { 30 this.value = value; 31 } 32 33 /** 34 * Creates a new SecretBigInteger with the content given in {@code value}. 35 * 36 * <p>The parameter {@code access} must be non-null. 37 */ fromBigInteger(BigInteger value, SecretKeyAccess access)38 public static SecretBigInteger fromBigInteger(BigInteger value, SecretKeyAccess access) { 39 if (access == null) { 40 throw new NullPointerException("SecretKeyAccess required"); 41 } 42 // Since BigInteger is immutable, there is no need to make a copy. 43 return new SecretBigInteger(value); 44 } 45 46 /** 47 * Returns the value wrapped by this object. 48 * 49 * <p>The parameter {@code access} must be non-null. 50 */ getBigInteger(SecretKeyAccess access)51 public BigInteger getBigInteger(SecretKeyAccess access) { 52 if (access == null) { 53 throw new NullPointerException("SecretKeyAccess required"); 54 } 55 return value; 56 } 57 58 /** 59 * Returns true if {@code other} has the same secret value. 60 * 61 * <p>Note that the time may depend on the length of the byte-encoding of the BigIntegers. 62 */ equalsSecretBigInteger(SecretBigInteger other)63 public boolean equalsSecretBigInteger(SecretBigInteger other) { 64 // BigInteger.toByteArray always return the minimal encoding, so it is not possible that two 65 // BigInteger of the same values return different encodings. 66 byte[] myArray = value.toByteArray(); 67 byte[] otherArray = other.value.toByteArray(); 68 return MessageDigest.isEqual(myArray, otherArray); 69 } 70 } 71