//引入標頭檔 //副程式, 在Zn集合中找出a的乘法反元素 int multiplicative_inverse( int r1, int r2, int t1, int t2 ){ /* 用遞迴實作extended Euclidean algorithm 先判斷r2是否為0是的話不繼續遞迴, 否則繼續遞迴 若r2為0在判斷r1是否為1 若r1為1表示有解->印出, 否則無解->印出 若r1為1在判斷t1是否小於零是的話mod t2(原始n)轉為正數並印出, 否則直接印出解答 */ return r2 ? multiplicative_inverse( r2, r1 % r2, t2, t1 - r1 / r2 * t2 ) : r1 == 1 ? ( t1 < 0 ? printf( "%d\n", t1 + t2 ) : printf( "%d\n", t1 ) ) : printf( "不存在\n" ); }//副程式的成對括號
RSAint RSACracker(RSAint e, RSAint n) { RSAint p=(((RSAint) 1) << 13), q; int i=0; bool foundPair = false, pIsPrime = false, qIsPrime=false; while(!foundPair) { q = (((RSAint) 1) << 13); qIsPrime = false; while(!pIsPrime) { if(isPrime(p)) { pIsPrime = true; } else { p++; } } while(!qIsPrime) { if(isPrime(q)) { if(p*q == n) { qIsPrime = true; foundPair = true; } else if(p*q < n) { q++; } else { p++; pIsPrime = false; qIsPrime = true; } } else if(p*q < n) { q++; } else { p++; pIsPrime = false; qIsPrime = true; } } } RSAint eFunc = (p-1)*(q-1); RSAint d = multiplicative_inverse(e,eFunc); return d; }
void generateKey(RSAint p, RSAint q, RSAint* e, RSAint* d, RSAint* n) { assert(e != NULL && d != NULL && n != NULL && p > minPrimeLimit && p < maxPrimeLimit && q > minPrimeLimit && q < maxPrimeLimit && p != q); *n = p*q; RSAint eFunc = (p-1)*(q-1); seedRand(); *e = randomPrime(2,eFunc); while(gcd(*e,eFunc) != 1) { *e = randomPrime(2,eFunc); } *d = multiplicative_inverse(*e,eFunc); assert((*n == p*q) && (*e**d % ((p-1)*(q-1)) == 1) && (*e > 10000)); }
//主程式 int main(){ //宣告Zn大小與某一整數a int n, a; //提示使用者輸入n值 printf( "請輸入Zn的大小 = " ); //讀取n值直到檔案結束 while( scanf( "%d", &n ) != EOF ){ //宣告索引i給迴圈使用 int i; //印出Zn printf( "Zn = {" ); //用迴圈印出Zn集合 for( i = 0; i < n; i++ ){ if( !i )//判斷第一個數字 printf( "%d", i );//印出集合數字 else//判斷第一個以外的數字 printf( ", %d", i );//印出集合數字 }//迴圈的成對括號 //印出Zn的結束框 printf( "}\n" ); //提示使用者輸入a值 printf( "請輸入Zn集合中的某一整數a = " ); //讀取a值 scanf( "%d", &a ); //由副程式去尋找a的加法反元素並印出 printf( "%d的加法反元素: %d\n", a, additive_inverse( n, a ) ); //準備要印出a的乘法反元素 printf( "%d的乘法反元素: ", a ); //由副程式去尋找a的乘法反元素並印出 multiplicative_inverse( n, a, 0, 1 ); //提示使用者輸入n值 printf( "------------------\n請輸入Zn的大小 = " ); }//迴圈的成對括號 return 0;//回傳給main代表程式結束 }//主程式的成對括號