8295010: Reduce if required in EC limbs operations
Reviewed-by: djelinski, jjiang
This commit is contained in:
parent
54e6d6aaeb
commit
b778cd52b3
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@ -293,7 +293,6 @@ public class ECOperations {
|
||||
t1.setValue(p.getY()).setProduct(p2.getY());
|
||||
t3.setValue(p2.getX()).setSum(p2.getY());
|
||||
t4.setValue(p.getX()).setSum(p.getY());
|
||||
p.getX().setReduced();
|
||||
t3.setProduct(t4);
|
||||
t4.setValue(t0).setSum(t1);
|
||||
|
||||
@ -366,7 +365,6 @@ public class ECOperations {
|
||||
p.getX().setProduct(p.getY());
|
||||
p.getY().setValue(t0).setSum(t2);
|
||||
p.getY().setAdditiveInverse().setSum(p.getX());
|
||||
p.getY().setReduced();
|
||||
|
||||
p.getZ().setValue(t2).setProduct(b);
|
||||
p.getX().setValue(p.getY()).setDifference(p.getZ());
|
||||
|
@ -191,14 +191,14 @@ public class Ed25519Operations extends EdECOperations {
|
||||
// x = A = x^2
|
||||
p.getY().setSquare();
|
||||
// y = B = y^2
|
||||
t2.setValue(p.getX()).setSum(p.getY()).setReduced();
|
||||
t2.setValue(p.getX()).setSum(p.getY());
|
||||
// t2 holds H
|
||||
p.getZ().setSquare().setProduct(two);
|
||||
// z holds C
|
||||
|
||||
p.getT().setValue(t2).setDifference(t1);
|
||||
// t holds E
|
||||
t1.setValue(p.getX()).setDifference(p.getY()).setReduced();
|
||||
t1.setValue(p.getX()).setDifference(p.getY());
|
||||
// t1 holds G
|
||||
|
||||
p.getZ().setSum(t1);
|
||||
|
@ -154,7 +154,7 @@ public class Ed448Operations extends EdECOperations {
|
||||
t3.setValue(d).setProduct(t1).setProduct(p1.getY());
|
||||
// t3 holds E
|
||||
// do part of the final calculation of x and y to free up t1
|
||||
p1.getX().setDifference(t1).setReduced().setDifference(p1.getY());
|
||||
p1.getX().setDifference(t1).setDifference(p1.getY());
|
||||
p1.getY().setDifference(t1);
|
||||
t1.setValue(p1.getZ()).setSquare();
|
||||
// t2 holds B
|
||||
@ -185,7 +185,7 @@ public class Ed448Operations extends EdECOperations {
|
||||
p.getZ().setSquare();
|
||||
// z holds H
|
||||
|
||||
t1.setValue(t2).setSum(p.getY()).setReduced();
|
||||
t1.setValue(t2).setSum(p.getY());
|
||||
// t1 holds E
|
||||
t2.setDifference(p.getY());
|
||||
p.getY().setValue(t1).setProduct(t2);
|
||||
|
@ -116,8 +116,6 @@ public class EdDSAOperations {
|
||||
IntegerModuloP rElem = subField.getElement(r);
|
||||
MutableIntegerModuloP S = kElem.mutable().setProduct(sElem);
|
||||
S.setSum(rElem);
|
||||
// need to be reduced before output conversion
|
||||
S.setReduced();
|
||||
byte[] sArr = S.asByteArray(byteLength);
|
||||
byte[] rArr = encode(byteLength, R);
|
||||
|
||||
|
@ -263,13 +263,6 @@ public class BigIntegerModuloP implements IntegerFieldModuloP {
|
||||
v = BigInteger.ZERO.subtract(v);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MutableElement setReduced() {
|
||||
// do nothing
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class SmallElement extends ImmutableElement implements SmallValue {
|
||||
|
@ -302,7 +302,7 @@ public class TestIntegerModuloP {
|
||||
if (elem.test.getField() instanceof IntegerPolynomial) {
|
||||
IntegerPolynomial field =
|
||||
(IntegerPolynomial) elem.test.getField();
|
||||
int numAdds = field.getMaxAdds();
|
||||
int numAdds = 10; // check for addition overflow
|
||||
for (int j = 1; j < numAdds; j++) {
|
||||
ElemFunction addFunc3 = ADD_FUNCTIONS.
|
||||
get(random.nextInt(ADD_FUNCTIONS.size()));
|
||||
|
Loading…
x
Reference in New Issue
Block a user