8295010: Reduce if required in EC limbs operations

Reviewed-by: djelinski, jjiang
This commit is contained in:
Xue-Lei Andrew Fan 2022-11-29 17:39:40 +00:00
parent 54e6d6aaeb
commit b778cd52b3
8 changed files with 107 additions and 57 deletions

View file

@ -150,13 +150,5 @@ public interface MutableIntegerModuloP extends IntegerModuloP {
* @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

@ -35,9 +35,7 @@ import java.util.Arrays;
/**
* A large number polynomial representation using sparse limbs of signed
* long (64-bit) values. Limb values will always fit within a long, so inputs
* to multiplication must be less than 32 bits. All IntegerPolynomial
* implementations allow at most one addition before multiplication. Additions
* after that will result in an ArithmeticException.
* to multiplication must be less than 32 bits.
*
* The following element operations are branch-free for all subclasses:
*
@ -553,16 +551,22 @@ public abstract sealed class IntegerPolynomial implements IntegerFieldModuloP
return new MutableElement(limbs.clone(), numAdds);
}
protected boolean isSummand() {
return numAdds < maxAdds;
}
@Override
public ImmutableElement add(IntegerModuloP genB) {
assert IntegerPolynomial.this == genB.getField();
Element b = (Element) genB;
if (!(isSummand() && b.isSummand())) {
throw new ArithmeticException("Not a valid summand");
Element b = (Element)genB;
// Reduce if required.
// if (numAdds >= maxAdds) {
if (numAdds > 32 - bitsPerLimb) {
reduce(limbs);
numAdds = 0;
}
// if (b.numAdds >= maxAdds) {
if (b.numAdds > 32 - bitsPerLimb) {
reduce(b.limbs);
b.numAdds = 0;
}
long[] newLimbs = new long[limbs.length];
@ -597,7 +601,18 @@ public abstract sealed class IntegerPolynomial implements IntegerFieldModuloP
@Override
public ImmutableElement multiply(IntegerModuloP genB) {
assert IntegerPolynomial.this == genB.getField();
Element b = (Element) genB;
Element b = (Element)genB;
// Reduce if required.
if (numAdds > maxAdds) {
reduce(limbs);
numAdds = 0;
}
if (b.numAdds > maxAdds) {
reduce(b.limbs);
b.numAdds = 0;
}
long[] newLimbs = new long[limbs.length];
mult(limbs, b.limbs, newLimbs);
@ -606,6 +621,12 @@ public abstract sealed class IntegerPolynomial implements IntegerFieldModuloP
@Override
public ImmutableElement square() {
// Reduce if required.
if (numAdds > maxAdds) {
reduce(limbs);
numAdds = 0;
}
long[] newLimbs = new long[limbs.length];
IntegerPolynomial.this.square(limbs, newLimbs);
return new ImmutableElement(newLimbs, 0);
@ -613,17 +634,29 @@ public abstract sealed class IntegerPolynomial implements IntegerFieldModuloP
public void addModPowerTwo(IntegerModuloP arg, byte[] result) {
assert IntegerPolynomial.this == arg.getField();
Element other = (Element) arg;
if (!(isSummand() && other.isSummand())) {
throw new ArithmeticException("Not a valid summand");
Element other = (Element)arg;
// Reduce if required.
if (numAdds > 32 - bitsPerLimb) {
reduce(limbs);
numAdds = 0;
}
if (other.numAdds > 32 - bitsPerLimb) {
reduce(other.limbs);
other.numAdds = 0;
}
addLimbsModPowerTwo(limbs, other.limbs, result);
}
public void asByteArray(byte[] result) {
if (!isSummand()) {
throw new ArithmeticException("Not a valid summand");
// Reduce if required.
if (numAdds != 0) {
reduce(limbs);
numAdds = 0;
}
limbsToByteArray(limbs, result);
}
@ -698,7 +731,19 @@ public abstract sealed class IntegerPolynomial implements IntegerFieldModuloP
@Override
public MutableElement setProduct(IntegerModuloP genB) {
assert IntegerPolynomial.this == genB.getField();
Element b = (Element) genB;
Element b = (Element)genB;
// Reduce if required.
if (numAdds > maxAdds) {
reduce(limbs);
numAdds = 0;
}
if (b.numAdds > maxAdds) {
reduce(b.limbs);
b.numAdds = 0;
}
mult(limbs, b.limbs, limbs);
numAdds = 0;
return this;
@ -706,7 +751,13 @@ public abstract sealed class IntegerPolynomial implements IntegerFieldModuloP
@Override
public MutableElement setProduct(SmallValue v) {
int value = ((Limb) v).value;
// Reduce if required.
if (numAdds > maxAdds) {
reduce(limbs);
numAdds = 0;
}
int value = ((Limb)v).value;
multByInt(limbs, value);
numAdds = 0;
return this;
@ -715,9 +766,19 @@ public abstract sealed class IntegerPolynomial implements IntegerFieldModuloP
@Override
public MutableElement setSum(IntegerModuloP genB) {
assert IntegerPolynomial.this == genB.getField();
Element b = (Element) genB;
if (!(isSummand() && b.isSummand())) {
throw new ArithmeticException("Not a valid summand");
Element b = (Element)genB;
// Reduce if required.
// if (numAdds >= maxAdds) {
if (numAdds > 32 - bitsPerLimb) {
reduce(limbs);
numAdds = 0;
}
// if (b.numAdds >= maxAdds) {
if (b.numAdds > 32 - bitsPerLimb) {
reduce(b.limbs);
b.numAdds = 0;
}
for (int i = 0; i < limbs.length; i++) {
@ -731,9 +792,19 @@ public abstract sealed class IntegerPolynomial implements IntegerFieldModuloP
@Override
public MutableElement setDifference(IntegerModuloP genB) {
assert IntegerPolynomial.this == genB.getField();
Element b = (Element) genB;
if (!(isSummand() && b.isSummand())) {
throw new ArithmeticException("Not a valid summand");
Element b = (Element)genB;
// Reduce if required.
// if (numAdds >= maxAdds) {
if (numAdds > 32 - bitsPerLimb) {
reduce(limbs);
numAdds = 0;
}
// if (b.numAdds >= maxAdds) {
if (b.numAdds > 32 - bitsPerLimb) {
reduce(b.limbs);
b.numAdds = 0;
}
for (int i = 0; i < limbs.length; i++) {
@ -746,6 +817,12 @@ public abstract sealed class IntegerPolynomial implements IntegerFieldModuloP
@Override
public MutableElement setSquare() {
// Reduce if required.
if (numAdds > maxAdds) {
reduce(limbs);
numAdds = 0;
}
IntegerPolynomial.this.square(limbs, limbs);
numAdds = 0;
return this;
@ -758,13 +835,6 @@ public abstract sealed class IntegerPolynomial implements IntegerFieldModuloP
}
return this;
}
@Override
public MutableElement setReduced() {
reduce(limbs);
numAdds = 0;
return this;
}
}
class ImmutableElement extends Element implements ImmutableIntegerModuloP {
@ -795,6 +865,5 @@ public abstract sealed class IntegerPolynomial implements IntegerFieldModuloP
this.value = value;
}
}
}