Как рассчитать удвоение в кривой1174 в Java? - PullRequest
0 голосов
/ 26 сентября 2019

Так сложно найти документацию по этому поводу, поэтому я здесь.

Я пытаюсь применить Curve1174 удвоение в Java, но есть проблема.Когда я использую BigInteger, он дает мне (0,0) Когда я использую BigDecimal, он дает

    Exception in thread “main” java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.

Я знаю, что должен использовать деление (blabla, length, RoundingMode), но какова точная длина в качестве стандарта, я надеваюНе знаю.

Мои коды приведены ниже. Можете ли вы помочь мне, пожалуйста, я размышлял в течение 3 дней, поэтому я собираюсь сойти с ума.

Код BigInteger

    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;

    }

}

Кстати, вот класс, который я использовал с 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;
    }
}

Вот моя основная функция и ее точный вывод

    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)

1 Ответ

1 голос
/ 26 сентября 2019

Вы должны использовать BigInteger для этого, а не BigDecimal.Но помните, что деление здесь - это модульное деление в области , а не нормальное деление.Это то же самое, что умножение на модульное обратное.

В вашем коде изменение двух строк, выполняющих деление, должно дать вам то, что вы хотите.

Изменить

resultX = (calculating1.add(calculating2)).divide(calculating3);

что-то вроде

resultX = (calculating1.add(calculating2)).multiply(calculating3.modInverse(p));

, где p определяется как (т. е. это простое поле)

BigInteger p = (BigDecimal) constantList.getConstant("pConstant");

Аналогичным образом изменить

resultY = (calculating1.subtract(calculating2)).divide(calculating3);

на

resultY = (calculating1.subtract(calculating2)).multiply(calculating3.modInverse(p));
...