Node eccAdd(Node P1, Node P2, BigNum a, BigNum b, BigNum p){ Node ret; initNode(&ret); BigNum x1 = copyBigNum(P1.x); BigNum y1 = copyBigNum(P1.y); BigNum x2 = copyBigNum(P2.x); BigNum y2 = copyBigNum(P2.y); // for P1 = inf or P2 = inf if(P1.inf){ ret = copyNode(P2); } else if(P2.inf){ ret = copyNode(P1); } else if(eqlNode(P1, P2)){ // P1 == P2 BigNum _3 = int2BigNum(3, p); BigNum _3x1_2 = mul(mul(_3, x1, p), x1, p); BigNum _3x2_a = add(_3x1_2, a, p); BigNum _2y1 = add(y1, y1, p); BigNum _0 = int2BigNum(0, p); if(compareBigNum(_0, _2y1) == 0){ ret.inf = true; return ret; } BigNum m = mul(_3x2_a, invFermat(_2y1, p), p); BigNum x3 = mul(m, m, p); x3 = sub(x3, x1, p); x3 = sub(x3, x2, p); BigNum y3 = mul(m, sub(x1, x3, p), p); y3 = sub(y3, y1, p); ret.inf = false; ret.x = copyBigNum(x3); ret.y = copyBigNum(y3); } else{ // P1 != P2 BigNum y2_y1 = sub(y2, y1, p); BigNum x2_x1 = sub(x2, x1, p); BigNum _0 = int2BigNum(0, p); if(compareBigNum(_0, x2_x1) == 0){ ret.inf = true; return ret; } BigNum invx2_x1 = invFermat(x2_x1, p); BigNum m = mul(y2_y1, invx2_x1, p); BigNum x3 = mul(m, m, p); x3 = sub(x3, x1, p); x3 = sub(x3, x2, p); BigNum y3 = mul(m, sub(x1, x3, p), p); y3 = sub(y3, y1, p); ret.inf = false; ret.x = copyBigNum(x3); ret.y = copyBigNum(y3); } return ret; }
bool eqlNode(Node P1, Node P2){ if(P1.inf && P2.inf){ return true; } else if(!P1.inf && !P2.inf){ if(compareBigNum(P1.x, P2.x) == 0 && compareBigNum(P1.y, P2.y) == 0){ return true; } } return false; }
bool eccHasY(BigNum y2, BigNum p){ BigNum e = copyBigNum(p); BigNum _1 = int2BigNum(1, p); BigNum ret; e = sub(e, _1, p); e = shiftR(e); //e = (p - 1) / 2 ret = expB(y2, e, p); if(compareBigNum(_1, ret) == 0){ return true; } return false; }
int main(int argc, char* argv[]) { string num1("9"); string num2("0019"); if(argc == 3) { num1 = argv[1]; num2 = argv[2]; } eliminateHeadZeros(num1); eliminateHeadZeros(num2); cout << "num1: " << num1 << endl; cout << "num2: " << num2 << endl; if(num1 == "" || num2 == "" || num1 == "+" || num1 == "-" || num2 == "+" || num2 == "-") { cout << "num1 == \"\" or num2 == \"\"" << endl; return -1; } if(checkNum(num1) || checkNum(num2)) { cout << "Num1 or Num2 illegal" << endl; return -1; } //Add string addResult = addBigNum(num1, num2); cout << num1 << " + " << num2 << " = " << addResult << endl; //Compare cout << num1; int compare = compareBigNum(num1, num2); if(compare == 0) { cout << " = "; } else if(compare < 0) { cout << " < "; } else { cout << " > "; } cout << num2 << endl; //Sub string subResult = subBigNum(num1, num2); eliminateHeadZeros(subResult); cout << num1 << " - " << num2 << " = " << subResult << endl; return 0; }
// single thread bruteforce BigNum bruteforce(Node P, Node Q, BigNum a, BigNum b, BigNum p){ BigNum _1 = int2BigNum(1, p); BigNum k = copyBigNum(_1); Node temp = copyNode(P); if(eqlNode(temp, Q)){ return k; } while(compareBigNum(k, p) < 0){ k = add(k, _1, p); temp = eccAdd(temp, P, a, b, p); if(eqlNode(temp, Q)){ printf("Bruteforce Rounds:\n"); printBigNum(k); return k; } } printf("Bruteforce Rounds:\n"); printBigNum(k); return k; }
// Actually this is not correct. Need to use schoof's to make the group prime first! BigNum pollard(Node P, Node Q, BigNum a, BigNum b, BigNum p, BigNum P_order){ //P's order <= p BigNum ret; initBigNum(&ret); // generate random X_0 = ap*P + bp*Q BigNum _0 = int2BigNum(0, P_order); BigNum ap = rdm2(_0, P_order); BigNum bp = rdm2(_0, P_order); BigNum _1 = int2BigNum(1, p); BigNum _2 = int2BigNum(2, p); Node a_P = eccMul(ap, P, a, b, p); Node b_P = eccMul(bp, Q, a, b, p); Node X_0 = eccAdd(a_P, b_P, a, b, p); BigNum k = copyBigNum(_0); // insert X_0 and start the random walk addNodeHT(X_0, ap, bp); // add the first Node unsigned int num_X; Node X_i = copyNode(X_0); num_X = HASH_COUNT(ht); while(true){ k = add(k, _1, p); // split into 3 sets by x mod 3 int t = rand_range(0, 2); // this is not the same as the paper... if(t == 0){ // add P X_i = eccAdd(X_i, P, a, b, p); ap = add(ap, _1, P_order); } else if(t == 1){ // 2X_i X_i = eccMul( _2, X_i, a, b, p); ap = mul(ap, _2, P_order); bp = mul(bp, _2, P_order); } else if(t == 2){ // add Q X_i = eccAdd(X_i, Q, a, b, p); bp = add(bp, _1, P_order); } if(X_i.inf){ printf("X_i hits infinity!\n"); BigNum b2_b1 = sub(P_order, bp, P_order); BigNum inv_b2_b1 = invFermat(b2_b1, P_order); BigNum a1_a2 = copyBigNum(ap); ret = mul(a1_a2, inv_b2_b1, P_order); break; } NodeHT *r = findNodeHT(X_i); if(r){ // found a collision! if(compareBigNum(r->bp, bp) != 0){ // b1 != b2 // d = (a1 - a2) / (b2 - b1); a1 is r->ap BigNum b2_b1 = sub(bp, r->bp, P_order); BigNum inv_b2_b1 = invFermat(b2_b1, P_order); BigNum a1_a2 = sub(r->ap, ap, P_order); ret = mul(a1_a2, inv_b2_b1, P_order); break; } } else addNodeHT(X_i, ap, bp); num_X = HASH_COUNT(ht); } printf("Pollard Rounds:\n"); printBigNum(k); return ret; }