feat(jdk8): move files to new folder to avoid resources compiled.

This commit is contained in:
2025-09-07 15:25:52 +08:00
parent 3f0047bf6f
commit 8c35cfb1c0
17415 changed files with 217 additions and 213 deletions

View File

@@ -0,0 +1,34 @@
/*
* 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;
/**
* An interface for immutable integers modulo a prime value.
*/
public interface ImmutableIntegerModuloP extends IntegerModuloP {
}

View File

@@ -0,0 +1,115 @@
/*
* 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;
/**
* An interface for the field of integers modulo a prime number. An
* implementation of this interface can be used to get properties of the
* field and to produce field elements of type ImmutableIntegerModuloP from
* other objects and representations of field elements.
*/
public interface IntegerFieldModuloP {
/**
* Get the size of the field as a BigInteger. This size is equal to the
* prime modulus used to construct the field.
*
* @return the size of the field.
*/
BigInteger getSize();
/**
* Get the additive identity element 0
*
* @return the additive identity element
*/
ImmutableIntegerModuloP get0();
/**
* Get the multiplicative identity element 1
*
* @return the multiplicative identity element
*/
ImmutableIntegerModuloP get1();
/**
* Get the field element equivalent to the supplied BigInteger value. The
* supplied value may be negative or larger than the modulus that defines
* the field.
*
* @param v a BigInteger value
* @return the field element corresponding to v
*/
ImmutableIntegerModuloP getElement(BigInteger v);
/**
* Get a "small" value according to this implementation. This value may
* be used in optimized forms of some operations to avoid unnecessary
* calculations. For example, multiplication is much faster when it is
* known that one of the numbers fits within a single limb.
*
* The definition of "small", and the range of accepted values, is
* implementation-specific.
*
* @param v the small integer value
* @throws IllegalArgumentException when the value is not small
*/
SmallValue getSmallValue(int v);
/**
* Get a field element from a little-endian unsigned integer stored in an
* array. The entire array will be used, and the supplied value may be
* larger than the modulus that defines the field. The array will not be
* modified.
*
* @param v an array containing a little-endian unsigned integer
* @return the field element corresponding to v
*/
default ImmutableIntegerModuloP getElement(byte[] v) {
return getElement(v, 0, v.length, (byte) 0);
}
/**
* Get a field element from a little-endian unsigned integer stored at the
* specified position in an array. The supplied value may be
* larger than the modulus that defines the field. This method also takes
* a byte which is interpreted as an additional high-order byte of the
* number. The array will not be modified.
*
* @param v an array containing a little-endian unsigned integer
* @param offset the starting position of the integer
* @param length the number of bytes to read
* @param highByte the high-order byte of the number
* @return the field element corresponding to the bytes at the specified
* position
*/
ImmutableIntegerModuloP getElement(byte[] v, int offset, int length,
byte highByte);
}

View File

@@ -0,0 +1,205 @@
/*
* 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();
}
}

View File

@@ -0,0 +1,162 @@
/*
* 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.nio.ByteBuffer;
/**
* An interface for mutable integers modulo a prime value. This interface
* should be used to improve performance and avoid the allocation of a large
* number of temporary objects.
*
* Methods in this interface that modify the value also return the modified
* element. This structure enables fluent expressions like:
* a.setSum(b).setProduct(c).setDifference(d).setSquare()
*
*/
public interface MutableIntegerModuloP extends IntegerModuloP {
/**
* Set this value to the value of b when set has the value 1.
* No change is made to this element when set has the value 0. The
* result is undefined when set has a value other than 0 or 1. The set
* parameter is an int (rather than boolean) to allow the implementation
* to perform the assignment using branch-free integer arithmetic.
*
* @param b the element to conditionally swap with
* @param set an int that determines whether to set
*/
void conditionalSet(IntegerModuloP b, int set);
/**
* Swap the value of this with the value of b when swap has the value 1.
* No change is made to either element when swap has the value 0. The
* result is undefined when swap has a value other than 0 or 1. The swap
* parameter is an int (rather than boolean) to allow the implementation
* to perform the swap using branch-free integer arithmetic.
*
* @param b the element to conditionally swap with
* @param swap an int that determines whether to swap
*/
void conditionalSwapWith(MutableIntegerModuloP b, int swap);
/**
* Set the value of this element equal to the value of the supplied
* element. The argument is not modified.
*
* @param v the element whose value should be copied to this
* @return this
*/
MutableIntegerModuloP setValue(IntegerModuloP v);
/**
* Set the value equal to the little-endian unsigned integer stored at the
* specified position in an array. The range of accepted values is
* implementation-specific. This method also takes a byte which is
* interpreted as an additional high-order byte of the number.
*
* @param v an array containing a little-endian unsigned integer
* @param offset the starting position of the integer
* @param length the number of bytes to read
* @param highByte the high-order byte of the number
* @return this
*/
MutableIntegerModuloP setValue(byte[] v, int offset, int length,
byte highByte);
/**
* Set the value equal to the little-endian unsigned integer stored in a
* buffer. The range of accepted values is implementation-specific.
* This method also takes a byte which is interpreted as an additional
* high-order byte of the number.
*
* @param buf a buffer containing a little-endian unsigned integer
* @param length the number of bytes to read
* @param highByte the high-order byte of the number
* @return this
*/
MutableIntegerModuloP setValue(ByteBuffer buf, int length, byte highByte);
/**
* Set the value of this element equal to this * this.
*
* @return this
*/
MutableIntegerModuloP setSquare();
/**
* Set the value of this element equal to this + b. The argument is
* not modified.
*
* @param b the sumand
* @return this
*/
MutableIntegerModuloP setSum(IntegerModuloP b);
/**
* Set the value of this element equal to this - b. The argument is
* not modified.
*
* @param b the subtrahend
* @return this
*/
MutableIntegerModuloP setDifference(IntegerModuloP b);
/**
* Set the value of this element equal to this * b. The argument is
* not modified.
*
* @param b the multiplicand
* @return this
*/
MutableIntegerModuloP setProduct(IntegerModuloP b);
/**
* Set the value of this element equal to this * v. The argument is
* not modified.
*
* @param v the small multiplicand
* @return this
*/
MutableIntegerModuloP setProduct(SmallValue v);
/**
* Set the value of this element equal to 0 - this.
*
* @return this
*/
MutableIntegerModuloP setAdditiveInverse();
/**
* Some implementations required reduction operations to be requested
* by the client at certain times. This method reduces the representation.
*
* @return this
*/
MutableIntegerModuloP setReduced();
}

View File

@@ -0,0 +1,38 @@
/*
* 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;
/**
* A "small" value that can be used with the field arithmetic library. This
* interface enables optimizations based on the fact that certain values are
* known to be small, where the definition of small is specific to the the
* arithmetic implementation.
*/
public interface SmallValue {
}

View File

@@ -0,0 +1,767 @@
/*
* 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.intpoly;
import sun.security.util.math.*;
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Arrays;
/**
* A large number polynomial representation using sparse limbs of signed
* long (64-bit) values. Limb values will always fit within a long, so inputs
* to multiplication must be less than 32 bits. All IntegerPolynomial
* implementations allow at most one addition before multiplication. Additions
* after that will result in an ArithmeticException.
*
* The following element operations are branch-free for all subclasses:
*
* fixed
* mutable
* add
* additiveInverse
* multiply
* square
* subtract
* conditionalSwapWith
* setValue (may branch on high-order byte parameter only)
* setSum
* setDifference
* setProduct
* setSquare
* addModPowerTwo
* asByteArray
*
* All other operations may branch in some subclasses.
*
*/
public abstract class IntegerPolynomial implements IntegerFieldModuloP {
protected static final BigInteger TWO = BigInteger.valueOf(2);
protected final int numLimbs;
private final BigInteger modulus;
protected final int bitsPerLimb;
private final long[] posModLimbs;
private final int maxAdds;
/**
* Reduce an IntegerPolynomial representation (a) and store the result
* in a. Requires that a.length == numLimbs.
*/
protected abstract void reduce(long[] a);
/**
* Multiply an IntegerPolynomial representation (a) with a long (b) and
* store the result in an IntegerPolynomial representation in a. Requires
* that a.length == numLimbs.
*/
protected void multByInt(long[] a, long b) {
for (int i = 0; i < a.length; i++) {
a[i] *= b;
}
reduce(a);
}
/**
* Multiply two IntegerPolynomial representations (a and b) and store the
* result in an IntegerPolynomial representation (r). Requires that
* a.length == b.length == r.length == numLimbs. It is allowed for a and r
* to be the same array.
*/
protected abstract void mult(long[] a, long[] b, long[] r);
/**
* Multiply an IntegerPolynomial representation (a) with itself and store
* the result in an IntegerPolynomialRepresentation (r). Requires that
* a.length == r.length == numLimbs. It is allowed for a and r
* to be the same array.
*/
protected abstract void square(long[] a, long[] r);
IntegerPolynomial(int bitsPerLimb,
int numLimbs,
int maxAdds,
BigInteger modulus) {
this.numLimbs = numLimbs;
this.modulus = modulus;
this.bitsPerLimb = bitsPerLimb;
this.maxAdds = maxAdds;
posModLimbs = setPosModLimbs();
}
private long[] setPosModLimbs() {
long[] result = new long[numLimbs];
setLimbsValuePositive(modulus, result);
return result;
}
protected int getNumLimbs() {
return numLimbs;
}
public int getMaxAdds() {
return maxAdds;
}
@Override
public BigInteger getSize() {
return modulus;
}
@Override
public ImmutableElement get0() {
return new ImmutableElement(false);
}
@Override
public ImmutableElement get1() {
return new ImmutableElement(true);
}
@Override
public ImmutableElement getElement(BigInteger v) {
return new ImmutableElement(v);
}
@Override
public SmallValue getSmallValue(int value) {
int maxMag = 1 << (bitsPerLimb - 1);
if (Math.abs(value) >= maxMag) {
throw new IllegalArgumentException(
"max magnitude is " + maxMag);
}
return new Limb(value);
}
/**
* This version of encode takes a ByteBuffer that is properly ordered, and
* may extract larger values (e.g. long) from the ByteBuffer for better
* performance. The implementation below only extracts bytes from the
* buffer, but this method may be overridden in field-specific
* implementations.
*/
protected void encode(ByteBuffer buf, int length, byte highByte,
long[] result) {
int numHighBits = 32 - Integer.numberOfLeadingZeros(highByte);
int numBits = 8 * length + numHighBits;
int requiredLimbs = (numBits + bitsPerLimb - 1) / bitsPerLimb;
if (requiredLimbs > numLimbs) {
long[] temp = new long[requiredLimbs];
encodeSmall(buf, length, highByte, temp);
// encode does a full carry/reduce
System.arraycopy(temp, 0, result, 0, result.length);
} else {
encodeSmall(buf, length, highByte, result);
}
}
protected void encodeSmall(ByteBuffer buf, int length, byte highByte,
long[] result) {
int limbIndex = 0;
long curLimbValue = 0;
int bitPos = 0;
for (int i = 0; i < length; i++) {
long curV = buf.get() & 0xFF;
if (bitPos + 8 >= bitsPerLimb) {
int bitsThisLimb = bitsPerLimb - bitPos;
curLimbValue += (curV & (0xFF >> (8 - bitsThisLimb))) << bitPos;
result[limbIndex++] = curLimbValue;
curLimbValue = curV >> bitsThisLimb;
bitPos = 8 - bitsThisLimb;
}
else {
curLimbValue += curV << bitPos;
bitPos += 8;
}
}
// one more for the high byte
if (highByte != 0) {
long curV = highByte & 0xFF;
if (bitPos + 8 >= bitsPerLimb) {
int bitsThisLimb = bitsPerLimb - bitPos;
curLimbValue += (curV & (0xFF >> (8 - bitsThisLimb))) << bitPos;
result[limbIndex++] = curLimbValue;
curLimbValue = curV >> bitsThisLimb;
}
else {
curLimbValue += curV << bitPos;
}
}
if (limbIndex < result.length) {
result[limbIndex++] = curLimbValue;
}
Arrays.fill(result, limbIndex, result.length, 0);
postEncodeCarry(result);
}
protected void encode(byte[] v, int offset, int length, byte highByte,
long[] result) {
ByteBuffer buf = ByteBuffer.wrap(v, offset, length);
buf.order(ByteOrder.LITTLE_ENDIAN);
encode(buf, length, highByte, result);
}
// Encode does not produce compressed limbs. A simplified carry/reduce
// operation can be used to compress the limbs.
protected void postEncodeCarry(long[] v) {
reduce(v);
}
public ImmutableElement getElement(byte[] v, int offset, int length,
byte highByte) {
long[] result = new long[numLimbs];
encode(v, offset, length, highByte, result);
return new ImmutableElement(result, 0);
}
protected BigInteger evaluate(long[] limbs) {
BigInteger result = BigInteger.ZERO;
for (int i = limbs.length - 1; i >= 0; i--) {
result = result.shiftLeft(bitsPerLimb)
.add(BigInteger.valueOf(limbs[i]));
}
return result.mod(modulus);
}
protected long carryValue(long x) {
// compressing carry operation
// if large positive number, carry one more to make it negative
// if large negative number (closer to zero), carry one fewer
return (x + (1 << (bitsPerLimb - 1))) >> bitsPerLimb;
}
protected void carry(long[] limbs, int start, int end) {
for (int i = start; i < end; i++) {
long carry = carryOut(limbs, i);
limbs[i + 1] += carry;
}
}
protected void carry(long[] limbs) {
carry(limbs, 0, limbs.length - 1);
}
/**
* Carry out of the specified position and return the carry value.
*/
protected long carryOut(long[] limbs, int index) {
long carry = carryValue(limbs[index]);
limbs[index] -= (carry << bitsPerLimb);
return carry;
}
private void setLimbsValue(BigInteger v, long[] limbs) {
// set all limbs positive, and then carry
setLimbsValuePositive(v, limbs);
carry(limbs);
}
protected void setLimbsValuePositive(BigInteger v, long[] limbs) {
BigInteger mod = BigInteger.valueOf(1 << bitsPerLimb);
for (int i = 0; i < limbs.length; i++) {
limbs[i] = v.mod(mod).longValue();
v = v.shiftRight(bitsPerLimb);
}
}
/**
* Carry out of the last limb and reduce back in. This method will be
* called as part of the "finalReduce" operation that puts the
* representation into a fully-reduced form. It is representation-
* specific, because representations have different amounts of empty
* space in the high-order limb. Requires that limbs.length=numLimbs.
*/
protected abstract void finalCarryReduceLast(long[] limbs);
/**
* Convert reduced limbs into a number between 0 and MODULUS-1.
* Requires that limbs.length == numLimbs. This method only works if the
* modulus has at most three terms.
*/
protected void finalReduce(long[] limbs) {
// This method works by doing several full carry/reduce operations.
// Some representations have extra high bits, so the carry/reduce out
// of the high position is implementation-specific. The "unsigned"
// carry operation always carries some (negative) value out of a
// position occupied by a negative value. So after a number of
// passes, all negative values are removed.
// The first pass may leave a negative value in the high position, but
// this only happens if something was carried out of the previous
// position. So the previous position must have a "small" value. The
// next full carry is guaranteed not to carry out of that position.
for (int pass = 0; pass < 2; pass++) {
// unsigned carry out of last position and reduce in to
// first position
finalCarryReduceLast(limbs);
// unsigned carry on all positions
long carry = 0;
for (int i = 0; i < numLimbs - 1; i++) {
limbs[i] += carry;
carry = limbs[i] >> bitsPerLimb;
limbs[i] -= carry << bitsPerLimb;
}
limbs[numLimbs - 1] += carry;
}
// Limbs are positive and all less than 2^bitsPerLimb, and the
// high-order limb may be even smaller due to the representation-
// specific carry/reduce out of the high position.
// The value may still be greater than the modulus.
// Subtract the max limb values only if all limbs end up non-negative
// This only works if there is at most one position where posModLimbs
// is less than 2^bitsPerLimb - 1 (not counting the high-order limb,
// if it has extra bits that are cleared by finalCarryReduceLast).
int smallerNonNegative = 1;
long[] smaller = new long[numLimbs];
for (int i = numLimbs - 1; i >= 0; i--) {
smaller[i] = limbs[i] - posModLimbs[i];
// expression on right is 1 if smaller[i] is nonnegative,
// 0 otherwise
smallerNonNegative *= (int) (smaller[i] >> 63) + 1;
}
conditionalSwap(smallerNonNegative, limbs, smaller);
}
/**
* Decode the value in v and store it in dst. Requires that v is final
* reduced. I.e. all limbs in [0, 2^bitsPerLimb) and value in [0, modulus).
*/
protected void decode(long[] v, byte[] dst, int offset, int length) {
int nextLimbIndex = 0;
long curLimbValue = v[nextLimbIndex++];
int bitPos = 0;
for (int i = 0; i < length; i++) {
int dstIndex = i + offset;
if (bitPos + 8 >= bitsPerLimb) {
dst[dstIndex] = (byte) curLimbValue;
curLimbValue = 0;
if (nextLimbIndex < v.length) {
curLimbValue = v[nextLimbIndex++];
}
int bitsAdded = bitsPerLimb - bitPos;
int bitsLeft = 8 - bitsAdded;
dst[dstIndex] += (curLimbValue & (0xFF >> bitsAdded))
<< bitsAdded;
curLimbValue >>= bitsLeft;
bitPos = bitsLeft;
} else {
dst[dstIndex] = (byte) curLimbValue;
curLimbValue >>= 8;
bitPos += 8;
}
}
}
/**
* Add two IntegerPolynomial representations (a and b) and store the result
* in an IntegerPolynomialRepresentation (dst). Requires that
* a.length == b.length == dst.length. It is allowed for a and
* dst to be the same array.
*/
protected void addLimbs(long[] a, long[] b, long[] dst) {
for (int i = 0; i < dst.length; i++) {
dst[i] = a[i] + b[i];
}
}
/**
* Branch-free conditional assignment of b to a. Requires that set is 0 or
* 1, and that a.length == b.length. If set==0, then the values of a and b
* will be unchanged. If set==1, then the values of b will be assigned to a.
* The behavior is undefined if swap has any value other than 0 or 1.
*/
protected static void conditionalAssign(int set, long[] a, long[] b) {
int maskValue = 0 - set;
for (int i = 0; i < a.length; i++) {
long dummyLimbs = maskValue & (a[i] ^ b[i]);
a[i] = dummyLimbs ^ a[i];
}
}
/**
* Branch-free conditional swap of a and b. Requires that swap is 0 or 1,
* and that a.length == b.length. If swap==0, then the values of a and b
* will be unchanged. If swap==1, then the values of a and b will be
* swapped. The behavior is undefined if swap has any value other than
* 0 or 1.
*/
protected static void conditionalSwap(int swap, long[] a, long[] b) {
int maskValue = 0 - swap;
for (int i = 0; i < a.length; i++) {
long dummyLimbs = maskValue & (a[i] ^ b[i]);
a[i] = dummyLimbs ^ a[i];
b[i] = dummyLimbs ^ b[i];
}
}
/**
* Stores the reduced, little-endian value of limbs in result.
*/
protected void limbsToByteArray(long[] limbs, byte[] result) {
long[] reducedLimbs = limbs.clone();
finalReduce(reducedLimbs);
decode(reducedLimbs, result, 0, result.length);
}
/**
* Add the reduced number corresponding to limbs and other, and store
* the low-order bytes of the sum in result. Requires that
* limbs.length==other.length. The result array may have any length.
*/
protected void addLimbsModPowerTwo(long[] limbs, long[] other,
byte[] result) {
long[] reducedOther = other.clone();
long[] reducedLimbs = limbs.clone();
finalReduce(reducedOther);
finalReduce(reducedLimbs);
addLimbs(reducedLimbs, reducedOther, reducedLimbs);
// may carry out a value which can be ignored
long carry = 0;
for (int i = 0; i < numLimbs; i++) {
reducedLimbs[i] += carry;
carry = reducedLimbs[i] >> bitsPerLimb;
reducedLimbs[i] -= carry << bitsPerLimb;
}
decode(reducedLimbs, result, 0, result.length);
}
private abstract class Element implements IntegerModuloP {
protected long[] limbs;
protected int numAdds;
public Element(BigInteger v) {
limbs = new long[numLimbs];
setValue(v);
}
public Element(boolean v) {
this.limbs = new long[numLimbs];
this.limbs[0] = v ? 1l : 0l;
this.numAdds = 0;
}
private Element(long[] limbs, int numAdds) {
this.limbs = limbs;
this.numAdds = numAdds;
}
private void setValue(BigInteger v) {
setLimbsValue(v, limbs);
this.numAdds = 0;
}
@Override
public IntegerFieldModuloP getField() {
return IntegerPolynomial.this;
}
@Override
public BigInteger asBigInteger() {
return evaluate(limbs);
}
@Override
public MutableElement mutable() {
return new MutableElement(limbs.clone(), numAdds);
}
protected boolean isSummand() {
return numAdds < maxAdds;
}
@Override
public ImmutableElement add(IntegerModuloP genB) {
Element b = (Element) genB;
if (!(isSummand() && b.isSummand())) {
throw new ArithmeticException("Not a valid summand");
}
long[] newLimbs = new long[limbs.length];
for (int i = 0; i < limbs.length; i++) {
newLimbs[i] = limbs[i] + b.limbs[i];
}
int newNumAdds = Math.max(numAdds, b.numAdds) + 1;
return new ImmutableElement(newLimbs, newNumAdds);
}
@Override
public ImmutableElement additiveInverse() {
long[] newLimbs = new long[limbs.length];
for (int i = 0; i < limbs.length; i++) {
newLimbs[i] = -limbs[i];
}
ImmutableElement result = new ImmutableElement(newLimbs, numAdds);
return result;
}
protected long[] cloneLow(long[] limbs) {
long[] newLimbs = new long[numLimbs];
copyLow(limbs, newLimbs);
return newLimbs;
}
protected void copyLow(long[] limbs, long[] out) {
System.arraycopy(limbs, 0, out, 0, out.length);
}
@Override
public ImmutableElement multiply(IntegerModuloP genB) {
Element b = (Element) genB;
long[] newLimbs = new long[limbs.length];
mult(limbs, b.limbs, newLimbs);
return new ImmutableElement(newLimbs, 0);
}
@Override
public ImmutableElement square() {
long[] newLimbs = new long[limbs.length];
IntegerPolynomial.this.square(limbs, newLimbs);
return new ImmutableElement(newLimbs, 0);
}
public void addModPowerTwo(IntegerModuloP arg, byte[] result) {
Element other = (Element) arg;
if (!(isSummand() && other.isSummand())) {
throw new ArithmeticException("Not a valid summand");
}
addLimbsModPowerTwo(limbs, other.limbs, result);
}
public void asByteArray(byte[] result) {
if (!isSummand()) {
throw new ArithmeticException("Not a valid summand");
}
limbsToByteArray(limbs, result);
}
}
protected class MutableElement extends Element
implements MutableIntegerModuloP {
protected MutableElement(long[] limbs, int numAdds) {
super(limbs, numAdds);
}
@Override
public ImmutableElement fixed() {
return new ImmutableElement(limbs.clone(), numAdds);
}
@Override
public void conditionalSet(IntegerModuloP b, int set) {
Element other = (Element) b;
conditionalAssign(set, limbs, other.limbs);
numAdds = other.numAdds;
}
@Override
public void conditionalSwapWith(MutableIntegerModuloP b, int swap) {
MutableElement other = (MutableElement) b;
conditionalSwap(swap, limbs, other.limbs);
int numAddsTemp = numAdds;
numAdds = other.numAdds;
other.numAdds = numAddsTemp;
}
@Override
public MutableElement setValue(IntegerModuloP v) {
Element other = (Element) v;
System.arraycopy(other.limbs, 0, limbs, 0, other.limbs.length);
numAdds = other.numAdds;
return this;
}
@Override
public MutableElement setValue(byte[] arr, int offset,
int length, byte highByte) {
encode(arr, offset, length, highByte, limbs);
this.numAdds = 0;
return this;
}
@Override
public MutableElement setValue(ByteBuffer buf, int length,
byte highByte) {
encode(buf, length, highByte, limbs);
numAdds = 0;
return this;
}
@Override
public MutableElement setProduct(IntegerModuloP genB) {
Element b = (Element) genB;
mult(limbs, b.limbs, limbs);
numAdds = 0;
return this;
}
@Override
public MutableElement setProduct(SmallValue v) {
int value = ((Limb) v).value;
multByInt(limbs, value);
numAdds = 0;
return this;
}
@Override
public MutableElement setSum(IntegerModuloP genB) {
Element b = (Element) genB;
if (!(isSummand() && b.isSummand())) {
throw new ArithmeticException("Not a valid summand");
}
for (int i = 0; i < limbs.length; i++) {
limbs[i] = limbs[i] + b.limbs[i];
}
numAdds = Math.max(numAdds, b.numAdds) + 1;
return this;
}
@Override
public MutableElement setDifference(IntegerModuloP genB) {
Element b = (Element) genB;
if (!(isSummand() && b.isSummand())) {
throw new ArithmeticException("Not a valid summand");
}
for (int i = 0; i < limbs.length; i++) {
limbs[i] = limbs[i] - b.limbs[i];
}
numAdds = Math.max(numAdds, b.numAdds) + 1;
return this;
}
@Override
public MutableElement setSquare() {
IntegerPolynomial.this.square(limbs, limbs);
numAdds = 0;
return this;
}
@Override
public MutableElement setAdditiveInverse() {
for (int i = 0; i < limbs.length; i++) {
limbs[i] = -limbs[i];
}
return this;
}
@Override
public MutableElement setReduced() {
reduce(limbs);
numAdds = 0;
return this;
}
}
class ImmutableElement extends Element implements ImmutableIntegerModuloP {
protected ImmutableElement(BigInteger v) {
super(v);
}
protected ImmutableElement(boolean v) {
super(v);
}
protected ImmutableElement(long[] limbs, int numAdds) {
super(limbs, numAdds);
}
@Override
public ImmutableElement fixed() {
return this;
}
}
class Limb implements SmallValue {
int value;
Limb(int value) {
this.value = value;
}
}
}

View File

@@ -0,0 +1,209 @@
/*
* 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.intpoly;
import java.lang.invoke.MethodHandles;
import java.math.BigInteger;
import java.nio.*;
/**
* An IntegerFieldModuloP designed for use with the Poly1305 authenticator.
* The representation uses 5 signed long values.
*/
public class IntegerPolynomial1305 extends IntegerPolynomial {
protected static final int SUBTRAHEND = 5;
protected static final int NUM_LIMBS = 5;
private static final int POWER = 130;
private static final int BITS_PER_LIMB = 26;
private static final BigInteger MODULUS
= TWO.pow(POWER).subtract(BigInteger.valueOf(SUBTRAHEND));
public IntegerPolynomial1305() {
super(BITS_PER_LIMB, NUM_LIMBS, 1, MODULUS);
}
protected void mult(long[] a, long[] b, long[] r) {
// Use grade-school multiplication into primitives to avoid the
// temporary array allocation. This is equivalent to the following
// code:
// long[] c = new long[2 * NUM_LIMBS - 1];
// for(int i = 0; i < NUM_LIMBS; i++) {
// for(int j - 0; j < NUM_LIMBS; j++) {
// c[i + j] += a[i] * b[j]
// }
// }
long c0 = (a[0] * b[0]);
long c1 = (a[0] * b[1]) + (a[1] * b[0]);
long c2 = (a[0] * b[2]) + (a[1] * b[1]) + (a[2] * b[0]);
long c3 = (a[0] * b[3]) + (a[1] * b[2]) + (a[2] * b[1]) + (a[3] * b[0]);
long c4 = (a[0] * b[4]) + (a[1] * b[3]) + (a[2] * b[2]) + (a[3] * b[1]) + (a[4] * b[0]);
long c5 = (a[1] * b[4]) + (a[2] * b[3]) + (a[3] * b[2]) + (a[4] * b[1]);
long c6 = (a[2] * b[4]) + (a[3] * b[3]) + (a[4] * b[2]);
long c7 = (a[3] * b[4]) + (a[4] * b[3]);
long c8 = (a[4] * b[4]);
carryReduce(r, c0, c1, c2, c3, c4, c5, c6, c7, c8);
}
private void carryReduce(long[] r, long c0, long c1, long c2, long c3,
long c4, long c5, long c6, long c7, long c8) {
//reduce(2, 2)
r[2] = c2 + (c7 * SUBTRAHEND);
c3 += (c8 * SUBTRAHEND);
// carry(3, 2)
long carry3 = carryValue(c3);
r[3] = c3 - (carry3 << BITS_PER_LIMB);
c4 += carry3;
long carry4 = carryValue(c4);
r[4] = c4 - (carry4 << BITS_PER_LIMB);
c5 += carry4;
// reduce(0, 2)
r[0] = c0 + (c5 * SUBTRAHEND);
r[1] = c1 + (c6 * SUBTRAHEND);
// carry(0, 4)
carry(r);
}
@Override
protected void square(long[] a, long[] r) {
// Use grade-school multiplication with a simple squaring optimization.
// Multiply into primitives to avoid the temporary array allocation.
// This is equivalent to the following code:
// long[] c = new long[2 * NUM_LIMBS - 1];
// for(int i = 0; i < NUM_LIMBS; i++) {
// c[2 * i] = a[i] * a[i];
// for(int j = i + 1; j < NUM_LIMBS; j++) {
// c[i + j] += 2 * a[i] * a[j]
// }
// }
long c0 = (a[0] * a[0]);
long c1 = 2 * (a[0] * a[1]);
long c2 = 2 * (a[0] * a[2]) + (a[1] * a[1]);
long c3 = 2 * (a[0] * a[3] + a[1] * a[2]);
long c4 = 2 * (a[0] * a[4] + a[1] * a[3]) + (a[2] * a[2]);
long c5 = 2 * (a[1] * a[4] + a[2] * a[3]);
long c6 = 2 * (a[2] * a[4]) + (a[3] * a[3]);
long c7 = 2 * (a[3] * a[4]);
long c8 = (a[4] * a[4]);
carryReduce(r, c0, c1, c2, c3, c4, c5, c6, c7, c8);
}
@Override
protected void encode(ByteBuffer buf, int length, byte highByte,
long[] result) {
if (length == 16) {
long low = buf.getLong();
long high = buf.getLong();
encode(high, low, highByte, result);
} else {
super.encode(buf, length, highByte, result);
}
}
protected void encode(long high, long low, byte highByte, long[] result) {
result[0] = low & 0x3FFFFFFL;
result[1] = (low >>> 26) & 0x3FFFFFFL;
result[2] = (low >>> 52) + ((high & 0x3FFFL) << 12);
result[3] = (high >>> 14) & 0x3FFFFFFL;
result[4] = (high >>> 40) + (highByte << 24L);
}
protected void encode(byte[] v, int offset, int length, byte highByte,
long[] result) {
if (length == 16) {
ByteBuffer asLongLEBuffer = ByteBuffer.wrap(v, offset, length)
.order(ByteOrder.LITTLE_ENDIAN);
long low = asLongLEBuffer.getLong();
long high = asLongLEBuffer.getLong();
encode(high, low, highByte, result);
} else {
super.encode(v, offset, length, highByte, result);
}
}
private void modReduceIn(long[] limbs, int index, long x) {
// this only works when BITS_PER_LIMB * NUM_LIMBS = POWER exactly
long reducedValue = (x * SUBTRAHEND);
limbs[index - NUM_LIMBS] += reducedValue;
}
@Override
protected void finalCarryReduceLast(long[] limbs) {
long carry = limbs[numLimbs - 1] >> bitsPerLimb;
limbs[numLimbs - 1] -= carry << bitsPerLimb;
modReduceIn(limbs, numLimbs, carry);
}
protected final void modReduce(long[] limbs, int start, int end) {
for (int i = start; i < end; i++) {
modReduceIn(limbs, i, limbs[i]);
limbs[i] = 0;
}
}
protected void modReduce(long[] limbs) {
modReduce(limbs, NUM_LIMBS, NUM_LIMBS - 1);
}
@Override
protected long carryValue(long x) {
// This representation has plenty of extra space, so we can afford to
// do a simplified carry operation that is more time-efficient.
return x >> BITS_PER_LIMB;
}
@Override
protected void postEncodeCarry(long[] v) {
// not needed because carry is unsigned
}
@Override
protected void reduce(long[] limbs) {
long carry3 = carryOut(limbs, 3);
long new4 = carry3 + limbs[4];
long carry4 = carryValue(new4);
limbs[4] = new4 - (carry4 << BITS_PER_LIMB);
modReduceIn(limbs, 5, carry4);
carry(limbs);
}
}

View File

@@ -0,0 +1,215 @@
/*
* 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.intpoly;
import java.math.BigInteger;
/**
* An IntegerFieldModuloP designed for use with the Curve25519.
* The representation uses 10 signed long values.
*/
public class IntegerPolynomial25519 extends IntegerPolynomial {
private static final int POWER = 255;
private static final int SUBTRAHEND = 19;
private static final int NUM_LIMBS = 10;
private static final int BITS_PER_LIMB = 26;
public static final BigInteger MODULUS
= TWO.pow(POWER).subtract(BigInteger.valueOf(SUBTRAHEND));
// BITS_PER_LIMB does not divide POWER, so reduction is a bit complicated
// The constants below help split up values during reduction
private static final int BIT_OFFSET = NUM_LIMBS * BITS_PER_LIMB - POWER;
private static final int LIMB_MASK = -1 >>> (64 - BITS_PER_LIMB);
private static final int RIGHT_BIT_OFFSET = BITS_PER_LIMB - BIT_OFFSET;
public IntegerPolynomial25519() {
super(BITS_PER_LIMB, NUM_LIMBS, 1, MODULUS);
}
@Override
protected void finalCarryReduceLast(long[] limbs) {
long reducedValue = limbs[numLimbs - 1] >> RIGHT_BIT_OFFSET;
limbs[numLimbs - 1] -= reducedValue << RIGHT_BIT_OFFSET;
limbs[0] += reducedValue * SUBTRAHEND;
}
@Override
protected void reduce(long[] a) {
// carry(8, 2)
long carry8 = carryValue(a[8]);
a[8] -= (carry8 << BITS_PER_LIMB);
a[9] += carry8;
long carry9 = carryValue(a[9]);
a[9] -= (carry9 << BITS_PER_LIMB);
// reduce(0, 1)
long reducedValue10 = (carry9 * SUBTRAHEND);
a[0] += ((reducedValue10 << BIT_OFFSET) & LIMB_MASK);
a[1] += reducedValue10 >> RIGHT_BIT_OFFSET;
// carry(0, 9)
carry(a, 0, 9);
}
@Override
protected void mult(long[] a, long[] b, long[] r) {
// Use grade-school multiplication into primitives to avoid the
// temporary array allocation. This is equivalent to the following
// code:
// long[] c = new long[2 * NUM_LIMBS - 1];
// for(int i = 0; i < NUM_LIMBS; i++) {
// for(int j - 0; j < NUM_LIMBS; j++) {
// c[i + j] += a[i] * b[j]
// }
// }
long c0 = (a[0] * b[0]);
long c1 = (a[0] * b[1]) + (a[1] * b[0]);
long c2 = (a[0] * b[2]) + (a[1] * b[1]) + (a[2] * b[0]);
long c3 = (a[0] * b[3]) + (a[1] * b[2]) + (a[2] * b[1]) + (a[3] * b[0]);
long c4 = (a[0] * b[4]) + (a[1] * b[3]) + (a[2] * b[2]) + (a[3] * b[1]) + (a[4] * b[0]);
long c5 = (a[0] * b[5]) + (a[1] * b[4]) + (a[2] * b[3]) + (a[3] * b[2]) + (a[4] * b[1]) + (a[5] * b[0]);
long c6 = (a[0] * b[6]) + (a[1] * b[5]) + (a[2] * b[4]) + (a[3] * b[3]) + (a[4] * b[2]) + (a[5] * b[1]) + (a[6] * b[0]);
long c7 = (a[0] * b[7]) + (a[1] * b[6]) + (a[2] * b[5]) + (a[3] * b[4]) + (a[4] * b[3]) + (a[5] * b[2]) + (a[6] * b[1]) + (a[7] * b[0]);
long c8 = (a[0] * b[8]) + (a[1] * b[7]) + (a[2] * b[6]) + (a[3] * b[5]) + (a[4] * b[4]) + (a[5] * b[3]) + (a[6] * b[2]) + (a[7] * b[1]) + (a[8] * b[0]);
long c9 = (a[0] * b[9]) + (a[1] * b[8]) + (a[2] * b[7]) + (a[3] * b[6]) + (a[4] * b[5]) + (a[5] * b[4]) + (a[6] * b[3]) + (a[7] * b[2]) + (a[8] * b[1]) + (a[9] * b[0]);
long c10 = (a[1] * b[9]) + (a[2] * b[8]) + (a[3] * b[7]) + (a[4] * b[6]) + (a[5] * b[5]) + (a[6] * b[4]) + (a[7] * b[3]) + (a[8] * b[2]) + (a[9] * b[1]);
long c11 = (a[2] * b[9]) + (a[3] * b[8]) + (a[4] * b[7]) + (a[5] * b[6]) + (a[6] * b[5]) + (a[7] * b[4]) + (a[8] * b[3]) + (a[9] * b[2]);
long c12 = (a[3] * b[9]) + (a[4] * b[8]) + (a[5] * b[7]) + (a[6] * b[6]) + (a[7] * b[5]) + (a[8] * b[4]) + (a[9] * b[3]);
long c13 = (a[4] * b[9]) + (a[5] * b[8]) + (a[6] * b[7]) + (a[7] * b[6]) + (a[8] * b[5]) + (a[9] * b[4]);
long c14 = (a[5] * b[9]) + (a[6] * b[8]) + (a[7] * b[7]) + (a[8] * b[6]) + (a[9] * b[5]);
long c15 = (a[6] * b[9]) + (a[7] * b[8]) + (a[8] * b[7]) + (a[9] * b[6]);
long c16 = (a[7] * b[9]) + (a[8] * b[8]) + (a[9] * b[7]);
long c17 = (a[8] * b[9]) + (a[9] * b[8]);
long c18 = a[9] * b[9];
carryReduce(r, c0, c1, c2, c3, c4, c5, c6, c7, c8,
c9, c10, c11, c12, c13, c14, c15, c16, c17, c18);
}
private void carryReduce(long[] r, long c0, long c1, long c2,
long c3, long c4, long c5, long c6,
long c7, long c8, long c9, long c10,
long c11, long c12, long c13, long c14,
long c15, long c16, long c17, long c18) {
// reduce(7,2)
long reducedValue17 = (c17 * SUBTRAHEND);
c7 += (reducedValue17 << BIT_OFFSET) & LIMB_MASK;
c8 += reducedValue17 >> RIGHT_BIT_OFFSET;
long reducedValue18 = (c18 * SUBTRAHEND);
c8 += (reducedValue18 << BIT_OFFSET) & LIMB_MASK;
c9 += reducedValue18 >> RIGHT_BIT_OFFSET;
// carry(8,2)
long carry8 = carryValue(c8);
r[8] = c8 - (carry8 << BITS_PER_LIMB);
c9 += carry8;
long carry9 = carryValue(c9);
r[9] = c9 - (carry9 << BITS_PER_LIMB);
c10 += carry9;
// reduce(0,7)
long reducedValue10 = (c10 * SUBTRAHEND);
r[0] = c0 + ((reducedValue10 << BIT_OFFSET) & LIMB_MASK);
c1 += reducedValue10 >> RIGHT_BIT_OFFSET;
long reducedValue11 = (c11 * SUBTRAHEND);
r[1] = c1 + ((reducedValue11 << BIT_OFFSET) & LIMB_MASK);
c2 += reducedValue11 >> RIGHT_BIT_OFFSET;
long reducedValue12 = (c12 * SUBTRAHEND);
r[2] = c2 + ((reducedValue12 << BIT_OFFSET) & LIMB_MASK);
c3 += reducedValue12 >> RIGHT_BIT_OFFSET;
long reducedValue13 = (c13 * SUBTRAHEND);
r[3] = c3 + ((reducedValue13 << BIT_OFFSET) & LIMB_MASK);
c4 += reducedValue13 >> RIGHT_BIT_OFFSET;
long reducedValue14 = (c14 * SUBTRAHEND);
r[4] = c4 + ((reducedValue14 << BIT_OFFSET) & LIMB_MASK);
c5 += reducedValue14 >> RIGHT_BIT_OFFSET;
long reducedValue15 = (c15 * SUBTRAHEND);
r[5] = c5 + ((reducedValue15 << BIT_OFFSET) & LIMB_MASK);
c6 += reducedValue15 >> RIGHT_BIT_OFFSET;
long reducedValue16 = (c16 * SUBTRAHEND);
r[6] = c6 + ((reducedValue16 << BIT_OFFSET) & LIMB_MASK);
r[7] = c7 + (reducedValue16 >> RIGHT_BIT_OFFSET);
// carry(0,9)
carry(r, 0, 9);
}
@Override
protected void square(long[] a, long[] r) {
// Use grade-school multiplication with a simple squaring optimization.
// Multiply into primitives to avoid the temporary array allocation.
// This is equivalent to the following code:
// long[] c = new long[2 * NUM_LIMBS - 1];
// for(int i = 0; i < NUM_LIMBS; i++) {
// c[2 * i] = a[i] * a[i];
// for(int j = i + 1; j < NUM_LIMBS; j++) {
// c[i + j] += 2 * a[i] * a[j]
// }
// }
long c0 = a[0] * a[0];
long c1 = 2 * a[0] * a[1];
long c2 = a[1] * a[1] + 2 * a[0] * a[2];
long c3 = 2 * (a[0] * a[3] + a[1] * a[2]);
long c4 = a[2] * a[2] + 2 * (a[0] * a[4] + a[1] * a[3]);
long c5 = 2 * (a[0] * a[5] + a[1] * a[4] + a[2] * a[3]);
long c6 = a[3] * a[3] + 2 * (a[0] * a[6] + a[1] * a[5] + a[2] * a[4]);
long c7 = 2 * (a[0] * a[7] + a[1] * a[6] + a[2] * a[5] + a[3] * a[4]);
long c8 = a[4] * a[4] + 2 * (a[0] * a[8] + a[1] * a[7] + a[2] * a[6] + a[3] * a[5]);
long c9 = 2 * (a[0] * a[9] + a[1] * a[8] + a[2] * a[7] + a[3] * a[6] + a[4] * a[5]);
long c10 = a[5] * a[5] + 2 * (a[1] * a[9] + a[2] * a[8] + a[3] * a[7] + a[4] * a[6]);
long c11 = 2 * (a[2] * a[9] + a[3] * a[8] + a[4] * a[7] + a[5] * a[6]);
long c12 = a[6] * a[6] + 2 * (a[3] * a[9] + a[4] * a[8] + a[5] * a[7]);
long c13 = 2 * (a[4] * a[9] + a[5] * a[8] + a[6] * a[7]);
long c14 = a[7] * a[7] + 2 * (a[5] * a[9] + a[6] * a[8]);
long c15 = 2 * (a[6] * a[9] + a[7] * a[8]);
long c16 = a[8] * a[8] + 2 * a[7] * a[9];
long c17 = 2 * a[8] * a[9];
long c18 = a[9] * a[9];
carryReduce(r, c0, c1, c2, c3, c4, c5, c6, c7, c8,
c9, c10, c11, c12, c13, c14, c15, c16, c17, c18);
}
}

View File

@@ -0,0 +1,251 @@
/*
* 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.intpoly;
import java.math.BigInteger;
/**
* An IntegerFieldModuloP designed for use with the Curve448.
* The representation uses 16 signed long values.
*/
public class IntegerPolynomial448 extends IntegerPolynomial {
private static final int POWER = 448;
private static final int NUM_LIMBS = 16;
private static final int BITS_PER_LIMB = 28;
public static final BigInteger MODULUS
= TWO.pow(POWER).subtract(TWO.pow(POWER / 2))
.subtract(BigInteger.valueOf(1));
public IntegerPolynomial448() {
super(BITS_PER_LIMB, NUM_LIMBS, 1, MODULUS);
}
private void modReduceIn(long[] limbs, int index, long x) {
limbs[index - NUM_LIMBS] += x;
limbs[index - NUM_LIMBS / 2] += x;
}
@Override
protected void finalCarryReduceLast(long[] limbs) {
long carry = limbs[numLimbs - 1] >> bitsPerLimb;
limbs[numLimbs - 1] -= carry << bitsPerLimb;
modReduceIn(limbs, numLimbs, carry);
}
@Override
protected void reduce(long[] a) {
// carry(14, 2)
long carry14 = carryValue(a[14]);
a[14] -= (carry14 << BITS_PER_LIMB);
a[15] += carry14;
long carry15 = carryValue(a[15]);
a[15] -= (carry15 << BITS_PER_LIMB);
// reduce(0, 1)
a[0] += carry15;
a[8] += carry15;
// carry(0, 15)
carry(a, 0, 15);
}
@Override
protected void mult(long[] a, long[] b, long[] r) {
// Use grade-school multiplication into primitives to avoid the
// temporary array allocation. This is equivalent to the following
// code:
// long[] c = new long[2 * NUM_LIMBS - 1];
// for(int i = 0; i < NUM_LIMBS; i++) {
// for(int j - 0; j < NUM_LIMBS; j++) {
// c[i + j] += a[i] * b[j]
// }
// }
long c0 = (a[0] * b[0]);
long c1 = (a[0] * b[1]) + (a[1] * b[0]);
long c2 = (a[0] * b[2]) + (a[1] * b[1]) + (a[2] * b[0]);
long c3 = (a[0] * b[3]) + (a[1] * b[2]) + (a[2] * b[1]) + (a[3] * b[0]);
long c4 = (a[0] * b[4]) + (a[1] * b[3]) + (a[2] * b[2]) + (a[3] * b[1]) + (a[4] * b[0]);
long c5 = (a[0] * b[5]) + (a[1] * b[4]) + (a[2] * b[3]) + (a[3] * b[2]) + (a[4] * b[1]) + (a[5] * b[0]);
long c6 = (a[0] * b[6]) + (a[1] * b[5]) + (a[2] * b[4]) + (a[3] * b[3]) + (a[4] * b[2]) + (a[5] * b[1]) + (a[6] * b[0]);
long c7 = (a[0] * b[7]) + (a[1] * b[6]) + (a[2] * b[5]) + (a[3] * b[4]) + (a[4] * b[3]) + (a[5] * b[2]) + (a[6] * b[1]) + (a[7] * b[0]);
long c8 = (a[0] * b[8]) + (a[1] * b[7]) + (a[2] * b[6]) + (a[3] * b[5]) + (a[4] * b[4]) + (a[5] * b[3]) + (a[6] * b[2]) + (a[7] * b[1]) + (a[8] * b[0]);
long c9 = (a[0] * b[9]) + (a[1] * b[8]) + (a[2] * b[7]) + (a[3] * b[6]) + (a[4] * b[5]) + (a[5] * b[4]) + (a[6] * b[3]) + (a[7] * b[2]) + (a[8] * b[1]) + (a[9] * b[0]);
long c10 = (a[0] * b[10]) + (a[1] * b[9]) + (a[2] * b[8]) + (a[3] * b[7]) + (a[4] * b[6]) + (a[5] * b[5]) + (a[6] * b[4]) + (a[7] * b[3]) + (a[8] * b[2]) + (a[9] * b[1]) + (a[10] * b[0]);
long c11 = (a[0] * b[11]) + (a[1] * b[10]) + (a[2] * b[9]) + (a[3] * b[8]) + (a[4] * b[7]) + (a[5] * b[6]) + (a[6] * b[5]) + (a[7] * b[4]) + (a[8] * b[3]) + (a[9] * b[2]) + (a[10] * b[1]) + (a[11] * b[0]);
long c12 = (a[0] * b[12]) + (a[1] * b[11]) + (a[2] * b[10]) + (a[3] * b[9]) + (a[4] * b[8]) + (a[5] * b[7]) + (a[6] * b[6]) + (a[7] * b[5]) + (a[8] * b[4]) + (a[9] * b[3]) + (a[10] * b[2]) + (a[11] * b[1]) + (a[12] * b[0]);
long c13 = (a[0] * b[13]) + (a[1] * b[12]) + (a[2] * b[11]) + (a[3] * b[10]) + (a[4] * b[9]) + (a[5] * b[8]) + (a[6] * b[7]) + (a[7] * b[6]) + (a[8] * b[5]) + (a[9] * b[4]) + (a[10] * b[3]) + (a[11] * b[2]) + (a[12] * b[1]) + (a[13] * b[0]);
long c14 = (a[0] * b[14]) + (a[1] * b[13]) + (a[2] * b[12]) + (a[3] * b[11]) + (a[4] * b[10]) + (a[5] * b[9]) + (a[6] * b[8]) + (a[7] * b[7]) + (a[8] * b[6]) + (a[9] * b[5]) + (a[10] * b[4]) + (a[11] * b[3]) + (a[12] * b[2]) + (a[13] * b[1]) + (a[14] * b[0]);
long c15 = (a[0] * b[15]) + (a[1] * b[14]) + (a[2] * b[13]) + (a[3] * b[12]) + (a[4] * b[11]) + (a[5] * b[10]) + (a[6] * b[9]) + (a[7] * b[8]) + (a[8] * b[7]) + (a[9] * b[6]) + (a[10] * b[5]) + (a[11] * b[4]) + (a[12] * b[3]) + (a[13] * b[2]) + (a[14] * b[1]) + (a[15] * b[0]);
long c16 = (a[1] * b[15]) + (a[2] * b[14]) + (a[3] * b[13]) + (a[4] * b[12]) + (a[5] * b[11]) + (a[6] * b[10]) + (a[7] * b[9]) + (a[8] * b[8]) + (a[9] * b[7]) + (a[10] * b[6]) + (a[11] * b[5]) + (a[12] * b[4]) + (a[13] * b[3]) + (a[14] * b[2]) + (a[15] * b[1]);
long c17 = (a[2] * b[15]) + (a[3] * b[14]) + (a[4] * b[13]) + (a[5] * b[12]) + (a[6] * b[11]) + (a[7] * b[10]) + (a[8] * b[9]) + (a[9] * b[8]) + (a[10] * b[7]) + (a[11] * b[6]) + (a[12] * b[5]) + (a[13] * b[4]) + (a[14] * b[3]) + (a[15] * b[2]);
long c18 = (a[3] * b[15]) + (a[4] * b[14]) + (a[5] * b[13]) + (a[6] * b[12]) + (a[7] * b[11]) + (a[8] * b[10]) + (a[9] * b[9]) + (a[10] * b[8]) + (a[11] * b[7]) + (a[12] * b[6]) + (a[13] * b[5]) + (a[14] * b[4]) + (a[15] * b[3]);
long c19 = (a[4] * b[15]) + (a[5] * b[14]) + (a[6] * b[13]) + (a[7] * b[12]) + (a[8] * b[11]) + (a[9] * b[10]) + (a[10] * b[9]) + (a[11] * b[8]) + (a[12] * b[7]) + (a[13] * b[6]) + (a[14] * b[5]) + (a[15] * b[4]);
long c20 = (a[5] * b[15]) + (a[6] * b[14]) + (a[7] * b[13]) + (a[8] * b[12]) + (a[9] * b[11]) + (a[10] * b[10]) + (a[11] * b[9]) + (a[12] * b[8]) + (a[13] * b[7]) + (a[14] * b[6]) + (a[15] * b[5]);
long c21 = (a[6] * b[15]) + (a[7] * b[14]) + (a[8] * b[13]) + (a[9] * b[12]) + (a[10] * b[11]) + (a[11] * b[10]) + (a[12] * b[9]) + (a[13] * b[8]) + (a[14] * b[7]) + (a[15] * b[6]);
long c22 = (a[7] * b[15]) + (a[8] * b[14]) + (a[9] * b[13]) + (a[10] * b[12]) + (a[11] * b[11]) + (a[12] * b[10]) + (a[13] * b[9]) + (a[14] * b[8]) + (a[15] * b[7]);
long c23 = (a[8] * b[15]) + (a[9] * b[14]) + (a[10] * b[13]) + (a[11] * b[12]) + (a[12] * b[11]) + (a[13] * b[10]) + (a[14] * b[9]) + (a[15] * b[8]);
long c24 = (a[9] * b[15]) + (a[10] * b[14]) + (a[11] * b[13]) + (a[12] * b[12]) + (a[13] * b[11]) + (a[14] * b[10]) + (a[15] * b[9]);
long c25 = (a[10] * b[15]) + (a[11] * b[14]) + (a[12] * b[13]) + (a[13] * b[12]) + (a[14] * b[11]) + (a[15] * b[10]);
long c26 = (a[11] * b[15]) + (a[12] * b[14]) + (a[13] * b[13]) + (a[14] * b[12]) + (a[15] * b[11]);
long c27 = (a[12] * b[15]) + (a[13] * b[14]) + (a[14] * b[13]) + (a[15] * b[12]);
long c28 = (a[13] * b[15]) + (a[14] * b[14]) + (a[15] * b[13]);
long c29 = (a[14] * b[15]) + (a[15] * b[14]);
long c30 = (a[15] * b[15]);
carryReduce(r, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12,
c13, c14, c15, c16, c17, c18, c19, c20, c21, c22, c23, c24, c25,
c26, c27, c28, c29, c30);
}
private void carryReduce(long[] r, long c0, long c1, long c2, long c3,
long c4, long c5, long c6, long c7, long c8,
long c9, long c10, long c11, long c12, long c13,
long c14, long c15, long c16, long c17, long c18,
long c19, long c20, long c21, long c22, long c23,
long c24, long c25, long c26, long c27, long c28,
long c29, long c30) {
// reduce(8, 7)
c8 += c24;
c16 += c24;
c9 += c25;
c17 += c25;
c10 += c26;
c18 += c26;
c11 += c27;
c19 += c27;
c12 += c28;
c20 += c28;
c13 += c29;
c21 += c29;
c14 += c30;
c22 += c30;
// reduce(4, 4)
r[4] = c4 + c20;
r[12] = c12 + c20;
r[5] = c5 + c21;
r[13] = c13 + c21;
r[6] = c6 + c22;
c14 += c22;
r[7] = c7 + c23;
c15 += c23;
//carry(14, 2)
long carry14 = carryValue(c14);
r[14] = c14 - (carry14 << BITS_PER_LIMB);
c15 += carry14;
long carry15 = carryValue(c15);
r[15] = c15 - (carry15 << BITS_PER_LIMB);
c16 += carry15;
// reduce(0, 4)
r[0] = c0 + c16;
r[8] = c8 + c16;
r[1] = c1 + c17;
r[9] = c9 + c17;
r[2] = c2 + c18;
r[10] = c10 + c18;
r[3] = c3 + c19;
r[11] = c11 + c19;
// carry(0, 15)
carry(r, 0, 15);
}
@Override
protected void square(long[] a, long[] r) {
// Use grade-school multiplication with a simple squaring optimization.
// Multiply into primitives to avoid the temporary array allocation.
// This is equivalent to the following code:
// long[] c = new long[2 * NUM_LIMBS - 1];
// for(int i = 0; i < NUM_LIMBS; i++) {
// c[2 * i] = a[i] * a[i];
// for(int j = i + 1; j < NUM_LIMBS; j++) {
// c[i + j] += 2 * a[i] * a[j]
// }
// }
long c0 = a[0] * a[0];
long c1 = 2 * a[0] * a[1];
long c2 = a[1] * a[1] + 2 * a[0] * a[2];
long c3 = 2 * (a[0] * a[3] + a[1] * a[2]);
long c4 = a[2] * a[2] + 2 * (a[0] * a[4] + a[1] * a[3]);
long c5 = 2 * (a[0] * a[5] + a[1] * a[4] + a[2] * a[3]);
long c6 = a[3] * a[3] + 2 * (a[0] * a[6] + a[1] * a[5] + a[2] * a[4]);
long c7 = 2 * (a[0] * a[7] + a[1] * a[6] + a[2] * a[5] + a[3] * a[4]);
long c8 = a[4] * a[4] + 2 * (a[0] * a[8] + a[1] * a[7] + a[2] * a[6] + a[3] * a[5]);
long c9 = 2 * (a[0] * a[9] + a[1] * a[8] + a[2] * a[7] + a[3] * a[6] + a[4] * a[5]);
long c10 = a[5] * a[5] + 2 * (a[0] * a[10] + a[1] * a[9] + a[2] * a[8] + a[3] * a[7] + a[4] * a[6]);
long c11 = 2 * (a[0] * a[11] + a[1] * a[10] + a[2] * a[9] + a[3] * a[8] + a[4] * a[7] + a[5] * a[6]);
long c12 = a[6] * a[6] + 2 * (a[0] * a[12] + a[1] * a[11] + a[2] * a[10] + a[3] * a[9] + a[4] * a[8] + a[5] * a[7]);
long c13 = 2 * (a[0] * a[13] + a[1] * a[12] + a[2] * a[11] + a[3] * a[10] + a[4] * a[9] + a[5] * a[8] + a[6] * a[7]);
long c14 = a[7] * a[7] + 2 * (a[0] * a[14] + a[1] * a[13] + a[2] * a[12] + a[3] * a[11] + a[4] * a[10] + a[5] * a[9] + a[6] * a[8]);
long c15 = 2 * (a[0] * a[15] + a[1] * a[14] + a[2] * a[13] + a[3] * a[12] + a[4] * a[11] + a[5] * a[10] + a[6] * a[9] + a[7] * a[8]);
long c16 = a[8] * a[8] + 2 * (a[1] * a[15] + a[2] * a[14] + a[3] * a[13] + a[4] * a[12] + a[5] * a[11] + a[6] * a[10] + a[7] * a[9]);
long c17 = 2 * (a[2] * a[15] + a[3] * a[14] + a[4] * a[13] + a[5] * a[12] + a[6] * a[11] + a[7] * a[10] + a[8] * a[9]);
long c18 = a[9] * a[9] + 2 * (a[3] * a[15] + a[4] * a[14] + a[5] * a[13] + a[6] * a[12] + a[7] * a[11] + a[8] * a[10]);
long c19 = 2 * (a[4] * a[15] + a[5] * a[14] + a[6] * a[13] + a[7] * a[12] + a[8] * a[11] + a[9] * a[10]);
long c20 = a[10] * a[10] + 2 * (a[5] * a[15] + a[6] * a[14] + a[7] * a[13] + a[8] * a[12] + a[9] * a[11]);
long c21 = 2 * (a[6] * a[15] + a[7] * a[14] + a[8] * a[13] + a[9] * a[12] + a[10] * a[11]);
long c22 = a[11] * a[11] + 2 * (a[7] * a[15] + a[8] * a[14] + a[9] * a[13] + a[10] * a[12]);
long c23 = 2 * (a[8] * a[15] + a[9] * a[14] + a[10] * a[13] + a[11] * a[12]);
long c24 = a[12] * a[12] + 2 * (a[9] * a[15] + a[10] * a[14] + a[11] * a[13]);
long c25 = 2 * (a[10] * a[15] + a[11] * a[14] + a[12] * a[13]);
long c26 = a[13] * a[13] + 2 * (a[11] * a[15] + a[12] * a[14]);
long c27 = 2 * (a[12] * a[15] + a[13] * a[14]);
long c28 = a[14] * a[14] + 2 * a[13] * a[15];
long c29 = 2 * a[14] * a[15];
long c30 = a[15] * a[15];
carryReduce(r, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12,
c13, c14, c15, c16, c17, c18, c19, c20, c21, c22, c23, c24, c25,
c26, c27, c28, c29, c30);
}
}

View File

@@ -0,0 +1,339 @@
/*
* 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.
*/
/*
* This file is generated by FieldGen.jsh. Do not modify it directly.
*/
package sun.security.util.math.intpoly;
import java.math.BigInteger;
public class IntegerPolynomialP256 extends IntegerPolynomial {
private static final int BITS_PER_LIMB = 26;
private static final int NUM_LIMBS = 10;
private static final int MAX_ADDS = 2;
public static final BigInteger MODULUS = evaluateModulus();
private static final long CARRY_ADD = 1 << 25;
private static final int LIMB_MASK = -1 >>> (64 - BITS_PER_LIMB);
public IntegerPolynomialP256() {
super(BITS_PER_LIMB, NUM_LIMBS, MAX_ADDS, MODULUS);
}
private static BigInteger evaluateModulus() {
BigInteger result = BigInteger.valueOf(2).pow(256);
result = result.subtract(BigInteger.valueOf(2).pow(224));
result = result.add(BigInteger.valueOf(2).pow(192));
result = result.add(BigInteger.valueOf(2).pow(96));
result = result.subtract(BigInteger.valueOf(1));
return result;
}
@Override
protected void finalCarryReduceLast(long[] limbs) {
long c = limbs[9] >> 22;
limbs[9] -= c << 22;
limbs[8] += (c << 16) & LIMB_MASK;
limbs[9] += c >> 10;
limbs[7] -= (c << 10) & LIMB_MASK;
limbs[8] -= c >> 16;
limbs[3] -= (c << 18) & LIMB_MASK;
limbs[4] -= c >> 8;
limbs[0] += c;
}
private void carryReduce(long[] r, long c0, long c1, long c2, long c3, long c4, long c5, long c6, long c7, long c8, long c9, long c10, long c11, long c12, long c13, long c14, long c15, long c16, long c17, long c18) {
long c19 = 0;
//reduce from position 18
c16 += (c18 << 20) & LIMB_MASK;
c17 += c18 >> 6;
c15 -= (c18 << 14) & LIMB_MASK;
c16 -= c18 >> 12;
c11 -= (c18 << 22) & LIMB_MASK;
c12 -= c18 >> 4;
c8 += (c18 << 4) & LIMB_MASK;
c9 += c18 >> 22;
//reduce from position 17
c15 += (c17 << 20) & LIMB_MASK;
c16 += c17 >> 6;
c14 -= (c17 << 14) & LIMB_MASK;
c15 -= c17 >> 12;
c10 -= (c17 << 22) & LIMB_MASK;
c11 -= c17 >> 4;
c7 += (c17 << 4) & LIMB_MASK;
c8 += c17 >> 22;
//reduce from position 16
c14 += (c16 << 20) & LIMB_MASK;
c15 += c16 >> 6;
c13 -= (c16 << 14) & LIMB_MASK;
c14 -= c16 >> 12;
c9 -= (c16 << 22) & LIMB_MASK;
c10 -= c16 >> 4;
c6 += (c16 << 4) & LIMB_MASK;
c7 += c16 >> 22;
//reduce from position 15
c13 += (c15 << 20) & LIMB_MASK;
c14 += c15 >> 6;
c12 -= (c15 << 14) & LIMB_MASK;
c13 -= c15 >> 12;
c8 -= (c15 << 22) & LIMB_MASK;
c9 -= c15 >> 4;
c5 += (c15 << 4) & LIMB_MASK;
c6 += c15 >> 22;
//reduce from position 14
c12 += (c14 << 20) & LIMB_MASK;
c13 += c14 >> 6;
c11 -= (c14 << 14) & LIMB_MASK;
c12 -= c14 >> 12;
c7 -= (c14 << 22) & LIMB_MASK;
c8 -= c14 >> 4;
c4 += (c14 << 4) & LIMB_MASK;
c5 += c14 >> 22;
//reduce from position 13
c11 += (c13 << 20) & LIMB_MASK;
c12 += c13 >> 6;
c10 -= (c13 << 14) & LIMB_MASK;
c11 -= c13 >> 12;
c6 -= (c13 << 22) & LIMB_MASK;
c7 -= c13 >> 4;
c3 += (c13 << 4) & LIMB_MASK;
c4 += c13 >> 22;
//reduce from position 12
c10 += (c12 << 20) & LIMB_MASK;
c11 += c12 >> 6;
c9 -= (c12 << 14) & LIMB_MASK;
c10 -= c12 >> 12;
c5 -= (c12 << 22) & LIMB_MASK;
c6 -= c12 >> 4;
c2 += (c12 << 4) & LIMB_MASK;
c3 += c12 >> 22;
//reduce from position 11
c9 += (c11 << 20) & LIMB_MASK;
c10 += c11 >> 6;
c8 -= (c11 << 14) & LIMB_MASK;
c9 -= c11 >> 12;
c4 -= (c11 << 22) & LIMB_MASK;
c5 -= c11 >> 4;
c1 += (c11 << 4) & LIMB_MASK;
c2 += c11 >> 22;
//reduce from position 10
c8 += (c10 << 20) & LIMB_MASK;
c9 += c10 >> 6;
c7 -= (c10 << 14) & LIMB_MASK;
c8 -= c10 >> 12;
c3 -= (c10 << 22) & LIMB_MASK;
c4 -= c10 >> 4;
c0 += (c10 << 4) & LIMB_MASK;
c1 += c10 >> 22;
c10 = 0;
carryReduce0(r, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16, c17, c18, c19);
}
void carryReduce0(long[] r, long c0, long c1, long c2, long c3, long c4, long c5, long c6, long c7, long c8, long c9, long c10, long c11, long c12, long c13, long c14, long c15, long c16, long c17, long c18, long c19) {
//carry from position 8
long t0 = (c8 + CARRY_ADD) >> 26;
c8 -= (t0 << 26);
c9 += t0;
//carry from position 9
t0 = (c9 + CARRY_ADD) >> 26;
c9 -= (t0 << 26);
c10 += t0;
//reduce from position 10
c8 += (c10 << 20) & LIMB_MASK;
c9 += c10 >> 6;
c7 -= (c10 << 14) & LIMB_MASK;
c8 -= c10 >> 12;
c3 -= (c10 << 22) & LIMB_MASK;
c4 -= c10 >> 4;
c0 += (c10 << 4) & LIMB_MASK;
c1 += c10 >> 22;
//carry from position 0
t0 = (c0 + CARRY_ADD) >> 26;
c0 -= (t0 << 26);
c1 += t0;
//carry from position 1
t0 = (c1 + CARRY_ADD) >> 26;
c1 -= (t0 << 26);
c2 += t0;
//carry from position 2
t0 = (c2 + CARRY_ADD) >> 26;
c2 -= (t0 << 26);
c3 += t0;
//carry from position 3
t0 = (c3 + CARRY_ADD) >> 26;
c3 -= (t0 << 26);
c4 += t0;
//carry from position 4
t0 = (c4 + CARRY_ADD) >> 26;
c4 -= (t0 << 26);
c5 += t0;
//carry from position 5
t0 = (c5 + CARRY_ADD) >> 26;
c5 -= (t0 << 26);
c6 += t0;
//carry from position 6
t0 = (c6 + CARRY_ADD) >> 26;
c6 -= (t0 << 26);
c7 += t0;
//carry from position 7
t0 = (c7 + CARRY_ADD) >> 26;
c7 -= (t0 << 26);
c8 += t0;
//carry from position 8
t0 = (c8 + CARRY_ADD) >> 26;
c8 -= (t0 << 26);
c9 += t0;
r[0] = c0;
r[1] = c1;
r[2] = c2;
r[3] = c3;
r[4] = c4;
r[5] = c5;
r[6] = c6;
r[7] = c7;
r[8] = c8;
r[9] = c9;
}
private void carryReduce(long[] r, long c0, long c1, long c2, long c3, long c4, long c5, long c6, long c7, long c8, long c9) {
long c10 = 0;
//carry from position 8
long t0 = (c8 + CARRY_ADD) >> 26;
c8 -= (t0 << 26);
c9 += t0;
//carry from position 9
t0 = (c9 + CARRY_ADD) >> 26;
c9 -= (t0 << 26);
c10 += t0;
//reduce from position 10
c8 += (c10 << 20) & LIMB_MASK;
c9 += c10 >> 6;
c7 -= (c10 << 14) & LIMB_MASK;
c8 -= c10 >> 12;
c3 -= (c10 << 22) & LIMB_MASK;
c4 -= c10 >> 4;
c0 += (c10 << 4) & LIMB_MASK;
c1 += c10 >> 22;
//carry from position 0
t0 = (c0 + CARRY_ADD) >> 26;
c0 -= (t0 << 26);
c1 += t0;
//carry from position 1
t0 = (c1 + CARRY_ADD) >> 26;
c1 -= (t0 << 26);
c2 += t0;
//carry from position 2
t0 = (c2 + CARRY_ADD) >> 26;
c2 -= (t0 << 26);
c3 += t0;
//carry from position 3
t0 = (c3 + CARRY_ADD) >> 26;
c3 -= (t0 << 26);
c4 += t0;
//carry from position 4
t0 = (c4 + CARRY_ADD) >> 26;
c4 -= (t0 << 26);
c5 += t0;
//carry from position 5
t0 = (c5 + CARRY_ADD) >> 26;
c5 -= (t0 << 26);
c6 += t0;
//carry from position 6
t0 = (c6 + CARRY_ADD) >> 26;
c6 -= (t0 << 26);
c7 += t0;
//carry from position 7
t0 = (c7 + CARRY_ADD) >> 26;
c7 -= (t0 << 26);
c8 += t0;
//carry from position 8
t0 = (c8 + CARRY_ADD) >> 26;
c8 -= (t0 << 26);
c9 += t0;
r[0] = c0;
r[1] = c1;
r[2] = c2;
r[3] = c3;
r[4] = c4;
r[5] = c5;
r[6] = c6;
r[7] = c7;
r[8] = c8;
r[9] = c9;
}
@Override
protected void mult(long[] a, long[] b, long[] r) {
long c0 = (a[0] * b[0]);
long c1 = (a[0] * b[1]) + (a[1] * b[0]);
long c2 = (a[0] * b[2]) + (a[1] * b[1]) + (a[2] * b[0]);
long c3 = (a[0] * b[3]) + (a[1] * b[2]) + (a[2] * b[1]) + (a[3] * b[0]);
long c4 = (a[0] * b[4]) + (a[1] * b[3]) + (a[2] * b[2]) + (a[3] * b[1]) + (a[4] * b[0]);
long c5 = (a[0] * b[5]) + (a[1] * b[4]) + (a[2] * b[3]) + (a[3] * b[2]) + (a[4] * b[1]) + (a[5] * b[0]);
long c6 = (a[0] * b[6]) + (a[1] * b[5]) + (a[2] * b[4]) + (a[3] * b[3]) + (a[4] * b[2]) + (a[5] * b[1]) + (a[6] * b[0]);
long c7 = (a[0] * b[7]) + (a[1] * b[6]) + (a[2] * b[5]) + (a[3] * b[4]) + (a[4] * b[3]) + (a[5] * b[2]) + (a[6] * b[1]) + (a[7] * b[0]);
long c8 = (a[0] * b[8]) + (a[1] * b[7]) + (a[2] * b[6]) + (a[3] * b[5]) + (a[4] * b[4]) + (a[5] * b[3]) + (a[6] * b[2]) + (a[7] * b[1]) + (a[8] * b[0]);
long c9 = (a[0] * b[9]) + (a[1] * b[8]) + (a[2] * b[7]) + (a[3] * b[6]) + (a[4] * b[5]) + (a[5] * b[4]) + (a[6] * b[3]) + (a[7] * b[2]) + (a[8] * b[1]) + (a[9] * b[0]);
long c10 = (a[1] * b[9]) + (a[2] * b[8]) + (a[3] * b[7]) + (a[4] * b[6]) + (a[5] * b[5]) + (a[6] * b[4]) + (a[7] * b[3]) + (a[8] * b[2]) + (a[9] * b[1]);
long c11 = (a[2] * b[9]) + (a[3] * b[8]) + (a[4] * b[7]) + (a[5] * b[6]) + (a[6] * b[5]) + (a[7] * b[4]) + (a[8] * b[3]) + (a[9] * b[2]);
long c12 = (a[3] * b[9]) + (a[4] * b[8]) + (a[5] * b[7]) + (a[6] * b[6]) + (a[7] * b[5]) + (a[8] * b[4]) + (a[9] * b[3]);
long c13 = (a[4] * b[9]) + (a[5] * b[8]) + (a[6] * b[7]) + (a[7] * b[6]) + (a[8] * b[5]) + (a[9] * b[4]);
long c14 = (a[5] * b[9]) + (a[6] * b[8]) + (a[7] * b[7]) + (a[8] * b[6]) + (a[9] * b[5]);
long c15 = (a[6] * b[9]) + (a[7] * b[8]) + (a[8] * b[7]) + (a[9] * b[6]);
long c16 = (a[7] * b[9]) + (a[8] * b[8]) + (a[9] * b[7]);
long c17 = (a[8] * b[9]) + (a[9] * b[8]);
long c18 = (a[9] * b[9]);
carryReduce(r, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16, c17, c18);
}
@Override
protected void reduce(long[] a) {
carryReduce(a, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9]);
}
@Override
protected void square(long[] a, long[] r) {
long c0 = (a[0] * a[0]);
long c1 = 2 * ((a[0] * a[1]));
long c2 = 2 * ((a[0] * a[2])) + (a[1] * a[1]);
long c3 = 2 * ((a[0] * a[3]) + (a[1] * a[2]));
long c4 = 2 * ((a[0] * a[4]) + (a[1] * a[3])) + (a[2] * a[2]);
long c5 = 2 * ((a[0] * a[5]) + (a[1] * a[4]) + (a[2] * a[3]));
long c6 = 2 * ((a[0] * a[6]) + (a[1] * a[5]) + (a[2] * a[4])) + (a[3] * a[3]);
long c7 = 2 * ((a[0] * a[7]) + (a[1] * a[6]) + (a[2] * a[5]) + (a[3] * a[4]));
long c8 = 2 * ((a[0] * a[8]) + (a[1] * a[7]) + (a[2] * a[6]) + (a[3] * a[5])) + (a[4] * a[4]);
long c9 = 2 * ((a[0] * a[9]) + (a[1] * a[8]) + (a[2] * a[7]) + (a[3] * a[6]) + (a[4] * a[5]));
long c10 = 2 * ((a[1] * a[9]) + (a[2] * a[8]) + (a[3] * a[7]) + (a[4] * a[6])) + (a[5] * a[5]);
long c11 = 2 * ((a[2] * a[9]) + (a[3] * a[8]) + (a[4] * a[7]) + (a[5] * a[6]));
long c12 = 2 * ((a[3] * a[9]) + (a[4] * a[8]) + (a[5] * a[7])) + (a[6] * a[6]);
long c13 = 2 * ((a[4] * a[9]) + (a[5] * a[8]) + (a[6] * a[7]));
long c14 = 2 * ((a[5] * a[9]) + (a[6] * a[8])) + (a[7] * a[7]);
long c15 = 2 * ((a[6] * a[9]) + (a[7] * a[8]));
long c16 = 2 * ((a[7] * a[9])) + (a[8] * a[8]);
long c17 = 2 * ((a[8] * a[9]));
long c18 = (a[9] * a[9]);
carryReduce(r, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16, c17, c18);
}
}

View File

@@ -0,0 +1,431 @@
/*
* 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.
*/
/*
* This file is generated by FieldGen.jsh. Do not modify it directly.
*/
package sun.security.util.math.intpoly;
import java.math.BigInteger;
public class IntegerPolynomialP384 extends IntegerPolynomial {
private static final int BITS_PER_LIMB = 28;
private static final int NUM_LIMBS = 14;
private static final int MAX_ADDS = 2;
public static final BigInteger MODULUS = evaluateModulus();
private static final long CARRY_ADD = 1 << 27;
private static final int LIMB_MASK = -1 >>> (64 - BITS_PER_LIMB);
public IntegerPolynomialP384() {
super(BITS_PER_LIMB, NUM_LIMBS, MAX_ADDS, MODULUS);
}
private static BigInteger evaluateModulus() {
BigInteger result = BigInteger.valueOf(2).pow(384);
result = result.subtract(BigInteger.valueOf(2).pow(128));
result = result.subtract(BigInteger.valueOf(2).pow(96));
result = result.add(BigInteger.valueOf(2).pow(32));
result = result.subtract(BigInteger.valueOf(1));
return result;
}
@Override
protected void finalCarryReduceLast(long[] limbs) {
long c = limbs[13] >> 20;
limbs[13] -= c << 20;
limbs[4] += (c << 16) & LIMB_MASK;
limbs[5] += c >> 12;
limbs[3] += (c << 12) & LIMB_MASK;
limbs[4] += c >> 16;
limbs[1] -= (c << 4) & LIMB_MASK;
limbs[2] -= c >> 24;
limbs[0] += c;
}
private void carryReduce(long[] r, long c0, long c1, long c2, long c3, long c4, long c5, long c6, long c7, long c8, long c9, long c10, long c11, long c12, long c13, long c14, long c15, long c16, long c17, long c18, long c19, long c20, long c21, long c22, long c23, long c24, long c25, long c26) {
long c27 = 0;
//reduce from position 26
c16 += (c26 << 24) & LIMB_MASK;
c17 += c26 >> 4;
c15 += (c26 << 20) & LIMB_MASK;
c16 += c26 >> 8;
c13 -= (c26 << 12) & LIMB_MASK;
c14 -= c26 >> 16;
c12 += (c26 << 8) & LIMB_MASK;
c13 += c26 >> 20;
//reduce from position 25
c15 += (c25 << 24) & LIMB_MASK;
c16 += c25 >> 4;
c14 += (c25 << 20) & LIMB_MASK;
c15 += c25 >> 8;
c12 -= (c25 << 12) & LIMB_MASK;
c13 -= c25 >> 16;
c11 += (c25 << 8) & LIMB_MASK;
c12 += c25 >> 20;
//reduce from position 24
c14 += (c24 << 24) & LIMB_MASK;
c15 += c24 >> 4;
c13 += (c24 << 20) & LIMB_MASK;
c14 += c24 >> 8;
c11 -= (c24 << 12) & LIMB_MASK;
c12 -= c24 >> 16;
c10 += (c24 << 8) & LIMB_MASK;
c11 += c24 >> 20;
//reduce from position 23
c13 += (c23 << 24) & LIMB_MASK;
c14 += c23 >> 4;
c12 += (c23 << 20) & LIMB_MASK;
c13 += c23 >> 8;
c10 -= (c23 << 12) & LIMB_MASK;
c11 -= c23 >> 16;
c9 += (c23 << 8) & LIMB_MASK;
c10 += c23 >> 20;
//reduce from position 22
c12 += (c22 << 24) & LIMB_MASK;
c13 += c22 >> 4;
c11 += (c22 << 20) & LIMB_MASK;
c12 += c22 >> 8;
c9 -= (c22 << 12) & LIMB_MASK;
c10 -= c22 >> 16;
c8 += (c22 << 8) & LIMB_MASK;
c9 += c22 >> 20;
//reduce from position 21
c11 += (c21 << 24) & LIMB_MASK;
c12 += c21 >> 4;
c10 += (c21 << 20) & LIMB_MASK;
c11 += c21 >> 8;
c8 -= (c21 << 12) & LIMB_MASK;
c9 -= c21 >> 16;
c7 += (c21 << 8) & LIMB_MASK;
c8 += c21 >> 20;
//reduce from position 20
c10 += (c20 << 24) & LIMB_MASK;
c11 += c20 >> 4;
c9 += (c20 << 20) & LIMB_MASK;
c10 += c20 >> 8;
c7 -= (c20 << 12) & LIMB_MASK;
c8 -= c20 >> 16;
c6 += (c20 << 8) & LIMB_MASK;
c7 += c20 >> 20;
//reduce from position 19
c9 += (c19 << 24) & LIMB_MASK;
c10 += c19 >> 4;
c8 += (c19 << 20) & LIMB_MASK;
c9 += c19 >> 8;
c6 -= (c19 << 12) & LIMB_MASK;
c7 -= c19 >> 16;
c5 += (c19 << 8) & LIMB_MASK;
c6 += c19 >> 20;
//reduce from position 18
c8 += (c18 << 24) & LIMB_MASK;
c9 += c18 >> 4;
c7 += (c18 << 20) & LIMB_MASK;
c8 += c18 >> 8;
c5 -= (c18 << 12) & LIMB_MASK;
c6 -= c18 >> 16;
c4 += (c18 << 8) & LIMB_MASK;
c5 += c18 >> 20;
//reduce from position 17
c7 += (c17 << 24) & LIMB_MASK;
c8 += c17 >> 4;
c6 += (c17 << 20) & LIMB_MASK;
c7 += c17 >> 8;
c4 -= (c17 << 12) & LIMB_MASK;
c5 -= c17 >> 16;
c3 += (c17 << 8) & LIMB_MASK;
c4 += c17 >> 20;
//reduce from position 16
c6 += (c16 << 24) & LIMB_MASK;
c7 += c16 >> 4;
c5 += (c16 << 20) & LIMB_MASK;
c6 += c16 >> 8;
c3 -= (c16 << 12) & LIMB_MASK;
c4 -= c16 >> 16;
c2 += (c16 << 8) & LIMB_MASK;
c3 += c16 >> 20;
//reduce from position 15
c5 += (c15 << 24) & LIMB_MASK;
c6 += c15 >> 4;
c4 += (c15 << 20) & LIMB_MASK;
c5 += c15 >> 8;
c2 -= (c15 << 12) & LIMB_MASK;
c3 -= c15 >> 16;
c1 += (c15 << 8) & LIMB_MASK;
c2 += c15 >> 20;
//reduce from position 14
c4 += (c14 << 24) & LIMB_MASK;
c5 += c14 >> 4;
c3 += (c14 << 20) & LIMB_MASK;
c4 += c14 >> 8;
c1 -= (c14 << 12) & LIMB_MASK;
c2 -= c14 >> 16;
c0 += (c14 << 8) & LIMB_MASK;
c1 += c14 >> 20;
c14 = 0;
carryReduce0(r, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16, c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27);
}
void carryReduce0(long[] r, long c0, long c1, long c2, long c3, long c4, long c5, long c6, long c7, long c8, long c9, long c10, long c11, long c12, long c13, long c14, long c15, long c16, long c17, long c18, long c19, long c20, long c21, long c22, long c23, long c24, long c25, long c26, long c27) {
//carry from position 12
long t0 = (c12 + CARRY_ADD) >> 28;
c12 -= (t0 << 28);
c13 += t0;
//carry from position 13
t0 = (c13 + CARRY_ADD) >> 28;
c13 -= (t0 << 28);
c14 += t0;
//reduce from position 14
c4 += (c14 << 24) & LIMB_MASK;
c5 += c14 >> 4;
c3 += (c14 << 20) & LIMB_MASK;
c4 += c14 >> 8;
c1 -= (c14 << 12) & LIMB_MASK;
c2 -= c14 >> 16;
c0 += (c14 << 8) & LIMB_MASK;
c1 += c14 >> 20;
//carry from position 0
t0 = (c0 + CARRY_ADD) >> 28;
c0 -= (t0 << 28);
c1 += t0;
//carry from position 1
t0 = (c1 + CARRY_ADD) >> 28;
c1 -= (t0 << 28);
c2 += t0;
//carry from position 2
t0 = (c2 + CARRY_ADD) >> 28;
c2 -= (t0 << 28);
c3 += t0;
//carry from position 3
t0 = (c3 + CARRY_ADD) >> 28;
c3 -= (t0 << 28);
c4 += t0;
//carry from position 4
t0 = (c4 + CARRY_ADD) >> 28;
c4 -= (t0 << 28);
c5 += t0;
//carry from position 5
t0 = (c5 + CARRY_ADD) >> 28;
c5 -= (t0 << 28);
c6 += t0;
//carry from position 6
t0 = (c6 + CARRY_ADD) >> 28;
c6 -= (t0 << 28);
c7 += t0;
//carry from position 7
t0 = (c7 + CARRY_ADD) >> 28;
c7 -= (t0 << 28);
c8 += t0;
//carry from position 8
t0 = (c8 + CARRY_ADD) >> 28;
c8 -= (t0 << 28);
c9 += t0;
//carry from position 9
t0 = (c9 + CARRY_ADD) >> 28;
c9 -= (t0 << 28);
c10 += t0;
//carry from position 10
t0 = (c10 + CARRY_ADD) >> 28;
c10 -= (t0 << 28);
c11 += t0;
//carry from position 11
t0 = (c11 + CARRY_ADD) >> 28;
c11 -= (t0 << 28);
c12 += t0;
//carry from position 12
t0 = (c12 + CARRY_ADD) >> 28;
c12 -= (t0 << 28);
c13 += t0;
r[0] = c0;
r[1] = c1;
r[2] = c2;
r[3] = c3;
r[4] = c4;
r[5] = c5;
r[6] = c6;
r[7] = c7;
r[8] = c8;
r[9] = c9;
r[10] = c10;
r[11] = c11;
r[12] = c12;
r[13] = c13;
}
private void carryReduce(long[] r, long c0, long c1, long c2, long c3, long c4, long c5, long c6, long c7, long c8, long c9, long c10, long c11, long c12, long c13) {
long c14 = 0;
//carry from position 12
long t0 = (c12 + CARRY_ADD) >> 28;
c12 -= (t0 << 28);
c13 += t0;
//carry from position 13
t0 = (c13 + CARRY_ADD) >> 28;
c13 -= (t0 << 28);
c14 += t0;
//reduce from position 14
c4 += (c14 << 24) & LIMB_MASK;
c5 += c14 >> 4;
c3 += (c14 << 20) & LIMB_MASK;
c4 += c14 >> 8;
c1 -= (c14 << 12) & LIMB_MASK;
c2 -= c14 >> 16;
c0 += (c14 << 8) & LIMB_MASK;
c1 += c14 >> 20;
//carry from position 0
t0 = (c0 + CARRY_ADD) >> 28;
c0 -= (t0 << 28);
c1 += t0;
//carry from position 1
t0 = (c1 + CARRY_ADD) >> 28;
c1 -= (t0 << 28);
c2 += t0;
//carry from position 2
t0 = (c2 + CARRY_ADD) >> 28;
c2 -= (t0 << 28);
c3 += t0;
//carry from position 3
t0 = (c3 + CARRY_ADD) >> 28;
c3 -= (t0 << 28);
c4 += t0;
//carry from position 4
t0 = (c4 + CARRY_ADD) >> 28;
c4 -= (t0 << 28);
c5 += t0;
//carry from position 5
t0 = (c5 + CARRY_ADD) >> 28;
c5 -= (t0 << 28);
c6 += t0;
//carry from position 6
t0 = (c6 + CARRY_ADD) >> 28;
c6 -= (t0 << 28);
c7 += t0;
//carry from position 7
t0 = (c7 + CARRY_ADD) >> 28;
c7 -= (t0 << 28);
c8 += t0;
//carry from position 8
t0 = (c8 + CARRY_ADD) >> 28;
c8 -= (t0 << 28);
c9 += t0;
//carry from position 9
t0 = (c9 + CARRY_ADD) >> 28;
c9 -= (t0 << 28);
c10 += t0;
//carry from position 10
t0 = (c10 + CARRY_ADD) >> 28;
c10 -= (t0 << 28);
c11 += t0;
//carry from position 11
t0 = (c11 + CARRY_ADD) >> 28;
c11 -= (t0 << 28);
c12 += t0;
//carry from position 12
t0 = (c12 + CARRY_ADD) >> 28;
c12 -= (t0 << 28);
c13 += t0;
r[0] = c0;
r[1] = c1;
r[2] = c2;
r[3] = c3;
r[4] = c4;
r[5] = c5;
r[6] = c6;
r[7] = c7;
r[8] = c8;
r[9] = c9;
r[10] = c10;
r[11] = c11;
r[12] = c12;
r[13] = c13;
}
@Override
protected void mult(long[] a, long[] b, long[] r) {
long c0 = (a[0] * b[0]);
long c1 = (a[0] * b[1]) + (a[1] * b[0]);
long c2 = (a[0] * b[2]) + (a[1] * b[1]) + (a[2] * b[0]);
long c3 = (a[0] * b[3]) + (a[1] * b[2]) + (a[2] * b[1]) + (a[3] * b[0]);
long c4 = (a[0] * b[4]) + (a[1] * b[3]) + (a[2] * b[2]) + (a[3] * b[1]) + (a[4] * b[0]);
long c5 = (a[0] * b[5]) + (a[1] * b[4]) + (a[2] * b[3]) + (a[3] * b[2]) + (a[4] * b[1]) + (a[5] * b[0]);
long c6 = (a[0] * b[6]) + (a[1] * b[5]) + (a[2] * b[4]) + (a[3] * b[3]) + (a[4] * b[2]) + (a[5] * b[1]) + (a[6] * b[0]);
long c7 = (a[0] * b[7]) + (a[1] * b[6]) + (a[2] * b[5]) + (a[3] * b[4]) + (a[4] * b[3]) + (a[5] * b[2]) + (a[6] * b[1]) + (a[7] * b[0]);
long c8 = (a[0] * b[8]) + (a[1] * b[7]) + (a[2] * b[6]) + (a[3] * b[5]) + (a[4] * b[4]) + (a[5] * b[3]) + (a[6] * b[2]) + (a[7] * b[1]) + (a[8] * b[0]);
long c9 = (a[0] * b[9]) + (a[1] * b[8]) + (a[2] * b[7]) + (a[3] * b[6]) + (a[4] * b[5]) + (a[5] * b[4]) + (a[6] * b[3]) + (a[7] * b[2]) + (a[8] * b[1]) + (a[9] * b[0]);
long c10 = (a[0] * b[10]) + (a[1] * b[9]) + (a[2] * b[8]) + (a[3] * b[7]) + (a[4] * b[6]) + (a[5] * b[5]) + (a[6] * b[4]) + (a[7] * b[3]) + (a[8] * b[2]) + (a[9] * b[1]) + (a[10] * b[0]);
long c11 = (a[0] * b[11]) + (a[1] * b[10]) + (a[2] * b[9]) + (a[3] * b[8]) + (a[4] * b[7]) + (a[5] * b[6]) + (a[6] * b[5]) + (a[7] * b[4]) + (a[8] * b[3]) + (a[9] * b[2]) + (a[10] * b[1]) + (a[11] * b[0]);
long c12 = (a[0] * b[12]) + (a[1] * b[11]) + (a[2] * b[10]) + (a[3] * b[9]) + (a[4] * b[8]) + (a[5] * b[7]) + (a[6] * b[6]) + (a[7] * b[5]) + (a[8] * b[4]) + (a[9] * b[3]) + (a[10] * b[2]) + (a[11] * b[1]) + (a[12] * b[0]);
long c13 = (a[0] * b[13]) + (a[1] * b[12]) + (a[2] * b[11]) + (a[3] * b[10]) + (a[4] * b[9]) + (a[5] * b[8]) + (a[6] * b[7]) + (a[7] * b[6]) + (a[8] * b[5]) + (a[9] * b[4]) + (a[10] * b[3]) + (a[11] * b[2]) + (a[12] * b[1]) + (a[13] * b[0]);
long c14 = (a[1] * b[13]) + (a[2] * b[12]) + (a[3] * b[11]) + (a[4] * b[10]) + (a[5] * b[9]) + (a[6] * b[8]) + (a[7] * b[7]) + (a[8] * b[6]) + (a[9] * b[5]) + (a[10] * b[4]) + (a[11] * b[3]) + (a[12] * b[2]) + (a[13] * b[1]);
long c15 = (a[2] * b[13]) + (a[3] * b[12]) + (a[4] * b[11]) + (a[5] * b[10]) + (a[6] * b[9]) + (a[7] * b[8]) + (a[8] * b[7]) + (a[9] * b[6]) + (a[10] * b[5]) + (a[11] * b[4]) + (a[12] * b[3]) + (a[13] * b[2]);
long c16 = (a[3] * b[13]) + (a[4] * b[12]) + (a[5] * b[11]) + (a[6] * b[10]) + (a[7] * b[9]) + (a[8] * b[8]) + (a[9] * b[7]) + (a[10] * b[6]) + (a[11] * b[5]) + (a[12] * b[4]) + (a[13] * b[3]);
long c17 = (a[4] * b[13]) + (a[5] * b[12]) + (a[6] * b[11]) + (a[7] * b[10]) + (a[8] * b[9]) + (a[9] * b[8]) + (a[10] * b[7]) + (a[11] * b[6]) + (a[12] * b[5]) + (a[13] * b[4]);
long c18 = (a[5] * b[13]) + (a[6] * b[12]) + (a[7] * b[11]) + (a[8] * b[10]) + (a[9] * b[9]) + (a[10] * b[8]) + (a[11] * b[7]) + (a[12] * b[6]) + (a[13] * b[5]);
long c19 = (a[6] * b[13]) + (a[7] * b[12]) + (a[8] * b[11]) + (a[9] * b[10]) + (a[10] * b[9]) + (a[11] * b[8]) + (a[12] * b[7]) + (a[13] * b[6]);
long c20 = (a[7] * b[13]) + (a[8] * b[12]) + (a[9] * b[11]) + (a[10] * b[10]) + (a[11] * b[9]) + (a[12] * b[8]) + (a[13] * b[7]);
long c21 = (a[8] * b[13]) + (a[9] * b[12]) + (a[10] * b[11]) + (a[11] * b[10]) + (a[12] * b[9]) + (a[13] * b[8]);
long c22 = (a[9] * b[13]) + (a[10] * b[12]) + (a[11] * b[11]) + (a[12] * b[10]) + (a[13] * b[9]);
long c23 = (a[10] * b[13]) + (a[11] * b[12]) + (a[12] * b[11]) + (a[13] * b[10]);
long c24 = (a[11] * b[13]) + (a[12] * b[12]) + (a[13] * b[11]);
long c25 = (a[12] * b[13]) + (a[13] * b[12]);
long c26 = (a[13] * b[13]);
carryReduce(r, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16, c17, c18, c19, c20, c21, c22, c23, c24, c25, c26);
}
@Override
protected void reduce(long[] a) {
carryReduce(a, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13]);
}
@Override
protected void square(long[] a, long[] r) {
long c0 = (a[0] * a[0]);
long c1 = 2 * ((a[0] * a[1]));
long c2 = 2 * ((a[0] * a[2])) + (a[1] * a[1]);
long c3 = 2 * ((a[0] * a[3]) + (a[1] * a[2]));
long c4 = 2 * ((a[0] * a[4]) + (a[1] * a[3])) + (a[2] * a[2]);
long c5 = 2 * ((a[0] * a[5]) + (a[1] * a[4]) + (a[2] * a[3]));
long c6 = 2 * ((a[0] * a[6]) + (a[1] * a[5]) + (a[2] * a[4])) + (a[3] * a[3]);
long c7 = 2 * ((a[0] * a[7]) + (a[1] * a[6]) + (a[2] * a[5]) + (a[3] * a[4]));
long c8 = 2 * ((a[0] * a[8]) + (a[1] * a[7]) + (a[2] * a[6]) + (a[3] * a[5])) + (a[4] * a[4]);
long c9 = 2 * ((a[0] * a[9]) + (a[1] * a[8]) + (a[2] * a[7]) + (a[3] * a[6]) + (a[4] * a[5]));
long c10 = 2 * ((a[0] * a[10]) + (a[1] * a[9]) + (a[2] * a[8]) + (a[3] * a[7]) + (a[4] * a[6])) + (a[5] * a[5]);
long c11 = 2 * ((a[0] * a[11]) + (a[1] * a[10]) + (a[2] * a[9]) + (a[3] * a[8]) + (a[4] * a[7]) + (a[5] * a[6]));
long c12 = 2 * ((a[0] * a[12]) + (a[1] * a[11]) + (a[2] * a[10]) + (a[3] * a[9]) + (a[4] * a[8]) + (a[5] * a[7])) + (a[6] * a[6]);
long c13 = 2 * ((a[0] * a[13]) + (a[1] * a[12]) + (a[2] * a[11]) + (a[3] * a[10]) + (a[4] * a[9]) + (a[5] * a[8]) + (a[6] * a[7]));
long c14 = 2 * ((a[1] * a[13]) + (a[2] * a[12]) + (a[3] * a[11]) + (a[4] * a[10]) + (a[5] * a[9]) + (a[6] * a[8])) + (a[7] * a[7]);
long c15 = 2 * ((a[2] * a[13]) + (a[3] * a[12]) + (a[4] * a[11]) + (a[5] * a[10]) + (a[6] * a[9]) + (a[7] * a[8]));
long c16 = 2 * ((a[3] * a[13]) + (a[4] * a[12]) + (a[5] * a[11]) + (a[6] * a[10]) + (a[7] * a[9])) + (a[8] * a[8]);
long c17 = 2 * ((a[4] * a[13]) + (a[5] * a[12]) + (a[6] * a[11]) + (a[7] * a[10]) + (a[8] * a[9]));
long c18 = 2 * ((a[5] * a[13]) + (a[6] * a[12]) + (a[7] * a[11]) + (a[8] * a[10])) + (a[9] * a[9]);
long c19 = 2 * ((a[6] * a[13]) + (a[7] * a[12]) + (a[8] * a[11]) + (a[9] * a[10]));
long c20 = 2 * ((a[7] * a[13]) + (a[8] * a[12]) + (a[9] * a[11])) + (a[10] * a[10]);
long c21 = 2 * ((a[8] * a[13]) + (a[9] * a[12]) + (a[10] * a[11]));
long c22 = 2 * ((a[9] * a[13]) + (a[10] * a[12])) + (a[11] * a[11]);
long c23 = 2 * ((a[10] * a[13]) + (a[11] * a[12]));
long c24 = 2 * ((a[11] * a[13])) + (a[12] * a[12]);
long c25 = 2 * ((a[12] * a[13]));
long c26 = (a[13] * a[13]);
carryReduce(r, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16, c17, c18, c19, c20, c21, c22, c23, c24, c25, c26);
}
}

View File

@@ -0,0 +1,417 @@
/*
* 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.
*/
/*
* This file is generated by FieldGen.jsh. Do not modify it directly.
*/
package sun.security.util.math.intpoly;
import java.math.BigInteger;
public class IntegerPolynomialP521 extends IntegerPolynomial {
private static final int BITS_PER_LIMB = 28;
private static final int NUM_LIMBS = 19;
private static final int MAX_ADDS = 2;
public static final BigInteger MODULUS = evaluateModulus();
private static final long CARRY_ADD = 1 << 27;
private static final int LIMB_MASK = -1 >>> (64 - BITS_PER_LIMB);
public IntegerPolynomialP521() {
super(BITS_PER_LIMB, NUM_LIMBS, MAX_ADDS, MODULUS);
}
private static BigInteger evaluateModulus() {
BigInteger result = BigInteger.valueOf(2).pow(521);
result = result.subtract(BigInteger.valueOf(1));
return result;
}
@Override
protected void finalCarryReduceLast(long[] limbs) {
long c = limbs[18] >> 17;
limbs[18] -= c << 17;
limbs[0] += c;
}
private void carryReduce(long[] r, long c0, long c1, long c2, long c3, long c4, long c5, long c6, long c7, long c8, long c9, long c10, long c11, long c12, long c13, long c14, long c15, long c16, long c17, long c18, long c19, long c20, long c21, long c22, long c23, long c24, long c25, long c26, long c27, long c28, long c29, long c30, long c31, long c32, long c33, long c34, long c35, long c36) {
long c37 = 0;
//reduce from position 36
c17 += (c36 << 11) & LIMB_MASK;
c18 += c36 >> 17;
//reduce from position 35
c16 += (c35 << 11) & LIMB_MASK;
c17 += c35 >> 17;
//reduce from position 34
c15 += (c34 << 11) & LIMB_MASK;
c16 += c34 >> 17;
//reduce from position 33
c14 += (c33 << 11) & LIMB_MASK;
c15 += c33 >> 17;
//reduce from position 32
c13 += (c32 << 11) & LIMB_MASK;
c14 += c32 >> 17;
//reduce from position 31
c12 += (c31 << 11) & LIMB_MASK;
c13 += c31 >> 17;
//reduce from position 30
c11 += (c30 << 11) & LIMB_MASK;
c12 += c30 >> 17;
//reduce from position 29
c10 += (c29 << 11) & LIMB_MASK;
c11 += c29 >> 17;
//reduce from position 28
c9 += (c28 << 11) & LIMB_MASK;
c10 += c28 >> 17;
//reduce from position 27
c8 += (c27 << 11) & LIMB_MASK;
c9 += c27 >> 17;
//reduce from position 26
c7 += (c26 << 11) & LIMB_MASK;
c8 += c26 >> 17;
//reduce from position 25
c6 += (c25 << 11) & LIMB_MASK;
c7 += c25 >> 17;
//reduce from position 24
c5 += (c24 << 11) & LIMB_MASK;
c6 += c24 >> 17;
//reduce from position 23
c4 += (c23 << 11) & LIMB_MASK;
c5 += c23 >> 17;
//reduce from position 22
c3 += (c22 << 11) & LIMB_MASK;
c4 += c22 >> 17;
//reduce from position 21
c2 += (c21 << 11) & LIMB_MASK;
c3 += c21 >> 17;
//reduce from position 20
c1 += (c20 << 11) & LIMB_MASK;
c2 += c20 >> 17;
//reduce from position 19
c0 += (c19 << 11) & LIMB_MASK;
c1 += c19 >> 17;
c19 = 0;
carryReduce0(r, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16, c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30, c31, c32, c33, c34, c35, c36, c37);
}
void carryReduce0(long[] r, long c0, long c1, long c2, long c3, long c4, long c5, long c6, long c7, long c8, long c9, long c10, long c11, long c12, long c13, long c14, long c15, long c16, long c17, long c18, long c19, long c20, long c21, long c22, long c23, long c24, long c25, long c26, long c27, long c28, long c29, long c30, long c31, long c32, long c33, long c34, long c35, long c36, long c37) {
//carry from position 17
long t0 = (c17 + CARRY_ADD) >> 28;
c17 -= (t0 << 28);
c18 += t0;
//carry from position 18
t0 = (c18 + CARRY_ADD) >> 28;
c18 -= (t0 << 28);
c19 += t0;
//reduce from position 19
c0 += (c19 << 11) & LIMB_MASK;
c1 += c19 >> 17;
//carry from position 0
t0 = (c0 + CARRY_ADD) >> 28;
c0 -= (t0 << 28);
c1 += t0;
//carry from position 1
t0 = (c1 + CARRY_ADD) >> 28;
c1 -= (t0 << 28);
c2 += t0;
//carry from position 2
t0 = (c2 + CARRY_ADD) >> 28;
c2 -= (t0 << 28);
c3 += t0;
//carry from position 3
t0 = (c3 + CARRY_ADD) >> 28;
c3 -= (t0 << 28);
c4 += t0;
//carry from position 4
t0 = (c4 + CARRY_ADD) >> 28;
c4 -= (t0 << 28);
c5 += t0;
//carry from position 5
t0 = (c5 + CARRY_ADD) >> 28;
c5 -= (t0 << 28);
c6 += t0;
//carry from position 6
t0 = (c6 + CARRY_ADD) >> 28;
c6 -= (t0 << 28);
c7 += t0;
//carry from position 7
t0 = (c7 + CARRY_ADD) >> 28;
c7 -= (t0 << 28);
c8 += t0;
//carry from position 8
t0 = (c8 + CARRY_ADD) >> 28;
c8 -= (t0 << 28);
c9 += t0;
//carry from position 9
t0 = (c9 + CARRY_ADD) >> 28;
c9 -= (t0 << 28);
c10 += t0;
//carry from position 10
t0 = (c10 + CARRY_ADD) >> 28;
c10 -= (t0 << 28);
c11 += t0;
//carry from position 11
t0 = (c11 + CARRY_ADD) >> 28;
c11 -= (t0 << 28);
c12 += t0;
//carry from position 12
t0 = (c12 + CARRY_ADD) >> 28;
c12 -= (t0 << 28);
c13 += t0;
//carry from position 13
t0 = (c13 + CARRY_ADD) >> 28;
c13 -= (t0 << 28);
c14 += t0;
//carry from position 14
t0 = (c14 + CARRY_ADD) >> 28;
c14 -= (t0 << 28);
c15 += t0;
//carry from position 15
t0 = (c15 + CARRY_ADD) >> 28;
c15 -= (t0 << 28);
c16 += t0;
//carry from position 16
t0 = (c16 + CARRY_ADD) >> 28;
c16 -= (t0 << 28);
c17 += t0;
//carry from position 17
t0 = (c17 + CARRY_ADD) >> 28;
c17 -= (t0 << 28);
c18 += t0;
r[0] = c0;
r[1] = c1;
r[2] = c2;
r[3] = c3;
r[4] = c4;
r[5] = c5;
r[6] = c6;
r[7] = c7;
r[8] = c8;
r[9] = c9;
r[10] = c10;
r[11] = c11;
r[12] = c12;
r[13] = c13;
r[14] = c14;
r[15] = c15;
r[16] = c16;
r[17] = c17;
r[18] = c18;
}
private void carryReduce(long[] r, long c0, long c1, long c2, long c3, long c4, long c5, long c6, long c7, long c8, long c9, long c10, long c11, long c12, long c13, long c14, long c15, long c16, long c17, long c18) {
long c19 = 0;
//carry from position 17
long t0 = (c17 + CARRY_ADD) >> 28;
c17 -= (t0 << 28);
c18 += t0;
//carry from position 18
t0 = (c18 + CARRY_ADD) >> 28;
c18 -= (t0 << 28);
c19 += t0;
//reduce from position 19
c0 += (c19 << 11) & LIMB_MASK;
c1 += c19 >> 17;
//carry from position 0
t0 = (c0 + CARRY_ADD) >> 28;
c0 -= (t0 << 28);
c1 += t0;
//carry from position 1
t0 = (c1 + CARRY_ADD) >> 28;
c1 -= (t0 << 28);
c2 += t0;
//carry from position 2
t0 = (c2 + CARRY_ADD) >> 28;
c2 -= (t0 << 28);
c3 += t0;
//carry from position 3
t0 = (c3 + CARRY_ADD) >> 28;
c3 -= (t0 << 28);
c4 += t0;
//carry from position 4
t0 = (c4 + CARRY_ADD) >> 28;
c4 -= (t0 << 28);
c5 += t0;
//carry from position 5
t0 = (c5 + CARRY_ADD) >> 28;
c5 -= (t0 << 28);
c6 += t0;
//carry from position 6
t0 = (c6 + CARRY_ADD) >> 28;
c6 -= (t0 << 28);
c7 += t0;
//carry from position 7
t0 = (c7 + CARRY_ADD) >> 28;
c7 -= (t0 << 28);
c8 += t0;
//carry from position 8
t0 = (c8 + CARRY_ADD) >> 28;
c8 -= (t0 << 28);
c9 += t0;
//carry from position 9
t0 = (c9 + CARRY_ADD) >> 28;
c9 -= (t0 << 28);
c10 += t0;
//carry from position 10
t0 = (c10 + CARRY_ADD) >> 28;
c10 -= (t0 << 28);
c11 += t0;
//carry from position 11
t0 = (c11 + CARRY_ADD) >> 28;
c11 -= (t0 << 28);
c12 += t0;
//carry from position 12
t0 = (c12 + CARRY_ADD) >> 28;
c12 -= (t0 << 28);
c13 += t0;
//carry from position 13
t0 = (c13 + CARRY_ADD) >> 28;
c13 -= (t0 << 28);
c14 += t0;
//carry from position 14
t0 = (c14 + CARRY_ADD) >> 28;
c14 -= (t0 << 28);
c15 += t0;
//carry from position 15
t0 = (c15 + CARRY_ADD) >> 28;
c15 -= (t0 << 28);
c16 += t0;
//carry from position 16
t0 = (c16 + CARRY_ADD) >> 28;
c16 -= (t0 << 28);
c17 += t0;
//carry from position 17
t0 = (c17 + CARRY_ADD) >> 28;
c17 -= (t0 << 28);
c18 += t0;
r[0] = c0;
r[1] = c1;
r[2] = c2;
r[3] = c3;
r[4] = c4;
r[5] = c5;
r[6] = c6;
r[7] = c7;
r[8] = c8;
r[9] = c9;
r[10] = c10;
r[11] = c11;
r[12] = c12;
r[13] = c13;
r[14] = c14;
r[15] = c15;
r[16] = c16;
r[17] = c17;
r[18] = c18;
}
@Override
protected void mult(long[] a, long[] b, long[] r) {
long c0 = (a[0] * b[0]);
long c1 = (a[0] * b[1]) + (a[1] * b[0]);
long c2 = (a[0] * b[2]) + (a[1] * b[1]) + (a[2] * b[0]);
long c3 = (a[0] * b[3]) + (a[1] * b[2]) + (a[2] * b[1]) + (a[3] * b[0]);
long c4 = (a[0] * b[4]) + (a[1] * b[3]) + (a[2] * b[2]) + (a[3] * b[1]) + (a[4] * b[0]);
long c5 = (a[0] * b[5]) + (a[1] * b[4]) + (a[2] * b[3]) + (a[3] * b[2]) + (a[4] * b[1]) + (a[5] * b[0]);
long c6 = (a[0] * b[6]) + (a[1] * b[5]) + (a[2] * b[4]) + (a[3] * b[3]) + (a[4] * b[2]) + (a[5] * b[1]) + (a[6] * b[0]);
long c7 = (a[0] * b[7]) + (a[1] * b[6]) + (a[2] * b[5]) + (a[3] * b[4]) + (a[4] * b[3]) + (a[5] * b[2]) + (a[6] * b[1]) + (a[7] * b[0]);
long c8 = (a[0] * b[8]) + (a[1] * b[7]) + (a[2] * b[6]) + (a[3] * b[5]) + (a[4] * b[4]) + (a[5] * b[3]) + (a[6] * b[2]) + (a[7] * b[1]) + (a[8] * b[0]);
long c9 = (a[0] * b[9]) + (a[1] * b[8]) + (a[2] * b[7]) + (a[3] * b[6]) + (a[4] * b[5]) + (a[5] * b[4]) + (a[6] * b[3]) + (a[7] * b[2]) + (a[8] * b[1]) + (a[9] * b[0]);
long c10 = (a[0] * b[10]) + (a[1] * b[9]) + (a[2] * b[8]) + (a[3] * b[7]) + (a[4] * b[6]) + (a[5] * b[5]) + (a[6] * b[4]) + (a[7] * b[3]) + (a[8] * b[2]) + (a[9] * b[1]) + (a[10] * b[0]);
long c11 = (a[0] * b[11]) + (a[1] * b[10]) + (a[2] * b[9]) + (a[3] * b[8]) + (a[4] * b[7]) + (a[5] * b[6]) + (a[6] * b[5]) + (a[7] * b[4]) + (a[8] * b[3]) + (a[9] * b[2]) + (a[10] * b[1]) + (a[11] * b[0]);
long c12 = (a[0] * b[12]) + (a[1] * b[11]) + (a[2] * b[10]) + (a[3] * b[9]) + (a[4] * b[8]) + (a[5] * b[7]) + (a[6] * b[6]) + (a[7] * b[5]) + (a[8] * b[4]) + (a[9] * b[3]) + (a[10] * b[2]) + (a[11] * b[1]) + (a[12] * b[0]);
long c13 = (a[0] * b[13]) + (a[1] * b[12]) + (a[2] * b[11]) + (a[3] * b[10]) + (a[4] * b[9]) + (a[5] * b[8]) + (a[6] * b[7]) + (a[7] * b[6]) + (a[8] * b[5]) + (a[9] * b[4]) + (a[10] * b[3]) + (a[11] * b[2]) + (a[12] * b[1]) + (a[13] * b[0]);
long c14 = (a[0] * b[14]) + (a[1] * b[13]) + (a[2] * b[12]) + (a[3] * b[11]) + (a[4] * b[10]) + (a[5] * b[9]) + (a[6] * b[8]) + (a[7] * b[7]) + (a[8] * b[6]) + (a[9] * b[5]) + (a[10] * b[4]) + (a[11] * b[3]) + (a[12] * b[2]) + (a[13] * b[1]) + (a[14] * b[0]);
long c15 = (a[0] * b[15]) + (a[1] * b[14]) + (a[2] * b[13]) + (a[3] * b[12]) + (a[4] * b[11]) + (a[5] * b[10]) + (a[6] * b[9]) + (a[7] * b[8]) + (a[8] * b[7]) + (a[9] * b[6]) + (a[10] * b[5]) + (a[11] * b[4]) + (a[12] * b[3]) + (a[13] * b[2]) + (a[14] * b[1]) + (a[15] * b[0]);
long c16 = (a[0] * b[16]) + (a[1] * b[15]) + (a[2] * b[14]) + (a[3] * b[13]) + (a[4] * b[12]) + (a[5] * b[11]) + (a[6] * b[10]) + (a[7] * b[9]) + (a[8] * b[8]) + (a[9] * b[7]) + (a[10] * b[6]) + (a[11] * b[5]) + (a[12] * b[4]) + (a[13] * b[3]) + (a[14] * b[2]) + (a[15] * b[1]) + (a[16] * b[0]);
long c17 = (a[0] * b[17]) + (a[1] * b[16]) + (a[2] * b[15]) + (a[3] * b[14]) + (a[4] * b[13]) + (a[5] * b[12]) + (a[6] * b[11]) + (a[7] * b[10]) + (a[8] * b[9]) + (a[9] * b[8]) + (a[10] * b[7]) + (a[11] * b[6]) + (a[12] * b[5]) + (a[13] * b[4]) + (a[14] * b[3]) + (a[15] * b[2]) + (a[16] * b[1]) + (a[17] * b[0]);
long c18 = (a[0] * b[18]) + (a[1] * b[17]) + (a[2] * b[16]) + (a[3] * b[15]) + (a[4] * b[14]) + (a[5] * b[13]) + (a[6] * b[12]) + (a[7] * b[11]) + (a[8] * b[10]) + (a[9] * b[9]) + (a[10] * b[8]) + (a[11] * b[7]) + (a[12] * b[6]) + (a[13] * b[5]) + (a[14] * b[4]) + (a[15] * b[3]) + (a[16] * b[2]) + (a[17] * b[1]) + (a[18] * b[0]);
long c19 = (a[1] * b[18]) + (a[2] * b[17]) + (a[3] * b[16]) + (a[4] * b[15]) + (a[5] * b[14]) + (a[6] * b[13]) + (a[7] * b[12]) + (a[8] * b[11]) + (a[9] * b[10]) + (a[10] * b[9]) + (a[11] * b[8]) + (a[12] * b[7]) + (a[13] * b[6]) + (a[14] * b[5]) + (a[15] * b[4]) + (a[16] * b[3]) + (a[17] * b[2]) + (a[18] * b[1]);
long c20 = (a[2] * b[18]) + (a[3] * b[17]) + (a[4] * b[16]) + (a[5] * b[15]) + (a[6] * b[14]) + (a[7] * b[13]) + (a[8] * b[12]) + (a[9] * b[11]) + (a[10] * b[10]) + (a[11] * b[9]) + (a[12] * b[8]) + (a[13] * b[7]) + (a[14] * b[6]) + (a[15] * b[5]) + (a[16] * b[4]) + (a[17] * b[3]) + (a[18] * b[2]);
long c21 = (a[3] * b[18]) + (a[4] * b[17]) + (a[5] * b[16]) + (a[6] * b[15]) + (a[7] * b[14]) + (a[8] * b[13]) + (a[9] * b[12]) + (a[10] * b[11]) + (a[11] * b[10]) + (a[12] * b[9]) + (a[13] * b[8]) + (a[14] * b[7]) + (a[15] * b[6]) + (a[16] * b[5]) + (a[17] * b[4]) + (a[18] * b[3]);
long c22 = (a[4] * b[18]) + (a[5] * b[17]) + (a[6] * b[16]) + (a[7] * b[15]) + (a[8] * b[14]) + (a[9] * b[13]) + (a[10] * b[12]) + (a[11] * b[11]) + (a[12] * b[10]) + (a[13] * b[9]) + (a[14] * b[8]) + (a[15] * b[7]) + (a[16] * b[6]) + (a[17] * b[5]) + (a[18] * b[4]);
long c23 = (a[5] * b[18]) + (a[6] * b[17]) + (a[7] * b[16]) + (a[8] * b[15]) + (a[9] * b[14]) + (a[10] * b[13]) + (a[11] * b[12]) + (a[12] * b[11]) + (a[13] * b[10]) + (a[14] * b[9]) + (a[15] * b[8]) + (a[16] * b[7]) + (a[17] * b[6]) + (a[18] * b[5]);
long c24 = (a[6] * b[18]) + (a[7] * b[17]) + (a[8] * b[16]) + (a[9] * b[15]) + (a[10] * b[14]) + (a[11] * b[13]) + (a[12] * b[12]) + (a[13] * b[11]) + (a[14] * b[10]) + (a[15] * b[9]) + (a[16] * b[8]) + (a[17] * b[7]) + (a[18] * b[6]);
long c25 = (a[7] * b[18]) + (a[8] * b[17]) + (a[9] * b[16]) + (a[10] * b[15]) + (a[11] * b[14]) + (a[12] * b[13]) + (a[13] * b[12]) + (a[14] * b[11]) + (a[15] * b[10]) + (a[16] * b[9]) + (a[17] * b[8]) + (a[18] * b[7]);
long c26 = (a[8] * b[18]) + (a[9] * b[17]) + (a[10] * b[16]) + (a[11] * b[15]) + (a[12] * b[14]) + (a[13] * b[13]) + (a[14] * b[12]) + (a[15] * b[11]) + (a[16] * b[10]) + (a[17] * b[9]) + (a[18] * b[8]);
long c27 = (a[9] * b[18]) + (a[10] * b[17]) + (a[11] * b[16]) + (a[12] * b[15]) + (a[13] * b[14]) + (a[14] * b[13]) + (a[15] * b[12]) + (a[16] * b[11]) + (a[17] * b[10]) + (a[18] * b[9]);
long c28 = (a[10] * b[18]) + (a[11] * b[17]) + (a[12] * b[16]) + (a[13] * b[15]) + (a[14] * b[14]) + (a[15] * b[13]) + (a[16] * b[12]) + (a[17] * b[11]) + (a[18] * b[10]);
long c29 = (a[11] * b[18]) + (a[12] * b[17]) + (a[13] * b[16]) + (a[14] * b[15]) + (a[15] * b[14]) + (a[16] * b[13]) + (a[17] * b[12]) + (a[18] * b[11]);
long c30 = (a[12] * b[18]) + (a[13] * b[17]) + (a[14] * b[16]) + (a[15] * b[15]) + (a[16] * b[14]) + (a[17] * b[13]) + (a[18] * b[12]);
long c31 = (a[13] * b[18]) + (a[14] * b[17]) + (a[15] * b[16]) + (a[16] * b[15]) + (a[17] * b[14]) + (a[18] * b[13]);
long c32 = (a[14] * b[18]) + (a[15] * b[17]) + (a[16] * b[16]) + (a[17] * b[15]) + (a[18] * b[14]);
long c33 = (a[15] * b[18]) + (a[16] * b[17]) + (a[17] * b[16]) + (a[18] * b[15]);
long c34 = (a[16] * b[18]) + (a[17] * b[17]) + (a[18] * b[16]);
long c35 = (a[17] * b[18]) + (a[18] * b[17]);
long c36 = (a[18] * b[18]);
carryReduce(r, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16, c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30, c31, c32, c33, c34, c35, c36);
}
@Override
protected void reduce(long[] a) {
carryReduce(a, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15], a[16], a[17], a[18]);
}
@Override
protected void square(long[] a, long[] r) {
long c0 = (a[0] * a[0]);
long c1 = 2 * ((a[0] * a[1]));
long c2 = 2 * ((a[0] * a[2])) + (a[1] * a[1]);
long c3 = 2 * ((a[0] * a[3]) + (a[1] * a[2]));
long c4 = 2 * ((a[0] * a[4]) + (a[1] * a[3])) + (a[2] * a[2]);
long c5 = 2 * ((a[0] * a[5]) + (a[1] * a[4]) + (a[2] * a[3]));
long c6 = 2 * ((a[0] * a[6]) + (a[1] * a[5]) + (a[2] * a[4])) + (a[3] * a[3]);
long c7 = 2 * ((a[0] * a[7]) + (a[1] * a[6]) + (a[2] * a[5]) + (a[3] * a[4]));
long c8 = 2 * ((a[0] * a[8]) + (a[1] * a[7]) + (a[2] * a[6]) + (a[3] * a[5])) + (a[4] * a[4]);
long c9 = 2 * ((a[0] * a[9]) + (a[1] * a[8]) + (a[2] * a[7]) + (a[3] * a[6]) + (a[4] * a[5]));
long c10 = 2 * ((a[0] * a[10]) + (a[1] * a[9]) + (a[2] * a[8]) + (a[3] * a[7]) + (a[4] * a[6])) + (a[5] * a[5]);
long c11 = 2 * ((a[0] * a[11]) + (a[1] * a[10]) + (a[2] * a[9]) + (a[3] * a[8]) + (a[4] * a[7]) + (a[5] * a[6]));
long c12 = 2 * ((a[0] * a[12]) + (a[1] * a[11]) + (a[2] * a[10]) + (a[3] * a[9]) + (a[4] * a[8]) + (a[5] * a[7])) + (a[6] * a[6]);
long c13 = 2 * ((a[0] * a[13]) + (a[1] * a[12]) + (a[2] * a[11]) + (a[3] * a[10]) + (a[4] * a[9]) + (a[5] * a[8]) + (a[6] * a[7]));
long c14 = 2 * ((a[0] * a[14]) + (a[1] * a[13]) + (a[2] * a[12]) + (a[3] * a[11]) + (a[4] * a[10]) + (a[5] * a[9]) + (a[6] * a[8])) + (a[7] * a[7]);
long c15 = 2 * ((a[0] * a[15]) + (a[1] * a[14]) + (a[2] * a[13]) + (a[3] * a[12]) + (a[4] * a[11]) + (a[5] * a[10]) + (a[6] * a[9]) + (a[7] * a[8]));
long c16 = 2 * ((a[0] * a[16]) + (a[1] * a[15]) + (a[2] * a[14]) + (a[3] * a[13]) + (a[4] * a[12]) + (a[5] * a[11]) + (a[6] * a[10]) + (a[7] * a[9])) + (a[8] * a[8]);
long c17 = 2 * ((a[0] * a[17]) + (a[1] * a[16]) + (a[2] * a[15]) + (a[3] * a[14]) + (a[4] * a[13]) + (a[5] * a[12]) + (a[6] * a[11]) + (a[7] * a[10]) + (a[8] * a[9]));
long c18 = 2 * ((a[0] * a[18]) + (a[1] * a[17]) + (a[2] * a[16]) + (a[3] * a[15]) + (a[4] * a[14]) + (a[5] * a[13]) + (a[6] * a[12]) + (a[7] * a[11]) + (a[8] * a[10])) + (a[9] * a[9]);
long c19 = 2 * ((a[1] * a[18]) + (a[2] * a[17]) + (a[3] * a[16]) + (a[4] * a[15]) + (a[5] * a[14]) + (a[6] * a[13]) + (a[7] * a[12]) + (a[8] * a[11]) + (a[9] * a[10]));
long c20 = 2 * ((a[2] * a[18]) + (a[3] * a[17]) + (a[4] * a[16]) + (a[5] * a[15]) + (a[6] * a[14]) + (a[7] * a[13]) + (a[8] * a[12]) + (a[9] * a[11])) + (a[10] * a[10]);
long c21 = 2 * ((a[3] * a[18]) + (a[4] * a[17]) + (a[5] * a[16]) + (a[6] * a[15]) + (a[7] * a[14]) + (a[8] * a[13]) + (a[9] * a[12]) + (a[10] * a[11]));
long c22 = 2 * ((a[4] * a[18]) + (a[5] * a[17]) + (a[6] * a[16]) + (a[7] * a[15]) + (a[8] * a[14]) + (a[9] * a[13]) + (a[10] * a[12])) + (a[11] * a[11]);
long c23 = 2 * ((a[5] * a[18]) + (a[6] * a[17]) + (a[7] * a[16]) + (a[8] * a[15]) + (a[9] * a[14]) + (a[10] * a[13]) + (a[11] * a[12]));
long c24 = 2 * ((a[6] * a[18]) + (a[7] * a[17]) + (a[8] * a[16]) + (a[9] * a[15]) + (a[10] * a[14]) + (a[11] * a[13])) + (a[12] * a[12]);
long c25 = 2 * ((a[7] * a[18]) + (a[8] * a[17]) + (a[9] * a[16]) + (a[10] * a[15]) + (a[11] * a[14]) + (a[12] * a[13]));
long c26 = 2 * ((a[8] * a[18]) + (a[9] * a[17]) + (a[10] * a[16]) + (a[11] * a[15]) + (a[12] * a[14])) + (a[13] * a[13]);
long c27 = 2 * ((a[9] * a[18]) + (a[10] * a[17]) + (a[11] * a[16]) + (a[12] * a[15]) + (a[13] * a[14]));
long c28 = 2 * ((a[10] * a[18]) + (a[11] * a[17]) + (a[12] * a[16]) + (a[13] * a[15])) + (a[14] * a[14]);
long c29 = 2 * ((a[11] * a[18]) + (a[12] * a[17]) + (a[13] * a[16]) + (a[14] * a[15]));
long c30 = 2 * ((a[12] * a[18]) + (a[13] * a[17]) + (a[14] * a[16])) + (a[15] * a[15]);
long c31 = 2 * ((a[13] * a[18]) + (a[14] * a[17]) + (a[15] * a[16]));
long c32 = 2 * ((a[14] * a[18]) + (a[15] * a[17])) + (a[16] * a[16]);
long c33 = 2 * ((a[15] * a[18]) + (a[16] * a[17]));
long c34 = 2 * ((a[16] * a[18])) + (a[17] * a[17]);
long c35 = 2 * ((a[17] * a[18]));
long c36 = (a[18] * a[18]);
carryReduce(r, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16, c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30, c31, c32, c33, c34, c35, c36);
}
}

View File

@@ -0,0 +1,673 @@
/*
* 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.
*/
/*
* This file is generated by FieldGen.jsh. Do not modify it directly.
*/
package sun.security.util.math.intpoly;
import java.math.BigInteger;
public class P256OrderField extends IntegerPolynomial {
private static final int BITS_PER_LIMB = 26;
private static final int NUM_LIMBS = 10;
private static final int MAX_ADDS = 1;
public static final BigInteger MODULUS = evaluateModulus();
private static final long CARRY_ADD = 1 << 25;
private static final int LIMB_MASK = -1 >>> (64 - BITS_PER_LIMB);
public P256OrderField() {
super(BITS_PER_LIMB, NUM_LIMBS, MAX_ADDS, MODULUS);
}
private static BigInteger evaluateModulus() {
BigInteger result = BigInteger.valueOf(2).pow(256);
result = result.add(BigInteger.valueOf(6497617));
result = result.subtract(BigInteger.valueOf(2).pow(26).multiply(BigInteger.valueOf(26038081)));
result = result.add(BigInteger.valueOf(2).pow(52).multiply(BigInteger.valueOf(32001852)));
result = result.subtract(BigInteger.valueOf(2).pow(78).multiply(BigInteger.valueOf(21586850)));
result = result.subtract(BigInteger.valueOf(2).pow(104).multiply(BigInteger.valueOf(4397317)));
result = result.add(BigInteger.valueOf(2).pow(182).multiply(BigInteger.valueOf(1024)));
result = result.subtract(BigInteger.valueOf(2).pow(208).multiply(BigInteger.valueOf(65536)));
return result;
}
@Override
protected void finalCarryReduceLast(long[] limbs) {
long c = limbs[9] >> 22;
limbs[9] -= c << 22;
long t0 = -6497617 * c;
limbs[0] += t0;
t0 = 26038081 * c;
limbs[1] += t0;
t0 = -32001852 * c;
limbs[2] += t0;
t0 = 21586850 * c;
limbs[3] += t0;
t0 = 4397317 * c;
limbs[4] += t0;
t0 = -1024 * c;
limbs[7] += t0;
t0 = 65536 * c;
limbs[8] += t0;
}
private void carryReduce(long[] r, long c0, long c1, long c2, long c3, long c4, long c5, long c6, long c7, long c8, long c9, long c10, long c11, long c12, long c13, long c14, long c15, long c16, long c17, long c18) {
long c19 = 0;
//carry from position 0
long t0 = (c0 + CARRY_ADD) >> 26;
c0 -= (t0 << 26);
c1 += t0;
//carry from position 1
t0 = (c1 + CARRY_ADD) >> 26;
c1 -= (t0 << 26);
c2 += t0;
//carry from position 2
t0 = (c2 + CARRY_ADD) >> 26;
c2 -= (t0 << 26);
c3 += t0;
//carry from position 3
t0 = (c3 + CARRY_ADD) >> 26;
c3 -= (t0 << 26);
c4 += t0;
//carry from position 4
t0 = (c4 + CARRY_ADD) >> 26;
c4 -= (t0 << 26);
c5 += t0;
//carry from position 5
t0 = (c5 + CARRY_ADD) >> 26;
c5 -= (t0 << 26);
c6 += t0;
//carry from position 6
t0 = (c6 + CARRY_ADD) >> 26;
c6 -= (t0 << 26);
c7 += t0;
//carry from position 7
t0 = (c7 + CARRY_ADD) >> 26;
c7 -= (t0 << 26);
c8 += t0;
//carry from position 8
t0 = (c8 + CARRY_ADD) >> 26;
c8 -= (t0 << 26);
c9 += t0;
//carry from position 9
t0 = (c9 + CARRY_ADD) >> 26;
c9 -= (t0 << 26);
c10 += t0;
//carry from position 10
t0 = (c10 + CARRY_ADD) >> 26;
c10 -= (t0 << 26);
c11 += t0;
//carry from position 11
t0 = (c11 + CARRY_ADD) >> 26;
c11 -= (t0 << 26);
c12 += t0;
//carry from position 12
t0 = (c12 + CARRY_ADD) >> 26;
c12 -= (t0 << 26);
c13 += t0;
//carry from position 13
t0 = (c13 + CARRY_ADD) >> 26;
c13 -= (t0 << 26);
c14 += t0;
//carry from position 14
t0 = (c14 + CARRY_ADD) >> 26;
c14 -= (t0 << 26);
c15 += t0;
//carry from position 15
t0 = (c15 + CARRY_ADD) >> 26;
c15 -= (t0 << 26);
c16 += t0;
//carry from position 16
t0 = (c16 + CARRY_ADD) >> 26;
c16 -= (t0 << 26);
c17 += t0;
//carry from position 17
t0 = (c17 + CARRY_ADD) >> 26;
c17 -= (t0 << 26);
c18 += t0;
//carry from position 18
t0 = (c18 + CARRY_ADD) >> 26;
c18 -= (t0 << 26);
c19 += t0;
carryReduce0(r, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16, c17, c18, c19);
}
void carryReduce0(long[] r, long c0, long c1, long c2, long c3, long c4, long c5, long c6, long c7, long c8, long c9, long c10, long c11, long c12, long c13, long c14, long c15, long c16, long c17, long c18, long c19) {
long t0;
//reduce from position 19
t0 = -6497617 * c19;
c9 += (t0 << 4) & LIMB_MASK;
c10 += t0 >> 22;
t0 = 26038081 * c19;
c10 += (t0 << 4) & LIMB_MASK;
c11 += t0 >> 22;
t0 = -32001852 * c19;
c11 += (t0 << 4) & LIMB_MASK;
c12 += t0 >> 22;
t0 = 21586850 * c19;
c12 += (t0 << 4) & LIMB_MASK;
c13 += t0 >> 22;
t0 = 4397317 * c19;
c13 += (t0 << 4) & LIMB_MASK;
c14 += t0 >> 22;
t0 = -1024 * c19;
c16 += (t0 << 4) & LIMB_MASK;
c17 += t0 >> 22;
t0 = 65536 * c19;
c17 += (t0 << 4) & LIMB_MASK;
c18 += t0 >> 22;
//reduce from position 18
t0 = -6497617 * c18;
c8 += (t0 << 4) & LIMB_MASK;
c9 += t0 >> 22;
t0 = 26038081 * c18;
c9 += (t0 << 4) & LIMB_MASK;
c10 += t0 >> 22;
t0 = -32001852 * c18;
c10 += (t0 << 4) & LIMB_MASK;
c11 += t0 >> 22;
t0 = 21586850 * c18;
c11 += (t0 << 4) & LIMB_MASK;
c12 += t0 >> 22;
t0 = 4397317 * c18;
c12 += (t0 << 4) & LIMB_MASK;
c13 += t0 >> 22;
t0 = -1024 * c18;
c15 += (t0 << 4) & LIMB_MASK;
c16 += t0 >> 22;
t0 = 65536 * c18;
c16 += (t0 << 4) & LIMB_MASK;
c17 += t0 >> 22;
//reduce from position 17
t0 = -6497617 * c17;
c7 += (t0 << 4) & LIMB_MASK;
c8 += t0 >> 22;
t0 = 26038081 * c17;
c8 += (t0 << 4) & LIMB_MASK;
c9 += t0 >> 22;
t0 = -32001852 * c17;
c9 += (t0 << 4) & LIMB_MASK;
c10 += t0 >> 22;
t0 = 21586850 * c17;
c10 += (t0 << 4) & LIMB_MASK;
c11 += t0 >> 22;
t0 = 4397317 * c17;
c11 += (t0 << 4) & LIMB_MASK;
c12 += t0 >> 22;
t0 = -1024 * c17;
c14 += (t0 << 4) & LIMB_MASK;
c15 += t0 >> 22;
t0 = 65536 * c17;
c15 += (t0 << 4) & LIMB_MASK;
c16 += t0 >> 22;
//reduce from position 16
t0 = -6497617 * c16;
c6 += (t0 << 4) & LIMB_MASK;
c7 += t0 >> 22;
t0 = 26038081 * c16;
c7 += (t0 << 4) & LIMB_MASK;
c8 += t0 >> 22;
t0 = -32001852 * c16;
c8 += (t0 << 4) & LIMB_MASK;
c9 += t0 >> 22;
t0 = 21586850 * c16;
c9 += (t0 << 4) & LIMB_MASK;
c10 += t0 >> 22;
t0 = 4397317 * c16;
c10 += (t0 << 4) & LIMB_MASK;
c11 += t0 >> 22;
t0 = -1024 * c16;
c13 += (t0 << 4) & LIMB_MASK;
c14 += t0 >> 22;
t0 = 65536 * c16;
c14 += (t0 << 4) & LIMB_MASK;
c15 += t0 >> 22;
//reduce from position 15
t0 = -6497617 * c15;
c5 += (t0 << 4) & LIMB_MASK;
c6 += t0 >> 22;
t0 = 26038081 * c15;
c6 += (t0 << 4) & LIMB_MASK;
c7 += t0 >> 22;
t0 = -32001852 * c15;
c7 += (t0 << 4) & LIMB_MASK;
c8 += t0 >> 22;
t0 = 21586850 * c15;
c8 += (t0 << 4) & LIMB_MASK;
c9 += t0 >> 22;
t0 = 4397317 * c15;
c9 += (t0 << 4) & LIMB_MASK;
c10 += t0 >> 22;
t0 = -1024 * c15;
c12 += (t0 << 4) & LIMB_MASK;
c13 += t0 >> 22;
t0 = 65536 * c15;
c13 += (t0 << 4) & LIMB_MASK;
c14 += t0 >> 22;
//reduce from position 14
t0 = -6497617 * c14;
c4 += (t0 << 4) & LIMB_MASK;
c5 += t0 >> 22;
t0 = 26038081 * c14;
c5 += (t0 << 4) & LIMB_MASK;
c6 += t0 >> 22;
t0 = -32001852 * c14;
c6 += (t0 << 4) & LIMB_MASK;
c7 += t0 >> 22;
t0 = 21586850 * c14;
c7 += (t0 << 4) & LIMB_MASK;
c8 += t0 >> 22;
t0 = 4397317 * c14;
c8 += (t0 << 4) & LIMB_MASK;
c9 += t0 >> 22;
t0 = -1024 * c14;
c11 += (t0 << 4) & LIMB_MASK;
c12 += t0 >> 22;
t0 = 65536 * c14;
c12 += (t0 << 4) & LIMB_MASK;
c13 += t0 >> 22;
//reduce from position 13
t0 = -6497617 * c13;
c3 += (t0 << 4) & LIMB_MASK;
c4 += t0 >> 22;
t0 = 26038081 * c13;
c4 += (t0 << 4) & LIMB_MASK;
c5 += t0 >> 22;
t0 = -32001852 * c13;
c5 += (t0 << 4) & LIMB_MASK;
c6 += t0 >> 22;
t0 = 21586850 * c13;
c6 += (t0 << 4) & LIMB_MASK;
c7 += t0 >> 22;
t0 = 4397317 * c13;
c7 += (t0 << 4) & LIMB_MASK;
c8 += t0 >> 22;
t0 = -1024 * c13;
c10 += (t0 << 4) & LIMB_MASK;
c11 += t0 >> 22;
t0 = 65536 * c13;
c11 += (t0 << 4) & LIMB_MASK;
c12 += t0 >> 22;
//reduce from position 12
t0 = -6497617 * c12;
c2 += (t0 << 4) & LIMB_MASK;
c3 += t0 >> 22;
t0 = 26038081 * c12;
c3 += (t0 << 4) & LIMB_MASK;
c4 += t0 >> 22;
t0 = -32001852 * c12;
c4 += (t0 << 4) & LIMB_MASK;
c5 += t0 >> 22;
t0 = 21586850 * c12;
c5 += (t0 << 4) & LIMB_MASK;
c6 += t0 >> 22;
t0 = 4397317 * c12;
c6 += (t0 << 4) & LIMB_MASK;
c7 += t0 >> 22;
t0 = -1024 * c12;
c9 += (t0 << 4) & LIMB_MASK;
c10 += t0 >> 22;
t0 = 65536 * c12;
c10 += (t0 << 4) & LIMB_MASK;
c11 += t0 >> 22;
//reduce from position 11
t0 = -6497617 * c11;
c1 += (t0 << 4) & LIMB_MASK;
c2 += t0 >> 22;
t0 = 26038081 * c11;
c2 += (t0 << 4) & LIMB_MASK;
c3 += t0 >> 22;
t0 = -32001852 * c11;
c3 += (t0 << 4) & LIMB_MASK;
c4 += t0 >> 22;
t0 = 21586850 * c11;
c4 += (t0 << 4) & LIMB_MASK;
c5 += t0 >> 22;
t0 = 4397317 * c11;
c5 += (t0 << 4) & LIMB_MASK;
c6 += t0 >> 22;
t0 = -1024 * c11;
c8 += (t0 << 4) & LIMB_MASK;
c9 += t0 >> 22;
t0 = 65536 * c11;
c9 += (t0 << 4) & LIMB_MASK;
c10 += t0 >> 22;
//reduce from position 10
t0 = -6497617 * c10;
c0 += (t0 << 4) & LIMB_MASK;
c1 += t0 >> 22;
t0 = 26038081 * c10;
c1 += (t0 << 4) & LIMB_MASK;
c2 += t0 >> 22;
t0 = -32001852 * c10;
c2 += (t0 << 4) & LIMB_MASK;
c3 += t0 >> 22;
t0 = 21586850 * c10;
c3 += (t0 << 4) & LIMB_MASK;
c4 += t0 >> 22;
t0 = 4397317 * c10;
c4 += (t0 << 4) & LIMB_MASK;
c5 += t0 >> 22;
t0 = -1024 * c10;
c7 += (t0 << 4) & LIMB_MASK;
c8 += t0 >> 22;
t0 = 65536 * c10;
c8 += (t0 << 4) & LIMB_MASK;
c9 += t0 >> 22;
c10 = 0;
carryReduce1(r, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16, c17, c18, c19);
}
void carryReduce1(long[] r, long c0, long c1, long c2, long c3, long c4, long c5, long c6, long c7, long c8, long c9, long c10, long c11, long c12, long c13, long c14, long c15, long c16, long c17, long c18, long c19) {
long t0;
//carry from position 0
t0 = (c0 + CARRY_ADD) >> 26;
c0 -= (t0 << 26);
c1 += t0;
//carry from position 1
t0 = (c1 + CARRY_ADD) >> 26;
c1 -= (t0 << 26);
c2 += t0;
//carry from position 2
t0 = (c2 + CARRY_ADD) >> 26;
c2 -= (t0 << 26);
c3 += t0;
//carry from position 3
t0 = (c3 + CARRY_ADD) >> 26;
c3 -= (t0 << 26);
c4 += t0;
//carry from position 4
t0 = (c4 + CARRY_ADD) >> 26;
c4 -= (t0 << 26);
c5 += t0;
//carry from position 5
t0 = (c5 + CARRY_ADD) >> 26;
c5 -= (t0 << 26);
c6 += t0;
//carry from position 6
t0 = (c6 + CARRY_ADD) >> 26;
c6 -= (t0 << 26);
c7 += t0;
//carry from position 7
t0 = (c7 + CARRY_ADD) >> 26;
c7 -= (t0 << 26);
c8 += t0;
//carry from position 8
t0 = (c8 + CARRY_ADD) >> 26;
c8 -= (t0 << 26);
c9 += t0;
//carry from position 9
t0 = (c9 + CARRY_ADD) >> 26;
c9 -= (t0 << 26);
c10 += t0;
carryReduce2(r, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16, c17, c18, c19);
}
void carryReduce2(long[] r, long c0, long c1, long c2, long c3, long c4, long c5, long c6, long c7, long c8, long c9, long c10, long c11, long c12, long c13, long c14, long c15, long c16, long c17, long c18, long c19) {
long t0;
//reduce from position 10
t0 = -6497617 * c10;
c0 += (t0 << 4) & LIMB_MASK;
c1 += t0 >> 22;
t0 = 26038081 * c10;
c1 += (t0 << 4) & LIMB_MASK;
c2 += t0 >> 22;
t0 = -32001852 * c10;
c2 += (t0 << 4) & LIMB_MASK;
c3 += t0 >> 22;
t0 = 21586850 * c10;
c3 += (t0 << 4) & LIMB_MASK;
c4 += t0 >> 22;
t0 = 4397317 * c10;
c4 += (t0 << 4) & LIMB_MASK;
c5 += t0 >> 22;
t0 = -1024 * c10;
c7 += (t0 << 4) & LIMB_MASK;
c8 += t0 >> 22;
t0 = 65536 * c10;
c8 += (t0 << 4) & LIMB_MASK;
c9 += t0 >> 22;
//carry from position 0
t0 = (c0 + CARRY_ADD) >> 26;
c0 -= (t0 << 26);
c1 += t0;
//carry from position 1
t0 = (c1 + CARRY_ADD) >> 26;
c1 -= (t0 << 26);
c2 += t0;
//carry from position 2
t0 = (c2 + CARRY_ADD) >> 26;
c2 -= (t0 << 26);
c3 += t0;
//carry from position 3
t0 = (c3 + CARRY_ADD) >> 26;
c3 -= (t0 << 26);
c4 += t0;
//carry from position 4
t0 = (c4 + CARRY_ADD) >> 26;
c4 -= (t0 << 26);
c5 += t0;
//carry from position 5
t0 = (c5 + CARRY_ADD) >> 26;
c5 -= (t0 << 26);
c6 += t0;
//carry from position 6
t0 = (c6 + CARRY_ADD) >> 26;
c6 -= (t0 << 26);
c7 += t0;
//carry from position 7
t0 = (c7 + CARRY_ADD) >> 26;
c7 -= (t0 << 26);
c8 += t0;
//carry from position 8
t0 = (c8 + CARRY_ADD) >> 26;
c8 -= (t0 << 26);
c9 += t0;
r[0] = c0;
r[1] = c1;
r[2] = c2;
r[3] = c3;
r[4] = c4;
r[5] = c5;
r[6] = c6;
r[7] = c7;
r[8] = c8;
r[9] = c9;
}
private void carryReduce(long[] r, long c0, long c1, long c2, long c3, long c4, long c5, long c6, long c7, long c8, long c9) {
long c10 = 0;
//carry from position 0
long t0 = (c0 + CARRY_ADD) >> 26;
c0 -= (t0 << 26);
c1 += t0;
//carry from position 1
t0 = (c1 + CARRY_ADD) >> 26;
c1 -= (t0 << 26);
c2 += t0;
//carry from position 2
t0 = (c2 + CARRY_ADD) >> 26;
c2 -= (t0 << 26);
c3 += t0;
//carry from position 3
t0 = (c3 + CARRY_ADD) >> 26;
c3 -= (t0 << 26);
c4 += t0;
//carry from position 4
t0 = (c4 + CARRY_ADD) >> 26;
c4 -= (t0 << 26);
c5 += t0;
//carry from position 5
t0 = (c5 + CARRY_ADD) >> 26;
c5 -= (t0 << 26);
c6 += t0;
//carry from position 6
t0 = (c6 + CARRY_ADD) >> 26;
c6 -= (t0 << 26);
c7 += t0;
//carry from position 7
t0 = (c7 + CARRY_ADD) >> 26;
c7 -= (t0 << 26);
c8 += t0;
//carry from position 8
t0 = (c8 + CARRY_ADD) >> 26;
c8 -= (t0 << 26);
c9 += t0;
//carry from position 9
t0 = (c9 + CARRY_ADD) >> 26;
c9 -= (t0 << 26);
c10 += t0;
carryReduce0(r, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10);
}
void carryReduce0(long[] r, long c0, long c1, long c2, long c3, long c4, long c5, long c6, long c7, long c8, long c9, long c10) {
long t0;
//reduce from position 10
t0 = -6497617 * c10;
c0 += (t0 << 4) & LIMB_MASK;
c1 += t0 >> 22;
t0 = 26038081 * c10;
c1 += (t0 << 4) & LIMB_MASK;
c2 += t0 >> 22;
t0 = -32001852 * c10;
c2 += (t0 << 4) & LIMB_MASK;
c3 += t0 >> 22;
t0 = 21586850 * c10;
c3 += (t0 << 4) & LIMB_MASK;
c4 += t0 >> 22;
t0 = 4397317 * c10;
c4 += (t0 << 4) & LIMB_MASK;
c5 += t0 >> 22;
t0 = -1024 * c10;
c7 += (t0 << 4) & LIMB_MASK;
c8 += t0 >> 22;
t0 = 65536 * c10;
c8 += (t0 << 4) & LIMB_MASK;
c9 += t0 >> 22;
//carry from position 0
t0 = (c0 + CARRY_ADD) >> 26;
c0 -= (t0 << 26);
c1 += t0;
//carry from position 1
t0 = (c1 + CARRY_ADD) >> 26;
c1 -= (t0 << 26);
c2 += t0;
//carry from position 2
t0 = (c2 + CARRY_ADD) >> 26;
c2 -= (t0 << 26);
c3 += t0;
//carry from position 3
t0 = (c3 + CARRY_ADD) >> 26;
c3 -= (t0 << 26);
c4 += t0;
//carry from position 4
t0 = (c4 + CARRY_ADD) >> 26;
c4 -= (t0 << 26);
c5 += t0;
//carry from position 5
t0 = (c5 + CARRY_ADD) >> 26;
c5 -= (t0 << 26);
c6 += t0;
//carry from position 6
t0 = (c6 + CARRY_ADD) >> 26;
c6 -= (t0 << 26);
c7 += t0;
//carry from position 7
t0 = (c7 + CARRY_ADD) >> 26;
c7 -= (t0 << 26);
c8 += t0;
//carry from position 8
t0 = (c8 + CARRY_ADD) >> 26;
c8 -= (t0 << 26);
c9 += t0;
r[0] = c0;
r[1] = c1;
r[2] = c2;
r[3] = c3;
r[4] = c4;
r[5] = c5;
r[6] = c6;
r[7] = c7;
r[8] = c8;
r[9] = c9;
}
@Override
protected void mult(long[] a, long[] b, long[] r) {
long c0 = (a[0] * b[0]);
long c1 = (a[0] * b[1]) + (a[1] * b[0]);
long c2 = (a[0] * b[2]) + (a[1] * b[1]) + (a[2] * b[0]);
long c3 = (a[0] * b[3]) + (a[1] * b[2]) + (a[2] * b[1]) + (a[3] * b[0]);
long c4 = (a[0] * b[4]) + (a[1] * b[3]) + (a[2] * b[2]) + (a[3] * b[1]) + (a[4] * b[0]);
long c5 = (a[0] * b[5]) + (a[1] * b[4]) + (a[2] * b[3]) + (a[3] * b[2]) + (a[4] * b[1]) + (a[5] * b[0]);
long c6 = (a[0] * b[6]) + (a[1] * b[5]) + (a[2] * b[4]) + (a[3] * b[3]) + (a[4] * b[2]) + (a[5] * b[1]) + (a[6] * b[0]);
long c7 = (a[0] * b[7]) + (a[1] * b[6]) + (a[2] * b[5]) + (a[3] * b[4]) + (a[4] * b[3]) + (a[5] * b[2]) + (a[6] * b[1]) + (a[7] * b[0]);
long c8 = (a[0] * b[8]) + (a[1] * b[7]) + (a[2] * b[6]) + (a[3] * b[5]) + (a[4] * b[4]) + (a[5] * b[3]) + (a[6] * b[2]) + (a[7] * b[1]) + (a[8] * b[0]);
long c9 = (a[0] * b[9]) + (a[1] * b[8]) + (a[2] * b[7]) + (a[3] * b[6]) + (a[4] * b[5]) + (a[5] * b[4]) + (a[6] * b[3]) + (a[7] * b[2]) + (a[8] * b[1]) + (a[9] * b[0]);
long c10 = (a[1] * b[9]) + (a[2] * b[8]) + (a[3] * b[7]) + (a[4] * b[6]) + (a[5] * b[5]) + (a[6] * b[4]) + (a[7] * b[3]) + (a[8] * b[2]) + (a[9] * b[1]);
long c11 = (a[2] * b[9]) + (a[3] * b[8]) + (a[4] * b[7]) + (a[5] * b[6]) + (a[6] * b[5]) + (a[7] * b[4]) + (a[8] * b[3]) + (a[9] * b[2]);
long c12 = (a[3] * b[9]) + (a[4] * b[8]) + (a[5] * b[7]) + (a[6] * b[6]) + (a[7] * b[5]) + (a[8] * b[4]) + (a[9] * b[3]);
long c13 = (a[4] * b[9]) + (a[5] * b[8]) + (a[6] * b[7]) + (a[7] * b[6]) + (a[8] * b[5]) + (a[9] * b[4]);
long c14 = (a[5] * b[9]) + (a[6] * b[8]) + (a[7] * b[7]) + (a[8] * b[6]) + (a[9] * b[5]);
long c15 = (a[6] * b[9]) + (a[7] * b[8]) + (a[8] * b[7]) + (a[9] * b[6]);
long c16 = (a[7] * b[9]) + (a[8] * b[8]) + (a[9] * b[7]);
long c17 = (a[8] * b[9]) + (a[9] * b[8]);
long c18 = (a[9] * b[9]);
carryReduce(r, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16, c17, c18);
}
@Override
protected void reduce(long[] a) {
carryReduce(a, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9]);
}
@Override
protected void square(long[] a, long[] r) {
long c0 = (a[0] * a[0]);
long c1 = 2 * ((a[0] * a[1]));
long c2 = 2 * ((a[0] * a[2])) + (a[1] * a[1]);
long c3 = 2 * ((a[0] * a[3]) + (a[1] * a[2]));
long c4 = 2 * ((a[0] * a[4]) + (a[1] * a[3])) + (a[2] * a[2]);
long c5 = 2 * ((a[0] * a[5]) + (a[1] * a[4]) + (a[2] * a[3]));
long c6 = 2 * ((a[0] * a[6]) + (a[1] * a[5]) + (a[2] * a[4])) + (a[3] * a[3]);
long c7 = 2 * ((a[0] * a[7]) + (a[1] * a[6]) + (a[2] * a[5]) + (a[3] * a[4]));
long c8 = 2 * ((a[0] * a[8]) + (a[1] * a[7]) + (a[2] * a[6]) + (a[3] * a[5])) + (a[4] * a[4]);
long c9 = 2 * ((a[0] * a[9]) + (a[1] * a[8]) + (a[2] * a[7]) + (a[3] * a[6]) + (a[4] * a[5]));
long c10 = 2 * ((a[1] * a[9]) + (a[2] * a[8]) + (a[3] * a[7]) + (a[4] * a[6])) + (a[5] * a[5]);
long c11 = 2 * ((a[2] * a[9]) + (a[3] * a[8]) + (a[4] * a[7]) + (a[5] * a[6]));
long c12 = 2 * ((a[3] * a[9]) + (a[4] * a[8]) + (a[5] * a[7])) + (a[6] * a[6]);
long c13 = 2 * ((a[4] * a[9]) + (a[5] * a[8]) + (a[6] * a[7]));
long c14 = 2 * ((a[5] * a[9]) + (a[6] * a[8])) + (a[7] * a[7]);
long c15 = 2 * ((a[6] * a[9]) + (a[7] * a[8]));
long c16 = 2 * ((a[7] * a[9])) + (a[8] * a[8]);
long c17 = 2 * ((a[8] * a[9]));
long c18 = (a[9] * a[9]);
carryReduce(r, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16, c17, c18);
}
}

View File

@@ -0,0 +1,881 @@
/*
* 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.
*/
/*
* This file is generated by FieldGen.jsh. Do not modify it directly.
*/
package sun.security.util.math.intpoly;
import java.math.BigInteger;
public class P384OrderField extends IntegerPolynomial {
private static final int BITS_PER_LIMB = 28;
private static final int NUM_LIMBS = 14;
private static final int MAX_ADDS = 1;
public static final BigInteger MODULUS = evaluateModulus();
private static final long CARRY_ADD = 1 << 27;
private static final int LIMB_MASK = -1 >>> (64 - BITS_PER_LIMB);
public P384OrderField() {
super(BITS_PER_LIMB, NUM_LIMBS, MAX_ADDS, MODULUS);
}
private static BigInteger evaluateModulus() {
BigInteger result = BigInteger.valueOf(2).pow(384);
result = result.subtract(BigInteger.valueOf(54187661));
result = result.subtract(BigInteger.valueOf(2).pow(28).multiply(BigInteger.valueOf(20867411)));
result = result.add(BigInteger.valueOf(2).pow(56).multiply(BigInteger.valueOf(10975981)));
result = result.add(BigInteger.valueOf(2).pow(84).multiply(BigInteger.valueOf(14361739)));
result = result.subtract(BigInteger.valueOf(2).pow(112).multiply(BigInteger.valueOf(35694566)));
result = result.subtract(BigInteger.valueOf(2).pow(140).multiply(BigInteger.valueOf(132168845)));
result = result.subtract(BigInteger.valueOf(2).pow(168).multiply(BigInteger.valueOf(3710130)));
return result;
}
@Override
protected void finalCarryReduceLast(long[] limbs) {
long c = limbs[13] >> 20;
limbs[13] -= c << 20;
long t0 = 54187661 * c;
limbs[0] += t0;
t0 = 20867411 * c;
limbs[1] += t0;
t0 = -10975981 * c;
limbs[2] += t0;
t0 = -14361739 * c;
limbs[3] += t0;
t0 = 35694566 * c;
limbs[4] += t0;
t0 = 132168845 * c;
limbs[5] += t0;
t0 = 3710130 * c;
limbs[6] += t0;
}
private void carryReduce(long[] r, long c0, long c1, long c2, long c3, long c4, long c5, long c6, long c7, long c8, long c9, long c10, long c11, long c12, long c13, long c14, long c15, long c16, long c17, long c18, long c19, long c20, long c21, long c22, long c23, long c24, long c25, long c26) {
long c27 = 0;
//carry from position 0
long t0 = (c0 + CARRY_ADD) >> 28;
c0 -= (t0 << 28);
c1 += t0;
//carry from position 1
t0 = (c1 + CARRY_ADD) >> 28;
c1 -= (t0 << 28);
c2 += t0;
//carry from position 2
t0 = (c2 + CARRY_ADD) >> 28;
c2 -= (t0 << 28);
c3 += t0;
//carry from position 3
t0 = (c3 + CARRY_ADD) >> 28;
c3 -= (t0 << 28);
c4 += t0;
//carry from position 4
t0 = (c4 + CARRY_ADD) >> 28;
c4 -= (t0 << 28);
c5 += t0;
//carry from position 5
t0 = (c5 + CARRY_ADD) >> 28;
c5 -= (t0 << 28);
c6 += t0;
//carry from position 6
t0 = (c6 + CARRY_ADD) >> 28;
c6 -= (t0 << 28);
c7 += t0;
//carry from position 7
t0 = (c7 + CARRY_ADD) >> 28;
c7 -= (t0 << 28);
c8 += t0;
//carry from position 8
t0 = (c8 + CARRY_ADD) >> 28;
c8 -= (t0 << 28);
c9 += t0;
//carry from position 9
t0 = (c9 + CARRY_ADD) >> 28;
c9 -= (t0 << 28);
c10 += t0;
//carry from position 10
t0 = (c10 + CARRY_ADD) >> 28;
c10 -= (t0 << 28);
c11 += t0;
//carry from position 11
t0 = (c11 + CARRY_ADD) >> 28;
c11 -= (t0 << 28);
c12 += t0;
//carry from position 12
t0 = (c12 + CARRY_ADD) >> 28;
c12 -= (t0 << 28);
c13 += t0;
//carry from position 13
t0 = (c13 + CARRY_ADD) >> 28;
c13 -= (t0 << 28);
c14 += t0;
//carry from position 14
t0 = (c14 + CARRY_ADD) >> 28;
c14 -= (t0 << 28);
c15 += t0;
//carry from position 15
t0 = (c15 + CARRY_ADD) >> 28;
c15 -= (t0 << 28);
c16 += t0;
//carry from position 16
t0 = (c16 + CARRY_ADD) >> 28;
c16 -= (t0 << 28);
c17 += t0;
//carry from position 17
t0 = (c17 + CARRY_ADD) >> 28;
c17 -= (t0 << 28);
c18 += t0;
//carry from position 18
t0 = (c18 + CARRY_ADD) >> 28;
c18 -= (t0 << 28);
c19 += t0;
//carry from position 19
t0 = (c19 + CARRY_ADD) >> 28;
c19 -= (t0 << 28);
c20 += t0;
//carry from position 20
t0 = (c20 + CARRY_ADD) >> 28;
c20 -= (t0 << 28);
c21 += t0;
//carry from position 21
t0 = (c21 + CARRY_ADD) >> 28;
c21 -= (t0 << 28);
c22 += t0;
//carry from position 22
t0 = (c22 + CARRY_ADD) >> 28;
c22 -= (t0 << 28);
c23 += t0;
//carry from position 23
t0 = (c23 + CARRY_ADD) >> 28;
c23 -= (t0 << 28);
c24 += t0;
//carry from position 24
t0 = (c24 + CARRY_ADD) >> 28;
c24 -= (t0 << 28);
c25 += t0;
//carry from position 25
t0 = (c25 + CARRY_ADD) >> 28;
c25 -= (t0 << 28);
c26 += t0;
//carry from position 26
t0 = (c26 + CARRY_ADD) >> 28;
c26 -= (t0 << 28);
c27 += t0;
carryReduce0(r, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16, c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27);
}
void carryReduce0(long[] r, long c0, long c1, long c2, long c3, long c4, long c5, long c6, long c7, long c8, long c9, long c10, long c11, long c12, long c13, long c14, long c15, long c16, long c17, long c18, long c19, long c20, long c21, long c22, long c23, long c24, long c25, long c26, long c27) {
long t0;
//reduce from position 27
t0 = 54187661 * c27;
c13 += (t0 << 8) & LIMB_MASK;
c14 += t0 >> 20;
t0 = 20867411 * c27;
c14 += (t0 << 8) & LIMB_MASK;
c15 += t0 >> 20;
t0 = -10975981 * c27;
c15 += (t0 << 8) & LIMB_MASK;
c16 += t0 >> 20;
t0 = -14361739 * c27;
c16 += (t0 << 8) & LIMB_MASK;
c17 += t0 >> 20;
t0 = 35694566 * c27;
c17 += (t0 << 8) & LIMB_MASK;
c18 += t0 >> 20;
t0 = 132168845 * c27;
c18 += (t0 << 8) & LIMB_MASK;
c19 += t0 >> 20;
t0 = 3710130 * c27;
c19 += (t0 << 8) & LIMB_MASK;
c20 += t0 >> 20;
//reduce from position 26
t0 = 54187661 * c26;
c12 += (t0 << 8) & LIMB_MASK;
c13 += t0 >> 20;
t0 = 20867411 * c26;
c13 += (t0 << 8) & LIMB_MASK;
c14 += t0 >> 20;
t0 = -10975981 * c26;
c14 += (t0 << 8) & LIMB_MASK;
c15 += t0 >> 20;
t0 = -14361739 * c26;
c15 += (t0 << 8) & LIMB_MASK;
c16 += t0 >> 20;
t0 = 35694566 * c26;
c16 += (t0 << 8) & LIMB_MASK;
c17 += t0 >> 20;
t0 = 132168845 * c26;
c17 += (t0 << 8) & LIMB_MASK;
c18 += t0 >> 20;
t0 = 3710130 * c26;
c18 += (t0 << 8) & LIMB_MASK;
c19 += t0 >> 20;
//reduce from position 25
t0 = 54187661 * c25;
c11 += (t0 << 8) & LIMB_MASK;
c12 += t0 >> 20;
t0 = 20867411 * c25;
c12 += (t0 << 8) & LIMB_MASK;
c13 += t0 >> 20;
t0 = -10975981 * c25;
c13 += (t0 << 8) & LIMB_MASK;
c14 += t0 >> 20;
t0 = -14361739 * c25;
c14 += (t0 << 8) & LIMB_MASK;
c15 += t0 >> 20;
t0 = 35694566 * c25;
c15 += (t0 << 8) & LIMB_MASK;
c16 += t0 >> 20;
t0 = 132168845 * c25;
c16 += (t0 << 8) & LIMB_MASK;
c17 += t0 >> 20;
t0 = 3710130 * c25;
c17 += (t0 << 8) & LIMB_MASK;
c18 += t0 >> 20;
//reduce from position 24
t0 = 54187661 * c24;
c10 += (t0 << 8) & LIMB_MASK;
c11 += t0 >> 20;
t0 = 20867411 * c24;
c11 += (t0 << 8) & LIMB_MASK;
c12 += t0 >> 20;
t0 = -10975981 * c24;
c12 += (t0 << 8) & LIMB_MASK;
c13 += t0 >> 20;
t0 = -14361739 * c24;
c13 += (t0 << 8) & LIMB_MASK;
c14 += t0 >> 20;
t0 = 35694566 * c24;
c14 += (t0 << 8) & LIMB_MASK;
c15 += t0 >> 20;
t0 = 132168845 * c24;
c15 += (t0 << 8) & LIMB_MASK;
c16 += t0 >> 20;
t0 = 3710130 * c24;
c16 += (t0 << 8) & LIMB_MASK;
c17 += t0 >> 20;
//reduce from position 23
t0 = 54187661 * c23;
c9 += (t0 << 8) & LIMB_MASK;
c10 += t0 >> 20;
t0 = 20867411 * c23;
c10 += (t0 << 8) & LIMB_MASK;
c11 += t0 >> 20;
t0 = -10975981 * c23;
c11 += (t0 << 8) & LIMB_MASK;
c12 += t0 >> 20;
t0 = -14361739 * c23;
c12 += (t0 << 8) & LIMB_MASK;
c13 += t0 >> 20;
t0 = 35694566 * c23;
c13 += (t0 << 8) & LIMB_MASK;
c14 += t0 >> 20;
t0 = 132168845 * c23;
c14 += (t0 << 8) & LIMB_MASK;
c15 += t0 >> 20;
t0 = 3710130 * c23;
c15 += (t0 << 8) & LIMB_MASK;
c16 += t0 >> 20;
//reduce from position 22
t0 = 54187661 * c22;
c8 += (t0 << 8) & LIMB_MASK;
c9 += t0 >> 20;
t0 = 20867411 * c22;
c9 += (t0 << 8) & LIMB_MASK;
c10 += t0 >> 20;
t0 = -10975981 * c22;
c10 += (t0 << 8) & LIMB_MASK;
c11 += t0 >> 20;
t0 = -14361739 * c22;
c11 += (t0 << 8) & LIMB_MASK;
c12 += t0 >> 20;
t0 = 35694566 * c22;
c12 += (t0 << 8) & LIMB_MASK;
c13 += t0 >> 20;
t0 = 132168845 * c22;
c13 += (t0 << 8) & LIMB_MASK;
c14 += t0 >> 20;
t0 = 3710130 * c22;
c14 += (t0 << 8) & LIMB_MASK;
c15 += t0 >> 20;
//reduce from position 21
t0 = 54187661 * c21;
c7 += (t0 << 8) & LIMB_MASK;
c8 += t0 >> 20;
t0 = 20867411 * c21;
c8 += (t0 << 8) & LIMB_MASK;
c9 += t0 >> 20;
t0 = -10975981 * c21;
c9 += (t0 << 8) & LIMB_MASK;
c10 += t0 >> 20;
t0 = -14361739 * c21;
c10 += (t0 << 8) & LIMB_MASK;
c11 += t0 >> 20;
t0 = 35694566 * c21;
c11 += (t0 << 8) & LIMB_MASK;
c12 += t0 >> 20;
t0 = 132168845 * c21;
c12 += (t0 << 8) & LIMB_MASK;
c13 += t0 >> 20;
t0 = 3710130 * c21;
c13 += (t0 << 8) & LIMB_MASK;
c14 += t0 >> 20;
//reduce from position 20
t0 = 54187661 * c20;
c6 += (t0 << 8) & LIMB_MASK;
c7 += t0 >> 20;
t0 = 20867411 * c20;
c7 += (t0 << 8) & LIMB_MASK;
c8 += t0 >> 20;
t0 = -10975981 * c20;
c8 += (t0 << 8) & LIMB_MASK;
c9 += t0 >> 20;
t0 = -14361739 * c20;
c9 += (t0 << 8) & LIMB_MASK;
c10 += t0 >> 20;
t0 = 35694566 * c20;
c10 += (t0 << 8) & LIMB_MASK;
c11 += t0 >> 20;
t0 = 132168845 * c20;
c11 += (t0 << 8) & LIMB_MASK;
c12 += t0 >> 20;
t0 = 3710130 * c20;
c12 += (t0 << 8) & LIMB_MASK;
c13 += t0 >> 20;
//reduce from position 19
t0 = 54187661 * c19;
c5 += (t0 << 8) & LIMB_MASK;
c6 += t0 >> 20;
t0 = 20867411 * c19;
c6 += (t0 << 8) & LIMB_MASK;
c7 += t0 >> 20;
t0 = -10975981 * c19;
c7 += (t0 << 8) & LIMB_MASK;
c8 += t0 >> 20;
t0 = -14361739 * c19;
c8 += (t0 << 8) & LIMB_MASK;
c9 += t0 >> 20;
t0 = 35694566 * c19;
c9 += (t0 << 8) & LIMB_MASK;
c10 += t0 >> 20;
t0 = 132168845 * c19;
c10 += (t0 << 8) & LIMB_MASK;
c11 += t0 >> 20;
t0 = 3710130 * c19;
c11 += (t0 << 8) & LIMB_MASK;
c12 += t0 >> 20;
//reduce from position 18
t0 = 54187661 * c18;
c4 += (t0 << 8) & LIMB_MASK;
c5 += t0 >> 20;
t0 = 20867411 * c18;
c5 += (t0 << 8) & LIMB_MASK;
c6 += t0 >> 20;
t0 = -10975981 * c18;
c6 += (t0 << 8) & LIMB_MASK;
c7 += t0 >> 20;
t0 = -14361739 * c18;
c7 += (t0 << 8) & LIMB_MASK;
c8 += t0 >> 20;
t0 = 35694566 * c18;
c8 += (t0 << 8) & LIMB_MASK;
c9 += t0 >> 20;
t0 = 132168845 * c18;
c9 += (t0 << 8) & LIMB_MASK;
c10 += t0 >> 20;
t0 = 3710130 * c18;
c10 += (t0 << 8) & LIMB_MASK;
c11 += t0 >> 20;
//reduce from position 17
t0 = 54187661 * c17;
c3 += (t0 << 8) & LIMB_MASK;
c4 += t0 >> 20;
t0 = 20867411 * c17;
c4 += (t0 << 8) & LIMB_MASK;
c5 += t0 >> 20;
t0 = -10975981 * c17;
c5 += (t0 << 8) & LIMB_MASK;
c6 += t0 >> 20;
t0 = -14361739 * c17;
c6 += (t0 << 8) & LIMB_MASK;
c7 += t0 >> 20;
t0 = 35694566 * c17;
c7 += (t0 << 8) & LIMB_MASK;
c8 += t0 >> 20;
t0 = 132168845 * c17;
c8 += (t0 << 8) & LIMB_MASK;
c9 += t0 >> 20;
t0 = 3710130 * c17;
c9 += (t0 << 8) & LIMB_MASK;
c10 += t0 >> 20;
//reduce from position 16
t0 = 54187661 * c16;
c2 += (t0 << 8) & LIMB_MASK;
c3 += t0 >> 20;
t0 = 20867411 * c16;
c3 += (t0 << 8) & LIMB_MASK;
c4 += t0 >> 20;
t0 = -10975981 * c16;
c4 += (t0 << 8) & LIMB_MASK;
c5 += t0 >> 20;
t0 = -14361739 * c16;
c5 += (t0 << 8) & LIMB_MASK;
c6 += t0 >> 20;
t0 = 35694566 * c16;
c6 += (t0 << 8) & LIMB_MASK;
c7 += t0 >> 20;
t0 = 132168845 * c16;
c7 += (t0 << 8) & LIMB_MASK;
c8 += t0 >> 20;
t0 = 3710130 * c16;
c8 += (t0 << 8) & LIMB_MASK;
c9 += t0 >> 20;
//reduce from position 15
t0 = 54187661 * c15;
c1 += (t0 << 8) & LIMB_MASK;
c2 += t0 >> 20;
t0 = 20867411 * c15;
c2 += (t0 << 8) & LIMB_MASK;
c3 += t0 >> 20;
t0 = -10975981 * c15;
c3 += (t0 << 8) & LIMB_MASK;
c4 += t0 >> 20;
t0 = -14361739 * c15;
c4 += (t0 << 8) & LIMB_MASK;
c5 += t0 >> 20;
t0 = 35694566 * c15;
c5 += (t0 << 8) & LIMB_MASK;
c6 += t0 >> 20;
t0 = 132168845 * c15;
c6 += (t0 << 8) & LIMB_MASK;
c7 += t0 >> 20;
t0 = 3710130 * c15;
c7 += (t0 << 8) & LIMB_MASK;
c8 += t0 >> 20;
//reduce from position 14
t0 = 54187661 * c14;
c0 += (t0 << 8) & LIMB_MASK;
c1 += t0 >> 20;
t0 = 20867411 * c14;
c1 += (t0 << 8) & LIMB_MASK;
c2 += t0 >> 20;
t0 = -10975981 * c14;
c2 += (t0 << 8) & LIMB_MASK;
c3 += t0 >> 20;
t0 = -14361739 * c14;
c3 += (t0 << 8) & LIMB_MASK;
c4 += t0 >> 20;
t0 = 35694566 * c14;
c4 += (t0 << 8) & LIMB_MASK;
c5 += t0 >> 20;
t0 = 132168845 * c14;
c5 += (t0 << 8) & LIMB_MASK;
c6 += t0 >> 20;
t0 = 3710130 * c14;
c6 += (t0 << 8) & LIMB_MASK;
c7 += t0 >> 20;
c14 = 0;
carryReduce1(r, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16, c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27);
}
void carryReduce1(long[] r, long c0, long c1, long c2, long c3, long c4, long c5, long c6, long c7, long c8, long c9, long c10, long c11, long c12, long c13, long c14, long c15, long c16, long c17, long c18, long c19, long c20, long c21, long c22, long c23, long c24, long c25, long c26, long c27) {
long t0;
//carry from position 0
t0 = (c0 + CARRY_ADD) >> 28;
c0 -= (t0 << 28);
c1 += t0;
//carry from position 1
t0 = (c1 + CARRY_ADD) >> 28;
c1 -= (t0 << 28);
c2 += t0;
//carry from position 2
t0 = (c2 + CARRY_ADD) >> 28;
c2 -= (t0 << 28);
c3 += t0;
//carry from position 3
t0 = (c3 + CARRY_ADD) >> 28;
c3 -= (t0 << 28);
c4 += t0;
//carry from position 4
t0 = (c4 + CARRY_ADD) >> 28;
c4 -= (t0 << 28);
c5 += t0;
//carry from position 5
t0 = (c5 + CARRY_ADD) >> 28;
c5 -= (t0 << 28);
c6 += t0;
//carry from position 6
t0 = (c6 + CARRY_ADD) >> 28;
c6 -= (t0 << 28);
c7 += t0;
//carry from position 7
t0 = (c7 + CARRY_ADD) >> 28;
c7 -= (t0 << 28);
c8 += t0;
//carry from position 8
t0 = (c8 + CARRY_ADD) >> 28;
c8 -= (t0 << 28);
c9 += t0;
//carry from position 9
t0 = (c9 + CARRY_ADD) >> 28;
c9 -= (t0 << 28);
c10 += t0;
//carry from position 10
t0 = (c10 + CARRY_ADD) >> 28;
c10 -= (t0 << 28);
c11 += t0;
//carry from position 11
t0 = (c11 + CARRY_ADD) >> 28;
c11 -= (t0 << 28);
c12 += t0;
//carry from position 12
t0 = (c12 + CARRY_ADD) >> 28;
c12 -= (t0 << 28);
c13 += t0;
//carry from position 13
t0 = (c13 + CARRY_ADD) >> 28;
c13 -= (t0 << 28);
c14 += t0;
carryReduce2(r, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16, c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27);
}
void carryReduce2(long[] r, long c0, long c1, long c2, long c3, long c4, long c5, long c6, long c7, long c8, long c9, long c10, long c11, long c12, long c13, long c14, long c15, long c16, long c17, long c18, long c19, long c20, long c21, long c22, long c23, long c24, long c25, long c26, long c27) {
long t0;
//reduce from position 14
t0 = 54187661 * c14;
c0 += (t0 << 8) & LIMB_MASK;
c1 += t0 >> 20;
t0 = 20867411 * c14;
c1 += (t0 << 8) & LIMB_MASK;
c2 += t0 >> 20;
t0 = -10975981 * c14;
c2 += (t0 << 8) & LIMB_MASK;
c3 += t0 >> 20;
t0 = -14361739 * c14;
c3 += (t0 << 8) & LIMB_MASK;
c4 += t0 >> 20;
t0 = 35694566 * c14;
c4 += (t0 << 8) & LIMB_MASK;
c5 += t0 >> 20;
t0 = 132168845 * c14;
c5 += (t0 << 8) & LIMB_MASK;
c6 += t0 >> 20;
t0 = 3710130 * c14;
c6 += (t0 << 8) & LIMB_MASK;
c7 += t0 >> 20;
//carry from position 0
t0 = (c0 + CARRY_ADD) >> 28;
c0 -= (t0 << 28);
c1 += t0;
//carry from position 1
t0 = (c1 + CARRY_ADD) >> 28;
c1 -= (t0 << 28);
c2 += t0;
//carry from position 2
t0 = (c2 + CARRY_ADD) >> 28;
c2 -= (t0 << 28);
c3 += t0;
//carry from position 3
t0 = (c3 + CARRY_ADD) >> 28;
c3 -= (t0 << 28);
c4 += t0;
//carry from position 4
t0 = (c4 + CARRY_ADD) >> 28;
c4 -= (t0 << 28);
c5 += t0;
//carry from position 5
t0 = (c5 + CARRY_ADD) >> 28;
c5 -= (t0 << 28);
c6 += t0;
//carry from position 6
t0 = (c6 + CARRY_ADD) >> 28;
c6 -= (t0 << 28);
c7 += t0;
//carry from position 7
t0 = (c7 + CARRY_ADD) >> 28;
c7 -= (t0 << 28);
c8 += t0;
//carry from position 8
t0 = (c8 + CARRY_ADD) >> 28;
c8 -= (t0 << 28);
c9 += t0;
//carry from position 9
t0 = (c9 + CARRY_ADD) >> 28;
c9 -= (t0 << 28);
c10 += t0;
//carry from position 10
t0 = (c10 + CARRY_ADD) >> 28;
c10 -= (t0 << 28);
c11 += t0;
//carry from position 11
t0 = (c11 + CARRY_ADD) >> 28;
c11 -= (t0 << 28);
c12 += t0;
//carry from position 12
t0 = (c12 + CARRY_ADD) >> 28;
c12 -= (t0 << 28);
c13 += t0;
r[0] = c0;
r[1] = c1;
r[2] = c2;
r[3] = c3;
r[4] = c4;
r[5] = c5;
r[6] = c6;
r[7] = c7;
r[8] = c8;
r[9] = c9;
r[10] = c10;
r[11] = c11;
r[12] = c12;
r[13] = c13;
}
private void carryReduce(long[] r, long c0, long c1, long c2, long c3, long c4, long c5, long c6, long c7, long c8, long c9, long c10, long c11, long c12, long c13) {
long c14 = 0;
//carry from position 0
long t0 = (c0 + CARRY_ADD) >> 28;
c0 -= (t0 << 28);
c1 += t0;
//carry from position 1
t0 = (c1 + CARRY_ADD) >> 28;
c1 -= (t0 << 28);
c2 += t0;
//carry from position 2
t0 = (c2 + CARRY_ADD) >> 28;
c2 -= (t0 << 28);
c3 += t0;
//carry from position 3
t0 = (c3 + CARRY_ADD) >> 28;
c3 -= (t0 << 28);
c4 += t0;
//carry from position 4
t0 = (c4 + CARRY_ADD) >> 28;
c4 -= (t0 << 28);
c5 += t0;
//carry from position 5
t0 = (c5 + CARRY_ADD) >> 28;
c5 -= (t0 << 28);
c6 += t0;
//carry from position 6
t0 = (c6 + CARRY_ADD) >> 28;
c6 -= (t0 << 28);
c7 += t0;
//carry from position 7
t0 = (c7 + CARRY_ADD) >> 28;
c7 -= (t0 << 28);
c8 += t0;
//carry from position 8
t0 = (c8 + CARRY_ADD) >> 28;
c8 -= (t0 << 28);
c9 += t0;
//carry from position 9
t0 = (c9 + CARRY_ADD) >> 28;
c9 -= (t0 << 28);
c10 += t0;
//carry from position 10
t0 = (c10 + CARRY_ADD) >> 28;
c10 -= (t0 << 28);
c11 += t0;
//carry from position 11
t0 = (c11 + CARRY_ADD) >> 28;
c11 -= (t0 << 28);
c12 += t0;
//carry from position 12
t0 = (c12 + CARRY_ADD) >> 28;
c12 -= (t0 << 28);
c13 += t0;
//carry from position 13
t0 = (c13 + CARRY_ADD) >> 28;
c13 -= (t0 << 28);
c14 += t0;
carryReduce0(r, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14);
}
void carryReduce0(long[] r, long c0, long c1, long c2, long c3, long c4, long c5, long c6, long c7, long c8, long c9, long c10, long c11, long c12, long c13, long c14) {
long t0;
//reduce from position 14
t0 = 54187661 * c14;
c0 += (t0 << 8) & LIMB_MASK;
c1 += t0 >> 20;
t0 = 20867411 * c14;
c1 += (t0 << 8) & LIMB_MASK;
c2 += t0 >> 20;
t0 = -10975981 * c14;
c2 += (t0 << 8) & LIMB_MASK;
c3 += t0 >> 20;
t0 = -14361739 * c14;
c3 += (t0 << 8) & LIMB_MASK;
c4 += t0 >> 20;
t0 = 35694566 * c14;
c4 += (t0 << 8) & LIMB_MASK;
c5 += t0 >> 20;
t0 = 132168845 * c14;
c5 += (t0 << 8) & LIMB_MASK;
c6 += t0 >> 20;
t0 = 3710130 * c14;
c6 += (t0 << 8) & LIMB_MASK;
c7 += t0 >> 20;
//carry from position 0
t0 = (c0 + CARRY_ADD) >> 28;
c0 -= (t0 << 28);
c1 += t0;
//carry from position 1
t0 = (c1 + CARRY_ADD) >> 28;
c1 -= (t0 << 28);
c2 += t0;
//carry from position 2
t0 = (c2 + CARRY_ADD) >> 28;
c2 -= (t0 << 28);
c3 += t0;
//carry from position 3
t0 = (c3 + CARRY_ADD) >> 28;
c3 -= (t0 << 28);
c4 += t0;
//carry from position 4
t0 = (c4 + CARRY_ADD) >> 28;
c4 -= (t0 << 28);
c5 += t0;
//carry from position 5
t0 = (c5 + CARRY_ADD) >> 28;
c5 -= (t0 << 28);
c6 += t0;
//carry from position 6
t0 = (c6 + CARRY_ADD) >> 28;
c6 -= (t0 << 28);
c7 += t0;
//carry from position 7
t0 = (c7 + CARRY_ADD) >> 28;
c7 -= (t0 << 28);
c8 += t0;
//carry from position 8
t0 = (c8 + CARRY_ADD) >> 28;
c8 -= (t0 << 28);
c9 += t0;
//carry from position 9
t0 = (c9 + CARRY_ADD) >> 28;
c9 -= (t0 << 28);
c10 += t0;
//carry from position 10
t0 = (c10 + CARRY_ADD) >> 28;
c10 -= (t0 << 28);
c11 += t0;
//carry from position 11
t0 = (c11 + CARRY_ADD) >> 28;
c11 -= (t0 << 28);
c12 += t0;
//carry from position 12
t0 = (c12 + CARRY_ADD) >> 28;
c12 -= (t0 << 28);
c13 += t0;
r[0] = c0;
r[1] = c1;
r[2] = c2;
r[3] = c3;
r[4] = c4;
r[5] = c5;
r[6] = c6;
r[7] = c7;
r[8] = c8;
r[9] = c9;
r[10] = c10;
r[11] = c11;
r[12] = c12;
r[13] = c13;
}
@Override
protected void mult(long[] a, long[] b, long[] r) {
long c0 = (a[0] * b[0]);
long c1 = (a[0] * b[1]) + (a[1] * b[0]);
long c2 = (a[0] * b[2]) + (a[1] * b[1]) + (a[2] * b[0]);
long c3 = (a[0] * b[3]) + (a[1] * b[2]) + (a[2] * b[1]) + (a[3] * b[0]);
long c4 = (a[0] * b[4]) + (a[1] * b[3]) + (a[2] * b[2]) + (a[3] * b[1]) + (a[4] * b[0]);
long c5 = (a[0] * b[5]) + (a[1] * b[4]) + (a[2] * b[3]) + (a[3] * b[2]) + (a[4] * b[1]) + (a[5] * b[0]);
long c6 = (a[0] * b[6]) + (a[1] * b[5]) + (a[2] * b[4]) + (a[3] * b[3]) + (a[4] * b[2]) + (a[5] * b[1]) + (a[6] * b[0]);
long c7 = (a[0] * b[7]) + (a[1] * b[6]) + (a[2] * b[5]) + (a[3] * b[4]) + (a[4] * b[3]) + (a[5] * b[2]) + (a[6] * b[1]) + (a[7] * b[0]);
long c8 = (a[0] * b[8]) + (a[1] * b[7]) + (a[2] * b[6]) + (a[3] * b[5]) + (a[4] * b[4]) + (a[5] * b[3]) + (a[6] * b[2]) + (a[7] * b[1]) + (a[8] * b[0]);
long c9 = (a[0] * b[9]) + (a[1] * b[8]) + (a[2] * b[7]) + (a[3] * b[6]) + (a[4] * b[5]) + (a[5] * b[4]) + (a[6] * b[3]) + (a[7] * b[2]) + (a[8] * b[1]) + (a[9] * b[0]);
long c10 = (a[0] * b[10]) + (a[1] * b[9]) + (a[2] * b[8]) + (a[3] * b[7]) + (a[4] * b[6]) + (a[5] * b[5]) + (a[6] * b[4]) + (a[7] * b[3]) + (a[8] * b[2]) + (a[9] * b[1]) + (a[10] * b[0]);
long c11 = (a[0] * b[11]) + (a[1] * b[10]) + (a[2] * b[9]) + (a[3] * b[8]) + (a[4] * b[7]) + (a[5] * b[6]) + (a[6] * b[5]) + (a[7] * b[4]) + (a[8] * b[3]) + (a[9] * b[2]) + (a[10] * b[1]) + (a[11] * b[0]);
long c12 = (a[0] * b[12]) + (a[1] * b[11]) + (a[2] * b[10]) + (a[3] * b[9]) + (a[4] * b[8]) + (a[5] * b[7]) + (a[6] * b[6]) + (a[7] * b[5]) + (a[8] * b[4]) + (a[9] * b[3]) + (a[10] * b[2]) + (a[11] * b[1]) + (a[12] * b[0]);
long c13 = (a[0] * b[13]) + (a[1] * b[12]) + (a[2] * b[11]) + (a[3] * b[10]) + (a[4] * b[9]) + (a[5] * b[8]) + (a[6] * b[7]) + (a[7] * b[6]) + (a[8] * b[5]) + (a[9] * b[4]) + (a[10] * b[3]) + (a[11] * b[2]) + (a[12] * b[1]) + (a[13] * b[0]);
long c14 = (a[1] * b[13]) + (a[2] * b[12]) + (a[3] * b[11]) + (a[4] * b[10]) + (a[5] * b[9]) + (a[6] * b[8]) + (a[7] * b[7]) + (a[8] * b[6]) + (a[9] * b[5]) + (a[10] * b[4]) + (a[11] * b[3]) + (a[12] * b[2]) + (a[13] * b[1]);
long c15 = (a[2] * b[13]) + (a[3] * b[12]) + (a[4] * b[11]) + (a[5] * b[10]) + (a[6] * b[9]) + (a[7] * b[8]) + (a[8] * b[7]) + (a[9] * b[6]) + (a[10] * b[5]) + (a[11] * b[4]) + (a[12] * b[3]) + (a[13] * b[2]);
long c16 = (a[3] * b[13]) + (a[4] * b[12]) + (a[5] * b[11]) + (a[6] * b[10]) + (a[7] * b[9]) + (a[8] * b[8]) + (a[9] * b[7]) + (a[10] * b[6]) + (a[11] * b[5]) + (a[12] * b[4]) + (a[13] * b[3]);
long c17 = (a[4] * b[13]) + (a[5] * b[12]) + (a[6] * b[11]) + (a[7] * b[10]) + (a[8] * b[9]) + (a[9] * b[8]) + (a[10] * b[7]) + (a[11] * b[6]) + (a[12] * b[5]) + (a[13] * b[4]);
long c18 = (a[5] * b[13]) + (a[6] * b[12]) + (a[7] * b[11]) + (a[8] * b[10]) + (a[9] * b[9]) + (a[10] * b[8]) + (a[11] * b[7]) + (a[12] * b[6]) + (a[13] * b[5]);
long c19 = (a[6] * b[13]) + (a[7] * b[12]) + (a[8] * b[11]) + (a[9] * b[10]) + (a[10] * b[9]) + (a[11] * b[8]) + (a[12] * b[7]) + (a[13] * b[6]);
long c20 = (a[7] * b[13]) + (a[8] * b[12]) + (a[9] * b[11]) + (a[10] * b[10]) + (a[11] * b[9]) + (a[12] * b[8]) + (a[13] * b[7]);
long c21 = (a[8] * b[13]) + (a[9] * b[12]) + (a[10] * b[11]) + (a[11] * b[10]) + (a[12] * b[9]) + (a[13] * b[8]);
long c22 = (a[9] * b[13]) + (a[10] * b[12]) + (a[11] * b[11]) + (a[12] * b[10]) + (a[13] * b[9]);
long c23 = (a[10] * b[13]) + (a[11] * b[12]) + (a[12] * b[11]) + (a[13] * b[10]);
long c24 = (a[11] * b[13]) + (a[12] * b[12]) + (a[13] * b[11]);
long c25 = (a[12] * b[13]) + (a[13] * b[12]);
long c26 = (a[13] * b[13]);
carryReduce(r, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16, c17, c18, c19, c20, c21, c22, c23, c24, c25, c26);
}
@Override
protected void reduce(long[] a) {
carryReduce(a, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13]);
}
@Override
protected void square(long[] a, long[] r) {
long c0 = (a[0] * a[0]);
long c1 = 2 * ((a[0] * a[1]));
long c2 = 2 * ((a[0] * a[2])) + (a[1] * a[1]);
long c3 = 2 * ((a[0] * a[3]) + (a[1] * a[2]));
long c4 = 2 * ((a[0] * a[4]) + (a[1] * a[3])) + (a[2] * a[2]);
long c5 = 2 * ((a[0] * a[5]) + (a[1] * a[4]) + (a[2] * a[3]));
long c6 = 2 * ((a[0] * a[6]) + (a[1] * a[5]) + (a[2] * a[4])) + (a[3] * a[3]);
long c7 = 2 * ((a[0] * a[7]) + (a[1] * a[6]) + (a[2] * a[5]) + (a[3] * a[4]));
long c8 = 2 * ((a[0] * a[8]) + (a[1] * a[7]) + (a[2] * a[6]) + (a[3] * a[5])) + (a[4] * a[4]);
long c9 = 2 * ((a[0] * a[9]) + (a[1] * a[8]) + (a[2] * a[7]) + (a[3] * a[6]) + (a[4] * a[5]));
long c10 = 2 * ((a[0] * a[10]) + (a[1] * a[9]) + (a[2] * a[8]) + (a[3] * a[7]) + (a[4] * a[6])) + (a[5] * a[5]);
long c11 = 2 * ((a[0] * a[11]) + (a[1] * a[10]) + (a[2] * a[9]) + (a[3] * a[8]) + (a[4] * a[7]) + (a[5] * a[6]));
long c12 = 2 * ((a[0] * a[12]) + (a[1] * a[11]) + (a[2] * a[10]) + (a[3] * a[9]) + (a[4] * a[8]) + (a[5] * a[7])) + (a[6] * a[6]);
long c13 = 2 * ((a[0] * a[13]) + (a[1] * a[12]) + (a[2] * a[11]) + (a[3] * a[10]) + (a[4] * a[9]) + (a[5] * a[8]) + (a[6] * a[7]));
long c14 = 2 * ((a[1] * a[13]) + (a[2] * a[12]) + (a[3] * a[11]) + (a[4] * a[10]) + (a[5] * a[9]) + (a[6] * a[8])) + (a[7] * a[7]);
long c15 = 2 * ((a[2] * a[13]) + (a[3] * a[12]) + (a[4] * a[11]) + (a[5] * a[10]) + (a[6] * a[9]) + (a[7] * a[8]));
long c16 = 2 * ((a[3] * a[13]) + (a[4] * a[12]) + (a[5] * a[11]) + (a[6] * a[10]) + (a[7] * a[9])) + (a[8] * a[8]);
long c17 = 2 * ((a[4] * a[13]) + (a[5] * a[12]) + (a[6] * a[11]) + (a[7] * a[10]) + (a[8] * a[9]));
long c18 = 2 * ((a[5] * a[13]) + (a[6] * a[12]) + (a[7] * a[11]) + (a[8] * a[10])) + (a[9] * a[9]);
long c19 = 2 * ((a[6] * a[13]) + (a[7] * a[12]) + (a[8] * a[11]) + (a[9] * a[10]));
long c20 = 2 * ((a[7] * a[13]) + (a[8] * a[12]) + (a[9] * a[11])) + (a[10] * a[10]);
long c21 = 2 * ((a[8] * a[13]) + (a[9] * a[12]) + (a[10] * a[11]));
long c22 = 2 * ((a[9] * a[13]) + (a[10] * a[12])) + (a[11] * a[11]);
long c23 = 2 * ((a[10] * a[13]) + (a[11] * a[12]));
long c24 = 2 * ((a[11] * a[13])) + (a[12] * a[12]);
long c25 = 2 * ((a[12] * a[13]));
long c26 = (a[13] * a[13]);
carryReduce(r, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16, c17, c18, c19, c20, c21, c22, c23, c24, c25, c26);
}
}

File diff suppressed because it is too large Load Diff