java-topology/test/jdk/com/sun/security/ec/ECOperationsFuzzTest.java
russell@unturf.com 0a580b313d undefect. CWE-407 — 63 sites patched across 27 ecosystems
Authors: russell@unturf.com · brackishbert@gmail.com · foxhop.net · TimeHexOn.com

Patches, unit tests, benchmarks, whitepaper, and outreach briefs.
Public domain — no copyright claimed. Use freely.
2026-03-26 17:11:57 -04:00

171 lines
No EOL
6.9 KiB
Java

/*
* Copyright (c) 2024, Intel Corporation. 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.
*/
import java.util.Random;
import java.math.BigInteger;
import java.lang.reflect.Field;
import java.security.spec.ECParameterSpec;
import sun.security.ec.ECOperations;
import sun.security.util.ECUtil;
import sun.security.util.NamedCurve;
import sun.security.util.CurveDB;
import sun.security.ec.point.*;
import java.security.spec.ECPoint;
import sun.security.util.KnownOIDs;
import sun.security.util.math.IntegerMontgomeryFieldModuloP;
import sun.security.util.math.intpoly.*;
/*
* @test
* @key randomness
* @modules java.base/sun.security.ec java.base/sun.security.ec.point
* java.base/sun.security.util java.base/sun.security.util.math
* java.base/sun.security.util.math.intpoly
* @run main/othervm/timeout=1200 --add-opens
* java.base/sun.security.ec=ALL-UNNAMED -XX:+UnlockDiagnosticVMOptions
* -XX:-UseIntPolyIntrinsics ECOperationsFuzzTest
* @summary Unit test ECOperationsFuzzTest.
*/
/*
* @test
* @key randomness
* @modules java.base/sun.security.ec java.base/sun.security.ec.point
* java.base/sun.security.util java.base/sun.security.util.math
* java.base/sun.security.util.math.intpoly
* @run main/othervm/timeout=1200 --add-opens
* java.base/sun.security.ec=ALL-UNNAMED -XX:+UnlockDiagnosticVMOptions
* -XX:+UseIntPolyIntrinsics ECOperationsFuzzTest
* @summary Unit test ECOperationsFuzzTest.
*/
// This test case is NOT entirely deterministic, it uses a random seed for
// pseudo-random number generator. If a failure occurs, hardcode the seed to
// make the test case deterministic
public class ECOperationsFuzzTest {
public static void main(String[] args) throws Exception {
// Note: it might be useful to increase this number during development
final int repeat = 10000;
test(repeat);
System.out.println("Fuzz Success");
}
private static void check(MutablePoint reference, MutablePoint testValue,
long seed, int iter) {
AffinePoint affineRef = reference.asAffine();
AffinePoint affine = testValue.asAffine();
if (!affineRef.equals(affine)) {
throw new RuntimeException(
"Found error with seed " + seed + "at iteration " + iter);
}
}
public static void test(int repeat) throws Exception {
Random rnd = new Random();
long seed = rnd.nextLong();
rnd.setSeed(seed);
int keySize = 256;
ECParameterSpec params = ECUtil.getECParameterSpec(keySize);
NamedCurve curve = CurveDB.lookup(KnownOIDs.secp256r1.value());
ECPoint generator = curve.getGenerator();
BigInteger b = curve.getCurve().getB();
if (params == null || generator == null) {
throw new RuntimeException(
"No EC parameters available for key size " + keySize + " bits");
}
ECOperations ops = ECOperations.forParameters(params).get();
ECOperations opsReference = new ECOperations(
IntegerPolynomialP256.ONE.getElement(b), P256OrderField.ONE);
boolean instanceTest1 = ops
.getField() instanceof IntegerMontgomeryFieldModuloP;
boolean instanceTest2 = opsReference
.getField() instanceof IntegerMontgomeryFieldModuloP;
if (instanceTest1 == false || instanceTest2 == true) {
throw new RuntimeException("Bad Initialization: ["
+ instanceTest1 + "," + instanceTest2 + "]");
}
byte[] multiple = new byte[keySize / 8];
rnd.nextBytes(multiple);
multiple[keySize/8 - 1] &= 0x7f; // from opsReference.seedToScalar(multiple);
MutablePoint referencePoint = opsReference.multiply(generator, multiple);
MutablePoint point = ops.multiply(generator, multiple);
check(referencePoint, point, seed, -1);
AffinePoint refAffineGenerator = AffinePoint.fromECPoint(generator,
referencePoint.getField());
AffinePoint montAffineGenerator = AffinePoint.fromECPoint(generator,
point.getField());
MutablePoint refProjGenerator = new ProjectivePoint.Mutable(
refAffineGenerator.getX(false).mutable(),
refAffineGenerator.getY(false).mutable(),
referencePoint.getField().get1().mutable());
MutablePoint projGenerator = new ProjectivePoint.Mutable(
montAffineGenerator.getX(false).mutable(),
montAffineGenerator.getY(false).mutable(),
point.getField().get1().mutable());
for (int i = 0; i < repeat; i++) {
rnd.nextBytes(multiple);
multiple[keySize/8 - 1] &= 0x7f; // opsReference.seedToScalar(multiple);
MutablePoint nextReferencePoint = opsReference
.multiply(referencePoint.asAffine(), multiple);
MutablePoint nextPoint = ops.multiply(point.asAffine().toECPoint(),
multiple);
check(nextReferencePoint, nextPoint, seed, i);
if (rnd.nextBoolean()) {
opsReference.setSum(nextReferencePoint, referencePoint);
ops.setSum(nextPoint, point);
check(nextReferencePoint, nextPoint, seed, i);
}
if (rnd.nextBoolean()) {
opsReference.setSum(nextReferencePoint, refProjGenerator);
ops.setSum(nextPoint, projGenerator);
check(nextReferencePoint, nextPoint, seed, i);
}
if (rnd.nextInt(100) < 10) { // 10% Reset point to generator, test
// generator multiplier
referencePoint = opsReference.multiply(generator, multiple);
point = ops.multiply(generator, multiple);
check(referencePoint, point, seed, i);
} else {
referencePoint = nextReferencePoint;
point = nextPoint;
}
}
}
}
// make test TEST="test/jdk/com/sun/security/ec/ECOperationsFuzzTest.java"