Search code examples
javacryptographybigintegerbigdecimalcurve

How to calculate doubling in curve1174 in java?


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)

Solution

  • 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));