package sun.security.ec.ed;
import sun.security.ec.point.*;
import sun.security.util.math.*;
import java.math.BigInteger;
import java.util.function.Function;
public class Ed448Operations extends EdECOperations {
private final SmallValue two;
private final ImmutableIntegerModuloP d;
private final ProjectivePoint.Immutable basePoint;
private static final BigInteger TWO = BigInteger.valueOf(2);
private static final BigInteger THREE = BigInteger.valueOf(3);
private static final BigInteger FIVE = BigInteger.valueOf(5);
private final BigInteger sizeMinus3;
public Ed448Operations(ImmutableIntegerModuloP d, BigInteger baseX,
BigInteger baseY) {
this.two = d.getField().getSmallValue(2);
this.d = d;
this.basePoint = of(new AffinePoint(
d.getField().getElement(baseX),
d.getField().getElement(baseY)
));
this.sizeMinus3 = d.getField().getSize().subtract(THREE);
}
@Override
public Point basePointMultiply(byte[] scalar) {
return setProduct(basePoint.mutable(), scalar);
}
@Override
protected ProjectivePoint.Immutable getNeutral() {
IntegerFieldModuloP field = d.getField();
return new ProjectivePoint.Immutable(field.get0(), field.get1(),
field.get1());
}
@Override
protected MutablePoint setSum(MutablePoint p1, MutablePoint p2,
MutableIntegerModuloP t1,
MutableIntegerModuloP t2,
MutableIntegerModuloP t3) {
ProjectivePoint.Mutable ehp1 = (ProjectivePoint.Mutable) p1;
ProjectivePoint.Mutable ehp2 = (ProjectivePoint.Mutable) p2;
return setSum(ehp1, ehp2, t1, t2, t3);
}
@Override
protected MutablePoint setDouble(MutablePoint p, MutableIntegerModuloP t1,
MutableIntegerModuloP t2) {
ProjectivePoint.Mutable ehp = (ProjectivePoint.Mutable) p;
return setDouble(ehp, t1, t2);
}
@Override
public ProjectivePoint.Immutable of(AffinePoint p) {
return new ProjectivePoint.Immutable(p.getX(), p.getY(),
p.getX().getField().get1());
}
@Override
public <T extends Throwable>
AffinePoint decodeAffinePoint(Function<String, T> exception, int xLSB,
IntegerModuloP y) throws T {
ImmutableIntegerModuloP y2 = y.square();
ImmutableIntegerModuloP u = y2.subtract(d.getField().get1());
MutableIntegerModuloP v = d.mutable().setProduct(y2)
.setDifference(d.getField().get1());
IntegerModuloP u5v3pow = u.pow(FIVE).multiply(v.pow(THREE))
.pow(sizeMinus3.shiftRight(2));
MutableIntegerModuloP x = v.mutable().setProduct(u.pow(THREE))
.setProduct(u5v3pow);
v.setProduct(x).setProduct(x);
if (v.asBigInteger().equals(u.asBigInteger())) {
} else {
throw exception.apply("Invalid point");
}
if (x.asBigInteger().equals(BigInteger.ZERO) && xLSB == 1) {
throw exception.apply("Invalid point");
}
if (xLSB != x.asBigInteger().mod(TWO).intValue()) {
x.setAdditiveInverse();
}
return new AffinePoint(x.fixed(), y.fixed());
}
ProjectivePoint.Mutable setSum(
ProjectivePoint.Mutable p1,
ProjectivePoint.Mutable p2,
MutableIntegerModuloP t1,
MutableIntegerModuloP t2,
MutableIntegerModuloP t3) {
t1.setValue(p1.getX()).setProduct(p2.getX());
t2.setValue(p2.getX()).setSum(p2.getY());
p1.getX().setSum(p1.getY()).setProduct(t2);
p1.getZ().setProduct(p2.getZ());
p1.getY().setProduct(p2.getY());
t3.setValue(d).setProduct(t1).setProduct(p1.getY());
p1.getX().setDifference(t1).setReduced().setDifference(p1.getY());
p1.getY().setDifference(t1);
t1.setValue(p1.getZ()).setSquare();
t2.setValue(t1).setDifference(t3);
t1.setSum(t3);
p1.getX().setProduct(t2).setProduct(p1.getZ());
p1.getY().setProduct(t1).setProduct(p1.getZ());
p1.getZ().setValue(t2.multiply(t1));
return p1;
}
protected ProjectivePoint.Mutable setDouble(ProjectivePoint.Mutable p,
MutableIntegerModuloP t1,
MutableIntegerModuloP t2) {
t2.setValue(p.getX()).setSquare();
p.getX().setSum(p.getY()).setSquare();
p.getY().setSquare();
p.getZ().setSquare();
t1.setValue(t2).setSum(p.getY()).setReduced();
t2.setDifference(p.getY());
p.getY().setValue(t1).setProduct(t2);
p.getZ().setProduct(two);
p.getZ().setAdditiveInverse().setSum(t1);
p.getX().setDifference(t1).setProduct(p.getZ());
p.getZ().setProduct(t1);
return p;
}
}