Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package rsa.release;
- import java.math.BigInteger;
- import java.util.Scanner;
- import static rsa.release.Lib.*;
- public class Gwinnett {
- private static VQC vqc = new VQC();
- public static void main(String[] args) {
- Scanner s = new Scanner(System.in);
- for (;;) {
- factor(s.nextBigInteger());
- System.out.println();
- }
- }
- public static void factor(BigInteger c) {
- /* Calculate E0, starting estimate */
- VQCElement c1 = vqc.getEntryElement(c);
- System.out.println(c1);
- VQCElement D = vqc.getElementBelowRoot(c1.e, one, c1.d);
- VQCElement D2 = vqc.getElement(c1.e, one, D.t.add(one));
- BigInteger i0 = D2.i;
- BigInteger j0 = D.d;
- int amount_of_tests = 24;
- for (int i = 0; i < amount_of_tests; i++) {
- /** Use in-class method to make d fixed to d from c */
- VQCElement E = getElementFromSquares(i0, j0, c1.d);
- /* if d is fixed, (c - c0) = (e - e0) */
- BigInteger diff = c.subtract(E.c);
- BigInteger root_diff = sqrt(diff.abs());
- VQCElement temp = vqc.getElementBelowRoot(E.e, E.n, c1.d);
- VQCElement E2 = vqc.getElement(E.e, E.n, temp.t.add(one));
- System.out.print(E);
- System.out.println();
- /* Evaluating estimate */
- if (isCorrectRoot(E.i, c)) {
- E = vqc.getFactorizationElement(c1, E.i.subtract(c1.d));
- System.out.println(c + " = " + E.a + " * " + E.b);
- return;
- }
- /* Adjusting */
- /* if c0 is less than c, move squares apart */
- if (lt(E.c, c)) {
- i0 = i0.add(root_diff);
- j0 = sqrt(i0.pow(2).subtract(c));
- /* Move squares closer */
- } else {
- j0 = j0.add(diff);
- i0 = sqrt(j0.pow(2).add(c));
- }
- }
- }
- private static VQCElement getElementFromSquares(BigInteger i, BigInteger j, BigInteger d) {
- BigInteger c = i.pow(2).subtract(j.pow(2));
- BigInteger e = c.subtract(d.pow(2));
- BigInteger n = i.subtract(d);
- BigInteger a = i.subtract(j);
- BigInteger t = vqc.getT(e, (d.subtract(a)));
- return vqc.getElement(e, n, t);
- }
- }
- /** Library stuff follows, main code is above */
- class Lib {
- public static BigInteger zero = BigInteger.ZERO;
- public static BigInteger one = BigInteger.ONE;
- public static BigInteger two = BigInteger.valueOf(2);
- public static boolean gt(BigInteger i, BigInteger i2) { return i.compareTo(i2) > 0; }
- public static boolean gteq(BigInteger i, BigInteger i2) { return i.compareTo(i2) >= 0; }
- public static boolean lt(BigInteger i, BigInteger i2) { return i.compareTo(i2) < 0; }
- public static boolean isCorrectRoot(BigInteger i, BigInteger c) {
- BigInteger i2 = i.multiply(i);
- BigInteger j2 = i2.subtract(c);
- if (!lt(j2, one)) {
- return isSquare(j2);
- } else {
- return false;
- }
- }
- public static boolean isEven(BigInteger e) { return (e.and(one)).equals(zero); }
- public static boolean isSquare(BigInteger value) { return sqrt(value).pow(2).equals(value); }
- /** Efficient Newton square root method */
- public static BigInteger sqrt(BigInteger n) {
- if (n.equals(zero)) return zero;
- n = n.abs();
- if (gt(n, zero)) {
- int bitLength = n.bitLength(); //ceil(log(n, 2))
- BigInteger root = one.shiftLeft(bitLength >> 1); //right-shifting by one equals dividing by two
- while (!sqrtImpl(n, root)) {
- root = root.add(n.divide(root));
- root = root.shiftRight(1);
- }
- return root;
- }
- throw new ArithmeticException("Complex result: sqrt(" + n + ")");
- }
- public static boolean sqrtImpl(BigInteger n, BigInteger root) {
- BigInteger lowerBound = root.multiply(root);
- BigInteger upperBound = root.add(one).multiply(root.add(one));
- return gteq(n, lowerBound) && lt(n, upperBound);
- }
- }
- class VQC {
- public VQC() {}
- public VQCElement getElement(BigInteger e, BigInteger n, BigInteger t) {
- VQCElement E = new VQCElement();
- E.e = e;
- E.n = n;
- E.t = t;
- if (e.equals(zero) || n.equals(zero)) {
- return getZeroIndexElement(E);
- }
- E.x = getX(e, t);
- /* define a(x) = ((x^2 + e) / (2*n)) // 1 */
- E.a = (E.x.pow(2)).add(e).divide(two.multiply(E.n));
- /* define define d(x) = ((x^2 + e) / (2*n) + x) // 1 */
- E.d = E.a.add(E.x);
- E.f = two.multiply(E.d).add(one).subtract(E.e);
- E._f = E.f.negate();
- E.b = E.a.add(two.multiply(E.x)).add(two.multiply(E.n));
- E.c = E.a.multiply(E.b);
- E.i = E.d.add(E.n);
- E.j = E.x.add(E.n);
- return E;
- }
- /** Get closest element with d value below input d in (e, n)
- * The element above it can be calculated to give the two elements whose d values d is between */
- public VQCElement getElementBelowRoot(BigInteger e, BigInteger n, BigInteger d) {
- BigInteger c = d.multiply(d).add(e);
- BigInteger f = (d.add(n)).pow(2).subtract(c);
- BigInteger xpn = sqrt(f);
- BigInteger x = xpn.subtract(n);
- if (!(isEven(e) == isEven(x))) {
- x = x.subtract(one);
- }
- return getElement(e, n, getT(e, x));
- }
- public VQCElement getEntryElement(BigInteger c) {
- BigInteger d = sqrt(c);
- BigInteger e = c.subtract(d.multiply(d));
- BigInteger N = c.add(one).divide(two).subtract(d);
- BigInteger X = d.subtract(one);
- BigInteger T = getT(e, X);
- return getElement(e, N, T);
- }
- public VQCElement getFactorizationElement(VQCElement c1, BigInteger n) {
- VQCElement ab = c1.clone();
- ab.n = n;
- ab.i = ab.d.add(ab.n);
- BigInteger i2 = ab.i.pow(2);
- BigInteger j2 = i2.subtract(ab.c);
- ab.j = sqrt(j2);
- ab.x = ab.j.subtract(n);
- ab.a = ab.d.subtract(ab.x);
- ab.b = ab.c.divide(ab.a);
- ab.t = getT(ab.e, ab.x);
- return ab;
- }
- /* Calculate the last row where d[D] = d */
- public BigInteger getT(BigInteger e, BigInteger x) {
- BigInteger addend = one;
- if (isEven(e)) {
- addend = two;
- }
- return x.add(addend).divide(two);
- }
- public BigInteger getX(BigInteger e, BigInteger t) {
- BigInteger subtrahend = one;
- if (isEven(e)) {
- subtrahend = two;
- }
- return two.multiply(t).subtract(subtrahend);
- }
- public VQCElement getZeroIndexElement(VQCElement E) {
- E.x = zero;
- E.a = E.t;
- E.d = E.a;
- E.b = E.a;
- E.c = E.a.multiply(E.b);
- E.f = two.multiply(E.d).add(one).subtract(E.e);
- E._f = E.f.negate();
- E.i = E.d;
- E.j = zero;
- return E;
- }
- }
- class VQCElement {
- public BigInteger a;
- public BigInteger b;
- public BigInteger c;
- public BigInteger d;
- public BigInteger e;
- public BigInteger f;
- public BigInteger _f; //-f
- public BigInteger i;
- public BigInteger j;
- public BigInteger n;
- public BigInteger x;
- public BigInteger t;
- public VQCElement clone() {
- VQCElement c = new VQCElement();
- c.a = a;
- c.b = b;
- c.c = this.c;
- c.d = d;
- c.e = e;
- c.f = f;
- c.i = i;
- c.j = j;
- c.n = n;
- c.x = x;
- c.t = t;
- return c;
- }
- public String getCoordinates() {
- return "(" + e + ", " + n + ", " + t + ")";
- }
- /**
- * without the coordinates
- */
- public String toElementString() {
- return "{" + e + ":" + n + ":" + d + ":" + x + ":" + a + ":" + b + "} ";
- }
- public String toString() {
- return toElementString() + getCoordinates();
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment