/* |
|
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. |
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
|
* |
|
* This code is free software; you can redistribute it and/or modify it |
|
* under the terms of the GNU General Public License version 2 only, as |
|
* published by the Free Software Foundation. Oracle designates this |
|
* particular file as subject to the "Classpath" exception as provided |
|
* by Oracle in the LICENSE file that accompanied this code. |
|
* |
|
* This code is distributed in the hope that it will be useful, but WITHOUT |
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
* version 2 for more details (a copy is included in the LICENSE file that |
|
* accompanied this code). |
|
* |
|
* You should have received a copy of the GNU General Public License version |
|
* 2 along with this work; if not, write to the Free Software Foundation, |
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
* |
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
|
* or visit www.oracle.com if you need additional information or have any |
|
* questions. |
|
*/ |
|
package sun.security.util.math; |
|
import java.math.BigInteger; |
|
/** |
|
* The base interface for integers modulo a prime value. Objects of this |
|
* type may be either mutable or immutable, and subinterfaces can be used |
|
* to specify that an object is mutable or immutable. This type should never |
|
* be used to declare local/member variables, but it may be used for |
|
* formal parameters of a method. None of the methods in this interface |
|
* modify the value of arguments or this. |
|
* |
|
* The behavior of this interface depends on the particular implementation. |
|
* For example, some implementations only support a limited number of add |
|
* operations before each multiply operation. See the documentation of the |
|
* implementation for details. |
|
* |
|
* @see ImmutableIntegerModuloP |
|
* @see MutableIntegerModuloP |
|
*/ |
|
public interface IntegerModuloP { |
|
/** |
|
* Get the field associated with this element. |
|
* |
|
* @return the field |
|
*/ |
|
IntegerFieldModuloP getField(); |
|
/** |
|
* Get the canonical value of this element as a BigInteger. This value |
|
* will always be in the range [0, p), where p is the prime that defines |
|
* the field. This method performs reduction and other computation to |
|
* produce the result. |
|
* |
|
* @return the value as a BigInteger |
|
*/ |
|
BigInteger asBigInteger(); |
|
/** |
|
* Return this value as a fixed (immutable) element. This method will |
|
* copy the underlying representation if the object is mutable. |
|
* |
|
* @return a fixed element with the same value |
|
*/ |
|
ImmutableIntegerModuloP fixed(); |
|
/** |
|
* Return this value as a mutable element. This method will always copy |
|
* the underlying representation. |
|
* |
|
* @return a mutable element with the same value |
|
*/ |
|
MutableIntegerModuloP mutable(); |
|
/** |
|
* Add this field element with the supplied element and return the result. |
|
* |
|
* @param b the sumand |
|
* @return this + b |
|
*/ |
|
ImmutableIntegerModuloP add(IntegerModuloP b); |
|
/** |
|
* Compute the additive inverse of the field element |
|
* @return the addditiveInverse (0 - this) |
|
*/ |
|
ImmutableIntegerModuloP additiveInverse(); |
|
/** |
|
* Multiply this field element with the supplied element and return the |
|
* result. |
|
* |
|
* @param b the multiplicand |
|
* @return this * b |
|
*/ |
|
ImmutableIntegerModuloP multiply(IntegerModuloP b); |
|
/** |
|
* Perform an addition modulo a power of two and return the little-endian |
|
* encoding of the result. The value is (this' + b') % 2^(8 * len), |
|
* where this' and b' are the canonical integer values equivalent to |
|
* this and b. |
|
* |
|
* @param b the sumand |
|
* @param len the length of the desired array |
|
* @return a byte array of length len containing the result |
|
*/ |
|
default byte[] addModPowerTwo(IntegerModuloP b, int len) { |
|
byte[] result = new byte[len]; |
|
addModPowerTwo(b, result); |
|
return result; |
|
} |
|
/** |
|
* Perform an addition modulo a power of two and store the little-endian |
|
* encoding of the result in the supplied array. The value is |
|
* (this' + b') % 2^(8 * result.length), where this' and b' are the |
|
* canonical integer values equivalent to this and b. |
|
* |
|
* @param b the sumand |
|
* @param result an array which stores the result upon return |
|
*/ |
|
void addModPowerTwo(IntegerModuloP b, byte[] result); |
|
/** |
|
* Returns the little-endian encoding of this' % 2^(8 * len), where this' |
|
* is the canonical integer value equivalent to this. |
|
* |
|
* @param len the length of the desired array |
|
* @return a byte array of length len containing the result |
|
*/ |
|
default byte[] asByteArray(int len) { |
|
byte[] result = new byte[len]; |
|
asByteArray(result); |
|
return result; |
|
} |
|
/** |
|
* Places the little-endian encoding of this' % 2^(8 * result.length) |
|
* into the supplied array, where this' is the canonical integer value |
|
* equivalent to this. |
|
* |
|
* @param result an array which stores the result upon return |
|
*/ |
|
void asByteArray(byte[] result); |
|
/** |
|
* Compute the multiplicative inverse of this field element. |
|
* |
|
* @return the multiplicative inverse (1 / this) |
|
*/ |
|
default ImmutableIntegerModuloP multiplicativeInverse() { |
|
return pow(getField().getSize().subtract(BigInteger.valueOf(2))); |
|
} |
|
/** |
|
* Subtract the supplied element from this one and return the result. |
|
* @param b the subtrahend |
|
* |
|
* @return the difference (this - b) |
|
*/ |
|
default ImmutableIntegerModuloP subtract(IntegerModuloP b) { |
|
return add(b.additiveInverse()); |
|
} |
|
/** |
|
* Calculate the square of this element and return the result. This method |
|
* should be used instead of a.multiply(a) because implementations may |
|
* include optimizations that only apply to squaring. |
|
* |
|
* @return the product (this * this) |
|
*/ |
|
default ImmutableIntegerModuloP square() { |
|
return multiply(this); |
|
} |
|
/** |
|
* Calculate the power this^b and return the result. |
|
* |
|
* @param b the exponent |
|
* @return the value of this^b |
|
*/ |
|
default ImmutableIntegerModuloP pow(BigInteger b) { |
|
//Default implementation is square and multiply |
|
MutableIntegerModuloP y = getField().get1().mutable(); |
|
MutableIntegerModuloP x = mutable(); |
|
int bitLength = b.bitLength(); |
|
for (int bit = 0; bit < bitLength; bit++) { |
|
if (b.testBit(bit)) { |
|
// odd |
|
y.setProduct(x); |
|
} |
|
x.setSquare(); |
|
} |
|
return y.fixed(); |
|
} |
|
} |
|