// we only consider p == 3 mod 4 ... BigNum eccGetY(BigNum y2, BigNum p){ BigNum ret; initBigNum(&ret); BigNum e = copyBigNum(p); BigNum _1 = int2BigNum(1, p); e = add_N(p, _1); e = shiftR(e); e = shiftR(e); // e = (p+1)/4 mod p ret = expB(y2, e, p); return ret; }
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() { FILE *stream = fopen("testdata", "r"); printf("0 to 16 in hex: "); bigint num[0x11]; for (int i = 0; i < 0x11; i++) { readBigint(stream, &num[i]); writeBigint(stdout, num[i]); printf(" "); } printf("\n"); printf("\nThe following two lines should be identical:\n"); printf("1 2 4 8 10 20 40 80 100 200 2000 800000000 1 0\n"); int shifts[11] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 22}; int totalShift = 0; bigint tmp; assign(num[1], &tmp); writeBigint(stdout, tmp); printf(" "); fflush(stdout); for (int i = 0; i < 11; i++) { shiftL(tmp, shifts[i], &tmp); writeBigint(stdout, tmp); printf(" "); fflush(stdout); totalShift += shifts[i]; } shiftR(tmp, totalShift, &tmp); writeBigint(stdout, tmp); printf(" "); shiftR(tmp, 1, &tmp); writeBigint(stdout, tmp); printf("\n"); bigint meaningOfLifeTheUniverseAndEverything; readBigint(stream, &meaningOfLifeTheUniverseAndEverything); modMult(num[6], num[7], meaningOfLifeTheUniverseAndEverything, &tmp); printBigint("\nsimple test: 6 * 7 % 42 = ", tmp); modMult(num[6], num[9], meaningOfLifeTheUniverseAndEverything, &tmp); printBigint("\nsimple test: 6 * 9 % 42 = ", tmp); modMult(num[2], num[3], num[5], &tmp); printBigint("\nsimple test: 2 * 3 % 5 = ", tmp); modExpt(num[5], num[3], meaningOfLifeTheUniverseAndEverything, &tmp); printBigint("\nsimple test: 5 ^ 3 % 42 = ", tmp); bigint n, e, d, p, q, u; readBigint(stream, &n); readBigint(stream, &e); readBigint(stream, &d); readBigint(stream, &p); readBigint(stream, &q); readBigint(stream, &u); printf("\nequal() test: "); if (!equal(meaningOfLifeTheUniverseAndEverything, num[5]) && equal(num[7], num[7]) && equal(n, n) && !equal(p, q)) { printf("PASS\n"); } else { printf("FAIL\n"); } bigint maxBI, pq; bigintMax(&maxBI); printf("\nmaxBI = "); writeBigint(stdout, maxBI); printf("\n\nHere is an RSA private key:"); printf("\n\nn = "); writeBigint(stdout, n); printf("\n\ne = "); writeBigint(stdout, e); printf("\n\nd = "); writeBigint(stdout, d); printf("\n\np = "); writeBigint(stdout, p); printf("\n\nq = "); writeBigint(stdout, q); printf("\n\nu = "); writeBigint(stdout, u); printf("\n\n"); modMult(p, q, maxBI, &pq); printf("\n\np * q mod maxBI = "); writeBigint(stdout, pq); printf("\n\nThe following statement should be true: "); printf("\nn == p * q mod maxBI"); printf("\nis it? "); if (equal(n, pq)) { printf("PASS\n"); } else { printf("FAIL\n"); printf("\nn = "); writeBigint(stdout, n); printf("\npq = "); writeBigint(stdout, pq); } printf("\n\nSHITS AND GIGGLES:\n"); bigint m, c, m2; readBigint(stream, &m); printf("\nm = "); writeBigint(stdout, m); printf("\n\n"); modExpt(m, e, n, &c); printf("\n\nm ^ e mod n = c = "); writeBigint(stdout, c); printf("\n\n"); modExpt(c, d, n, &m2); printf("\n\nc ^ d mod n = m = "); writeBigint(stdout, m2); printf("\n\nIs the plaintext equal to the deciphered ciphertext? "); if (equal(m,m2)) { printf("PASS\n"); } else { printf("FAIL\n"); printf("\nm = "); writeBigint(stdout, m); printf("\nm2 = "); writeBigint(stdout, m2); } /*printf("\nAri's silly test\n"); bigint a =num[3], b = num[8], c=num[7]; printf("input operands: "); writeBigint(stdout,a); printf("\t"); writeBigint(stdout,b); printf("\t"); writeBigint(stdout,c); printf("\n\n"); modMultMagic(a,b, c,&tmp); printf("\n\nresult: \t"); writeBigint(stdout, tmp); printf("\n"); */ }
int main(int numargs, char *args[]){ //should have either 4, 5, 6, or 7 arguments //if 7, [1] must be -r, [2,3,4] must be ints, initial and goal are letters //if 6, must not include -r, include all else //if 5 must include -r and not height OR width //if 4, must have int for maxlength and letters for other, and nothing else //height and width are ints between 2 and 5 (Default is 3) //maxlength is non-negative int (can be 0) //INITIAL and GOAL have the necessary number of letters for the size of the tray //letters between only A and L (duplicates ok) int width = 3; //width of the tray, default is 3 int height = 3; //height of the tray, default is 3 int maxlength = -1; //maxlength of the pattern int tilelen; //number of tiles char *temp; bool flag; //true is -r is specified bool used; char *initial; //initial position char *goal; //goal position //if all the command-line args follow the rules for 4 args if((numargs == 4) && checkNum(args[1]) && checkTiles(args[2], args[3])){ maxlength = (int)strtol(args[1], &temp, 10); tilelen = strlen(args[2]); flag = false; //no flag present initial = args[2]; goal = args[3]; } //if all the command-line args follow the rules for 5 args else if((numargs == 5) && checkFlag(args[1]) && checkNum(args[2]) && checkTiles(args[3], args[4])){ maxlength = (int)strtol(args[2], &temp, 10); tilelen = strlen(args[3]); flag = true; //flag present initial = args[3]; goal = args[4]; } //if all the command-line args follow the rules for 6 args else if((numargs == 6) && checkNum(args[1]) && checkNum(args[2]) && checkNum(args[3]) && checkTiles(args[4], args[5])){ height = (int)strtol(args[1], &temp, 10); width = (int)strtol(args[2], &temp, 10); maxlength = (int)strtol(args[3], &temp, 10); tilelen = strlen(args[4]); flag = false; //no flag present initial = args[4]; goal = args[5]; } //if all the command-line args follow the rules for 7 args else if((numargs == 7) && checkFlag(args[1]) && checkNum(args[2]) && checkNum(args[3]) && checkNum(args[4]) && checkTiles(args[5], args[6])){ height = (int)strtol(args[2], &temp, 10); width = (int)strtol(args[3], &temp, 10); maxlength = (int)strtol(args[4], &temp, 10); tilelen = strlen(args[5]); flag = true; //flag present initial = args[5]; goal = args[6]; } else{//invalid command line args fprintf(stderr, "Invalid command line arguments\n"); exit(1); } if((height >= 2) && (height <= 5) && (width >= 2) && (width <= 5) && (tilelen == height*width)){} else{//if the height and width aren't right, then quit fprintf(stderr, "Invalid command line arguments\n"); exit(1); } Stack q1; //create the two stacks for the queue Stack q2; createS(&q1); createS(&q2); char *nextStr; //holds what is popped off queue 'P' int nextLen; //holds the length of P Trie root; //root of the trie dictionary root.len = -1; root.from = NULL; for(int k = 0; k < 12; k++) root.children[k] = NULL; insert(&root, goal, NULL, 0); //insert root in queue & dictionary pushS(&q1, goal); if(!(strcmp(goal, initial))){ //if goal is initial printf("%s\n", initial); destroyS(&q1); destroyS(&q2); return 0; } while(!(isEmptyS(&q1) && isEmptyS(&q2))){ //while queue not empty popQ(&q1, &q2, &nextStr); nextLen = lenInTrie(&root, nextStr); used = false; if(nextLen < maxlength){ //generate all the possible tiles for(int c = 0; c < width; c++){ //for all column shifts if(flag){//-r, then do it for all possible shifts for(int sh = 1; sh < width; sh++){ char *nextTiles = shiftC(nextStr, height, width, c, height - sh); //next tile pattern generated by a shift if(!strcmp(nextTiles, initial)){ insert(&root, nextTiles, nextStr, nextLen + 1); printSteps(root, nextTiles); destroyS(&q1); destroyS(&q2); return 0; } if(insert(&root, nextTiles, nextStr, nextLen + 1)){ pushS(&q1, nextTiles); //add it to the queue and dictionary used = true; } else free(nextTiles); } } else{//else do it for shift is one step only char *nextTiles = shiftC(nextStr, height, width, c, height - 1); //next tile pattern generated by a shift if(!strcmp(nextTiles, initial)){ insert(&root, nextTiles, nextStr, nextLen + 1); printSteps(root, nextTiles); destroyS(&q1); destroyS(&q2); return 0; } if(insert(&root, nextTiles, nextStr, nextLen + 1)){ pushS(&q1, nextTiles); //add it to the queue and dictionary used = true; } else free(nextTiles); } } for(int r = 0; r < height; r++){//for all possible row shifts if(flag){//-r, then do it for all possible shifts for(int sh = 1; sh < height; sh++){ char *nextTiles = shiftR(nextStr, height, width, r, width - sh); //next tile pattern generated by a shift if(!strcmp(nextTiles, initial)){ insert(&root, nextTiles, nextStr, nextLen + 1); printSteps(root, nextTiles); destroyS(&q1); destroyS(&q2); return 0; } if(insert(&root, nextTiles, nextStr, nextLen + 1)){ pushS(&q1, nextTiles); //add it to the queue and dictionary used = true; } else free(nextTiles); } } else{//else do it for shift is one step only char *nextTiles = shiftR(nextStr, height, width, r, width - 1); //next tile pattern generated by a shift if(!strcmp(nextTiles, initial)){ insert(&root, nextTiles, nextStr, nextLen + 1); printSteps(root, nextTiles); destroyS(&q1); destroyS(&q2); return 0; } if(insert(&root, nextTiles, nextStr, nextLen + 1)){ pushS(&q1, nextTiles); //add it to the queue and dictionary used = true; } else free(nextTiles); } } } if(!used) free(nextStr); }//end of while queue is not empty destroyS(&q1); destroyS(&q2); return 0; }