package x3_1;
import java.math.BigInteger;
import java.security.spec.ECPoint;
public class Miller_Algorithm {
static BigInteger A, B, p;
static ECPoint P, Q;
static BigInteger f = new BigInteger("1");
public static BigInteger Miller(ECPoint P, ECPoint Q, BigInteger r,
int k, BigInteger A, BigInteger B, BigInteger p) {
setA(A);
setB(B);
setP(p);
ECPoint V = P;
int t = r.bitLength();
for (int i = t - 1; i >= 0; i--) {
f = f.multiply(f).multiply(tangentLine(V, Q));
V = Elictip_Adder.ECpointAdder(A, B, p, V, V);
if (r.testBit(i)) {
f = f.multiply(PointLine(V, P, Q));
V = Elictip_Adder.ECpointAdder(A, B, p, V, P);
}
}
int pow = (int) Math.pow(Double.valueOf(2), k);
int finalPower = (pow -1)/Integer.valueOf(r.toString());
f = f.pow(finalPower);
return f;
}
public static BigInteger PointLine(ECPoint V, ECPoint P, ECPoint Q) {
BigInteger a, b, c;
BigInteger vx = V.getAffineX();
BigInteger vy = V.getAffineY();
BigInteger px = P.getAffineX();
BigInteger py = P.getAffineY();
BigInteger qx = Q.getAffineX();
BigInteger qy = Q.getAffineY();
a = py.subtract(vy);
b = vx.subtract(px);
c = a.multiply(vx).add(b.multiply(vy)).negate();
BigInteger output;
output = a.multiply(qx).add(b.multiply(qy)).add(c);
return output;
}
public static BigInteger tangentLine(ECPoint V, ECPoint Q) {
BigInteger a, b, c;
BigInteger vx = V.getAffineX();
BigInteger vy = V.getAffineY();
BigInteger qx = Q.getAffineX();
BigInteger qy = Q.getAffineY();
a = vx.multiply(vx).multiply(new BigInteger("3")).add(A);
b = vy.negate();
c = a.multiply(vx).add(b.multiply(vy)).negate();
BigInteger output;
output = a.multiply(qx).add(b.multiply(qy)).add(c);
return output.mod(p);
}
public static BigInteger getA() {
return A;
}
public static void setA(BigInteger a) {
A = a;
}
public static BigInteger getB() {
return B;
}
public static void setB(BigInteger b) {
B = b;
}
public static ECPoint getP() {
return P;
}
public static void setP(ECPoint p) {
P = p;
}
public static ECPoint getQ() {
return Q;
}
public static void setQ(ECPoint q) {
Q = q;
}
public static void setP(BigInteger p) {
Miller_Algorithm.p = p;
}
}