It is so hard to find documentation about it so I am here.
I am trying to apply Curve1174 doubling in java but there is a problem.
When I use BigInteger it gives me (0,0)
When I use BigDecimal it gives that
Exception in thread “main” java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.
I know I must use divide(blabla , length , RoundingMode) but what is the exact length as a standard I don't know.
My codes are below can you help me please I have pondered for 3 days so I am about to go mad.
BigInteger Code
public class ECCprocess {
// C1174
// COSTRUCTOR
public static ECPoint operate(ECPoint point1,ECPoint point2){
ECPoint resultPoint;
BigInteger resultX;
BigInteger resultY;
CONSTANTlist constantList = new CONSTANTlist();
BigInteger calculating1 = point1.getAffineX().multiply(point2.getAffineY());
BigInteger calculating2 = point2.getAffineX().multiply(point1.getAffineY());
BigInteger calculating3 = ((BigInteger)constantList.getConstant("dConstant"));
calculating3 = (calculating3.multiply(point1.getAffineX().multiply(point2.getAffineX()).multiply(point1.getAffineY()).multiply(point2.getAffineY()))).add(new BigInteger("1"));
resultX = (calculating1.add(calculating2)).divide(calculating3);
calculating1 = point1.getAffineY().multiply(point2.getAffineY());
calculating2 = point1.getAffineX().multiply(point2.getAffineX());
calculating3 = ((BigInteger)constantList.getConstant("dConstant")).multiply(point1.getAffineX()).multiply(point1.getAffineY()).multiply(point2.getAffineX()).multiply(point2.getAffineY());
calculating3 = (new BigInteger("1")).subtract(calculating3);
resultY = (calculating1.subtract(calculating2)).divide(calculating3);
resultX = resultX.remainder((BigInteger)constantList.getConstant("pConstant"));
resultY = resultY.remainder((BigInteger)constantList.getConstant("pConstant"));
resultPoint = new ECPoint(resultX, resultY);
return resultPoint;
}
}
BigDecimal Code
public class ECCprocess2 {
// C1174
public static ECCpoint operate(ECCpoint point1,ECCpoint point2){
ECCpoint resultPoint;
BigDecimal resultX;
BigDecimal resultY;
CONSTANTlist constantList = new CONSTANTlist();
point1.setX(point1.getX().remainder((BigDecimal) constantList.getConstant("pConstant")));
point1.setY(point1.getY().remainder((BigDecimal) constantList.getConstant("pConstant")));
point2.setX(point2.getX().remainder((BigDecimal) constantList.getConstant("pConstant")));
point2.setY(point2.getY().remainder((BigDecimal) constantList.getConstant("pConstant")));
BigDecimal calculating1 = point1.getX().multiply(point2.getY());
BigDecimal calculating2 = point2.getX().multiply(point1.getY());
BigDecimal calculating3 = ((BigDecimal)constantList.getConstant("dConstant")).multiply(point1.getX().multiply(point1.getY()).multiply(point2.getX()).multiply(point2.getY()));
resultX = (calculating1.add(calculating2)).divide(calculating3.add(new BigDecimal("1")),100,RoundingMode.HALF_EVEN);
calculating1 = point1.getY().multiply(point2.getY());
calculating2 = point1.getX().multiply(point2.getX());
calculating3 = ((BigDecimal) constantList.getConstant("dConstant")).multiply(point1.getX().multiply(point1.getY()).multiply(point2.getX()).multiply(point2.getY()));
calculating3 = (new BigDecimal("1")).subtract(calculating3);
resultY = (calculating1.subtract(calculating2)).divide(calculating3,100,RoundingMode.HALF_EVEN);
resultX = resultX.remainder((BigDecimal)constantList.getConstant("pConstant"));
resultY = resultY.remainder((BigDecimal)constantList.getConstant("pConstant"));
resultPoint = new ECCpoint(resultX, resultY);
return resultPoint;
}
}
By the way here is the class I used with BigDecimal
public class ECCpoint {
private BigDecimal x;
private BigDecimal y;
private ECPoint point;
// CONSTRUCTOR
public ECCpoint(BigDecimal x,BigDecimal y){
setX(x);
setY(y);
}
// GETTERS
public BigDecimal getX(){
return this.x;
}
public BigDecimal getY(){
return this.y;
}
// SETTERS
public void setX(BigDecimal x){
this.x = x;
}
public void setY(BigDecimal y){
this.y = y;
}
}
Here are my main function and its exact output
public static void main(String[] args) throws Exception {
ECCpoint result;
ECCpoint point = new ECCpoint(new BigDecimal("2025"), new BigDecimal("588747530266665079407582947937120321357732884331117971504880828350684014295"));
result = ECCprocess2.operate(point, point);
System.out.println(result.getX());
System.out.println(result.getY());
}
run:
-1.4289195326809714896E-81
2.077216903248689341047078303547341201311658613556384884404177594774968601568246831530179235E-10
BUILD SUCCESSFUL (total time: 0 seconds)
You should be using BigInteger
for this, not BigDecimal
. But remember division here is modular division in the field, not normal division. This is the same as multiplication by the modular inverse.
In your code changing the two lines performing the division should give you what you want.
Change
resultX = (calculating1.add(calculating2)).divide(calculating3);
to something like
resultX = (calculating1.add(calculating2)).multiply(calculating3.modInverse(p));
where p
is defined as (i.e. it is the field prime)
BigInteger p = (BigDecimal) constantList.getConstant("pConstant");
Similarly change
resultY = (calculating1.subtract(calculating2)).divide(calculating3);
to
resultY = (calculating1.subtract(calculating2)).multiply(calculating3.modInverse(p));