This commit is contained in:
Prasanta Sadhukhan 2018-12-12 15:04:47 +05:30
commit 597c61458e
488 changed files with 38649 additions and 14968 deletions

View file

@ -681,11 +681,12 @@ class Character implements java.io.Serializable, Comparable<Character> {
*/
public static final class UnicodeBlock extends Subset {
/**
* 649 - the expected number of entities
* 667 - the expected number of entities
* 0.75 - the default load factor of HashMap
*/
private static final int NUM_ENTITIES = 667;
private static Map<String, UnicodeBlock> map =
new HashMap<>((int)(649 / 0.75f + 1.0f));
new HashMap<>((int)(NUM_ENTITIES / 0.75f + 1.0f));
/**
* Creates a UnicodeBlock with the given identifier name.

View file

@ -94,12 +94,10 @@ public class Object {
* programmer should be aware that producing distinct integer results
* for unequal objects may improve the performance of hash tables.
* </ul>
* <p>
* As much as is reasonably practical, the hashCode method defined
* by class {@code Object} does return distinct integers for
* distinct objects. (The hashCode may or may not be implemented
* as some function of an object's memory address at some point
* in time.)
*
* @implSpec
* As far as is reasonably practical, the {@code hashCode} method defined
* by class {@code Object} returns distinct integers for distinct objects.
*
* @return a hash code value for this object.
* @see java.lang.Object#equals(java.lang.Object)

View file

@ -25,6 +25,7 @@
package java.net;
import java.io.File;
import java.io.IOException;
import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
@ -36,6 +37,7 @@ import java.nio.charset.CharsetDecoder;
import java.nio.charset.CoderResult;
import java.nio.charset.CodingErrorAction;
import java.nio.charset.CharacterCodingException;
import java.nio.file.Path;
import java.text.Normalizer;
import jdk.internal.access.JavaNetUriAccess;
import jdk.internal.access.SharedSecrets;
@ -458,6 +460,27 @@ import java.lang.NullPointerException; // for javadoc
* resolution as well as the network I/O operations of looking up the host and
* opening a connection to the specified resource.
*
* @apiNote
*
* Applications working with file paths and file URIs should take great
* care to use the appropriate methods to convert between the two.
* The {@link Path#of(URI)} factory method and the {@link File#File(URI)}
* constructor can be used to create {@link Path} or {@link File}
* objects from a file URI. {@link Path#toUri()} and {@link File#toURI()}
* can be used to create a {@link URI} from a file path.
* Applications should never try to {@linkplain
* #URI(String, String, String, int, String, String, String)
* construct}, {@linkplain #URI(String) parse}, or
* {@linkplain #resolve(String) resolve} a {@code URI}
* from the direct string representation of a {@code File} or {@code Path}
* instance.
* <p>
* Some components of a URL or URI, such as <i>userinfo</i>, may
* be abused to construct misleading URLs or URIs. Applications
* that deal with URLs or URIs should take into account
* the recommendations advised in <a
* href="https://tools.ietf.org/html/rfc3986#section-7">RFC3986,
* Section 7, Security Considerations</a>.
*
* @author Mark Reinhold
* @since 1.4

View file

@ -25,9 +25,11 @@
package java.net;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.spi.URLStreamHandlerProvider;
import java.nio.file.Path;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Hashtable;
@ -145,6 +147,27 @@ import sun.security.action.GetPropertyAction;
* used, but only for HTML form encoding, which is not the same
* as the encoding scheme defined in RFC2396.
*
* @apiNote
*
* Applications working with file paths and file URIs should take great
* care to use the appropriate methods to convert between the two.
* The {@link Path#of(URI)} factory method and the {@link File#File(URI)}
* constructor can be used to create {@link Path} or {@link File}
* objects from a file URI. {@link Path#toUri()} and {@link File#toURI()}
* can be used to create a {@link URI} from a file path, which can be
* converted to URL using {@link URI#toURL()}.
* Applications should never try to {@linkplain #URL(String, String, String)
* construct} or {@linkplain #URL(String) parse} a {@code URL}
* from the direct string representation of a {@code File} or {@code Path}
* instance.
* <p>
* Some components of a URL or URI, such as <i>userinfo</i>, may
* be abused to construct misleading URLs or URIs. Applications
* that deal with URLs or URIs should take into account
* the recommendations advised in <a
* href="https://tools.ietf.org/html/rfc3986#section-7">RFC3986,
* Section 7, Security Considerations</a>.
*
* @author James Gosling
* @since 1.0
*/

View file

@ -80,7 +80,7 @@ import java.util.stream.StreamSupport;
* in security-sensitive applications. Additionally,
* default-constructed instances do not use a cryptographically random
* seed unless the {@linkplain System#getProperty system property}
* {@code java.util.secureRandomSeed} is set to {@code true}.
* {@systemProperty java.util.secureRandomSeed} is set to {@code true}.
*
* @author Guy Steele
* @author Doug Lea

View file

@ -2334,17 +2334,15 @@ public class ConcurrentHashMap<K,V> extends AbstractMap<K,V>
Node<K,V>[] tab, nt; int n, sc;
while (s >= (long)(sc = sizeCtl) && (tab = table) != null &&
(n = tab.length) < MAXIMUM_CAPACITY) {
int rs = resizeStamp(n);
int rs = resizeStamp(n) << RESIZE_STAMP_SHIFT;
if (sc < 0) {
if ((sc >>> RESIZE_STAMP_SHIFT) != rs || sc == rs + 1 ||
sc == rs + MAX_RESIZERS || (nt = nextTable) == null ||
transferIndex <= 0)
if (sc == rs + MAX_RESIZERS || sc == rs + 1 ||
(nt = nextTable) == null || transferIndex <= 0)
break;
if (U.compareAndSetInt(this, SIZECTL, sc, sc + 1))
transfer(tab, nt);
}
else if (U.compareAndSetInt(this, SIZECTL, sc,
(rs << RESIZE_STAMP_SHIFT) + 2))
else if (U.compareAndSetInt(this, SIZECTL, sc, rs + 2))
transfer(tab, null);
s = sumCount();
}
@ -2358,11 +2356,11 @@ public class ConcurrentHashMap<K,V> extends AbstractMap<K,V>
Node<K,V>[] nextTab; int sc;
if (tab != null && (f instanceof ForwardingNode) &&
(nextTab = ((ForwardingNode<K,V>)f).nextTable) != null) {
int rs = resizeStamp(tab.length);
int rs = resizeStamp(tab.length) << RESIZE_STAMP_SHIFT;
while (nextTab == nextTable && table == tab &&
(sc = sizeCtl) < 0) {
if ((sc >>> RESIZE_STAMP_SHIFT) != rs || sc == rs + 1 ||
sc == rs + MAX_RESIZERS || transferIndex <= 0)
if (sc == rs + MAX_RESIZERS || sc == rs + 1 ||
transferIndex <= 0)
break;
if (U.compareAndSetInt(this, SIZECTL, sc, sc + 1)) {
transfer(tab, nextTab);

View file

@ -136,17 +136,17 @@ import java.util.concurrent.locks.LockSupport;
* <p>The parameters used to construct the common pool may be controlled by
* setting the following {@linkplain System#getProperty system properties}:
* <ul>
* <li>{@code java.util.concurrent.ForkJoinPool.common.parallelism}
* <li>{@systemProperty java.util.concurrent.ForkJoinPool.common.parallelism}
* - the parallelism level, a non-negative integer
* <li>{@code java.util.concurrent.ForkJoinPool.common.threadFactory}
* <li>{@systemProperty java.util.concurrent.ForkJoinPool.common.threadFactory}
* - the class name of a {@link ForkJoinWorkerThreadFactory}.
* The {@linkplain ClassLoader#getSystemClassLoader() system class loader}
* is used to load this class.
* <li>{@code java.util.concurrent.ForkJoinPool.common.exceptionHandler}
* <li>{@systemProperty java.util.concurrent.ForkJoinPool.common.exceptionHandler}
* - the class name of a {@link UncaughtExceptionHandler}.
* The {@linkplain ClassLoader#getSystemClassLoader() system class loader}
* is used to load this class.
* <li>{@code java.util.concurrent.ForkJoinPool.common.maximumSpares}
* <li>{@systemProperty java.util.concurrent.ForkJoinPool.common.maximumSpares}
* - the maximum number of allowed extra threads to maintain target
* parallelism (default 256).
* </ul>
@ -445,8 +445,7 @@ public class ForkJoinPool extends AbstractExecutorService {
* if to its current value). This would be extremely costly. So
* we relax it in several ways: (1) Producers only signal when
* their queue is possibly empty at some point during a push
* operation (which requires conservatively checking size zero or
* one to cover races). (2) Other workers propagate this signal
* operation. (2) Other workers propagate this signal
* when they find tasks in a queue with size greater than one. (3)
* Workers only enqueue after scanning (see below) and not finding
* any tasks. (4) Rather than CASing ctl to its current value in
@ -762,10 +761,8 @@ public class ForkJoinPool extends AbstractExecutorService {
/**
* The maximum number of top-level polls per worker before
* checking other queues, expressed as a bit shift to, in effect,
* multiply by pool size, and then use as random value mask, so
* average bound is about poolSize*(1<<TOP_BOUND_SHIFT). See
* above for rationale.
* checking other queues, expressed as a bit shift. See above for
* rationale.
*/
static final int TOP_BOUND_SHIFT = 10;
@ -841,18 +838,17 @@ public class ForkJoinPool extends AbstractExecutorService {
*/
final void push(ForkJoinTask<?> task) {
ForkJoinTask<?>[] a;
int s = top, d, cap, m;
int s = top, d = s - base, cap, m;
ForkJoinPool p = pool;
if ((a = array) != null && (cap = a.length) > 0) {
QA.setRelease(a, (m = cap - 1) & s, task);
top = s + 1;
if (((d = s - (int)BASE.getAcquire(this)) & ~1) == 0 &&
p != null) { // size 0 or 1
VarHandle.fullFence();
p.signalWork();
}
else if (d == m)
if (d == m)
growArray(false);
else if (QA.getAcquire(a, m & (s - 1)) == null && p != null) {
VarHandle.fullFence(); // was empty
p.signalWork(null);
}
}
}
@ -863,16 +859,16 @@ public class ForkJoinPool extends AbstractExecutorService {
final boolean lockedPush(ForkJoinTask<?> task) {
ForkJoinTask<?>[] a;
boolean signal = false;
int s = top, b = base, cap, d;
int s = top, d = s - base, cap, m;
if ((a = array) != null && (cap = a.length) > 0) {
a[(cap - 1) & s] = task;
a[(m = (cap - 1)) & s] = task;
top = s + 1;
if (b - s + cap - 1 == 0)
if (d == m)
growArray(true);
else {
phase = 0; // full volatile unlock
if (((s - base) & ~1) == 0) // size 0 or 1
signal = true;
if (a[m & (s - 1)] == null)
signal = true; // was empty
}
}
return signal;
@ -1014,25 +1010,30 @@ public class ForkJoinPool extends AbstractExecutorService {
* queue, up to bound n (to avoid infinite unfairness).
*/
final void topLevelExec(ForkJoinTask<?> t, WorkQueue q, int n) {
if (t != null && q != null) { // hoist checks
int nstolen = 1;
for (;;) {
int nstolen = 1;
for (int j = 0;;) {
if (t != null)
t.doExec();
if (n-- < 0)
break;
else if ((t = nextLocalTask()) == null) {
if ((t = q.poll()) == null)
break;
else
++nstolen;
}
if (j++ <= n)
t = nextLocalTask();
else {
j = 0;
t = null;
}
if (t == null) {
if (q != null && (t = q.poll()) != null) {
++nstolen;
j = 0;
}
else if (j != 0)
break;
}
ForkJoinWorkerThread thread = owner;
nsteals += nstolen;
source = 0;
if (thread != null)
thread.afterTopLevelExec();
}
ForkJoinWorkerThread thread = owner;
nsteals += nstolen;
source = 0;
if (thread != null)
thread.afterTopLevelExec();
}
/**
@ -1455,7 +1456,7 @@ public class ForkJoinPool extends AbstractExecutorService {
if (!tryTerminate(false, false) && // possibly replace worker
w != null && w.array != null) // avoid repeated failures
signalWork();
signalWork(null);
if (ex == null) // help clean on way out
ForkJoinTask.helpExpungeStaleExceptions();
@ -1465,8 +1466,9 @@ public class ForkJoinPool extends AbstractExecutorService {
/**
* Tries to create or release a worker if too few are running.
* @param q if non-null recheck if empty on CAS failure
*/
final void signalWork() {
final void signalWork(WorkQueue q) {
for (;;) {
long c; int sp; WorkQueue[] ws; int i; WorkQueue v;
if ((c = ctl) >= 0L) // enough workers
@ -1493,6 +1495,8 @@ public class ForkJoinPool extends AbstractExecutorService {
LockSupport.unpark(vt);
break;
}
else if (q != null && q.isEmpty()) // no need to retry
break;
}
}
}
@ -1613,19 +1617,24 @@ public class ForkJoinPool extends AbstractExecutorService {
else if (rc <= 0 && (md & SHUTDOWN) != 0 &&
tryTerminate(false, false))
break; // quiescent shutdown
else if (rc <= 0 && pred != 0 && phase == (int)c) {
long nc = (UC_MASK & (c - TC_UNIT)) | (SP_MASK & pred);
long d = keepAlive + System.currentTimeMillis();
LockSupport.parkUntil(this, d);
if (ctl == c && // drop on timeout if all idle
d - System.currentTimeMillis() <= TIMEOUT_SLOP &&
CTL.compareAndSet(this, c, nc)) {
w.phase = QUIET;
break;
else if (w.phase < 0) {
if (rc <= 0 && pred != 0 && phase == (int)c) {
long nc = (UC_MASK & (c - TC_UNIT)) | (SP_MASK & pred);
long d = keepAlive + System.currentTimeMillis();
LockSupport.parkUntil(this, d);
if (ctl == c && // drop on timeout if all idle
d - System.currentTimeMillis() <= TIMEOUT_SLOP &&
CTL.compareAndSet(this, c, nc)) {
w.phase = QUIET;
break;
}
}
else {
LockSupport.park(this);
if (w.phase < 0) // one spurious wakeup check
LockSupport.park(this);
}
}
else if (w.phase < 0)
LockSupport.park(this); // OK if spuriously woken
w.source = 0; // disable signal
}
}
@ -1641,8 +1650,8 @@ public class ForkJoinPool extends AbstractExecutorService {
WorkQueue[] ws; int n;
if ((ws = workQueues) != null && (n = ws.length) > 0 && w != null) {
for (int m = n - 1, j = r & m;;) {
WorkQueue q; int b;
if ((q = ws[j]) != null && q.top != (b = q.base)) {
WorkQueue q; int b, s;
if ((q = ws[j]) != null && (s = q.top) != (b = q.base)) {
int qid = q.id;
ForkJoinTask<?>[] a; int cap, k; ForkJoinTask<?> t;
if ((a = q.array) != null && (cap = a.length) > 0) {
@ -1651,10 +1660,10 @@ public class ForkJoinPool extends AbstractExecutorService {
QA.compareAndSet(a, k, t, null)) {
q.base = b;
w.source = qid;
if (q.top - b > 0)
signalWork();
if (s != b && a[(cap - 1) & b] != null)
signalWork(q); // help signal if more tasks
w.topLevelExec(t, q, // random fairness bound
r & ((n << TOP_BOUND_SHIFT) - 1));
(r | (1 << TOP_BOUND_SHIFT)) & SMASK);
}
}
return true;
@ -1900,7 +1909,7 @@ public class ForkJoinPool extends AbstractExecutorService {
r = ThreadLocalRandom.advanceProbe(r);
else {
if (q.lockedPush(task))
signalWork();
signalWork(null);
return;
}
}

View file

@ -122,7 +122,7 @@ import java.util.concurrent.TimeUnit;
* <p>All {@code Lock} implementations <em>must</em> enforce the same
* memory synchronization semantics as provided by the built-in monitor
* lock, as described in
* <a href="https://docs.oracle.com/javase/specs/jls/se8/html/jls-17.html#jls-17.4">
* <a href="https://docs.oracle.com/javase/specs/jls/se11/html/jls-17.html#jls-17.4">
* Chapter 17 of
* <cite>The Java&trade; Language Specification</cite></a>:
* <ul>

View file

@ -133,7 +133,7 @@ import jdk.internal.vm.annotation.ReservedStackAccess;
* <p><b>Memory Synchronization.</b> Methods with the effect of
* successfully locking in any mode have the same memory
* synchronization effects as a <em>Lock</em> action described in
* <a href="https://docs.oracle.com/javase/specs/jls/se8/html/jls-17.html#jls-17.4">
* <a href="https://docs.oracle.com/javase/specs/jls/se11/html/jls-17.html#jls-17.4">
* Chapter 17 of <cite>The Java&trade; Language Specification</cite></a>.
* Methods successfully unlocking in write mode have the same memory
* synchronization effects as an <em>Unlock</em> action. In optimistic

View file

@ -226,7 +226,7 @@
*
* <h2 id="MemoryVisibility">Memory Consistency Properties</h2>
*
* <a href="https://docs.oracle.com/javase/specs/jls/se8/html/jls-17.html#jls-17.4.5">
* <a href="https://docs.oracle.com/javase/specs/jls/se11/html/jls-17.html#jls-17.4.5">
* Chapter 17 of
* <cite>The Java&trade; Language Specification</cite></a> defines the
* <i>happens-before</i> relation on memory operations such as reads and

View file

@ -90,6 +90,9 @@ class ClientHandshakeContext extends HandshakeContext {
ClientHelloMessage initialClientHelloMsg = null;
// PSK identity is selected in first Hello and used again after HRR
byte[] pskIdentity;
ClientHandshakeContext(SSLContextImpl sslContext,
TransportContext conContext) throws IOException {
super(sslContext, conContext);

View file

@ -656,7 +656,11 @@ final class PreSharedKeyExtension {
return null;
}
SecretKey psk = pskOpt.get();
Optional<byte[]> pskIdOpt = chc.resumingSession.consumePskIdentity();
// The PSK ID can only be used in one connections, but this method
// may be called twice in a connection if the server sends HRR.
// ID is saved in the context so it can be used in the second call.
Optional<byte[]> pskIdOpt = Optional.ofNullable(chc.pskIdentity)
.or(chc.resumingSession::consumePskIdentity);
if (!pskIdOpt.isPresent()) {
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
SSLLogger.fine(
@ -664,7 +668,7 @@ final class PreSharedKeyExtension {
}
return null;
}
byte[] pskId = pskIdOpt.get();
chc.pskIdentity = pskIdOpt.get();
//The session cannot be used again. Remove it from the cache.
SSLSessionContextImpl sessionCache = (SSLSessionContextImpl)
@ -681,7 +685,7 @@ final class PreSharedKeyExtension {
chc.resumingSession.getTicketCreationTime());
int obfuscatedAge =
ageMillis + chc.resumingSession.getTicketAgeAdd();
identities.add(new PskIdentity(pskId, obfuscatedAge));
identities.add(new PskIdentity(chc.pskIdentity, obfuscatedAge));
SecretKey binderKey = deriveBinderKey(psk, chc.resumingSession);
ClientHelloMessage clientHello = (ClientHelloMessage)message;

View file

@ -52,4 +52,21 @@ public final class ArrayUtil {
// NPE is thrown when array is null
Preconditions.checkFromIndexSize(offset, len, array.length, AIOOBE_SUPPLIER);
}
private static void swap(byte[] arr, int i, int j) {
byte tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
public static void reverse(byte [] arr) {
int i = 0;
int j = arr.length - 1;
while (i < j) {
swap(arr, i, j);
i++;
j--;
}
}
}

View file

@ -40,6 +40,18 @@ import java.nio.ByteBuffer;
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
@ -131,5 +143,20 @@ public interface MutableIntegerModuloP extends IntegerModuloP {
* @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,851 @@
/*
* 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.
*
* 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 used to generated optimized finite field implementations.
* Required settings are included in the file. To generate, use jshell:
* jshell < FieldGen.jsh
*/
import java.io.*;
import java.math.BigInteger;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;
public class FieldGen {
static FieldParams Curve25519 = new FieldParams("IntegerPolynomial25519", 26, 10, 1, 255,
Arrays.asList(
new Term(0, -19)
),
Curve25519CrSequence(), simpleSmallCrSequence(10)
);
private static List<CarryReduce> Curve25519CrSequence() {
List<CarryReduce> result = new ArrayList<CarryReduce>();
// reduce(7,2)
result.add(new Reduce(17));
result.add(new Reduce(18));
// carry(8,2)
result.add(new Carry(8));
result.add(new Carry(9));
// reduce(0,7)
for (int i = 10; i < 17; i++) {
result.add(new Reduce(i));
}
// carry(0,9)
result.addAll(fullCarry(10));
return result;
}
static FieldParams Curve448 = new FieldParams("IntegerPolynomial448", 28, 16, 1, 448,
Arrays.asList(
new Term(224, -1),
new Term(0, -1)
),
Curve448CrSequence(), simpleSmallCrSequence(16)
);
private static List<CarryReduce> Curve448CrSequence() {
List<CarryReduce> result = new ArrayList<CarryReduce>();
// reduce(8, 7)
for (int i = 24; i < 31; i++) {
result.add(new Reduce(i));
}
// reduce(4, 4)
for (int i = 20; i < 24; i++) {
result.add(new Reduce(i));
}
//carry(14, 2)
result.add(new Carry(14));
result.add(new Carry(15));
// reduce(0, 4)
for (int i = 16; i < 20; i++) {
result.add(new Reduce(i));
}
// carry(0, 15)
result.addAll(fullCarry(16));
return result;
}
static FieldParams P256 = new FieldParams("IntegerPolynomialP256", 26, 10, 2, 256,
Arrays.asList(
new Term(224, -1),
new Term(192, 1),
new Term(96, 1),
new Term(0, -1)
),
P256CrSequence(), simpleSmallCrSequence(10)
);
private static List<CarryReduce> P256CrSequence() {
List<CarryReduce> result = new ArrayList<CarryReduce>();
result.addAll(fullReduce(10));
result.addAll(simpleSmallCrSequence(10));
return result;
}
static FieldParams P384 = new FieldParams("IntegerPolynomialP384", 28, 14, 2, 384,
Arrays.asList(
new Term(128, -1),
new Term(96, -1),
new Term(32, 1),
new Term(0, -1)
),
P384CrSequence(), simpleSmallCrSequence(14)
);
private static List<CarryReduce> P384CrSequence() {
List<CarryReduce> result = new ArrayList<CarryReduce>();
result.addAll(fullReduce(14));
result.addAll(simpleSmallCrSequence(14));
return result;
}
static FieldParams P521 = new FieldParams("IntegerPolynomialP521", 28, 19, 2, 521,
Arrays.asList(new Term(0, -1)), P521CrSequence(), simpleSmallCrSequence(19)
);
private static List<CarryReduce> P521CrSequence() {
List<CarryReduce> result = new ArrayList<CarryReduce>();
result.addAll(fullReduce(19));
result.addAll(simpleSmallCrSequence(19));
return result;
}
static FieldParams O256 = new FieldParams("P256OrderField", 26, 10, 1, 256,
new BigInteger("26959946660873538059280334323273029441504803697035324946844617595567"),
orderFieldCrSequence(10), orderFieldSmallCrSequence(10)
);
static FieldParams O384 = new FieldParams("P384OrderField", 28, 14, 1, 384,
new BigInteger("1388124618062372383947042015309946732620727252194336364173"),
orderFieldCrSequence(14), orderFieldSmallCrSequence(14)
);
static FieldParams O521 = new FieldParams("P521OrderField", 28, 19, 1, 521,
new BigInteger("657877501894328237357444332315020117536923257219387276263472201219398408051703"),
o521crSequence(19), orderFieldSmallCrSequence(19)
);
private static List<CarryReduce> o521crSequence(int numLimbs) {
// split the full reduce in half, with a carry in between
List<CarryReduce> result = new ArrayList<CarryReduce>();
result.addAll(fullCarry(2 * numLimbs));
for (int i = 2 * numLimbs - 1; i >= numLimbs + numLimbs/2; i--) {
result.add(new Reduce(i));
}
// carry
for (int i = numLimbs; i < numLimbs + numLimbs / 2 - 1; i++) {
result.add(new Carry(i));
}
// rest of reduce
for (int i = numLimbs + numLimbs/2 - 1; i >= numLimbs; i--) {
result.add(new Reduce(i));
}
result.addAll(orderFieldSmallCrSequence(numLimbs));
return result;
}
private static List<CarryReduce> orderFieldCrSequence(int numLimbs) {
List<CarryReduce> result = new ArrayList<CarryReduce>();
result.addAll(fullCarry(2 * numLimbs));
result.add(new Reduce(2 * numLimbs - 1));
result.addAll(fullReduce(numLimbs));
result.addAll(fullCarry(numLimbs + 1));
result.add(new Reduce(numLimbs));
result.addAll(fullCarry(numLimbs));
return result;
}
private static List<CarryReduce> orderFieldSmallCrSequence(int numLimbs) {
List<CarryReduce> result = new ArrayList<CarryReduce>();
result.addAll(fullCarry(numLimbs + 1));
result.add(new Reduce(numLimbs));
result.addAll(fullCarry(numLimbs));
return result;
}
static final FieldParams[] ALL_FIELDS = {P256, P384, P521, O256, O384, O521};
public static class Term {
private final int power;
private final int coefficient;
public Term(int power, int coefficient) {
this.power = power;
this.coefficient = coefficient;
}
public int getPower() {
return power;
}
public int getCoefficient() {
return coefficient;
}
public BigInteger getValue() {
return BigInteger.valueOf(2).pow(power).multiply(BigInteger.valueOf(coefficient));
}
}
static abstract class CarryReduce {
private final int index;
protected CarryReduce(int index) {
this.index = index;
}
public int getIndex() {
return index;
}
public abstract void write(CodeBuffer out, FieldParams params, String prefix, Iterable<CarryReduce> remaining);
}
static class Carry extends CarryReduce {
public Carry(int index) {
super(index);
}
public void write(CodeBuffer out, FieldParams params, String prefix, Iterable<CarryReduce> remaining) {
carry(out, params, prefix, getIndex());
}
}
static class Reduce extends CarryReduce {
public Reduce(int index) {
super(index);
}
public void write(CodeBuffer out, FieldParams params, String prefix, Iterable<CarryReduce> remaining) {
reduce(out, params, prefix, getIndex(), remaining);
}
}
static class FieldParams {
private final String className;
private final int bitsPerLimb;
private final int numLimbs;
private final int maxAdds;
private final int power;
private final Iterable<Term> terms;
private final List<CarryReduce> crSequence;
private final List<CarryReduce> smallCrSequence;
public FieldParams(String className, int bitsPerLimb, int numLimbs, int maxAdds, int power,
Iterable<Term> terms, List<CarryReduce> crSequence, List<CarryReduce> smallCrSequence) {
this.className = className;
this.bitsPerLimb = bitsPerLimb;
this.numLimbs = numLimbs;
this.maxAdds = maxAdds;
this.power = power;
this.terms = terms;
this.crSequence = crSequence;
this.smallCrSequence = smallCrSequence;
}
public FieldParams(String className, int bitsPerLimb, int numLimbs, int maxAdds, int power,
BigInteger term, List<CarryReduce> crSequence, List<CarryReduce> smallCrSequence) {
this.className = className;
this.bitsPerLimb = bitsPerLimb;
this.numLimbs = numLimbs;
this.maxAdds = maxAdds;
this.power = power;
this.crSequence = crSequence;
this.smallCrSequence = smallCrSequence;
terms = buildTerms(term);
}
private Iterable<Term> buildTerms(BigInteger sub) {
// split a large subtrahend into smaller terms that are aligned with limbs
List<Term> result = new ArrayList<Term>();
BigInteger mod = BigInteger.valueOf(1 << bitsPerLimb);
int termIndex = 0;
while (!sub.equals(BigInteger.ZERO)) {
int coef = sub.mod(mod).intValue();
boolean plusOne = false;
if (coef > (1 << (bitsPerLimb - 1))) {
coef = coef - (1 << bitsPerLimb);
plusOne = true;
}
if (coef != 0) {
int pow = termIndex * bitsPerLimb;
result.add(new Term(pow, -coef));
}
sub = sub.shiftRight(bitsPerLimb);
if (plusOne) {
sub = sub.add(BigInteger.ONE);
}
++termIndex;
}
return result;
}
public String getClassName() {
return className;
}
public int getBitsPerLimb() {
return bitsPerLimb;
}
public int getNumLimbs() {
return numLimbs;
}
public int getMaxAdds() {
return maxAdds;
}
public int getPower() {
return power;
}
public Iterable<Term> getTerms() {
return terms;
}
public List<CarryReduce> getCrSequence() {
return crSequence;
}
public List<CarryReduce> getSmallCrSequence() {
return smallCrSequence;
}
}
static Collection<Carry> fullCarry(int numLimbs) {
List<Carry> result = new ArrayList<Carry>();
for (int i = 0; i < numLimbs - 1; i++) {
result.add(new Carry(i));
}
return result;
}
static Collection<Reduce> fullReduce(int numLimbs) {
List<Reduce> result = new ArrayList<Reduce>();
for (int i = numLimbs - 2; i >= 0; i--) {
result.add(new Reduce(i + numLimbs));
}
return result;
}
static List<CarryReduce> simpleCrSequence(int numLimbs) {
List<CarryReduce> result = new ArrayList<CarryReduce>();
for(int i = 0; i < 4; i++) {
result.addAll(fullCarry(2 * numLimbs - 1));
result.addAll(fullReduce(numLimbs));
}
return result;
}
static List<CarryReduce> simpleSmallCrSequence(int numLimbs) {
List<CarryReduce> result = new ArrayList<CarryReduce>();
// carry a few positions at the end
for (int i = numLimbs - 2; i < numLimbs; i++) {
result.add(new Carry(i));
}
// this carries out a single value that must be reduced back in
result.add(new Reduce(numLimbs));
// finish with a full carry
result.addAll(fullCarry(numLimbs));
return result;
}
private final String packageName;
private final String parentName;
public FieldGen(String packageName, String parentName) {
this.packageName = packageName;
this.parentName = parentName;
}
public static void main(String[] args) throws Exception {
FieldGen gen = new FieldGen("sun.security.util.math.intpoly", "IntegerPolynomial");
for(FieldParams p : ALL_FIELDS) {
gen.generateFile(p);
}
}
private void generateFile(FieldParams params) throws IOException {
String text = generate(params);
String fileName = params.getClassName() + ".java";
PrintWriter out = new PrintWriter(new FileWriter(fileName));
out.println(text);
out.close();
}
static class CodeBuffer {
private int nextTemporary = 0;
private Set<String> temporaries = new HashSet<String>();
private StringBuffer buffer = new StringBuffer();
private int indent = 0;
private Class lastCR;
private int lastCrCount = 0;
private int crMethodBreakCount = 0;
private int crNumLimbs = 0;
public void incrIndent() {
indent++;
}
public void decrIndent() {
indent--;
}
public void newTempScope() {
nextTemporary = 0;
temporaries.clear();
}
public void appendLine(String s) {
appendIndent();
buffer.append(s + "\n");
}
public void appendLine() {
buffer.append("\n");
}
public String toString() {
return buffer.toString();
}
public void startCrSequence(int numLimbs) {
this.crNumLimbs = numLimbs;
lastCrCount = 0;
crMethodBreakCount = 0;
lastCR = null;
}
/*
* Record a carry/reduce of the specified type. This method is used to
* break up large carry/reduce sequences into multiple methods to make
* JIT/optimization easier
*/
public void record(Class type) {
if (type == lastCR) {
lastCrCount++;
} else {
if (lastCrCount >= 8) {
insertCrMethodBreak();
}
lastCR = type;
lastCrCount = 0;
}
}
private void insertCrMethodBreak() {
appendLine();
// call the new method
appendIndent();
append("carryReduce" + crMethodBreakCount + "(r");
for(int i = 0; i < crNumLimbs; i++) {
append(", c" + i);
}
// temporaries are not live between operations, no need to send
append(");\n");
decrIndent();
appendLine("}");
// make the method
appendIndent();
append("void carryReduce" + crMethodBreakCount + "(long[] r");
for(int i = 0; i < crNumLimbs; i++) {
append (", long c" + i);
}
append(") {\n");
incrIndent();
// declare temporaries
for(String temp : temporaries) {
appendLine("long " + temp + ";");
}
append("\n");
crMethodBreakCount++;
}
public String getTemporary(String type, String value) {
Iterator<String> iter = temporaries.iterator();
if(iter.hasNext()) {
String result = iter.next();
iter.remove();
appendLine(result + " = " + value + ";");
return result;
} else {
String result = "t" + (nextTemporary++);
appendLine(type + " " + result + " = " + value + ";");
return result;
}
}
public void freeTemporary(String temp) {
temporaries.add(temp);
}
public void appendIndent() {
for(int i = 0; i < indent; i++) {
buffer.append(" ");
}
}
public void append(String s) {
buffer.append(s);
}
}
private String generate(FieldParams params) throws IOException {
CodeBuffer result = new CodeBuffer();
String header = readHeader();
result.appendLine(header);
if (packageName != null) {
result.appendLine("package " + packageName + ";");
result.appendLine();
}
result.appendLine("import java.math.BigInteger;");
result.appendLine("public class " + params.getClassName() + " extends " + this.parentName + " {");
result.incrIndent();
result.appendLine("private static final int BITS_PER_LIMB = " + params.getBitsPerLimb() + ";");
result.appendLine("private static final int NUM_LIMBS = " + params.getNumLimbs() + ";");
result.appendLine("private static final int MAX_ADDS = " + params.getMaxAdds() + ";");
result.appendLine("public static final BigInteger MODULUS = evaluateModulus();");
result.appendLine("private static final long CARRY_ADD = 1 << " + (params.getBitsPerLimb() - 1) + ";");
if (params.getBitsPerLimb() * params.getNumLimbs() != params.getPower()) {
result.appendLine("private static final int LIMB_MASK = -1 >>> (64 - BITS_PER_LIMB);");
}
int termIndex = 0;
result.appendLine("public " + params.getClassName() + "() {");
result.appendLine();
result.appendLine(" super(BITS_PER_LIMB, NUM_LIMBS, MAX_ADDS, MODULUS);");
result.appendLine();
result.appendLine("}");
result.appendLine("private static BigInteger evaluateModulus() {");
result.incrIndent();
result.appendLine("BigInteger result = BigInteger.valueOf(2).pow(" + params.getPower() + ");");
for(Term t : params.getTerms()) {
boolean subtract = false;
int coefValue = t.getCoefficient();
if (coefValue < 0) {
coefValue = 0 - coefValue;
subtract = true;
}
String coefExpr = "BigInteger.valueOf(" + coefValue + ")";
String powExpr = "BigInteger.valueOf(2).pow(" + t.getPower() + ")";
String termExpr = "ERROR";
if (t.getPower() == 0) {
termExpr = coefExpr;
} else if (coefValue == 1) {
termExpr = powExpr;
} else {
termExpr = powExpr + ".multiply(" + coefExpr + ")";
}
if (subtract) {
result.appendLine("result = result.subtract(" + termExpr + ");");
} else {
result.appendLine("result = result.add(" + termExpr + ");");
}
}
result.appendLine("return result;");
result.decrIndent();
result.appendLine("}");
result.appendLine("@Override");
result.appendLine("protected void finalCarryReduceLast(long[] limbs) {");
result.incrIndent();
int extraBits = params.getBitsPerLimb() * params.getNumLimbs() - params.getPower();
int highBits = params.getBitsPerLimb() - extraBits;
result.appendLine("long c = limbs[" + (params.getNumLimbs() - 1) + "] >> " + highBits + ";");
result.appendLine("limbs[" + (params.getNumLimbs() - 1) + "] -= c << " + highBits + ";");
for (Term t : params.getTerms()) {
int reduceBits = params.getPower() + extraBits - t.getPower();
int negatedCoefficient = -1 * t.getCoefficient();
modReduceInBits(result, params, true, "limbs", params.getNumLimbs(), reduceBits, negatedCoefficient, "c");
}
result.decrIndent();
result.appendLine("}");
// full carry/reduce sequence
result.appendIndent();
result.append("private void carryReduce(long[] r, ");
for(int i = 0; i < 2 * params.getNumLimbs() - 1; i++) {
result.append ("long c" + i);
if (i < 2 * params.getNumLimbs() - 2) {
result.append(", ");
}
}
result.append(") {\n");
result.newTempScope();
result.incrIndent();
result.appendLine("long c" + (2 * params.getNumLimbs() - 1) + " = 0;");
write(result, params.getCrSequence(), params, "c", 2 * params.getNumLimbs());
result.appendLine();
for (int i = 0; i < params.getNumLimbs(); i++) {
result.appendLine("r[" + i + "] = c" + i + ";");
}
result.decrIndent();
result.appendLine("}");
// small carry/reduce sequence
result.appendIndent();
result.append("private void carryReduce(long[] r, ");
for(int i = 0; i < params.getNumLimbs(); i++) {
result.append ("long c" + i);
if (i < params.getNumLimbs() - 1) {
result.append(", ");
}
}
result.append(") {\n");
result.newTempScope();
result.incrIndent();
result.appendLine("long c" + params.getNumLimbs() + " = 0;");
write(result, params.getSmallCrSequence(), params, "c", params.getNumLimbs() + 1);
result.appendLine();
for (int i = 0; i < params.getNumLimbs(); i++) {
result.appendLine("r[" + i + "] = c" + i + ";");
}
result.decrIndent();
result.appendLine("}");
result.appendLine("@Override");
result.appendLine("protected void mult(long[] a, long[] b, long[] r) {");
result.incrIndent();
for (int i = 0; i < 2 * params.getNumLimbs() - 1; i++) {
result.appendIndent();
result.append("long c" + i + " = ");
int startJ = Math.max(i + 1 - params.getNumLimbs(), 0);
int endJ = Math.min(params.getNumLimbs(), i + 1);
for (int j = startJ; j < endJ; j++) {
int bIndex = i - j;
result.append("(a[" + j + "] * b[" + bIndex + "])");
if (j < endJ - 1) {
result.append(" + ");
}
}
result.append(";\n");
}
result.appendLine();
result.appendIndent();
result.append("carryReduce(r, ");
for (int i = 0; i < 2 * params.getNumLimbs() - 1; i++) {
result.append("c" + i);
if (i < 2 * params.getNumLimbs() - 2) {
result.append(", ");
}
}
result.append(");\n");
result.decrIndent();
result.appendLine("}");
result.appendLine("@Override");
result.appendLine("protected void reduce(long[] a) {");
result.incrIndent();
result.appendIndent();
result.append("carryReduce(a, ");
for (int i = 0; i < params.getNumLimbs(); i++) {
result.append("a[" + i + "]");
if (i < params.getNumLimbs() - 1) {
result.append(", ");
}
}
result.append(");\n");
result.decrIndent();
result.appendLine("}");
result.appendLine("@Override");
result.appendLine("protected void square(long[] a, long[] r) {");
result.incrIndent();
for (int i = 0; i < 2 * params.getNumLimbs() - 1; i++) {
result.appendIndent();
result.append("long c" + i + " = ");
int startJ = Math.max(i + 1 - params.getNumLimbs(), 0);
int endJ = Math.min(params.getNumLimbs(), i + 1);
int jDiff = endJ - startJ;
if (jDiff > 1) {
result.append("2 * (");
}
for (int j = 0; j < jDiff / 2; j++) {
int aIndex = j + startJ;
int bIndex = i - aIndex;
result.append("(a[" + aIndex + "] * a[" + bIndex + "])");
if (j < (jDiff / 2) - 1) {
result.append(" + ");
}
}
if (jDiff > 1) {
result.append(")");
}
if (jDiff % 2 == 1) {
int aIndex = i / 2;
if (jDiff > 1) {
result.append (" + ");
}
result.append("(a[" + aIndex + "] * a[" + aIndex + "])");
}
result.append(";\n");
}
result.appendLine();
result.appendIndent();
result.append("carryReduce(r, ");
for (int i = 0; i < 2 * params.getNumLimbs() - 1; i++) {
result.append("c" + i);
if (i < 2 * params.getNumLimbs() - 2) {
result.append(", ");
}
}
result.append(");\n");
result.decrIndent();
result.appendLine("}");
result.decrIndent();
result.appendLine("}"); // end class
return result.toString();
}
private static void write(CodeBuffer out, List<CarryReduce> sequence, FieldParams params, String prefix, int numLimbs) {
out.startCrSequence(numLimbs);
for (int i = 0; i < sequence.size(); i++) {
CarryReduce cr = sequence.get(i);
Iterator<CarryReduce> remainingIter = sequence.listIterator(i + 1);
List<CarryReduce> remaining = new ArrayList<CarryReduce>();
remainingIter.forEachRemaining(remaining::add);
cr.write(out, params, prefix, remaining);
}
}
private static void reduce(CodeBuffer out, FieldParams params, String prefix, int index, Iterable<CarryReduce> remaining) {
out.record(Reduce.class);
out.appendLine("//reduce from position " + index);
String reduceFrom = indexedExpr(false, prefix, index);
boolean referenced = false;
for (CarryReduce cr : remaining) {
if(cr.index == index) {
referenced = true;
}
}
for (Term t : params.getTerms()) {
int reduceBits = params.getPower() - t.getPower();
int negatedCoefficient = -1 * t.getCoefficient();
modReduceInBits(out, params, false, prefix, index, reduceBits, negatedCoefficient, reduceFrom);
}
if (referenced) {
out.appendLine(reduceFrom + " = 0;");
}
}
private static void carry(CodeBuffer out, FieldParams params, String prefix, int index) {
out.record(Carry.class);
out.appendLine("//carry from position " + index);
String carryFrom = prefix + index;
String carryTo = prefix + (index + 1);
String carry = "(" + carryFrom + " + CARRY_ADD) >> " + params.getBitsPerLimb();
String temp = out.getTemporary("long", carry);
out.appendLine(carryFrom + " -= (" + temp + " << " + params.getBitsPerLimb() + ");");
out.appendLine(carryTo + " += " + temp + ";");
out.freeTemporary(temp);
}
private static String indexedExpr(boolean isArray, String prefix, int index) {
String result = prefix + index;
if (isArray) {
result = prefix + "[" + index + "]";
}
return result;
}
private static void modReduceInBits(CodeBuffer result, FieldParams params, boolean isArray, String prefix, int index, int reduceBits, int coefficient, String c) {
String x = coefficient + " * " + c;
String accOp = "+=";
String temp = null;
if (coefficient == 1) {
x = c;
} else if (coefficient == -1) {
x = c;
accOp = "-=";
} else {
temp = result.getTemporary("long", x);
x = temp;
}
if (reduceBits % params.getBitsPerLimb() == 0) {
int pos = reduceBits / params.getBitsPerLimb();
result.appendLine(indexedExpr(isArray, prefix, (index - pos)) + " " + accOp + " " + x + ";");
} else {
int secondPos = reduceBits / params.getBitsPerLimb();
int bitOffset = (secondPos + 1) * params.getBitsPerLimb() - reduceBits;
int rightBitOffset = params.getBitsPerLimb() - bitOffset;
result.appendLine(indexedExpr(isArray, prefix, (index - (secondPos + 1))) + " " + accOp + " (" + x + " << " + bitOffset + ") & LIMB_MASK;");
result.appendLine(indexedExpr(isArray, prefix, (index - secondPos)) + " " + accOp + " " + x + " >> " + rightBitOffset + ";");
}
if (temp != null) {
result.freeTemporary(temp);
}
}
private String readHeader() throws IOException {
BufferedReader reader = Files.newBufferedReader(Paths.get("header.txt"));
StringBuffer result = new StringBuffer();
reader.lines().forEach(s -> result.append(s + "\n"));
return result.toString();
}
}
FieldGen.main(null);

View file

@ -69,14 +69,25 @@ public abstract class IntegerPolynomial implements IntegerFieldModuloP {
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 (r). Requires
* that a.length == r.length == numLimbs. It is allowed for a and r to be
* the same array.
* store the result in an IntegerPolynomial representation in a. Requires
* that a.length == numLimbs.
*/
protected abstract void multByInt(long[] a, long b, long[] r);
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
@ -96,12 +107,14 @@ public abstract class IntegerPolynomial implements IntegerFieldModuloP {
IntegerPolynomial(int bitsPerLimb,
int numLimbs,
int maxAdds,
BigInteger modulus) {
this.numLimbs = numLimbs;
this.modulus = modulus;
this.bitsPerLimb = bitsPerLimb;
this.maxAdds = maxAdds;
posModLimbs = setPosModLimbs();
}
@ -116,6 +129,10 @@ public abstract class IntegerPolynomial implements IntegerFieldModuloP {
return numLimbs;
}
public int getMaxAdds() {
return maxAdds;
}
@Override
public BigInteger getSize() {
return modulus;
@ -155,12 +172,22 @@ public abstract class IntegerPolynomial implements IntegerFieldModuloP {
*/
protected void encode(ByteBuffer buf, int length, byte highByte,
long[] result) {
int numHighBits = 32 - Integer.numberOfLeadingZeros(highByte);
int numBits = 8 * length + numHighBits;
int maxBits = bitsPerLimb * result.length;
if (numBits > maxBits) {
throw new ArithmeticException("Value is too large.");
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;
@ -195,10 +222,10 @@ public abstract class IntegerPolynomial implements IntegerFieldModuloP {
}
}
if (limbIndex < numLimbs) {
if (limbIndex < result.length) {
result[limbIndex++] = curLimbValue;
}
Arrays.fill(result, limbIndex, numLimbs, 0);
Arrays.fill(result, limbIndex, result.length, 0);
postEncodeCarry(result);
}
@ -211,8 +238,10 @@ public abstract class IntegerPolynomial implements IntegerFieldModuloP {
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) {
carry(v);
reduce(v);
}
public ImmutableElement getElement(byte[] v, int offset, int length,
@ -222,7 +251,7 @@ public abstract class IntegerPolynomial implements IntegerFieldModuloP {
encode(v, offset, length, highByte, result);
return new ImmutableElement(result, true);
return new ImmutableElement(result, 0);
}
protected BigInteger evaluate(long[] limbs) {
@ -386,6 +415,20 @@ public abstract class IntegerPolynomial implements IntegerFieldModuloP {
}
}
/**
* 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
@ -442,7 +485,7 @@ public abstract class IntegerPolynomial implements IntegerFieldModuloP {
private abstract class Element implements IntegerModuloP {
protected long[] limbs;
protected boolean summand = false;
protected int numAdds;
public Element(BigInteger v) {
limbs = new long[numLimbs];
@ -450,19 +493,19 @@ public abstract class IntegerPolynomial implements IntegerFieldModuloP {
}
public Element(boolean v) {
limbs = new long[numLimbs];
limbs[0] = v ? 1l : 0l;
summand = true;
this.limbs = new long[numLimbs];
this.limbs[0] = v ? 1l : 0l;
this.numAdds = 0;
}
private Element(long[] limbs, boolean summand) {
private Element(long[] limbs, int numAdds) {
this.limbs = limbs;
this.summand = summand;
this.numAdds = numAdds;
}
private void setValue(BigInteger v) {
setLimbsValue(v, limbs);
summand = true;
this.numAdds = 0;
}
@Override
@ -477,14 +520,18 @@ public abstract class IntegerPolynomial implements IntegerFieldModuloP {
@Override
public MutableElement mutable() {
return new MutableElement(limbs.clone(), summand);
return new MutableElement(limbs.clone(), numAdds);
}
protected boolean isSummand() {
return numAdds < maxAdds;
}
@Override
public ImmutableElement add(IntegerModuloP genB) {
Element b = (Element) genB;
if (!(summand && b.summand)) {
if (!(isSummand() && b.isSummand())) {
throw new ArithmeticException("Not a valid summand");
}
@ -493,7 +540,8 @@ public abstract class IntegerPolynomial implements IntegerFieldModuloP {
newLimbs[i] = limbs[i] + b.limbs[i];
}
return new ImmutableElement(newLimbs, false);
int newNumAdds = Math.max(numAdds, b.numAdds) + 1;
return new ImmutableElement(newLimbs, newNumAdds);
}
@Override
@ -504,7 +552,7 @@ public abstract class IntegerPolynomial implements IntegerFieldModuloP {
newLimbs[i] = -limbs[i];
}
ImmutableElement result = new ImmutableElement(newLimbs, summand);
ImmutableElement result = new ImmutableElement(newLimbs, numAdds);
return result;
}
@ -524,43 +572,52 @@ public abstract class IntegerPolynomial implements IntegerFieldModuloP {
long[] newLimbs = new long[limbs.length];
mult(limbs, b.limbs, newLimbs);
return new ImmutableElement(newLimbs, true);
return new ImmutableElement(newLimbs, 0);
}
@Override
public ImmutableElement square() {
long[] newLimbs = new long[limbs.length];
IntegerPolynomial.this.square(limbs, newLimbs);
return new ImmutableElement(newLimbs, true);
return new ImmutableElement(newLimbs, 0);
}
public void addModPowerTwo(IntegerModuloP arg, byte[] result) {
Element other = (Element) arg;
if (!(summand && other.summand)) {
if (!(isSummand() && other.isSummand())) {
throw new ArithmeticException("Not a valid summand");
}
addLimbsModPowerTwo(limbs, other.limbs, result);
}
public void asByteArray(byte[] result) {
if (!summand) {
if (!isSummand()) {
throw new ArithmeticException("Not a valid summand");
}
limbsToByteArray(limbs, result);
}
}
private class MutableElement extends Element
protected class MutableElement extends Element
implements MutableIntegerModuloP {
protected MutableElement(long[] limbs, boolean summand) {
super(limbs, summand);
protected MutableElement(long[] limbs, int numAdds) {
super(limbs, numAdds);
}
@Override
public ImmutableElement fixed() {
return new ImmutableElement(limbs.clone(), summand);
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
@ -569,9 +626,9 @@ public abstract class IntegerPolynomial implements IntegerFieldModuloP {
MutableElement other = (MutableElement) b;
conditionalSwap(swap, limbs, other.limbs);
boolean summandTemp = summand;
summand = other.summand;
other.summand = summandTemp;
int numAddsTemp = numAdds;
numAdds = other.numAdds;
other.numAdds = numAddsTemp;
}
@ -580,7 +637,7 @@ public abstract class IntegerPolynomial implements IntegerFieldModuloP {
Element other = (Element) v;
System.arraycopy(other.limbs, 0, limbs, 0, other.limbs.length);
summand = other.summand;
numAdds = other.numAdds;
return this;
}
@ -589,7 +646,7 @@ public abstract class IntegerPolynomial implements IntegerFieldModuloP {
int length, byte highByte) {
encode(arr, offset, length, highByte, limbs);
summand = true;
this.numAdds = 0;
return this;
}
@ -599,7 +656,7 @@ public abstract class IntegerPolynomial implements IntegerFieldModuloP {
byte highByte) {
encode(buf, length, highByte, limbs);
summand = true;
numAdds = 0;
return this;
}
@ -608,15 +665,15 @@ public abstract class IntegerPolynomial implements IntegerFieldModuloP {
public MutableElement setProduct(IntegerModuloP genB) {
Element b = (Element) genB;
mult(limbs, b.limbs, limbs);
summand = true;
numAdds = 0;
return this;
}
@Override
public MutableElement setProduct(SmallValue v) {
int value = ((Limb) v).value;
multByInt(limbs, value, limbs);
summand = true;
multByInt(limbs, value);
numAdds = 0;
return this;
}
@ -624,7 +681,7 @@ public abstract class IntegerPolynomial implements IntegerFieldModuloP {
public MutableElement setSum(IntegerModuloP genB) {
Element b = (Element) genB;
if (!(summand && b.summand)) {
if (!(isSummand() && b.isSummand())) {
throw new ArithmeticException("Not a valid summand");
}
@ -632,7 +689,7 @@ public abstract class IntegerPolynomial implements IntegerFieldModuloP {
limbs[i] = limbs[i] + b.limbs[i];
}
summand = false;
numAdds = Math.max(numAdds, b.numAdds) + 1;
return this;
}
@ -640,7 +697,7 @@ public abstract class IntegerPolynomial implements IntegerFieldModuloP {
public MutableElement setDifference(IntegerModuloP genB) {
Element b = (Element) genB;
if (!(summand && b.summand)) {
if (!(isSummand() && b.isSummand())) {
throw new ArithmeticException("Not a valid summand");
}
@ -648,16 +705,33 @@ public abstract class IntegerPolynomial implements IntegerFieldModuloP {
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);
summand = true;
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 {
@ -670,8 +744,8 @@ public abstract class IntegerPolynomial implements IntegerFieldModuloP {
super(v);
}
protected ImmutableElement(long[] limbs, boolean summand) {
super(limbs, summand);
protected ImmutableElement(long[] limbs, int numAdds) {
super(limbs, numAdds);
}
@Override

View file

@ -45,7 +45,7 @@ public class IntegerPolynomial1305 extends IntegerPolynomial {
= TWO.pow(POWER).subtract(BigInteger.valueOf(SUBTRAHEND));
public IntegerPolynomial1305() {
super(BITS_PER_LIMB, NUM_LIMBS, MODULUS);
super(BITS_PER_LIMB, NUM_LIMBS, 1, MODULUS);
}
protected void mult(long[] a, long[] b, long[] r) {
@ -96,15 +96,6 @@ public class IntegerPolynomial1305 extends IntegerPolynomial {
carry(r);
}
protected void multByInt(long[] a, long b, long[] r) {
for (int i = 0; i < a.length; i++) {
r[i] = a[i] * b;
}
reduce(r);
}
@Override
protected void square(long[] a, long[] r) {
// Use grade-school multiplication with a simple squaring optimization.
@ -199,7 +190,12 @@ public class IntegerPolynomial1305 extends IntegerPolynomial {
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];

View file

@ -48,7 +48,7 @@ public class IntegerPolynomial25519 extends IntegerPolynomial {
private static final int RIGHT_BIT_OFFSET = BITS_PER_LIMB - BIT_OFFSET;
public IntegerPolynomial25519() {
super(BITS_PER_LIMB, NUM_LIMBS, MODULUS);
super(BITS_PER_LIMB, NUM_LIMBS, 1, MODULUS);
}
@Override
@ -59,6 +59,26 @@ public class IntegerPolynomial25519 extends IntegerPolynomial {
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) {
@ -153,28 +173,6 @@ public class IntegerPolynomial25519 extends IntegerPolynomial {
carry(r, 0, 9);
}
protected void multByInt(long[] a, long b, long[] r) {
for (int i = 0; i < a.length; i++) {
r[i] = a[i] * b;
}
// carry(8, 2)
long carry8 = carryValue(r[8]);
r[8] -= (carry8 << BITS_PER_LIMB);
r[9] += carry8;
long carry9 = carryValue(r[9]);
r[9] -= (carry9 << BITS_PER_LIMB);
// reduce(0, 1)
long reducedValue10 = (carry9 * SUBTRAHEND);
r[0] += ((reducedValue10 << BIT_OFFSET) & LIMB_MASK);
r[1] += reducedValue10 >> RIGHT_BIT_OFFSET;
// carry(0, 9)
carry(r, 0, 9);
}
@Override
protected void square(long[] a, long[] r) {

View file

@ -42,7 +42,7 @@ public class IntegerPolynomial448 extends IntegerPolynomial {
.subtract(BigInteger.valueOf(1));
public IntegerPolynomial448() {
super(BITS_PER_LIMB, NUM_LIMBS, MODULUS);
super(BITS_PER_LIMB, NUM_LIMBS, 1, MODULUS);
}
private void modReduceIn(long[] limbs, int index, long x) {
@ -57,6 +57,25 @@ public class IntegerPolynomial448 extends IntegerPolynomial {
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) {
@ -176,27 +195,6 @@ public class IntegerPolynomial448 extends IntegerPolynomial {
carry(r, 0, 15);
}
protected void multByInt(long[] a, long b, long[] r) {
for (int i = 0; i < a.length; i++) {
r[i] = a[i] * b;
}
// carry(14, 2)
long carry14 = carryValue(r[14]);
r[14] -= (carry14 << BITS_PER_LIMB);
r[15] += carry14;
long carry15 = carryValue(r[15]);
r[15] -= (carry15 << BITS_PER_LIMB);
// reduce(0, 1)
r[0] += carry15;
r[8] += carry15;
// carry(0, 15)
carry(r, 0, 15);
}
@Override
protected void square(long[] a, long[] r) {

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

View file

@ -0,0 +1,28 @@
/*
* 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.
*/

View file

@ -0,0 +1,103 @@
/*
* 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.validator;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.Security;
import java.security.cert.X509Certificate;
import java.util.EnumSet;
import sun.security.util.Debug;
/**
* Policies for distrusting a certificate authority (CA). See the
* jdk.security.caDistrustPolicies security property for more information.
*/
enum CADistrustPolicy {
/**
* Distrust TLS Server certificates anchored by a Symantec root CA and
* issued after April 16, 2019. If enabled, this policy is currently
* enforced by the PKIX and SunX509 TrustManager implementations of the
* SunJSSE provider implementation.
*/
SYMANTEC_TLS {
void checkDistrust(String variant, X509Certificate anchor,
X509Certificate ee) throws ValidatorException {
if (!variant.equals(Validator.VAR_TLS_SERVER)) {
return;
}
SymantecTLSPolicy.checkDistrust(anchor, ee);
}
};
/**
* Checks if the end-entity certificate is distrusted.
*
* @param variant the type of certificate being checked
* @param anchor the trust anchor certificate
* @param ee the end-entity certificate to check
* @throws ValidatorException if the end-entity certificate is distrusted
*/
abstract void checkDistrust(String variant,
X509Certificate anchor,
X509Certificate ee) throws ValidatorException;
// The policies set in the jdk.security.caDistrustPolicies property.
static final EnumSet<CADistrustPolicy> POLICIES = parseProperty();
private static EnumSet<CADistrustPolicy> parseProperty() {
String property = AccessController.doPrivileged(
new PrivilegedAction<>() {
@Override
public String run() {
return Security.getProperty(
"jdk.security.caDistrustPolicies");
}
});
EnumSet<CADistrustPolicy> set = EnumSet.noneOf(CADistrustPolicy.class);
// if property is null or empty, the restrictions are not enforced
if (property == null || property.isEmpty()) {
return set;
}
String[] policies = property.split(",");
for (String policy : policies) {
policy = policy.trim();
try {
CADistrustPolicy caPolicy =
Enum.valueOf(CADistrustPolicy.class, policy);
set.add(caPolicy);
} catch (IllegalArgumentException iae) {
// ignore unknown values but log it
Debug debug = Debug.getInstance("certpath");
if (debug != null) {
debug.println("Unknown value for the " +
"jdk.security.caDistrustPolicies property: "
+ policy);
}
}
}
return set;
}
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2002, 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
@ -133,7 +133,9 @@ class EndEntityChecker {
}
void check(X509Certificate cert, Object parameter,
boolean checkUnresolvedCritExts) throws CertificateException {
boolean checkUnresolvedCritExts, X509Certificate anchor)
throws CertificateException {
if (variant.equals(Validator.VAR_GENERIC)) {
return; // no checks
}
@ -159,6 +161,12 @@ class EndEntityChecker {
if (checkUnresolvedCritExts) {
checkRemainingExtensions(exts);
}
// check if certificate should be distrusted according to policies
// set in the jdk.security.caDistrustPolicies security property
for (CADistrustPolicy policy : CADistrustPolicy.POLICIES) {
policy.checkDistrust(variant, anchor, cert);
}
}
/**

View file

@ -0,0 +1,157 @@
/*
* 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.validator;
import java.security.cert.X509Certificate;
import java.time.LocalDate;
import java.time.Month;
import java.time.ZoneOffset;
import java.util.Date;
import java.util.Set;
import sun.security.x509.X509CertImpl;
/**
* This class checks if Symantec issued TLS Server certificates should be
* restricted.
*/
final class SymantecTLSPolicy {
// SHA-256 certificate fingerprints of distrusted roots
private static final Set<String> FINGERPRINTS = Set.of(
// cacerts alias: geotrustglobalca
// DN: CN=GeoTrust Global CA, O=GeoTrust Inc., C=US
"FF856A2D251DCD88D36656F450126798CFABAADE40799C722DE4D2B5DB36A73A",
// cacerts alias: geotrustprimaryca
// DN: CN=GeoTrust Primary Certification Authority,
// O=GeoTrust Inc., C=US
"37D51006C512EAAB626421F1EC8C92013FC5F82AE98EE533EB4619B8DEB4D06C",
// cacerts alias: geotrustprimarycag2
// DN: CN=GeoTrust Primary Certification Authority - G2,
// OU=(c) 2007 GeoTrust Inc. - For authorized use only,
// O=GeoTrust Inc., C=US
"5EDB7AC43B82A06A8761E8D7BE4979EBF2611F7DD79BF91C1C6B566A219ED766",
// cacerts alias: geotrustprimarycag3
// DN: CN=GeoTrust Primary Certification Authority - G3,
// OU=(c) 2008 GeoTrust Inc. - For authorized use only,
// O=GeoTrust Inc., C=US
"B478B812250DF878635C2AA7EC7D155EAA625EE82916E2CD294361886CD1FBD4",
// cacerts alias: geotrustuniversalca
// DN: CN=GeoTrust Universal CA, O=GeoTrust Inc., C=US
"A0459B9F63B22559F5FA5D4C6DB3F9F72FF19342033578F073BF1D1B46CBB912",
// cacerts alias: thawteprimaryrootca
// DN: CN=thawte Primary Root CA,
// OU="(c) 2006 thawte, Inc. - For authorized use only",
// OU=Certification Services Division, O="thawte, Inc.", C=US
"8D722F81A9C113C0791DF136A2966DB26C950A971DB46B4199F4EA54B78BFB9F",
// cacerts alias: thawteprimaryrootcag2
// DN: CN=thawte Primary Root CA - G2,
// OU="(c) 2007 thawte, Inc. - For authorized use only",
// O="thawte, Inc.", C=US
"A4310D50AF18A6447190372A86AFAF8B951FFB431D837F1E5688B45971ED1557",
// cacerts alias: thawteprimaryrootcag3
// DN: CN=thawte Primary Root CA - G3,
// OU="(c) 2008 thawte, Inc. - For authorized use only",
// OU=Certification Services Division, O="thawte, Inc.", C=US
"4B03F45807AD70F21BFC2CAE71C9FDE4604C064CF5FFB686BAE5DBAAD7FDD34C",
// cacerts alias: thawtepremiumserverca
// DN: EMAILADDRESS=premium-server@thawte.com,
// CN=Thawte Premium Server CA, OU=Certification Services Division,
// O=Thawte Consulting cc, L=Cape Town, ST=Western Cape, C=ZA
"3F9F27D583204B9E09C8A3D2066C4B57D3A2479C3693650880505698105DBCE9",
// cacerts alias: verisignclass2g2ca
// DN: OU=VeriSign Trust Network,
// OU="(c) 1998 VeriSign, Inc. - For authorized use only",
// OU=Class 2 Public Primary Certification Authority - G2,
// O="VeriSign, Inc.", C=US
"3A43E220FE7F3EA9653D1E21742EAC2B75C20FD8980305BC502CAF8C2D9B41A1",
// cacerts alias: verisignclass3ca
// DN: OU=Class 3 Public Primary Certification Authority,
// O="VeriSign, Inc.", C=US
"A4B6B3996FC2F306B3FD8681BD63413D8C5009CC4FA329C2CCF0E2FA1B140305",
// cacerts alias: verisignclass3g2ca
// DN: OU=VeriSign Trust Network,
// OU="(c) 1998 VeriSign, Inc. - For authorized use only",
// OU=Class 3 Public Primary Certification Authority - G2,
// O="VeriSign, Inc.", C=US
"83CE3C1229688A593D485F81973C0F9195431EDA37CC5E36430E79C7A888638B",
// cacerts alias: verisignclass3g3ca
// DN: CN=VeriSign Class 3 Public Primary Certification Authority - G3,
// OU="(c) 1999 VeriSign, Inc. - For authorized use only",
// OU=VeriSign Trust Network, O="VeriSign, Inc.", C=US
"EB04CF5EB1F39AFA762F2BB120F296CBA520C1B97DB1589565B81CB9A17B7244",
// cacerts alias: verisignclass3g4ca
// DN: CN=VeriSign Class 3 Public Primary Certification Authority - G4,
// OU="(c) 2007 VeriSign, Inc. - For authorized use only",
// OU=VeriSign Trust Network, O="VeriSign, Inc.", C=US
"69DDD7EA90BB57C93E135DC85EA6FCD5480B603239BDC454FC758B2A26CF7F79",
// cacerts alias: verisignclass3g5ca
// DN: CN=VeriSign Class 3 Public Primary Certification Authority - G5,
// OU="(c) 2006 VeriSign, Inc. - For authorized use only",
// OU=VeriSign Trust Network, O="VeriSign, Inc.", C=US
"9ACFAB7E43C8D880D06B262A94DEEEE4B4659989C3D0CAF19BAF6405E41AB7DF",
// cacerts alias: verisignuniversalrootca
// DN: CN=VeriSign Universal Root Certification Authority,
// OU="(c) 2008 VeriSign, Inc. - For authorized use only",
// OU=VeriSign Trust Network, O="VeriSign, Inc.", C=US
"2399561127A57125DE8CEFEA610DDF2FA078B5C8067F4E828290BFB860E84B3C"
);
// Any TLS Server certificate that is anchored by one of the Symantec
// roots above and is issued after this date will be distrusted.
private static final LocalDate APRIL_16_2019 =
LocalDate.of(2019, Month.APRIL, 16);
/**
* This method assumes the eeCert is a TLS Server Cert and chains back to
* the anchor.
*
* @param anchor the trust anchor certificate
* @param eeCert the certificate to check
* @throws ValidatorException if the certificate is distrusted
*/
static void checkDistrust(X509Certificate anchor,
X509Certificate eeCert)
throws ValidatorException {
String fp = (anchor instanceof X509CertImpl)
? ((X509CertImpl)anchor).getFingerprint("SHA-256")
: X509CertImpl.getFingerprint("SHA-256", anchor);
if (FINGERPRINTS.contains(fp)) {
// reject if certificate is issued after April 16, 2019
Date notBefore = eeCert.getNotBefore();
LocalDate ldNotBefore = LocalDate.ofInstant(notBefore.toInstant(),
ZoneOffset.UTC);
if (ldNotBefore.isAfter(APRIL_16_2019)) {
throw new ValidatorException
("TLS Server certificate issued after " + APRIL_16_2019 +
" and anchored by a distrusted legacy Symantec root CA: "
+ anchor.getSubjectX500Principal(),
ValidatorException.T_UNTRUSTED_CERT, anchor);
}
}
}
private SymantecTLSPolicy() {}
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2002, 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
@ -275,7 +275,8 @@ public abstract class Validator {
boolean checkUnresolvedCritExts =
(type == TYPE_PKIX) ? false : true;
endEntityChecker.check(chain[0], parameter,
checkUnresolvedCritExts);
checkUnresolvedCritExts,
chain[chain.length-1]);
}
return chain;