Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

8329538: Accelerate P256 on x86_64 using Montgomery intrinsic #18583

Closed
wants to merge 17 commits into from
Closed
2 changes: 1 addition & 1 deletion make/jdk/src/classes/build/tools/intpoly/FieldGen.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2024, 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
2 changes: 1 addition & 1 deletion make/test/BuildMicrobenchmark.gmk
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#
# Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2018, 2024, 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
42 changes: 21 additions & 21 deletions src/hotspot/cpu/x86/stubGenerator_x86_64_poly_mont.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2022, Intel Corporation. All rights reserved.
* Copyright (c) 2024, Intel Corporation. All rights reserved.
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -30,50 +30,50 @@
#define __ _masm->

ATTRIBUTE_ALIGNED(64) uint64_t MODULUS_P256[] = {
0x000fffffffffffff, 0x00000fffffffffff,
0x0000000000000000, 0x0000001000000000,
0x0000ffffffff0000, 0x0000000000000000,
0x0000000000000000, 0x0000000000000000
0x000fffffffffffffULL, 0x00000fffffffffffULL,
0x0000000000000000ULL, 0x0000001000000000ULL,
0x0000ffffffff0000ULL, 0x0000000000000000ULL,
0x0000000000000000ULL, 0x0000000000000000ULL
};
static address modulus_p256() {
return (address)MODULUS_P256;
}

ATTRIBUTE_ALIGNED(64) uint64_t P256_MASK52[] = {
0x000fffffffffffff, 0x000fffffffffffff,
0x000fffffffffffff, 0x000fffffffffffff,
0xffffffffffffffff, 0xffffffffffffffff,
0xffffffffffffffff, 0xffffffffffffffff,
0x000fffffffffffffULL, 0x000fffffffffffffULL,
0x000fffffffffffffULL, 0x000fffffffffffffULL,
0xffffffffffffffffULL, 0xffffffffffffffffULL,
0xffffffffffffffffULL, 0xffffffffffffffffULL,
};
static address p256_mask52() {
return (address)P256_MASK52;
}

ATTRIBUTE_ALIGNED(64) uint64_t BROADCAST5[] = {
0x0000000000000004, 0x0000000000000004,
0x0000000000000004, 0x0000000000000004,
0x0000000000000004, 0x0000000000000004,
0x0000000000000004, 0x0000000000000004,
0x0000000000000004ULL, 0x0000000000000004ULL,
0x0000000000000004ULL, 0x0000000000000004ULL,
0x0000000000000004ULL, 0x0000000000000004ULL,
0x0000000000000004ULL, 0x0000000000000004ULL,
};
static address broadcast_5() {
return (address)BROADCAST5;
}

ATTRIBUTE_ALIGNED(64) uint64_t SHIFT1R[] = {
0x0000000000000001, 0x0000000000000002,
0x0000000000000003, 0x0000000000000004,
0x0000000000000005, 0x0000000000000006,
0x0000000000000007, 0x0000000000000000,
0x0000000000000001ULL, 0x0000000000000002ULL,
0x0000000000000003ULL, 0x0000000000000004ULL,
0x0000000000000005ULL, 0x0000000000000006ULL,
0x0000000000000007ULL, 0x0000000000000000ULL,
};
static address shift_1R() {
return (address)SHIFT1R;
}

ATTRIBUTE_ALIGNED(64) uint64_t SHIFT1L[] = {
0x0000000000000007, 0x0000000000000000,
0x0000000000000001, 0x0000000000000002,
0x0000000000000003, 0x0000000000000004,
0x0000000000000005, 0x0000000000000006,
0x0000000000000007ULL, 0x0000000000000000ULL,
0x0000000000000001ULL, 0x0000000000000002ULL,
0x0000000000000003ULL, 0x0000000000000004ULL,
0x0000000000000005ULL, 0x0000000000000006ULL,
};
static address shift_1L() {
return (address)SHIFT1L;
2 changes: 1 addition & 1 deletion src/hotspot/share/classfile/vmIntrinsics.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 2024, 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
2 changes: 1 addition & 1 deletion src/hotspot/share/opto/library_call.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 2024, 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
2 changes: 1 addition & 1 deletion src/hotspot/share/opto/runtime.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2024, 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
2 changes: 1 addition & 1 deletion src/hotspot/share/runtime/stubRoutines.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2024, 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
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2024, 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
42 changes: 8 additions & 34 deletions src/java.base/share/classes/sun/security/ec/ECOperations.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2024, 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
@@ -59,7 +59,7 @@ static class IntermediateValueException extends Exception {
}

static final Map<BigInteger, IntegerFieldModuloP> fields = Map.of(
IntegerPolynomialP256.MODULUS, IntegerPolynomialP256.ONE,
IntegerPolynomialP256.MODULUS, MontgomeryIntegerPolynomialP256.ONE,
IntegerPolynomialP384.MODULUS, IntegerPolynomialP384.ONE,
IntegerPolynomialP521.MODULUS, IntegerPolynomialP521.ONE
);
@@ -70,14 +70,6 @@ static class IntermediateValueException extends Exception {
P521OrderField.MODULUS, P521OrderField.ONE
);

// This field is optional.
// It is set, when the operations are also available in Montgomery domain.
private ECOperations montgomeryOps;

static final Map<BigInteger, IntegerMontgomeryFieldModuloP> montgomeryFields = Map.of(
IntegerPolynomialP256.MODULUS, MontgomeryIntegerPolynomialP256.ONE
);

public static Optional<ECOperations> forParameters(ECParameterSpec params) {

EllipticCurve curve = params.getCurve();
@@ -99,14 +91,8 @@ public static Optional<ECOperations> forParameters(ECParameterSpec params) {
return Optional.empty();
}

ECOperations montOps = null;
IntegerMontgomeryFieldModuloP montField = montgomeryFields.get(primeField.getP());
if (montField != null) {
montOps = new ECOperations(montField.getElement(curve.getB()), orderField);
}

ImmutableIntegerModuloP b = field.getElement(curve.getB());
ECOperations ecOps = new ECOperations(b, orderField, montOps);
ECOperations ecOps = new ECOperations(b, orderField);
return Optional.of(ecOps);
}

@@ -119,11 +105,6 @@ public static Optional<ECOperations> forParameters(ECParameterSpec params) {
private final IntegerFieldModuloP orderField;

public ECOperations(IntegerModuloP b, IntegerFieldModuloP orderField) {
this(b, orderField, null);
}

private ECOperations(IntegerModuloP b, IntegerFieldModuloP orderField, ECOperations montgomeryOps) {
this.montgomeryOps = montgomeryOps;
this.b = b.fixed();
this.orderField = orderField;

@@ -225,14 +206,14 @@ public MutablePoint multiply(AffinePoint affineP, byte[] s) {

ECPoint ecPoint = affineP.toECPoint();
PointMultiplier multiplier = null;
if (montgomeryOps == null) {
if (!(b.getField() instanceof IntegerMontgomeryFieldModuloP)) {
multiplier = new DefaultMultiplier(this, affineP);
} else if (ecPoint.equals(Secp256R1GeneratorMontgomeryMultiplier.generator)) {
// Lazy class loading upon function call (large static constant table)
multiplier = Secp256R1GeneratorMontgomeryMultiplier.multiplier;
} else {
// affineP is in residue domain, use ecPoint to get domain conversion
multiplier = new DefaultMontgomeryMultiplier(montgomeryOps, ecPoint);
multiplier = new DefaultMontgomeryMultiplier(this, ecPoint);
}

return multiplier.pointMultiply(s);
@@ -242,13 +223,13 @@ public MutablePoint multiply(ECPoint ecPoint, byte[] s) {
// Route to Basepoint and/or Montgomery pointMultiply as appropriate

PointMultiplier multiplier = null;
if (montgomeryOps == null) {
if (!(b.getField() instanceof IntegerMontgomeryFieldModuloP)) {
multiplier = new DefaultMultiplier(this, ecPoint);
} else if (ecPoint.equals(Secp256R1GeneratorMontgomeryMultiplier.generator)) {
// Lazy class loading upon function call (large static constant table)
multiplier = Secp256R1GeneratorMontgomeryMultiplier.multiplier;
} else {
multiplier = new DefaultMontgomeryMultiplier(montgomeryOps, ecPoint);
multiplier = new DefaultMontgomeryMultiplier(this, ecPoint);
}

return multiplier.pointMultiply(s);
@@ -315,14 +296,7 @@ public void setSum(MutablePoint p, MutablePoint p2) {
MutableIntegerModuloP t3 = zero.mutable();
MutableIntegerModuloP t4 = zero.mutable();

// Route to Montgomery setSum, if field implemented
ECOperations ops = this;
if (this.montgomeryOps != null) {
assert p.getField() instanceof IntegerMontgomeryFieldModuloP;
assert p2.getField() instanceof IntegerMontgomeryFieldModuloP;
ops = this.montgomeryOps;
}
ops.setSum((ProjectivePoint.Mutable) p, (ProjectivePoint.Mutable) p2, t0, t1, t2, t3, t4);
setSum((ProjectivePoint.Mutable) p, (ProjectivePoint.Mutable) p2, t0, t1, t2, t3, t4);
}

/*
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2024, 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
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2024, 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
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2024, 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
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2024, 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
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 2024, 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
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2024, 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
19 changes: 8 additions & 11 deletions test/jdk/com/sun/security/ec/ECOperationsFuzzTest.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2023, Intel Corporation. All rights reserved.
* Copyright (c) 2024, Intel Corporation. All rights reserved.
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -34,6 +34,7 @@
import java.security.spec.ECPoint;
import sun.security.util.KnownOIDs;
import sun.security.util.math.IntegerMontgomeryFieldModuloP;
import sun.security.util.math.intpoly.*;

/*
* @test
@@ -79,22 +80,18 @@ public static void test(int repeat) throws Exception {
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 = ECOperations.forParameters(params).get();
ECOperations opsReference = new ECOperations(IntegerPolynomialP256.ONE.getElement(b), P256OrderField.ONE);

try {
Field montgomeryOps = ECOperations.class.getDeclaredField("montgomeryOps");
montgomeryOps.setAccessible(true);
if (montgomeryOps.get(ops) == null) {
throw new RuntimeException("Expected to find montgomery field for P256");
}
montgomeryOps.set(opsReference, null); // Disable Montgomery field operations
} catch (NoSuchFieldException | IllegalAccessException ex) {
throw new RuntimeException(ex);
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];
19 changes: 8 additions & 11 deletions test/jdk/com/sun/security/ec/ECOperationsKATTest.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2023, Intel Corporation. All rights reserved.
* Copyright (c) 2024, Intel Corporation. All rights reserved.
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -36,6 +36,7 @@
import java.security.spec.ECPoint;
import sun.security.util.KnownOIDs;
import sun.security.util.math.IntegerMontgomeryFieldModuloP;
import sun.security.util.math.intpoly.*;

/*
* @test
@@ -161,22 +162,18 @@ private static boolean runSingleTest(TestData testData) {
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 = ECOperations.forParameters(params).get();
ECOperations opsReference = new ECOperations(IntegerPolynomialP256.ONE.getElement(b), P256OrderField.ONE);

try {
Field montgomeryOps = ECOperations.class.getDeclaredField("montgomeryOps");
montgomeryOps.setAccessible(true);
if (montgomeryOps.get(ops) == null) {
throw new RuntimeException("Expected to find montgomery field for P256");
}
montgomeryOps.set(opsReference, null); // Disable Montgomery field operations
} catch (NoSuchFieldException | IllegalAccessException ex) {
throw new RuntimeException(ex);
boolean instanceTest1 = ops.getField() instanceof IntegerMontgomeryFieldModuloP;
boolean instanceTest2 = opsReference.getField() instanceof IntegerMontgomeryFieldModuloP;
if (instanceTest1 == false || instanceTest2 == true) {
throw new RuntimeException("Bad Initialization: ["+instanceTest1+","+instanceTest2+"]");
}

MutablePoint nextPoint = ops.multiply(generator, testData.multiplier);
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2022, Intel Corporation. All rights reserved.
* Copyright (c) 2024, Intel Corporation. All rights reserved.
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2022, Intel Corporation. All rights reserved.
* Copyright (c) 2024, Intel Corporation. All rights reserved.
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2024, 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