/* * Function to find the multiplicative inverse of a given poly * @param: a valid poly * @output: multiplicative inverse of poly if it has one and print out the processes to stdout */ void inverse(uint8_t inv_poly[]) { //Construct lookup_table to find multiplicative inverse of a byte struct lookup_table mytable = construct_table(); uint8_t temp[5]; //initialize temp to be x^4 + 1 or {01}{00}{00}{00}{01}, but ignore the coefficient of x^4 uint8_t quo[4]; uint8_t aux[4]; uint8_t temp_aux[4]; uint8_t rem[4]; //initialize reminder, quotient and aux for(int k=0; k < 4; k++) { quo[k] = 0x00; aux[k] = 0x00; rem[k] = 0x00; temp[k] = 0x00; temp_aux[k] = 0x00; } //set the last byte of temp to be {01} since we have x^4 + 1 temp[3] = 0x01; //print first round printOutput_inverse(1, temp, quo, temp_aux); //Set rem to be poly memcpy(rem, inv_poly, 4); //set last byte of aux to be {01} since now x=1 for second round aux[3] = 0x01; //print second round printOutput_inverse(2, rem, quo, aux); /* * Now go through the last 4 rounds to complete our multiplicative inverse process. * We could end sooner if the poly has no inverse (rem = 00) or we arrive at rem = const sooner than 4 rounds */ int isInverse = 1; for(int k = 3; k < 7; k++) { struct long_division result; if(k == 3) //take special care for first division since the dividend has 4th degree (x^4 + 1) { result = divide(temp, rem, mytable, 1); } else { result = divide(temp, rem, mytable, 0); } /* * Compute aux */ struct modprod_result quo_aux = modprod(result.quo, aux, 0); //aux holder to later update the previous aux uint8_t aux_holder[4]; memcpy(aux_holder, aux, 4); //Perform XOR with previous aux for(int i = 0; i < 4; i++) { aux[i] = quo_aux.modprod_poly[i] ^ temp_aux[i]; } //Update previous aux memcpy(temp_aux, aux_holder, 4); //print output printOutput_inverse(k, result.rem, result.quo, aux); /* * Perform check on rem to see if we can stop early for the following cases: * Case 1: rem = {00}{00}{00}{00} - stop the loop and report that the input poly does not have multiplicative inverse * Case 2: rem = {00}{00}{00}{01} - rem is a constant with reminder = 01 signaling that we are done */ if(result.rem[0] == 0x00 && result.rem[1] == 0x00 && result.rem[2] == 0x00) { if(result.rem[3] == 0x00) { isInverse = 0; break; } else if(result.rem[3] == 0x01) { break; } } /* * Update temp and rem for next round * now temp = rem and rem = result.rem */ memcpy(temp, rem, 4); memcpy(rem, result.rem, 4); } //print last statement for inverse process if(!isInverse) { fprintf(stdout, "{%02x}{%02x}{%02x}{%02x} does not have a multiplicative inverse\n", inv_poly[0], inv_poly[1], inv_poly[2], inv_poly[3]); } else { fprintf(stdout, "Multiplicative inverse of {%02x}{%02x}{%02x}{%02x} is {%02x}{%02x}{%02x}{%02x}\n", inv_poly[0], inv_poly[1], inv_poly[2], inv_poly[3], aux[0], aux[1], aux[2], aux[3]); } }
// Main method of HW6, mostly taking user input and running the correct prog int main(int argc, char *argv[]) { // Look for correct command line arguments if(argc <= 1) { usage(); return 0; } else { if(strcmp(argv[1], "tablecheck") == 0) { // Tablecheck prog should be run FILE* tablefile = NULL; for(int i=2; i<argc; i++) { if(strncmp(argv[i], "-t=", 3) == 0) { tablefile = fopen(argv[i]+3, "r"); if(tablefile == NULL) { fprintf(stderr, "ERROR: invalid file '%s' for reading.\n", argv[i]+3); return 0; } } } if(tablefile) { tablecheck(tablefile); fclose(tablefile); } else { usage("tablecheck"); } } else if(strcmp(argv[1], "modprod") == 0) { // Modprod prog should be run char *poly1 = NULL; char *poly2 = NULL; for(int i=2; i<argc; i++) { if(strncmp(argv[i], "-p1=", 4) == 0) { poly1 = argv[i]+4; } else if(strncmp(argv[i], "-p2=", 4) == 0) { poly2 = argv[i]+4; } } if(poly1 && poly2) { modprod(poly1, poly2); } else { usage("modprod"); } } else if(strcmp(argv[1], "keyexpand") == 0) { // Keyexpand prog should be run char *key = NULL; FILE* tablefile = NULL; for(int i=2; i<argc; i++) { if(strncmp(argv[i], "-k=", 3) == 0) { key = argv[i]+3; } else if(strncmp(argv[i], "-t=", 3) == 0) { tablefile = fopen(argv[i]+3, "r"); if(tablefile == NULL) { fprintf(stderr, "ERROR: invalid file '%s' for reading.\n", argv[i]+3); return 0; } } } if(key && tablefile) { keyexpand(key, tablefile); fclose(tablefile); } else { usage("keyexpand"); } } else if(strcmp(argv[1], "encrypt") == 0) { // Encrypt prog should be run char *key = NULL; FILE* tablefile = NULL; for(int i=2; i<argc; i++) { if(strncmp(argv[i], "-k=", 3) == 0) { key = argv[i]+3; } else if(strncmp(argv[i], "-t=", 3) == 0) { tablefile = fopen(argv[i]+3, "r"); if(tablefile == NULL) { fprintf(stderr, "ERROR: invalid file '%s' for reading.\n", argv[i]+3); return 0; } } } if(key && tablefile) { if(argv[argc-1][0] != '-') { // Take input from file FILE* fin = NULL; fin = fopen(argv[argc-1], "r"); if(fin == NULL) { fprintf(stderr, "ERROR: invalid file '%s' for reading.\n", argv[argc-1]); return 0; } encrypt(key, tablefile, fin); fclose(fin); } else { // Take input from cmd line encrypt(key, tablefile, stdin); } fclose(tablefile); } else { usage("encrypt"); } } else if(strcmp(argv[1], "decrypt") == 0) { // Decrypt prog should be run char *key = NULL; FILE* tablefile = NULL; for(int i=2; i<argc; i++) { if(strncmp(argv[i], "-k=", 3) == 0) { key = argv[i]+3; } else if(strncmp(argv[i], "-t=", 3) == 0) { tablefile = fopen(argv[i]+3, "r"); if(tablefile == NULL) { fprintf(stderr, "ERROR: invalid file '%s' for reading.\n", argv[i]+3); return 0; } } } if(key && tablefile) { if(argv[argc-1][0] != '-') { // Take input from file FILE* fin = NULL; fin = fopen(argv[argc-1], "r"); if(fin == NULL) { fprintf(stderr, "ERROR: invalid file '%s' for reading.\n", argv[argc-1]); return 0; } decrypt(key, tablefile, fin); fclose(fin); } else { // Take input from cmd line decrypt(key, tablefile, stdin); } fclose(tablefile); } else { usage("decrypt"); } } else if(strcmp(argv[1], "inverse") == 0) { // Inverse prog should be run char *poly = NULL; for(int i=2; i<argc; i++) { if(strncmp(argv[i], "-p=", 3) == 0) { poly = argv[i]+3; } } if(poly) { inverse(poly); } else { usage("inverse"); } } else { // Failed input usage(); } } return 0; }