Java personalizado de generación de clave pública (Bitcoin)

podludek:

Una clave privada se genera al azar y no se correlaciona con cualquier cartera.

Quiero preparar a medida aplicación (ingenua) de generación de clave pública de un Bitcoin. Sin embargo, después de algunos intentos mis resultados eran incorrectos. Los comparé con los generadores en línea. He reconocido Solía división en lugar de modinv. Por desgracia, después de cambiar la división en modinv llegué "java.lang.ArithmeticException: BigInteger no invertible.". Me cansado para seguir https://www.mobilefish.com/services/cryptocurrency/cryptocurrency.html#refProdedure y https://en.wikipedia.org/wiki/Elliptic_curve_point_multiplication Podría usted ayudarme a reconocer donde hice un error?

public class ECDSAUtils {

    private static final CurvePoint G = new CurvePoint(new BigInteger("79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", 16), new BigInteger("483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", 16));
    private static CurvePoint zero;
    private static BigInteger base;
    private static final BigInteger three = new BigInteger("3", 10);

    public static void main(String[] args){
        ECDSAUtils e = new ECDSAUtils();
        BigInteger privateKey = new BigInteger("fdc668381ab251673ef8552851a2c7cf346a6e09ea86be0f55a94d2a12253557", 16);
        CurvePoint r = e.mult(G, privateKey);
        System.out.println(r.x.toString(16).toUpperCase() + " " + r.y.toString(16).toUpperCase());
    }

    public ECDSAUtils(){
        zero = new CurvePoint(new BigInteger("0", 16), new BigInteger("0", 16));
        base = new BigInteger("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", 16);
    }

    public static CurvePoint add(CurvePoint p, CurvePoint q){
        CurvePoint result = null;
        if (p.equals(zero)){
            result = q;
        } else if (q.equals(zero)){
            result = p;
        } else {
            BigInteger lambda = q.y.subtract(p.y).modInverse(q.x.subtract(p.x)).mod(base);
            BigInteger x = lambda.multiply(lambda).subtract(p.x).subtract(q.x).mod(base);
            BigInteger y = lambda.multiply(p.x.subtract(x)).subtract(p.y).mod(base);
            result = new CurvePoint(x, y);
        }
        return result;
    }

    public static CurvePoint doublePoint(CurvePoint p){
        BigInteger lambda = p.x.multiply(p.x).multiply(three).modInverse(p.y.add(p.y)).mod(base);
        BigInteger x = lambda.multiply(lambda).subtract(p.x).subtract(p.x).mod(base);
        BigInteger y = lambda.multiply(p.x.subtract(x)).subtract(p.y).mod(base);
        return new CurvePoint(x, y);
    }

    public CurvePoint mult(CurvePoint N, BigInteger p) {
        CurvePoint Q = zero;
//EDIT:
        for (int i = p.bitLength() - 1; i > -1; i --) {
            if (p.testBit(i)) {
                Q = add(Q, N);
            }
            N = doublePoint(N);
        }

        return Q;
    }
}

public class CurvePoint {
    BigInteger x;
    BigInteger y;

    public CurvePoint(BigInteger x, BigInteger y) {
        this.x = x;
        this.y = y;
    }
}

Exception in thread "main" java.lang.ArithmeticException: BigInteger not invertible.
    at java.math.MutableBigInteger.mutableModInverse(MutableBigInteger.java:1986)
    at java.math.BigInteger.modInverse(BigInteger.java:3154)
    at naive.ECDSAUtils.doublePoint(ECDSAUtils.java:41)
    at naive.ECDSAUtils.mult(ECDSAUtils.java:51)
    at naive.ECDSAUtils.main(ECDSAUtils.java:15)
Topaco:
  • Actualmente la expresión

    se codifica como sigue:

    y.modInverse(x).mod(p)
    

    Esto está mal y hace que el mensaje de error observado. se aplica lo siguiente:

    que debe ser codificada como sigue:

    y.multiply(x.modInverse(p)).mod(p)
    
  • En el addmétodo, el caso:

    No se maneja. Aquí, el addmétodo debe devolver zero(es decir, el punto que representa el punto en el infinito). Geométricamente, este caso corresponde a una secante vertical (2 intersecciones).

  • De forma análoga, el caso

    no se maneja en el doublePointmétodo. En este caso, el doublePointmétodo debe devolver zerotambién. Geométricamente, este caso corresponde a una tangente vertical (1 intersección).

  • El multmétodo no funciona. Pero con respecto a la observación en el código esta es probablemente conocido.

  • La prueba es más fácil si se utiliza un pequeño campo finito primo. Aquí puede especificar las curvas elípticas y determinar los puntos correspondientes. Nota, que una curva con b != 0utilizar debe, de lo contrario el punto (0,0)es un punto regular de la curva y no se podría utilizar como un representante del punto en el infinito.

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=230019&siteId=1
Recomendado
Clasificación