This commit is contained in:
Henry Jen 2018-12-13 11:47:35 -08:00
commit d77f96b0b2
684 changed files with 47732 additions and 20486 deletions

View file

@ -53,7 +53,6 @@ import java.util.*;
import java.security.AlgorithmParameters;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import javax.crypto.spec.PBEParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
@ -70,6 +69,7 @@ import sun.security.util.DerOutputStream;
import sun.security.util.DerValue;
import sun.security.util.ObjectIdentifier;
import sun.security.pkcs.ContentInfo;
import sun.security.util.SecurityProperties;
import sun.security.x509.AlgorithmId;
import sun.security.pkcs.EncryptedPrivateKeyInfo;
import sun.security.provider.JavaKeyStore.JKS;
@ -81,9 +81,11 @@ import sun.security.util.KeyStoreDelegator;
* Implements the PKCS#12 PFX protected using the Password privacy mode.
* The contents are protected using Password integrity mode.
*
* Currently we support following PBE algorithms:
* - pbeWithSHAAnd3KeyTripleDESCBC to encrypt private keys
* - pbeWithSHAAnd40BitRC2CBC to encrypt certificates
* Currently these PBE algorithms are used by default:
* - PBEWithSHA1AndDESede to encrypt private keys, iteration count 50000.
* - PBEWithSHA1AndRC2_40 to encrypt certificates, iteration count 50000.
*
* The default Mac algorithm is HmacPBESHA1, iteration count 100000.
*
* Supported encryption of various implementations :
*
@ -126,11 +128,7 @@ import sun.security.util.KeyStoreDelegator;
* @author Jeff Nisewanger
* @author Jan Luehe
*
* @see KeyProtector
* @see java.security.KeyStoreSpi
* @see KeyTool
*
*
*/
public final class PKCS12KeyStore extends KeyStoreSpi {
@ -143,14 +141,7 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
public static final int VERSION_3 = 3;
private static final String[] KEY_PROTECTION_ALGORITHM = {
"keystore.pkcs12.keyProtectionAlgorithm",
"keystore.PKCS12.keyProtectionAlgorithm"
};
private static final int MAX_ITERATION_COUNT = 5000000;
private static final int PBE_ITERATION_COUNT = 50000; // default
private static final int MAC_ITERATION_COUNT = 100000; // default
private static final int SALT_LEN = 20;
// friendlyName, localKeyId, trustedKeyUsage
@ -171,10 +162,6 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
private static final int[] pkcs9certType = {1, 2, 840, 113549, 1, 9, 22, 1};
private static final int[] pbeWithSHAAnd40BitRC2CBC =
{1, 2, 840, 113549, 1, 12, 1, 6};
private static final int[] pbeWithSHAAnd3KeyTripleDESCBC =
{1, 2, 840, 113549, 1, 12, 1, 3};
private static final int[] pbes2 = {1, 2, 840, 113549, 1, 5, 13};
// TODO: temporary Oracle OID
/*
@ -185,17 +172,15 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
{2, 16, 840, 1, 113894, 746875, 1, 1};
private static final int[] AnyExtendedKeyUsage = {2, 5, 29, 37, 0};
private static ObjectIdentifier PKCS8ShroudedKeyBag_OID;
private static ObjectIdentifier CertBag_OID;
private static ObjectIdentifier SecretBag_OID;
private static ObjectIdentifier PKCS9FriendlyName_OID;
private static ObjectIdentifier PKCS9LocalKeyId_OID;
private static ObjectIdentifier PKCS9CertType_OID;
private static ObjectIdentifier pbeWithSHAAnd40BitRC2CBC_OID;
private static ObjectIdentifier pbeWithSHAAnd3KeyTripleDESCBC_OID;
private static ObjectIdentifier pbes2_OID;
private static ObjectIdentifier TrustedKeyUsage_OID;
private static ObjectIdentifier[] AnyUsage;
private static final ObjectIdentifier PKCS8ShroudedKeyBag_OID;
private static final ObjectIdentifier CertBag_OID;
private static final ObjectIdentifier SecretBag_OID;
private static final ObjectIdentifier PKCS9FriendlyName_OID;
private static final ObjectIdentifier PKCS9LocalKeyId_OID;
private static final ObjectIdentifier PKCS9CertType_OID;
private static final ObjectIdentifier pbes2_OID;
private static final ObjectIdentifier TrustedKeyUsage_OID;
private static final ObjectIdentifier[] AnyUsage;
private int counter = 0;
@ -210,6 +195,17 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
// certificate count
private int certificateCount = 0;
// Alg/params used for *this* keystore. Initialized as -1 for ic and
// null for algorithm names. When an existing file is read, they will be
// assigned inside engineLoad() so storing an existing keystore uses the
// old alg/params. This makes sure if a keystore is created password-less
// it will be password-less forever. Otherwise, engineStore() will read
// the default values. These fields are always reset when load() is called.
private String certProtectionAlgorithm = null;
private int certPbeIterationCount = -1;
private String macAlgorithm = null;
private int macIterationCount = -1;
// the source of randomness
private SecureRandom random;
@ -221,16 +217,12 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
PKCS9FriendlyName_OID = new ObjectIdentifier(pkcs9Name);
PKCS9LocalKeyId_OID = new ObjectIdentifier(pkcs9KeyId);
PKCS9CertType_OID = new ObjectIdentifier(pkcs9certType);
pbeWithSHAAnd40BitRC2CBC_OID =
new ObjectIdentifier(pbeWithSHAAnd40BitRC2CBC);
pbeWithSHAAnd3KeyTripleDESCBC_OID =
new ObjectIdentifier(pbeWithSHAAnd3KeyTripleDESCBC);
pbes2_OID = new ObjectIdentifier(pbes2);
TrustedKeyUsage_OID = new ObjectIdentifier(TrustedKeyUsage);
AnyUsage = new ObjectIdentifier[]{
new ObjectIdentifier(AnyExtendedKeyUsage)};
} catch (IOException ioe) {
// should not happen
throw new AssertionError("OID not initialized", ioe);
}
}
@ -391,7 +383,7 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
ic = pbeSpec.getIterationCount();
if (ic > MAX_ITERATION_COUNT) {
throw new IOException("PBE iteration count too large");
throw new IOException("key PBE iteration count too large");
}
} else {
ic = 0;
@ -424,7 +416,7 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
if (debug != null) {
debug.println("Retrieved a protected private key at alias" +
" '" + alias + "' (" +
new AlgorithmId(algOid).getName() +
mapPBEParamsToAlgorithm(algOid, algParams) +
" iterations: " + ic + ")");
}
return tmp;
@ -449,7 +441,7 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
if (debug != null) {
debug.println("Retrieved a protected secret key at alias " +
"'" + alias + "' (" +
new AlgorithmId(algOid).getName() +
mapPBEParamsToAlgorithm(algOid, algParams) +
" iterations: " + ic + ")");
}
return tmp;
@ -701,7 +693,7 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
entries.put(alias.toLowerCase(Locale.ENGLISH), entry);
} catch (Exception nsae) {
throw new KeyStoreException("Key protection " +
throw new KeyStoreException("Key protection" +
" algorithm not found: " + nsae, nsae);
}
}
@ -801,14 +793,13 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
/*
* Generate PBE Algorithm Parameters
*/
private AlgorithmParameters getPBEAlgorithmParameters(String algorithm)
throws IOException
{
private AlgorithmParameters getPBEAlgorithmParameters(
String algorithm, int iterationCount) throws IOException {
AlgorithmParameters algParams = null;
// create PBE parameters from salt and iteration count
PBEParameterSpec paramSpec =
new PBEParameterSpec(getSalt(), PBE_ITERATION_COUNT);
new PBEParameterSpec(getSalt(), iterationCount);
try {
algParams = AlgorithmParameters.getInstance(algorithm);
algParams.init(paramSpec);
@ -871,13 +862,14 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
}
/*
* Encrypt private key using Password-based encryption (PBE)
* Encrypt private key or secret key using Password-based encryption (PBE)
* as defined in PKCS#5.
*
* NOTE: By default, pbeWithSHAAnd3-KeyTripleDES-CBC algorithmID is
* used to derive the key and IV.
*
* @return encrypted private key encoded as EncryptedPrivateKeyInfo
* @return encrypted private key or secret key encoded as
* EncryptedPrivateKeyInfo
*/
private byte[] encryptPrivateKey(byte[] data,
KeyStore.PasswordProtection passwordProtection)
@ -899,27 +891,14 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
algParams = AlgorithmParameters.getInstance(algorithm);
algParams.init(algParamSpec);
} else {
algParams = getPBEAlgorithmParameters(algorithm);
algParams = getPBEAlgorithmParameters(algorithm,
defaultKeyPbeIterationCount());
}
} else {
// Check default key protection algorithm for PKCS12 keystores
algorithm = AccessController.doPrivileged(
new PrivilegedAction<String>() {
public String run() {
String prop =
Security.getProperty(
KEY_PROTECTION_ALGORITHM[0]);
if (prop == null) {
prop = Security.getProperty(
KEY_PROTECTION_ALGORITHM[1]);
}
return prop;
}
});
if (algorithm == null || algorithm.isEmpty()) {
algorithm = "PBEWithSHA1AndDESede";
}
algParams = getPBEAlgorithmParameters(algorithm);
algorithm = defaultKeyProtectionAlgorithm();
algParams = getPBEAlgorithmParameters(algorithm,
defaultKeyPbeIterationCount());
}
ObjectIdentifier pbeOID = mapPBEAlgorithmToOID(algorithm);
@ -977,7 +956,7 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
if (algorithm.equals(pbes2_OID) && algParams != null) {
return algParams.toString();
}
return algorithm.toString();
return new AlgorithmId(algorithm).getName();
}
/**
@ -1209,10 +1188,6 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
public synchronized void engineStore(OutputStream stream, char[] password)
throws IOException, NoSuchAlgorithmException, CertificateException
{
// password is mandatory when storing
if (password == null) {
throw new IllegalArgumentException("password can't be null");
}
// -- Create PFX
DerOutputStream pfx = new DerOutputStream();
@ -1245,16 +1220,28 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
// -- create EncryptedContentInfo
if (certificateCount > 0) {
if (certProtectionAlgorithm == null) {
certProtectionAlgorithm = defaultCertProtectionAlgorithm();
}
if (certPbeIterationCount < 0) {
certPbeIterationCount = defaultCertPbeIterationCount();
}
if (debug != null) {
debug.println("Storing " + certificateCount +
" certificate(s) in a PKCS#7 encryptedData");
}
byte[] encrData = createEncryptedData(password);
ContentInfo encrContentInfo =
new ContentInfo(ContentInfo.ENCRYPTED_DATA_OID,
if (!certProtectionAlgorithm.equalsIgnoreCase("NONE")) {
ContentInfo encrContentInfo =
new ContentInfo(ContentInfo.ENCRYPTED_DATA_OID,
new DerValue(encrData));
encrContentInfo.encode(authSafeContentInfo);
encrContentInfo.encode(authSafeContentInfo);
} else {
ContentInfo dataContentInfo = new ContentInfo(encrData);
dataContentInfo.encode(authSafeContentInfo);
}
}
// wrap as SequenceOf ContentInfos
@ -1269,9 +1256,16 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
pfx.write(authSafeData);
// -- MAC
byte[] macData = calculateMac(password, authenticatedSafe);
pfx.write(macData);
if (macAlgorithm == null) {
macAlgorithm = defaultMacAlgorithm();
}
if (macIterationCount < 0) {
macIterationCount = defaultMacIterationCount();
}
if (!macAlgorithm.equalsIgnoreCase("NONE")) {
byte[] macData = calculateMac(password, authenticatedSafe);
pfx.write(macData);
}
// write PFX to output stream
DerOutputStream pfxout = new DerOutputStream();
pfxout.write(DerValue.tag_Sequence, pfx);
@ -1481,24 +1475,6 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
return entry.attributes;
}
/*
* Generate Hash.
*/
private byte[] generateHash(byte[] data) throws IOException
{
byte[] digest = null;
try {
MessageDigest md = MessageDigest.getInstance("SHA1");
md.update(data);
digest = md.digest();
} catch (Exception e) {
throw new IOException("generateHash failed: " + e, e);
}
return digest;
}
/*
* Calculate MAC using HMAC algorithm (required for password integrity)
*
@ -1509,16 +1485,16 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
throws IOException
{
byte[] mData = null;
String algName = "SHA1";
String algName = macAlgorithm.substring(7);
try {
// Generate a random salt.
byte[] salt = getSalt();
// generate MAC (MAC key is generated within JCE)
Mac m = Mac.getInstance("HmacPBESHA1");
Mac m = Mac.getInstance(macAlgorithm);
PBEParameterSpec params =
new PBEParameterSpec(salt, MAC_ITERATION_COUNT);
new PBEParameterSpec(salt, macIterationCount);
SecretKey key = getPBEKey(passwd);
m.init(key, params);
m.update(data);
@ -1526,7 +1502,7 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
// encode as MacData
MacData macData = new MacData(algName, macResult, salt,
MAC_ITERATION_COUNT);
macIterationCount);
DerOutputStream bytes = new DerOutputStream();
bytes.write(macData.getEncoded());
mData = bytes.toByteArray();
@ -1799,15 +1775,19 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
byte[] safeBagData = safeBagValue.toByteArray();
// encrypt the content (EncryptedContentInfo)
byte[] encrContentInfo = encryptContent(safeBagData, password);
if (!certProtectionAlgorithm.equalsIgnoreCase("NONE")) {
byte[] encrContentInfo = encryptContent(safeBagData, password);
// -- SEQUENCE of EncryptedData
DerOutputStream encrData = new DerOutputStream();
DerOutputStream encrDataContent = new DerOutputStream();
encrData.putInteger(0);
encrData.write(encrContentInfo);
encrDataContent.write(DerValue.tag_Sequence, encrData);
return encrDataContent.toByteArray();
// -- SEQUENCE of EncryptedData
DerOutputStream encrData = new DerOutputStream();
DerOutputStream encrDataContent = new DerOutputStream();
encrData.putInteger(0);
encrData.write(encrContentInfo);
encrDataContent.write(DerValue.tag_Sequence, encrData);
return encrDataContent.toByteArray();
} else {
return safeBagData;
}
}
/*
@ -1916,47 +1896,52 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
byte[] encryptedData = null;
// create AlgorithmParameters
AlgorithmParameters algParams =
getPBEAlgorithmParameters("PBEWithSHA1AndRC2_40");
DerOutputStream bytes = new DerOutputStream();
AlgorithmId algId =
new AlgorithmId(pbeWithSHAAnd40BitRC2CBC_OID, algParams);
algId.encode(bytes);
byte[] encodedAlgId = bytes.toByteArray();
try {
// create AlgorithmParameters
AlgorithmParameters algParams = getPBEAlgorithmParameters(
certProtectionAlgorithm, certPbeIterationCount);
DerOutputStream bytes = new DerOutputStream();
// Use JCE
SecretKey skey = getPBEKey(password);
Cipher cipher = Cipher.getInstance("PBEWithSHA1AndRC2_40");
Cipher cipher = Cipher.getInstance(certProtectionAlgorithm);
cipher.init(Cipher.ENCRYPT_MODE, skey, algParams);
encryptedData = cipher.doFinal(data);
AlgorithmId algId = new AlgorithmId(
mapPBEAlgorithmToOID(certProtectionAlgorithm),
cipher.getParameters());
// cipher.getParameters() now has IV
algId.encode(bytes);
byte[] encodedAlgId = bytes.toByteArray();
if (debug != null) {
debug.println(" (Cipher algorithm: " + cipher.getAlgorithm() +
")");
")");
}
// create EncryptedContentInfo
DerOutputStream bytes2 = new DerOutputStream();
bytes2.putOID(ContentInfo.DATA_OID);
bytes2.write(encodedAlgId);
// Wrap encrypted data in a context-specific tag.
DerOutputStream tmpout2 = new DerOutputStream();
tmpout2.putOctetString(encryptedData);
bytes2.writeImplicit(DerValue.createTag(DerValue.TAG_CONTEXT,
false, (byte) 0), tmpout2);
// wrap EncryptedContentInfo in a Sequence
DerOutputStream out = new DerOutputStream();
out.write(DerValue.tag_Sequence, bytes2);
return out.toByteArray();
} catch (IOException ioe) {
throw ioe;
} catch (Exception e) {
throw new IOException("Failed to encrypt" +
" safe contents entry: " + e, e);
}
// create EncryptedContentInfo
DerOutputStream bytes2 = new DerOutputStream();
bytes2.putOID(ContentInfo.DATA_OID);
bytes2.write(encodedAlgId);
// Wrap encrypted data in a context-specific tag.
DerOutputStream tmpout2 = new DerOutputStream();
tmpout2.putOctetString(encryptedData);
bytes2.writeImplicit(DerValue.createTag(DerValue.TAG_CONTEXT,
false, (byte)0), tmpout2);
// wrap EncryptedContentInfo in a Sequence
DerOutputStream out = new DerOutputStream();
out.write(DerValue.tag_Sequence, bytes2);
return out.toByteArray();
}
/**
@ -1979,10 +1964,12 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
public synchronized void engineLoad(InputStream stream, char[] password)
throws IOException, NoSuchAlgorithmException, CertificateException
{
DataInputStream dis;
CertificateFactory cf = null;
ByteArrayInputStream bais = null;
byte[] encoded = null;
// Reset config when loading a different keystore.
certProtectionAlgorithm = null;
certPbeIterationCount = -1;
macAlgorithm = null;
macIterationCount = -1;
if (stream == null)
return;
@ -2022,6 +2009,8 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
secretKeyCount = 0;
certificateCount = 0;
boolean seeEncBag = false;
/*
* Spin over the ContentInfos.
*/
@ -2047,6 +2036,21 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
debug.println("Warning: skipping PKCS#7 encryptedData" +
" - no password was supplied");
}
// No password to decrypt ENCRYPTED_DATA_OID. *Skip it*.
// This means user will see a PrivateKeyEntry without
// certificates and a whole TrustedCertificateEntry will
// be lost. This is not a perfect solution but alternative
// solutions are more disruptive:
//
// We cannot just fail, since KeyStore.load(is, null)
// has been known to never fail because of a null password.
//
// We cannot just throw away the whole PrivateKeyEntry,
// this is too silent and no one will notice anything.
//
// We also cannot fail when getCertificate() on such a
// PrivateKeyEntry is called, since the method has not
// specified this behavior.
continue;
}
@ -2084,13 +2088,18 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
ic = pbeSpec.getIterationCount();
if (ic > MAX_ITERATION_COUNT) {
throw new IOException("PBE iteration count too large");
throw new IOException("cert PBE iteration count too large");
}
certProtectionAlgorithm
= mapPBEParamsToAlgorithm(algOid, algParams);
certPbeIterationCount = ic;
seeEncBag = true;
}
if (debug != null) {
debug.println("Loading PKCS#7 encryptedData " +
"(" + new AlgorithmId(algOid).getName() +
"(" + mapPBEParamsToAlgorithm(algOid, algParams) +
" iterations: " + ic + ")");
}
@ -2115,48 +2124,62 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
}
}
// No ENCRYPTED_DATA_OID but see certificate. Must be passwordless.
if (!seeEncBag && certificateCount > 0) {
certProtectionAlgorithm = "NONE";
}
// The MacData is optional.
if (password != null && s.available() > 0) {
MacData macData = new MacData(s);
int ic = macData.getIterations();
if (s.available() > 0) {
// If there is no password, we cannot fail. KeyStore.load(is, null)
// has been known to never fail because of a null password.
if (password != null) {
MacData macData = new MacData(s);
int ic = macData.getIterations();
try {
if (ic > MAX_ITERATION_COUNT) {
throw new InvalidAlgorithmParameterException(
"MAC iteration count too large: " + ic);
try {
if (ic > MAX_ITERATION_COUNT) {
throw new InvalidAlgorithmParameterException(
"MAC iteration count too large: " + ic);
}
String algName =
macData.getDigestAlgName().toUpperCase(Locale.ENGLISH);
// Change SHA-1 to SHA1
algName = algName.replace("-", "");
macAlgorithm = "HmacPBE" + algName;
macIterationCount = ic;
// generate MAC (MAC key is created within JCE)
Mac m = Mac.getInstance(macAlgorithm);
PBEParameterSpec params =
new PBEParameterSpec(macData.getSalt(), ic);
RetryWithZero.run(pass -> {
SecretKey key = getPBEKey(pass);
m.init(key, params);
m.update(authSafeData);
byte[] macResult = m.doFinal();
if (debug != null) {
debug.println("Checking keystore integrity " +
"(" + m.getAlgorithm() + " iterations: " + ic + ")");
}
if (!MessageDigest.isEqual(macData.getDigest(), macResult)) {
throw new UnrecoverableKeyException("Failed PKCS12" +
" integrity checking");
}
return (Void) null;
}, password);
} catch (Exception e) {
throw new IOException("Integrity check failed: " + e, e);
}
String algName =
macData.getDigestAlgName().toUpperCase(Locale.ENGLISH);
// Change SHA-1 to SHA1
algName = algName.replace("-", "");
// generate MAC (MAC key is created within JCE)
Mac m = Mac.getInstance("HmacPBE" + algName);
PBEParameterSpec params =
new PBEParameterSpec(macData.getSalt(), ic);
RetryWithZero.run(pass -> {
SecretKey key = getPBEKey(pass);
m.init(key, params);
m.update(authSafeData);
byte[] macResult = m.doFinal();
if (debug != null) {
debug.println("Checking keystore integrity " +
"(" + m.getAlgorithm() + " iterations: " + ic + ")");
}
if (!MessageDigest.isEqual(macData.getDigest(), macResult)) {
throw new UnrecoverableKeyException("Failed PKCS12" +
" integrity checking");
}
return (Void)null;
}, password);
} catch (Exception e) {
throw new IOException("Integrity check failed: " + e, e);
}
} else {
macAlgorithm = "NONE";
}
/*
@ -2196,8 +2219,14 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
cert = certsMap.get(issuerDN);
}
/* Update existing KeyEntry in entries table */
if (chain.size() > 0)
if (chain.size() > 0) {
entry.chain = chain.toArray(new Certificate[chain.size()]);
} else {
// Remove private key entries where there is no associated
// certs. Most likely the keystore is loaded with a null
// password.
entries.remove(entry);
}
}
}
@ -2221,6 +2250,46 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
keyList.clear();
}
/**
* Returns if a pkcs12 file is password-less. This means no cert is
* encrypted and there is no Mac. Please note that the private key
* can be encrypted.
*
* This is a simplified version of {@link #engineLoad} that only looks
* at the ContentInfo types.
*
* @param f the pkcs12 file
* @return if it's password-less
* @throws IOException
*/
public static boolean isPasswordless(File f) throws IOException {
try (FileInputStream stream = new FileInputStream(f)) {
DerValue val = new DerValue(stream);
DerInputStream s = val.toDerInputStream();
s.getInteger(); // skip version
ContentInfo authSafe = new ContentInfo(s);
DerInputStream as = new DerInputStream(authSafe.getData());
for (DerValue seq : as.getSequence(2)) {
DerInputStream sci = new DerInputStream(seq.toByteArray());
ContentInfo safeContents = new ContentInfo(sci);
if (safeContents.getContentType()
.equals(ContentInfo.ENCRYPTED_DATA_OID)) {
// Certificate encrypted
return false;
}
}
if (s.available() > 0) {
// The MacData exists.
return false;
}
}
return true;
}
/**
* Locates a matched CertEntry from certEntries, and returns its cert.
* @param entry the KeyEntry to match
@ -2368,8 +2437,8 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
if (bagItem instanceof KeyEntry) {
KeyEntry entry = (KeyEntry)bagItem;
if (bagItem instanceof PrivateKeyEntry) {
if (keyId == null) {
if (keyId == null) {
if (bagItem instanceof PrivateKeyEntry) {
// Insert a localKeyID for the privateKey
// Note: This is a workaround to allow null localKeyID
// attribute in pkcs12 with one private key entry and
@ -2379,6 +2448,9 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
} else {
continue;
}
} else {
// keyId in a SecretKeyEntry is not significant
keyId = "00".getBytes("UTF8");
}
}
entry.keyId = keyId;
@ -2518,4 +2590,83 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
return result;
}
// 8076190: Customizing the generation of a PKCS12 keystore
private static String defaultCertProtectionAlgorithm() {
String result = SecurityProperties.privilegedGetOverridable(
"keystore.pkcs12.certProtectionAlgorithm");
return (result != null && !result.isEmpty())
? result : "PBEWithSHA1AndRC2_40";
}
private static int defaultCertPbeIterationCount() {
String result = SecurityProperties.privilegedGetOverridable(
"keystore.pkcs12.certPbeIterationCount");
return (result != null && !result.isEmpty())
? string2IC("certPbeIterationCount", result) : 50000;
}
// Read both "keystore.pkcs12.keyProtectionAlgorithm" and
// "keystore.PKCS12.keyProtectionAlgorithm" for compatibility.
private static String defaultKeyProtectionAlgorithm() {
String result = AccessController.doPrivileged(new PrivilegedAction<String>() {
public String run() {
String result;
String name1 = "keystore.pkcs12.keyProtectionAlgorithm";
String name2 = "keystore.PKCS12.keyProtectionAlgorithm";
result = System.getProperty(name1);
if (result != null) {
return result;
}
result = System.getProperty(name2);
if (result != null) {
return result;
}
result = Security.getProperty(name1);
if (result != null) {
return result;
}
return Security.getProperty(name2);
}
});
return (result != null && !result.isEmpty())
? result : "PBEWithSHA1AndDESede";
}
private static int defaultKeyPbeIterationCount() {
String result = SecurityProperties.privilegedGetOverridable(
"keystore.pkcs12.keyPbeIterationCount");
return (result != null && !result.isEmpty())
? string2IC("keyPbeIterationCount", result) : 50000;
}
private static String defaultMacAlgorithm() {
String result = SecurityProperties.privilegedGetOverridable(
"keystore.pkcs12.macAlgorithm");
return (result != null && !result.isEmpty())
? result : "HmacPBESHA1";
}
private static int defaultMacIterationCount() {
String result = SecurityProperties.privilegedGetOverridable(
"keystore.pkcs12.macIterationCount");
return (result != null && !result.isEmpty())
? string2IC("macIterationCount", result) : 100000;
}
private static int string2IC(String type, String value) {
int number;
try {
number = Integer.parseInt(value);
} catch (NumberFormatException e) {
throw new IllegalArgumentException("keystore.pkcs12." + type
+ " is not a number: " + value);
}
if (number <= 0 || number > MAX_ITERATION_COUNT) {
throw new IllegalArgumentException("Invalid keystore.pkcs12."
+ type + ": " + value);
}
return number;
}
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 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
@ -28,7 +28,6 @@ package sun.security.provider;
import java.util.*;
import java.security.*;
import sun.security.action.PutAllAction;
import static sun.security.util.SecurityConstants.PROVIDER_VER;
@ -51,17 +50,27 @@ public final class Sun extends Provider {
/* We are the SUN provider */
super("SUN", PROVIDER_VER, INFO);
Provider p = this;
Iterator<Provider.Service> serviceIter = new SunEntries(p).iterator();
// if there is no security manager installed, put directly into
// the provider. Otherwise, create a temporary map and use a
// doPrivileged() call at the end to transfer the contents
// the provider
if (System.getSecurityManager() == null) {
SunEntries.putEntries(this);
putEntries(serviceIter);
} else {
// use LinkedHashMap to preserve the order of the PRNGs
Map<Object, Object> map = new LinkedHashMap<>();
SunEntries.putEntries(map);
AccessController.doPrivileged(new PutAllAction(this, map));
AccessController.doPrivileged(new PrivilegedAction<Void>() {
@Override
public Void run() {
putEntries(serviceIter);
return null;
}
});
}
}
void putEntries(Iterator<Provider.Service> i) {
while (i.hasNext()) {
putService(i.next());
}
}
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 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
@ -27,7 +27,7 @@ package sun.security.provider;
import java.io.*;
import java.net.*;
import java.util.Map;
import java.util.*;
import java.security.*;
import jdk.internal.util.StaticProperty;
@ -75,17 +75,28 @@ import sun.security.action.GetPropertyAction;
* - JavaLoginConfig is the default file-based LoginModule Configuration type.
*/
final class SunEntries {
public final class SunEntries {
private static final boolean useLegacyDSA =
Boolean.parseBoolean(GetPropertyAction.privilegedGetProperty
("jdk.security.legacyDSAKeyPairGenerator"));
private SunEntries() {
// empty
// create an aliases List from the specified aliases
public static List<String> createAliases(String ... aliases) {
return Arrays.asList(aliases);
}
static void putEntries(Map<Object, Object> map) {
// create an aliases List from the specified oid followed by other aliases
public static List<String> createAliasesWithOid(String ... oids) {
String[] result = Arrays.copyOf(oids, oids.length + 1);
result[result.length - 1] = "OID." + oids[0];
return Arrays.asList(result);
}
// extend LinkedHashSet to preserve the ordering (needed by SecureRandom?)
SunEntries(Provider p) {
services = new LinkedHashSet<>(50, 0.9f);
// start populating content using the specified provider
// common attribute map
HashMap<String, String> attrs = new HashMap<>(3);
/*
* SecureRandom
@ -100,266 +111,217 @@ final class SunEntries {
boolean useNativePRNG = seedSource.equals(URL_DEV_URANDOM) ||
seedSource.equals(URL_DEV_RANDOM);
attrs.put("ThreadSafe", "true");
if (nativeAvailable && useNativePRNG) {
map.put("SecureRandom.NativePRNG",
"sun.security.provider.NativePRNG");
map.put("SecureRandom.NativePRNG ThreadSafe", "true");
add(p, "SecureRandom", "NativePRNG",
"sun.security.provider.NativePRNG", null, attrs);
}
map.put("SecureRandom.DRBG", "sun.security.provider.DRBG");
map.put("SecureRandom.DRBG ThreadSafe", "true");
map.put("SecureRandom.SHA1PRNG",
"sun.security.provider.SecureRandom");
map.put("SecureRandom.SHA1PRNG ThreadSafe", "true");
attrs.put("ImplementedIn", "Software");
add(p, "SecureRandom", "DRBG", "sun.security.provider.DRBG", null, attrs);
add(p, "SecureRandom", "SHA1PRNG",
"sun.security.provider.SecureRandom", null, attrs);
attrs.remove("ImplementedIn");
if (nativeAvailable && !useNativePRNG) {
map.put("SecureRandom.NativePRNG",
"sun.security.provider.NativePRNG");
map.put("SecureRandom.NativePRNG ThreadSafe", "true");
add(p, "SecureRandom", "NativePRNG", "sun.security.provider.NativePRNG",
null, attrs);
}
if (NativePRNG.Blocking.isAvailable()) {
map.put("SecureRandom.NativePRNGBlocking",
"sun.security.provider.NativePRNG$Blocking");
map.put("SecureRandom.NativePRNGBlocking ThreadSafe", "true");
add(p, "SecureRandom", "NativePRNGBlocking",
"sun.security.provider.NativePRNG$Blocking", null, attrs);
}
if (NativePRNG.NonBlocking.isAvailable()) {
map.put("SecureRandom.NativePRNGNonBlocking",
"sun.security.provider.NativePRNG$NonBlocking");
map.put("SecureRandom.NativePRNGNonBlocking ThreadSafe", "true");
add(p, "SecureRandom", "NativePRNGNonBlocking",
"sun.security.provider.NativePRNG$NonBlocking", null, attrs);
}
/*
* Signature engines
*/
map.put("Signature.SHA1withDSA",
"sun.security.provider.DSA$SHA1withDSA");
map.put("Signature.NONEwithDSA", "sun.security.provider.DSA$RawDSA");
map.put("Alg.Alias.Signature.RawDSA", "NONEwithDSA");
map.put("Signature.SHA224withDSA",
"sun.security.provider.DSA$SHA224withDSA");
map.put("Signature.SHA256withDSA",
"sun.security.provider.DSA$SHA256withDSA");
map.put("Signature.SHA1withDSAinP1363Format",
"sun.security.provider.DSA$SHA1withDSAinP1363Format");
map.put("Signature.NONEwithDSAinP1363Format",
"sun.security.provider.DSA$RawDSAinP1363Format");
map.put("Signature.SHA224withDSAinP1363Format",
"sun.security.provider.DSA$SHA224withDSAinP1363Format");
map.put("Signature.SHA256withDSAinP1363Format",
"sun.security.provider.DSA$SHA256withDSAinP1363Format");
attrs.clear();
String dsaKeyClasses = "java.security.interfaces.DSAPublicKey" +
"|java.security.interfaces.DSAPrivateKey";
map.put("Signature.SHA1withDSA SupportedKeyClasses", dsaKeyClasses);
map.put("Signature.NONEwithDSA SupportedKeyClasses", dsaKeyClasses);
map.put("Signature.SHA224withDSA SupportedKeyClasses", dsaKeyClasses);
map.put("Signature.SHA256withDSA SupportedKeyClasses", dsaKeyClasses);
attrs.put("SupportedKeyClasses", dsaKeyClasses);
attrs.put("ImplementedIn", "Software");
map.put("Alg.Alias.Signature.DSA", "SHA1withDSA");
map.put("Alg.Alias.Signature.DSS", "SHA1withDSA");
map.put("Alg.Alias.Signature.SHA/DSA", "SHA1withDSA");
map.put("Alg.Alias.Signature.SHA-1/DSA", "SHA1withDSA");
map.put("Alg.Alias.Signature.SHA1/DSA", "SHA1withDSA");
map.put("Alg.Alias.Signature.SHAwithDSA", "SHA1withDSA");
map.put("Alg.Alias.Signature.DSAWithSHA1", "SHA1withDSA");
map.put("Alg.Alias.Signature.OID.1.2.840.10040.4.3",
"SHA1withDSA");
map.put("Alg.Alias.Signature.1.2.840.10040.4.3", "SHA1withDSA");
map.put("Alg.Alias.Signature.1.3.14.3.2.13", "SHA1withDSA");
map.put("Alg.Alias.Signature.1.3.14.3.2.27", "SHA1withDSA");
map.put("Alg.Alias.Signature.OID.2.16.840.1.101.3.4.3.1",
"SHA224withDSA");
map.put("Alg.Alias.Signature.2.16.840.1.101.3.4.3.1", "SHA224withDSA");
map.put("Alg.Alias.Signature.OID.2.16.840.1.101.3.4.3.2",
"SHA256withDSA");
map.put("Alg.Alias.Signature.2.16.840.1.101.3.4.3.2", "SHA256withDSA");
attrs.put("KeySize", "1024"); // for NONE and SHA1 DSA signatures
add(p, "Signature", "SHA1withDSA",
"sun.security.provider.DSA$SHA1withDSA",
createAliasesWithOid("1.2.840.10040.4.3", "DSA", "DSS", "SHA/DSA",
"SHA-1/DSA", "SHA1/DSA", "SHAwithDSA", "DSAWithSHA1",
"1.3.14.3.2.13", "1.3.14.3.2.27"), attrs);
add(p, "Signature", "NONEwithDSA", "sun.security.provider.DSA$RawDSA",
createAliases("RawDSA"), attrs);
attrs.put("KeySize", "2048"); // for SHA224 and SHA256 DSA signatures
add(p, "Signature", "SHA224withDSA",
"sun.security.provider.DSA$SHA224withDSA",
createAliasesWithOid("2.16.840.1.101.3.4.3.1"), attrs);
add(p, "Signature", "SHA256withDSA",
"sun.security.provider.DSA$SHA256withDSA",
createAliasesWithOid("2.16.840.1.101.3.4.3.2"), attrs);
attrs.remove("KeySize");
add(p, "Signature", "SHA1withDSAinP1363Format",
"sun.security.provider.DSA$SHA1withDSAinP1363Format",
null, null);
add(p, "Signature", "NONEwithDSAinP1363Format",
"sun.security.provider.DSA$RawDSAinP1363Format",
null, null);
add(p, "Signature", "SHA224withDSAinP1363Format",
"sun.security.provider.DSA$SHA224withDSAinP1363Format",
null, null);
add(p, "Signature", "SHA256withDSAinP1363Format",
"sun.security.provider.DSA$SHA256withDSAinP1363Format",
null, null);
/*
* Key Pair Generator engines
*/
attrs.clear();
attrs.put("ImplementedIn", "Software");
attrs.put("KeySize", "2048"); // for DSA KPG and APG only
String dsaOid = "1.2.840.10040.4.1";
List<String> dsaAliases = createAliasesWithOid(dsaOid, "1.3.14.3.2.12");
String dsaKPGImplClass = "sun.security.provider.DSAKeyPairGenerator$";
dsaKPGImplClass += (useLegacyDSA? "Legacy" : "Current");
map.put("KeyPairGenerator.DSA", dsaKPGImplClass);
map.put("Alg.Alias.KeyPairGenerator.OID.1.2.840.10040.4.1", "DSA");
map.put("Alg.Alias.KeyPairGenerator.1.2.840.10040.4.1", "DSA");
map.put("Alg.Alias.KeyPairGenerator.1.3.14.3.2.12", "DSA");
/*
* Digest engines
*/
map.put("MessageDigest.MD2", "sun.security.provider.MD2");
map.put("MessageDigest.MD5", "sun.security.provider.MD5");
map.put("MessageDigest.SHA", "sun.security.provider.SHA");
map.put("Alg.Alias.MessageDigest.SHA-1", "SHA");
map.put("Alg.Alias.MessageDigest.SHA1", "SHA");
map.put("Alg.Alias.MessageDigest.1.3.14.3.2.26", "SHA");
map.put("Alg.Alias.MessageDigest.OID.1.3.14.3.2.26", "SHA");
map.put("MessageDigest.SHA-224", "sun.security.provider.SHA2$SHA224");
map.put("Alg.Alias.MessageDigest.2.16.840.1.101.3.4.2.4", "SHA-224");
map.put("Alg.Alias.MessageDigest.OID.2.16.840.1.101.3.4.2.4",
"SHA-224");
map.put("MessageDigest.SHA-256", "sun.security.provider.SHA2$SHA256");
map.put("Alg.Alias.MessageDigest.2.16.840.1.101.3.4.2.1", "SHA-256");
map.put("Alg.Alias.MessageDigest.OID.2.16.840.1.101.3.4.2.1",
"SHA-256");
map.put("MessageDigest.SHA-384", "sun.security.provider.SHA5$SHA384");
map.put("Alg.Alias.MessageDigest.2.16.840.1.101.3.4.2.2", "SHA-384");
map.put("Alg.Alias.MessageDigest.OID.2.16.840.1.101.3.4.2.2",
"SHA-384");
map.put("MessageDigest.SHA-512", "sun.security.provider.SHA5$SHA512");
map.put("Alg.Alias.MessageDigest.2.16.840.1.101.3.4.2.3", "SHA-512");
map.put("Alg.Alias.MessageDigest.OID.2.16.840.1.101.3.4.2.3",
"SHA-512");
map.put("MessageDigest.SHA-512/224", "sun.security.provider.SHA5$SHA512_224");
map.put("Alg.Alias.MessageDigest.2.16.840.1.101.3.4.2.5", "SHA-512/224");
map.put("Alg.Alias.MessageDigest.OID.2.16.840.1.101.3.4.2.5",
"SHA-512/224");
map.put("MessageDigest.SHA-512/256", "sun.security.provider.SHA5$SHA512_256");
map.put("Alg.Alias.MessageDigest.2.16.840.1.101.3.4.2.6", "SHA-512/256");
map.put("Alg.Alias.MessageDigest.OID.2.16.840.1.101.3.4.2.6",
"SHA-512/256");
map.put("MessageDigest.SHA3-224", "sun.security.provider.SHA3$SHA224");
map.put("Alg.Alias.MessageDigest.2.16.840.1.101.3.4.2.7", "SHA3-224");
map.put("Alg.Alias.MessageDigest.OID.2.16.840.1.101.3.4.2.7",
"SHA3-224");
map.put("MessageDigest.SHA3-256", "sun.security.provider.SHA3$SHA256");
map.put("Alg.Alias.MessageDigest.2.16.840.1.101.3.4.2.8", "SHA3-256");
map.put("Alg.Alias.MessageDigest.OID.2.16.840.1.101.3.4.2.8",
"SHA3-256");
map.put("MessageDigest.SHA3-384", "sun.security.provider.SHA3$SHA384");
map.put("Alg.Alias.MessageDigest.2.16.840.1.101.3.4.2.9", "SHA3-384");
map.put("Alg.Alias.MessageDigest.OID.2.16.840.1.101.3.4.2.9",
"SHA3-384");
map.put("MessageDigest.SHA3-512", "sun.security.provider.SHA3$SHA512");
map.put("Alg.Alias.MessageDigest.2.16.840.1.101.3.4.2.10", "SHA3-512");
map.put("Alg.Alias.MessageDigest.OID.2.16.840.1.101.3.4.2.10",
"SHA3-512");
add(p, "KeyPairGenerator", "DSA", dsaKPGImplClass, dsaAliases, attrs);
/*
* Algorithm Parameter Generator engines
*/
map.put("AlgorithmParameterGenerator.DSA",
"sun.security.provider.DSAParameterGenerator");
add(p, "AlgorithmParameterGenerator", "DSA",
"sun.security.provider.DSAParameterGenerator", dsaAliases, attrs);
attrs.remove("KeySize");
/*
* Algorithm Parameter engines
*/
map.put("AlgorithmParameters.DSA",
"sun.security.provider.DSAParameters");
map.put("Alg.Alias.AlgorithmParameters.OID.1.2.840.10040.4.1", "DSA");
map.put("Alg.Alias.AlgorithmParameters.1.2.840.10040.4.1", "DSA");
map.put("Alg.Alias.AlgorithmParameters.1.3.14.3.2.12", "DSA");
add(p, "AlgorithmParameters", "DSA",
"sun.security.provider.DSAParameters", dsaAliases, attrs);
/*
* Key factories
*/
map.put("KeyFactory.DSA", "sun.security.provider.DSAKeyFactory");
map.put("Alg.Alias.KeyFactory.OID.1.2.840.10040.4.1", "DSA");
map.put("Alg.Alias.KeyFactory.1.2.840.10040.4.1", "DSA");
map.put("Alg.Alias.KeyFactory.1.3.14.3.2.12", "DSA");
add(p, "KeyFactory", "DSA", "sun.security.provider.DSAKeyFactory",
dsaAliases, attrs);
/*
* Digest engines
*/
add(p, "MessageDigest", "MD2", "sun.security.provider.MD2", null, attrs);
add(p, "MessageDigest", "MD5", "sun.security.provider.MD5", null, attrs);
add(p, "MessageDigest", "SHA", "sun.security.provider.SHA",
createAliasesWithOid("1.3.14.3.2.26", "SHA-1", "SHA1"), attrs);
String sha2BaseOid = "2.16.840.1.101.3.4.2";
add(p, "MessageDigest", "SHA-224", "sun.security.provider.SHA2$SHA224",
createAliasesWithOid(sha2BaseOid + ".4"), attrs);
add(p, "MessageDigest", "SHA-256", "sun.security.provider.SHA2$SHA256",
createAliasesWithOid(sha2BaseOid + ".1"), attrs);
add(p, "MessageDigest", "SHA-384", "sun.security.provider.SHA5$SHA384",
createAliasesWithOid(sha2BaseOid + ".2"), attrs);
add(p, "MessageDigest", "SHA-512", "sun.security.provider.SHA5$SHA512",
createAliasesWithOid(sha2BaseOid + ".3"), attrs);
add(p, "MessageDigest", "SHA-512/224",
"sun.security.provider.SHA5$SHA512_224",
createAliasesWithOid(sha2BaseOid + ".5"), attrs);
add(p, "MessageDigest", "SHA-512/256",
"sun.security.provider.SHA5$SHA512_256",
createAliasesWithOid(sha2BaseOid + ".6"), attrs);
add(p, "MessageDigest", "SHA3-224", "sun.security.provider.SHA3$SHA224",
createAliasesWithOid(sha2BaseOid + ".7"), attrs);
add(p, "MessageDigest", "SHA3-256", "sun.security.provider.SHA3$SHA256",
createAliasesWithOid(sha2BaseOid + ".8"), attrs);
add(p, "MessageDigest", "SHA3-384", "sun.security.provider.SHA3$SHA384",
createAliasesWithOid(sha2BaseOid + ".9"), attrs);
add(p, "MessageDigest", "SHA3-512", "sun.security.provider.SHA3$SHA512",
createAliasesWithOid(sha2BaseOid + ".10"), attrs);
/*
* Certificates
*/
map.put("CertificateFactory.X.509",
"sun.security.provider.X509Factory");
map.put("Alg.Alias.CertificateFactory.X509", "X.509");
add(p, "CertificateFactory", "X.509",
"sun.security.provider.X509Factory",
createAliases("X509"), attrs);
/*
* KeyStore
*/
map.put("KeyStore.PKCS12",
"sun.security.pkcs12.PKCS12KeyStore$DualFormatPKCS12");
map.put("KeyStore.JKS",
"sun.security.provider.JavaKeyStore$DualFormatJKS");
map.put("KeyStore.CaseExactJKS",
"sun.security.provider.JavaKeyStore$CaseExactJKS");
map.put("KeyStore.DKS", "sun.security.provider.DomainKeyStore$DKS");
add(p, "KeyStore", "PKCS12",
"sun.security.pkcs12.PKCS12KeyStore$DualFormatPKCS12",
null, null);
add(p, "KeyStore", "JKS",
"sun.security.provider.JavaKeyStore$DualFormatJKS",
null, attrs);
add(p, "KeyStore", "CaseExactJKS",
"sun.security.provider.JavaKeyStore$CaseExactJKS",
null, attrs);
add(p, "KeyStore", "DKS", "sun.security.provider.DomainKeyStore$DKS",
null, attrs);
/*
* Policy
*/
map.put("Policy.JavaPolicy", "sun.security.provider.PolicySpiFile");
/*
* Configuration
*/
map.put("Configuration.JavaLoginConfig",
"sun.security.provider.ConfigFile$Spi");
/*
* CertPathBuilder
*/
map.put("CertPathBuilder.PKIX",
"sun.security.provider.certpath.SunCertPathBuilder");
map.put("CertPathBuilder.PKIX ValidationAlgorithm",
"RFC5280");
/*
* CertPathValidator
*/
map.put("CertPathValidator.PKIX",
"sun.security.provider.certpath.PKIXCertPathValidator");
map.put("CertPathValidator.PKIX ValidationAlgorithm",
"RFC5280");
/*
* CertStores
*/
map.put("CertStore.Collection",
"sun.security.provider.certpath.CollectionCertStore");
map.put("CertStore.com.sun.security.IndexedCollection",
"sun.security.provider.certpath.IndexedCollectionCertStore");
add(p, "CertStore", "Collection",
"sun.security.provider.certpath.CollectionCertStore",
null, attrs);
add(p, "CertStore", "com.sun.security.IndexedCollection",
"sun.security.provider.certpath.IndexedCollectionCertStore",
null, attrs);
/*
* KeySize
* Policy
*/
map.put("Signature.NONEwithDSA KeySize", "1024");
map.put("Signature.SHA1withDSA KeySize", "1024");
map.put("Signature.SHA224withDSA KeySize", "2048");
map.put("Signature.SHA256withDSA KeySize", "2048");
map.put("KeyPairGenerator.DSA KeySize", "2048");
map.put("AlgorithmParameterGenerator.DSA KeySize", "2048");
add(p, "Policy", "JavaPolicy", "sun.security.provider.PolicySpiFile",
null, null);
/*
* Implementation type: software or hardware
* Configuration
*/
map.put("Signature.SHA1withDSA ImplementedIn", "Software");
map.put("KeyPairGenerator.DSA ImplementedIn", "Software");
map.put("MessageDigest.MD5 ImplementedIn", "Software");
map.put("MessageDigest.SHA ImplementedIn", "Software");
map.put("AlgorithmParameterGenerator.DSA ImplementedIn",
"Software");
map.put("AlgorithmParameters.DSA ImplementedIn", "Software");
map.put("KeyFactory.DSA ImplementedIn", "Software");
map.put("SecureRandom.SHA1PRNG ImplementedIn", "Software");
map.put("SecureRandom.DRBG ImplementedIn", "Software");
map.put("CertificateFactory.X.509 ImplementedIn", "Software");
map.put("KeyStore.JKS ImplementedIn", "Software");
map.put("CertPathValidator.PKIX ImplementedIn", "Software");
map.put("CertPathBuilder.PKIX ImplementedIn", "Software");
map.put("CertStore.Collection ImplementedIn", "Software");
map.put("CertStore.com.sun.security.IndexedCollection ImplementedIn",
"Software");
add(p, "Configuration", "JavaLoginConfig",
"sun.security.provider.ConfigFile$Spi", null, null);
/*
* CertPathBuilder and CertPathValidator
*/
attrs.clear();
attrs.put("ValidationAlgorithm", "RFC5280");
attrs.put("ImplementedIn", "Software");
add(p, "CertPathBuilder", "PKIX",
"sun.security.provider.certpath.SunCertPathBuilder",
null, attrs);
add(p, "CertPathValidator", "PKIX",
"sun.security.provider.certpath.PKIXCertPathValidator",
null, attrs);
}
Iterator<Provider.Service> iterator() {
return services.iterator();
}
private void add(Provider p, String type, String algo, String cn,
List<String> aliases, HashMap<String, String> attrs) {
services.add(new Provider.Service(p, type, algo, cn, aliases, attrs));
}
private LinkedHashSet<Provider.Service> services;
// name of the *System* property, takes precedence over PROP_RNDSOURCE
private static final String PROP_EGD = "java.security.egd";
// name of the *Security* property
private static final String PROP_RNDSOURCE = "securerandom.source";
private static final boolean useLegacyDSA =
Boolean.parseBoolean(GetPropertyAction.privilegedGetProperty
("jdk.security.legacyDSAKeyPairGenerator"));
static final String URL_DEV_RANDOM = "file:/dev/random";
static final String URL_DEV_URANDOM = "file:/dev/urandom";

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 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
@ -28,8 +28,6 @@ package sun.security.provider;
import java.util.*;
import java.security.*;
import sun.security.action.PutAllAction;
import sun.security.rsa.SunRsaSignEntries;
import static sun.security.util.SecurityConstants.PROVIDER_VER;
@ -70,18 +68,30 @@ public final class VerificationProvider extends Provider {
return;
}
Provider p = this;
Iterator<Provider.Service> sunIter = new SunEntries(p).iterator();
Iterator<Provider.Service> rsaIter =
new SunRsaSignEntries(p).iterator();
// if there is no security manager installed, put directly into
// the provider. Otherwise, create a temporary map and use a
// doPrivileged() call at the end to transfer the contents
// the provider
if (System.getSecurityManager() == null) {
SunEntries.putEntries(this);
SunRsaSignEntries.putEntries(this);
putEntries(sunIter);
putEntries(rsaIter);
} else {
// use LinkedHashMap to preserve the order of the PRNGs
Map<Object, Object> map = new LinkedHashMap<>();
SunEntries.putEntries(map);
SunRsaSignEntries.putEntries(map);
AccessController.doPrivileged(new PutAllAction(this, map));
AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Void run() {
putEntries(sunIter);
putEntries(rsaIter);
return null;
}
});
}
}
void putEntries(Iterator<Provider.Service> i) {
while (i.hasNext()) {
putService(i.next());
}
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 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
@ -29,7 +29,6 @@ import java.util.*;
import java.security.*;
import sun.security.action.PutAllAction;
import static sun.security.util.SecurityConstants.PROVIDER_VER;
/**
@ -46,17 +45,24 @@ public final class SunRsaSign extends Provider {
public SunRsaSign() {
super("SunRsaSign", PROVIDER_VER, "Sun RSA signature provider");
// if there is no security manager installed, put directly into
// the provider. Otherwise, create a temporary map and use a
// doPrivileged() call at the end to transfer the contents
Provider p = this;
Iterator<Provider.Service> serviceIter = new SunRsaSignEntries(p).iterator();
if (System.getSecurityManager() == null) {
SunRsaSignEntries.putEntries(this);
putEntries(serviceIter);
} else {
// use LinkedHashMap to preserve the order of the PRNGs
Map<Object, Object> map = new HashMap<>();
SunRsaSignEntries.putEntries(map);
AccessController.doPrivileged(new PutAllAction(this, map));
AccessController.doPrivileged(new PrivilegedAction<Void>() {
@Override
public Void run() {
putEntries(serviceIter);
return null;
}
});
}
}
void putEntries(Iterator<Provider.Service> i) {
while (i.hasNext()) {
putService(i.next());
}
}
}

View file

@ -25,7 +25,9 @@
package sun.security.rsa;
import java.util.Map;
import java.util.*;
import java.security.Provider;
import static sun.security.provider.SunEntries.createAliasesWithOid;
/**
* Defines the entries of the SunRsaSign provider.
@ -34,102 +36,81 @@ import java.util.Map;
*/
public final class SunRsaSignEntries {
private SunRsaSignEntries() {
// empty
private void add(Provider p, String type, String algo, String cn,
List<String> aliases, HashMap<String, String> attrs) {
services.add(new Provider.Service(p, type, algo, cn, aliases, attrs));
}
public static void putEntries(Map<Object, Object> map) {
// extend LinkedHashSet for consistency with SunEntries
// used by sun.security.provider.VerificationProvider
public SunRsaSignEntries(Provider p) {
services = new LinkedHashSet<>(20, 0.9f);
// main algorithms
map.put("KeyFactory.RSA",
"sun.security.rsa.RSAKeyFactory$Legacy");
map.put("KeyPairGenerator.RSA",
"sun.security.rsa.RSAKeyPairGenerator$Legacy");
map.put("Signature.MD2withRSA",
"sun.security.rsa.RSASignature$MD2withRSA");
map.put("Signature.MD5withRSA",
"sun.security.rsa.RSASignature$MD5withRSA");
map.put("Signature.SHA1withRSA",
"sun.security.rsa.RSASignature$SHA1withRSA");
map.put("Signature.SHA224withRSA",
"sun.security.rsa.RSASignature$SHA224withRSA");
map.put("Signature.SHA256withRSA",
"sun.security.rsa.RSASignature$SHA256withRSA");
map.put("Signature.SHA384withRSA",
"sun.security.rsa.RSASignature$SHA384withRSA");
map.put("Signature.SHA512withRSA",
"sun.security.rsa.RSASignature$SHA512withRSA");
map.put("Signature.SHA512/224withRSA",
"sun.security.rsa.RSASignature$SHA512_224withRSA");
map.put("Signature.SHA512/256withRSA",
"sun.security.rsa.RSASignature$SHA512_256withRSA");
// start populating content using the specified provider
map.put("KeyFactory.RSASSA-PSS",
"sun.security.rsa.RSAKeyFactory$PSS");
map.put("KeyPairGenerator.RSASSA-PSS",
"sun.security.rsa.RSAKeyPairGenerator$PSS");
map.put("Signature.RSASSA-PSS",
"sun.security.rsa.RSAPSSSignature");
map.put("AlgorithmParameters.RSASSA-PSS",
"sun.security.rsa.PSSParameters");
// common oids
String rsaOid = "1.2.840.113549.1.1";
List<String> rsaAliases = createAliasesWithOid(rsaOid);
List<String> rsapssAliases = createAliasesWithOid(rsaOid + ".10");
String sha1withRSAOid2 = "1.3.14.3.2.29";
// attributes for supported key classes
String rsaKeyClasses = "java.security.interfaces.RSAPublicKey" +
"|java.security.interfaces.RSAPrivateKey";
map.put("Signature.MD2withRSA SupportedKeyClasses", rsaKeyClasses);
map.put("Signature.MD5withRSA SupportedKeyClasses", rsaKeyClasses);
map.put("Signature.SHA1withRSA SupportedKeyClasses", rsaKeyClasses);
map.put("Signature.SHA224withRSA SupportedKeyClasses", rsaKeyClasses);
map.put("Signature.SHA256withRSA SupportedKeyClasses", rsaKeyClasses);
map.put("Signature.SHA384withRSA SupportedKeyClasses", rsaKeyClasses);
map.put("Signature.SHA512withRSA SupportedKeyClasses", rsaKeyClasses);
map.put("Signature.SHA512/224withRSA SupportedKeyClasses", rsaKeyClasses);
map.put("Signature.SHA512/256withRSA SupportedKeyClasses", rsaKeyClasses);
map.put("Signature.RSASSA-PSS SupportedKeyClasses", rsaKeyClasses);
// common attribute map
HashMap<String, String> attrs = new HashMap<>(3);
attrs.put("SupportedKeyClasses",
"java.security.interfaces.RSAPublicKey" +
"|java.security.interfaces.RSAPrivateKey");
// aliases
map.put("Alg.Alias.KeyFactory.1.2.840.113549.1.1", "RSA");
map.put("Alg.Alias.KeyFactory.OID.1.2.840.113549.1.1", "RSA");
add(p, "KeyFactory", "RSA",
"sun.security.rsa.RSAKeyFactory$Legacy",
rsaAliases, null);
add(p, "KeyPairGenerator", "RSA",
"sun.security.rsa.RSAKeyPairGenerator$Legacy",
rsaAliases, null);
add(p, "Signature", "MD2withRSA",
"sun.security.rsa.RSASignature$MD2withRSA",
createAliasesWithOid(rsaOid + ".2"), attrs);
add(p, "Signature", "MD5withRSA",
"sun.security.rsa.RSASignature$MD5withRSA",
createAliasesWithOid(rsaOid + ".4"), attrs);
add(p, "Signature", "SHA1withRSA",
"sun.security.rsa.RSASignature$SHA1withRSA",
createAliasesWithOid(rsaOid + ".5", sha1withRSAOid2), attrs);
add(p, "Signature", "SHA224withRSA",
"sun.security.rsa.RSASignature$SHA224withRSA",
createAliasesWithOid(rsaOid + ".14"), attrs);
add(p, "Signature", "SHA256withRSA",
"sun.security.rsa.RSASignature$SHA256withRSA",
createAliasesWithOid(rsaOid + ".11"), attrs);
add(p, "Signature", "SHA384withRSA",
"sun.security.rsa.RSASignature$SHA384withRSA",
createAliasesWithOid(rsaOid + ".12"), attrs);
add(p, "Signature", "SHA512withRSA",
"sun.security.rsa.RSASignature$SHA512withRSA",
createAliasesWithOid(rsaOid + ".13"), attrs);
add(p, "Signature", "SHA512/224withRSA",
"sun.security.rsa.RSASignature$SHA512_224withRSA",
createAliasesWithOid(rsaOid + ".15"), attrs);
add(p, "Signature", "SHA512/256withRSA",
"sun.security.rsa.RSASignature$SHA512_256withRSA",
createAliasesWithOid(rsaOid + ".16"), attrs);
map.put("Alg.Alias.KeyPairGenerator.1.2.840.113549.1.1", "RSA");
map.put("Alg.Alias.KeyPairGenerator.OID.1.2.840.113549.1.1", "RSA");
map.put("Alg.Alias.Signature.1.2.840.113549.1.1.2", "MD2withRSA");
map.put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.2", "MD2withRSA");
map.put("Alg.Alias.Signature.1.2.840.113549.1.1.4", "MD5withRSA");
map.put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.4", "MD5withRSA");
map.put("Alg.Alias.Signature.1.2.840.113549.1.1.5", "SHA1withRSA");
map.put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.5", "SHA1withRSA");
map.put("Alg.Alias.Signature.1.3.14.3.2.29", "SHA1withRSA");
map.put("Alg.Alias.Signature.1.2.840.113549.1.1.14", "SHA224withRSA");
map.put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.14", "SHA224withRSA");
map.put("Alg.Alias.Signature.1.2.840.113549.1.1.11", "SHA256withRSA");
map.put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.11", "SHA256withRSA");
map.put("Alg.Alias.Signature.1.2.840.113549.1.1.12", "SHA384withRSA");
map.put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.12", "SHA384withRSA");
map.put("Alg.Alias.Signature.1.2.840.113549.1.1.13", "SHA512withRSA");
map.put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.13", "SHA512withRSA");
map.put("Alg.Alias.Signature.1.2.840.113549.1.1.15", "SHA512/224withRSA");
map.put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.15", "SHA512/224withRSA");
map.put("Alg.Alias.Signature.1.2.840.113549.1.1.16", "SHA512/256withRSA");
map.put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.16", "SHA512/256withRSA");
map.put("Alg.Alias.KeyFactory.1.2.840.113549.1.1.10", "RSASSA-PSS");
map.put("Alg.Alias.KeyFactory.OID.1.2.840.113549.1.1.10", "RSASSA-PSS");
map.put("Alg.Alias.KeyPairGenerator.1.2.840.113549.1.1.10", "RSASSA-PSS");
map.put("Alg.Alias.KeyPairGenerator.OID.1.2.840.113549.1.1.10", "RSASSA-PSS");
map.put("Alg.Alias.Signature.1.2.840.113549.1.1.10", "RSASSA-PSS");
map.put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.10", "RSASSA-PSS");
map.put("Alg.Alias.AlgorithmParameters.1.2.840.113549.1.1.10", "RSASSA-PSS");
map.put("Alg.Alias.AlgorithmParameters.OID.1.2.840.113549.1.1.10", "RSASSA-PSS");
add(p, "KeyFactory", "RSASSA-PSS",
"sun.security.rsa.RSAKeyFactory$PSS",
rsapssAliases, null);
add(p, "KeyPairGenerator", "RSASSA-PSS",
"sun.security.rsa.RSAKeyPairGenerator$PSS",
rsapssAliases, null);
add(p, "Signature", "RSASSA-PSS",
"sun.security.rsa.RSAPSSSignature",
rsapssAliases, attrs);
add(p, "AlgorithmParameters", "RSASSA-PSS",
"sun.security.rsa.PSSParameters",
rsapssAliases, null);
}
public Iterator<Provider.Service> iterator() {
return services.iterator();
}
private LinkedHashSet<Provider.Service> services;
}

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

@ -26,7 +26,10 @@
package sun.security.ssl;
import java.security.*;
import java.util.*;
import sun.security.rsa.SunRsaSignEntries;
import static sun.security.util.SecurityConstants.PROVIDER_VER;
import static sun.security.provider.SunEntries.createAliases;
/**
* The JSSE provider.
@ -157,86 +160,62 @@ public abstract class SunJSSE extends java.security.Provider {
});
}
private void ps(String type, String algo, String cn,
List<String> aliases, HashMap<String, String> attrs) {
putService(new Provider.Service(this, type, algo, cn, aliases, attrs));
}
private void doRegister(boolean isfips) {
if (isfips == false) {
put("KeyFactory.RSA",
"sun.security.rsa.RSAKeyFactory$Legacy");
put("Alg.Alias.KeyFactory.1.2.840.113549.1.1", "RSA");
put("Alg.Alias.KeyFactory.OID.1.2.840.113549.1.1", "RSA");
put("KeyPairGenerator.RSA",
"sun.security.rsa.RSAKeyPairGenerator$Legacy");
put("Alg.Alias.KeyPairGenerator.1.2.840.113549.1.1", "RSA");
put("Alg.Alias.KeyPairGenerator.OID.1.2.840.113549.1.1", "RSA");
put("Signature.MD2withRSA",
"sun.security.rsa.RSASignature$MD2withRSA");
put("Alg.Alias.Signature.1.2.840.113549.1.1.2", "MD2withRSA");
put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.2",
"MD2withRSA");
put("Signature.MD5withRSA",
"sun.security.rsa.RSASignature$MD5withRSA");
put("Alg.Alias.Signature.1.2.840.113549.1.1.4", "MD5withRSA");
put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.4",
"MD5withRSA");
put("Signature.SHA1withRSA",
"sun.security.rsa.RSASignature$SHA1withRSA");
put("Alg.Alias.Signature.1.2.840.113549.1.1.5", "SHA1withRSA");
put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.5",
"SHA1withRSA");
put("Alg.Alias.Signature.1.3.14.3.2.29", "SHA1withRSA");
put("Alg.Alias.Signature.OID.1.3.14.3.2.29", "SHA1withRSA");
Iterator<Provider.Service> rsaIter =
new SunRsaSignEntries(this).iterator();
while (rsaIter.hasNext()) {
putService(rsaIter.next());
}
}
put("Signature.MD5andSHA1withRSA",
"sun.security.ssl.RSASignature");
ps("Signature", "MD5andSHA1withRSA",
"sun.security.ssl.RSASignature", null, null);
put("KeyManagerFactory.SunX509",
"sun.security.ssl.KeyManagerFactoryImpl$SunX509");
put("KeyManagerFactory.NewSunX509",
"sun.security.ssl.KeyManagerFactoryImpl$X509");
put("Alg.Alias.KeyManagerFactory.PKIX", "NewSunX509");
ps("KeyManagerFactory", "SunX509",
"sun.security.ssl.KeyManagerFactoryImpl$SunX509", null, null);
ps("KeyManagerFactory", "NewSunX509",
"sun.security.ssl.KeyManagerFactoryImpl$X509",
createAliases("PKIX"), null);
put("TrustManagerFactory.SunX509",
"sun.security.ssl.TrustManagerFactoryImpl$SimpleFactory");
put("TrustManagerFactory.PKIX",
"sun.security.ssl.TrustManagerFactoryImpl$PKIXFactory");
put("Alg.Alias.TrustManagerFactory.SunPKIX", "PKIX");
put("Alg.Alias.TrustManagerFactory.X509", "PKIX");
put("Alg.Alias.TrustManagerFactory.X.509", "PKIX");
ps("TrustManagerFactory", "SunX509",
"sun.security.ssl.TrustManagerFactoryImpl$SimpleFactory", null, null);
ps("TrustManagerFactory", "PKIX",
"sun.security.ssl.TrustManagerFactoryImpl$PKIXFactory",
createAliases("SunPKIX", "X509", "X.509"), null);
put("SSLContext.TLSv1",
"sun.security.ssl.SSLContextImpl$TLS10Context");
put("SSLContext.TLSv1.1",
"sun.security.ssl.SSLContextImpl$TLS11Context");
put("SSLContext.TLSv1.2",
"sun.security.ssl.SSLContextImpl$TLS12Context");
put("SSLContext.TLSv1.3",
"sun.security.ssl.SSLContextImpl$TLS13Context");
put("SSLContext.TLS",
"sun.security.ssl.SSLContextImpl$TLSContext");
if (isfips == false) {
put("Alg.Alias.SSLContext.SSL", "TLS");
put("Alg.Alias.SSLContext.SSLv3", "TLSv1");
}
ps("SSLContext", "TLSv1",
"sun.security.ssl.SSLContextImpl$TLS10Context",
(isfips? null : createAliases("SSLv3")), null);
ps("SSLContext", "TLSv1.1",
"sun.security.ssl.SSLContextImpl$TLS11Context", null, null);
ps("SSLContext", "TLSv1.2",
"sun.security.ssl.SSLContextImpl$TLS12Context", null, null);
ps("SSLContext", "TLSv1.3",
"sun.security.ssl.SSLContextImpl$TLS13Context", null, null);
ps("SSLContext", "TLS",
"sun.security.ssl.SSLContextImpl$TLSContext",
(isfips? null : createAliases("SSL")), null);
put("SSLContext.DTLSv1.0",
"sun.security.ssl.SSLContextImpl$DTLS10Context");
put("SSLContext.DTLSv1.2",
"sun.security.ssl.SSLContextImpl$DTLS12Context");
put("SSLContext.DTLS",
"sun.security.ssl.SSLContextImpl$DTLSContext");
ps("SSLContext", "DTLSv1.0",
"sun.security.ssl.SSLContextImpl$DTLS10Context", null, null);
ps("SSLContext", "DTLSv1.2",
"sun.security.ssl.SSLContextImpl$DTLS12Context", null, null);
ps("SSLContext", "DTLS",
"sun.security.ssl.SSLContextImpl$DTLSContext", null, null);
put("SSLContext.Default",
"sun.security.ssl.SSLContextImpl$DefaultSSLContext");
ps("SSLContext", "Default",
"sun.security.ssl.SSLContextImpl$DefaultSSLContext", null, null);
/*
* KeyStore
*/
put("KeyStore.PKCS12",
"sun.security.pkcs12.PKCS12KeyStore");
ps("KeyStore", "PKCS12",
"sun.security.pkcs12.PKCS12KeyStore", null, null);
}
// com.sun.net.ssl.internal.ssl.Provider has been deprecated since JDK 9

View file

@ -70,6 +70,7 @@ import java.security.cert.X509CRLSelector;
import javax.security.auth.x500.X500Principal;
import java.util.Base64;
import sun.security.pkcs12.PKCS12KeyStore;
import sun.security.util.ECKeySizeParameterSpec;
import sun.security.util.KeyUtil;
import sun.security.util.NamedCurve;
@ -79,6 +80,7 @@ import sun.security.pkcs10.PKCS10Attribute;
import sun.security.provider.X509Factory;
import sun.security.provider.certpath.ssl.SSLServerCertStore;
import sun.security.util.Password;
import sun.security.util.SecurityProperties;
import sun.security.util.SecurityProviderConstants;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
@ -188,6 +190,7 @@ public final class Main {
private static final Set<CryptoPrimitive> SIG_PRIMITIVE_SET = Collections
.unmodifiableSet(EnumSet.of(CryptoPrimitive.SIGNATURE));
private boolean isPasswordlessKeyStore = false;
enum Command {
CERTREQ("Generates.a.certificate.request",
@ -919,6 +922,9 @@ public final class Main {
storetype == null && !inplaceImport) {
keyStore = KeyStore.getInstance(ksfile, storePass);
storetype = keyStore.getType();
if (storetype.equalsIgnoreCase("pkcs12")) {
isPasswordlessKeyStore = PKCS12KeyStore.isPasswordless(ksfile);
}
} else {
if (storetype == null) {
storetype = KeyStore.getDefaultType();
@ -928,6 +934,15 @@ public final class Main {
} else {
keyStore = KeyStore.getInstance(storetype, providerName);
}
// When creating a new pkcs12 file, Do not prompt for storepass
// if certProtectionAlgorithm and macAlgorithm are both NONE.
if (storetype.equalsIgnoreCase("pkcs12")) {
isPasswordlessKeyStore =
"NONE".equals(SecurityProperties.privilegedGetOverridable(
"keystore.pkcs12.certProtectionAlgorithm"))
&& "NONE".equals(SecurityProperties.privilegedGetOverridable(
"keystore.pkcs12.macAlgorithm"));
}
/*
* Load the keystore data.
@ -979,11 +994,10 @@ public final class Main {
("Keystore.password.must.be.at.least.6.characters"));
}
} else if (storePass == null) {
// only prompt if (protectedPath == false)
if (!protectedPath && !KeyStoreUtil.isWindowsKeyStore(storetype) &&
(command == CERTREQ ||
if (!protectedPath && !KeyStoreUtil.isWindowsKeyStore(storetype)
&& isKeyStoreRelated(command)
&& !isPasswordlessKeyStore) {
if (command == CERTREQ ||
command == DELETE ||
command == GENKEYPAIR ||
command == GENSECKEY ||
@ -995,59 +1009,58 @@ public final class Main {
command == SELFCERT ||
command == STOREPASSWD ||
command == KEYPASSWD ||
command == IDENTITYDB)) {
int count = 0;
do {
if (command == IMPORTKEYSTORE) {
System.err.print
(rb.getString("Enter.destination.keystore.password."));
} else {
System.err.print
(rb.getString("Enter.keystore.password."));
}
System.err.flush();
storePass = Password.readPassword(System.in);
passwords.add(storePass);
command == IDENTITYDB) {
int count = 0;
do {
if (command == IMPORTKEYSTORE) {
System.err.print
(rb.getString("Enter.destination.keystore.password."));
} else {
System.err.print
(rb.getString("Enter.keystore.password."));
}
System.err.flush();
storePass = Password.readPassword(System.in);
passwords.add(storePass);
// If we are creating a new non nullStream-based keystore,
// insist that the password be at least 6 characters
if (!nullStream && (storePass == null || storePass.length < 6)) {
System.err.println(rb.getString
("Keystore.password.is.too.short.must.be.at.least.6.characters"));
storePass = null;
}
// If the keystore file does not exist and needs to be
// created, the storepass should be prompted twice.
if (storePass != null && !nullStream && ksStream == null) {
System.err.print(rb.getString("Re.enter.new.password."));
char[] storePassAgain = Password.readPassword(System.in);
passwords.add(storePassAgain);
if (!Arrays.equals(storePass, storePassAgain)) {
System.err.println
(rb.getString("They.don.t.match.Try.again"));
// If we are creating a new non nullStream-based keystore,
// insist that the password be at least 6 characters
if (!nullStream && (storePass == null || storePass.length < 6)) {
System.err.println(rb.getString
("Keystore.password.is.too.short.must.be.at.least.6.characters"));
storePass = null;
}
// If the keystore file does not exist and needs to be
// created, the storepass should be prompted twice.
if (storePass != null && !nullStream && ksStream == null) {
System.err.print(rb.getString("Re.enter.new.password."));
char[] storePassAgain = Password.readPassword(System.in);
passwords.add(storePassAgain);
if (!Arrays.equals(storePass, storePassAgain)) {
System.err.println
(rb.getString("They.don.t.match.Try.again"));
storePass = null;
}
}
count++;
} while ((storePass == null) && count < 3);
if (storePass == null) {
System.err.println
(rb.getString("Too.many.failures.try.later"));
return;
}
} else {
// here we have EXPORTCERT and LIST (info valid until STOREPASSWD)
if (command != PRINTCRL) {
System.err.print(rb.getString("Enter.keystore.password."));
System.err.flush();
storePass = Password.readPassword(System.in);
passwords.add(storePass);
}
count++;
} while ((storePass == null) && count < 3);
if (storePass == null) {
System.err.println
(rb.getString("Too.many.failures.try.later"));
return;
}
} else if (!protectedPath
&& !KeyStoreUtil.isWindowsKeyStore(storetype)
&& isKeyStoreRelated(command)) {
// here we have EXPORTCERT and LIST (info valid until STOREPASSWD)
if (command != PRINTCRL) {
System.err.print(rb.getString("Enter.keystore.password."));
System.err.flush();
storePass = Password.readPassword(System.in);
passwords.add(storePass);
}
}
@ -1233,7 +1246,8 @@ public final class Main {
kssave = true;
} else if (command == LIST) {
if (storePass == null
&& !KeyStoreUtil.isWindowsKeyStore(storetype)) {
&& !KeyStoreUtil.isWindowsKeyStore(storetype)
&& !isPasswordlessKeyStore) {
printNoIntegrityWarning();
}
@ -1602,7 +1616,8 @@ public final class Main {
throws Exception
{
if (storePass == null
&& !KeyStoreUtil.isWindowsKeyStore(storetype)) {
&& !KeyStoreUtil.isWindowsKeyStore(storetype)
&& !isPasswordlessKeyStore) {
printNoIntegrityWarning();
}
if (alias == null) {
@ -1633,7 +1648,7 @@ public final class Main {
* @param origPass the password to copy from if user press ENTER
*/
private char[] promptForKeyPass(String alias, String orig, char[] origPass) throws Exception{
if (P12KEYSTORE.equalsIgnoreCase(storetype)) {
if (origPass != null && P12KEYSTORE.equalsIgnoreCase(storetype)) {
return origPass;
} else if (!token && !protectedPath) {
// Prompt for key password
@ -1642,22 +1657,25 @@ public final class Main {
MessageFormat form = new MessageFormat(rb.getString
("Enter.key.password.for.alias."));
Object[] source = {alias};
System.err.println(form.format(source));
if (orig == null) {
System.err.print(rb.getString
(".RETURN.if.same.as.keystore.password."));
} else {
form = new MessageFormat(rb.getString
(".RETURN.if.same.as.for.otherAlias."));
Object[] src = {orig};
System.err.print(form.format(src));
System.err.print(form.format(source));
if (origPass != null) {
System.err.println();
if (orig == null) {
System.err.print(rb.getString
(".RETURN.if.same.as.keystore.password."));
} else {
form = new MessageFormat(rb.getString
(".RETURN.if.same.as.for.otherAlias."));
Object[] src = {orig};
System.err.print(form.format(src));
}
}
System.err.flush();
char[] entered = Password.readPassword(System.in);
passwords.add(entered);
if (entered == null) {
if (entered == null && origPass != null) {
return origPass;
} else if (entered.length >= 6) {
} else if (entered != null && entered.length >= 6) {
System.err.print(rb.getString("Re.enter.new.password."));
char[] passAgain = Password.readPassword(System.in);
passwords.add(passAgain);
@ -2066,6 +2084,9 @@ public final class Main {
getCertFingerPrint("SHA-256", chain[0]));
checkWeak(label, chain);
}
} else {
out.println(rb.getString
("Certificate.chain.length.") + 0);
}
} else if (keyStore.entryInstanceOf(alias,
KeyStore.TrustedCertificateEntry.class)) {
@ -2130,6 +2151,7 @@ public final class Main {
InputStream is = null;
File srcksfile = null;
boolean srcIsPasswordless = false;
if (P11KEYSTORE.equalsIgnoreCase(srcstoretype) ||
KeyStoreUtil.isWindowsKeyStore(srcstoretype)) {
@ -2151,6 +2173,9 @@ public final class Main {
srcstoretype == null) {
store = KeyStore.getInstance(srcksfile, srcstorePass);
srcstoretype = store.getType();
if (srcstoretype.equalsIgnoreCase("pkcs12")) {
srcIsPasswordless = PKCS12KeyStore.isPasswordless(srcksfile);
}
} else {
if (srcstoretype == null) {
srcstoretype = KeyStore.getDefaultType();
@ -2164,7 +2189,8 @@ public final class Main {
if (srcstorePass == null
&& !srcprotectedPath
&& !KeyStoreUtil.isWindowsKeyStore(srcstoretype)) {
&& !KeyStoreUtil.isWindowsKeyStore(srcstoretype)
&& !srcIsPasswordless) {
System.err.print(rb.getString("Enter.source.keystore.password."));
System.err.flush();
srcstorePass = Password.readPassword(System.in);
@ -2191,6 +2217,7 @@ public final class Main {
}
if (srcstorePass == null
&& !srcIsPasswordless
&& !KeyStoreUtil.isWindowsKeyStore(srcstoretype)) {
// anti refactoring, copied from printNoIntegrityWarning(),
// but change 2 lines
@ -3537,25 +3564,25 @@ public final class Main {
if (keyPass == null) {
// Try to recover the key using the keystore password
try {
key = keyStore.getKey(alias, storePass);
keyPass = storePass;
passwords.add(keyPass);
} catch (UnrecoverableKeyException e) {
// Did not work out, so prompt user for key password
if (!token) {
keyPass = getKeyPasswd(alias, null, null);
key = keyStore.getKey(alias, keyPass);
} else {
throw e;
if (storePass != null) {
try {
key = keyStore.getKey(alias, storePass);
passwords.add(storePass);
return Pair.of(key, storePass);
} catch (UnrecoverableKeyException e) {
if (token) {
throw e;
}
}
}
// prompt user for key password
keyPass = getKeyPasswd(alias, null, null);
key = keyStore.getKey(alias, keyPass);
return Pair.of(key, keyPass);
} else {
key = keyStore.getKey(alias, keyPass);
return Pair.of(key, keyPass);
}
return Pair.of(key, keyPass);
}
/**
@ -3570,68 +3597,59 @@ public final class Main {
char[] pstore,
char[] pkey) throws Exception {
if (ks.containsAlias(alias) == false) {
MessageFormat form = new MessageFormat
(rb.getString("Alias.alias.does.not.exist"));
if (!ks.containsAlias(alias)) {
MessageFormat form = new MessageFormat(
rb.getString("Alias.alias.does.not.exist"));
Object[] source = {alias};
throw new Exception(form.format(source));
}
PasswordProtection pp = null;
Entry entry;
// Step 1: First attempt to access entry without key password
// (PKCS11 entry or trusted certificate entry, for example).
// If fail, go next.
try {
// First attempt to access entry without key password
// (PKCS11 entry or trusted certificate entry, for example)
entry = ks.getEntry(alias, pp);
pkey = null;
Entry entry = ks.getEntry(alias, null);
return Pair.of(entry, null);
} catch (UnrecoverableEntryException une) {
if(P11KEYSTORE.equalsIgnoreCase(ks.getType()) ||
KeyStoreUtil.isWindowsKeyStore(ks.getType())) {
KeyStoreUtil.isWindowsKeyStore(ks.getType())) {
// should not happen, but a possibility
throw une;
}
}
// entry is protected
// entry is protected
if (pkey != null) {
// Step 2: try pkey if not null. If fail, fail.
if (pkey != null) {
PasswordProtection pp = new PasswordProtection(pkey);
Entry entry = ks.getEntry(alias, pp);
return Pair.of(entry, pkey);
}
// try provided key password
pp = new PasswordProtection(pkey);
entry = ks.getEntry(alias, pp);
} else {
// try store pass
try {
pp = new PasswordProtection(pstore);
entry = ks.getEntry(alias, pp);
pkey = pstore;
} catch (UnrecoverableEntryException une2) {
if (P12KEYSTORE.equalsIgnoreCase(ks.getType())) {
// P12 keystore currently does not support separate
// store and entry passwords
throw une2;
} else {
// prompt for entry password
pkey = getKeyPasswd(alias, null, null);
pp = new PasswordProtection(pkey);
entry = ks.getEntry(alias, pp);
}
// Step 3: try pstore if not null. If fail, go next.
if (pstore != null) {
try {
PasswordProtection pp = new PasswordProtection(pstore);
Entry entry = ks.getEntry(alias, pp);
return Pair.of(entry, pstore);
} catch (UnrecoverableEntryException une) {
if (P12KEYSTORE.equalsIgnoreCase(ks.getType())) {
// P12 keystore currently does not support separate
// store and entry passwords. We will not prompt for
// entry password.
throw une;
}
}
}
// Step 4: prompt for entry password
pkey = getKeyPasswd(alias, null, null);
PasswordProtection pp = new PasswordProtection(pkey);
Entry entry = ks.getEntry(alias, pp);
return Pair.of(entry, pkey);
}
/**
* Gets the requested finger print of the certificate.
*/

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

@ -1,5 +1,5 @@
/*
* Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2006, 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
@ -26,17 +26,11 @@
package sun.security.util;
import java.io.IOException;
import java.math.BigInteger;
import java.security.*;
import java.security.interfaces.*;
import java.security.spec.*;
import java.util.Arrays;
import sun.security.x509.X509Key;
public class ECUtil {
@ -227,5 +221,64 @@ public class ECUtil {
return nameSpec.getName();
}
// Convert the concatenation R and S in into their DER encoding
public static byte[] encodeSignature(byte[] signature) throws SignatureException {
try {
int n = signature.length >> 1;
byte[] bytes = new byte[n];
System.arraycopy(signature, 0, bytes, 0, n);
BigInteger r = new BigInteger(1, bytes);
System.arraycopy(signature, n, bytes, 0, n);
BigInteger s = new BigInteger(1, bytes);
DerOutputStream out = new DerOutputStream(signature.length + 10);
out.putInteger(r);
out.putInteger(s);
DerValue result =
new DerValue(DerValue.tag_Sequence, out.toByteArray());
return result.toByteArray();
} catch (Exception e) {
throw new SignatureException("Could not encode signature", e);
}
}
// Convert the DER encoding of R and S into a concatenation of R and S
public static byte[] decodeSignature(byte[] sig) throws SignatureException {
try {
// Enforce strict DER checking for signatures
DerInputStream in = new DerInputStream(sig, 0, sig.length, false);
DerValue[] values = in.getSequence(2);
// check number of components in the read sequence
// and trailing data
if ((values.length != 2) || (in.available() != 0)) {
throw new IOException("Invalid encoding for signature");
}
BigInteger r = values[0].getPositiveBigInteger();
BigInteger s = values[1].getPositiveBigInteger();
// trim leading zeroes
byte[] rBytes = trimZeroes(r.toByteArray());
byte[] sBytes = trimZeroes(s.toByteArray());
int k = Math.max(rBytes.length, sBytes.length);
// r and s each occupy half the array
byte[] result = new byte[k << 1];
System.arraycopy(rBytes, 0, result, k - rBytes.length,
rBytes.length);
System.arraycopy(sBytes, 0, result, result.length - sBytes.length,
sBytes.length);
return result;
} catch (Exception e) {
throw new SignatureException("Invalid encoding for signature", e);
}
}
private ECUtil() {}
}

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;

View file

@ -771,8 +771,14 @@ public class AlgorithmId implements Serializable, DerEncoder {
ObjectIdentifier.newInternal(new int[] {1, 2, 840, 113549, 1, 5, 10});
public static final ObjectIdentifier pbeWithSHA1AndRC2_oid =
ObjectIdentifier.newInternal(new int[] {1, 2, 840, 113549, 1, 5, 11});
public static ObjectIdentifier pbeWithSHA1AndRC4_128_oid =
ObjectIdentifier.newInternal(new int[] {1, 2, 840, 113549, 1, 12, 1, 1});
public static ObjectIdentifier pbeWithSHA1AndRC4_40_oid =
ObjectIdentifier.newInternal(new int[] {1, 2, 840, 113549, 1, 12, 1, 2});
public static ObjectIdentifier pbeWithSHA1AndDESede_oid =
ObjectIdentifier.newInternal(new int[] {1, 2, 840, 113549, 1, 12, 1, 3});
public static ObjectIdentifier pbeWithSHA1AndRC2_128_oid =
ObjectIdentifier.newInternal(new int[] {1, 2, 840, 113549, 1, 12, 1, 5});
public static ObjectIdentifier pbeWithSHA1AndRC2_40_oid =
ObjectIdentifier.newInternal(new int[] {1, 2, 840, 113549, 1, 12, 1, 6});
@ -961,7 +967,10 @@ public class AlgorithmId implements Serializable, DerEncoder {
nameTable.put(pbeWithMD5AndRC2_oid, "PBEWithMD5AndRC2");
nameTable.put(pbeWithSHA1AndDES_oid, "PBEWithSHA1AndDES");
nameTable.put(pbeWithSHA1AndRC2_oid, "PBEWithSHA1AndRC2");
nameTable.put(pbeWithSHA1AndRC4_128_oid, "PBEWithSHA1AndRC4_128");
nameTable.put(pbeWithSHA1AndRC4_40_oid, "PBEWithSHA1AndRC4_40");
nameTable.put(pbeWithSHA1AndDESede_oid, "PBEWithSHA1AndDESede");
nameTable.put(pbeWithSHA1AndRC2_128_oid, "PBEWithSHA1AndRC2_128");
nameTable.put(pbeWithSHA1AndRC2_40_oid, "PBEWithSHA1AndRC2_40");
}