BOOL RABIN_BuildPrivateKey_BI(RSA_PRIVATE_KEY_ST *privateKey, BI_DIGIT *p, DWORD pDigits, BI_DIGIT *q, DWORD qDigits, DWORD nDigits, DWORD nBits) { BI_DIGIT d[MAX_BI_DIGITS], dP[MAX_BI_DIGITS], dQ[MAX_BI_DIGITS], n[MAX_BI_DIGITS], phiN[MAX_BI_DIGITS], pMinus1[MAX_BI_DIGITS], qInv[MAX_BI_DIGITS], qMinus1[MAX_BI_DIGITS], t[MAX_BI_DIGITS]; DWORD pqDigits; /* Sort so that p > q. (p = q case is extremely unlikely.) */ if (pDigits > qDigits) pqDigits = pDigits; else pqDigits = qDigits; if (BI_Cmp (p, q, pqDigits) < 0) { BI_Assign (t, p, pqDigits); BI_Assign (p, q, pqDigits); BI_Assign (q, t, pqDigits); } if (!RABIN_ComputePrivateKey_BI(d, nDigits, p, q, pqDigits)) return FALSE; /* Compute n = pq, qInv = q^{-1} mod p, d = e^{-1} mod (p-1)(q-1), dP = d mod p-1, dQ = d mod q-1. */ BI_Mult (n, p, q, pqDigits); BI_ModInv (qInv, q, p, pqDigits); BI_ASSIGN_DIGIT (t, 1, pqDigits); BI_Sub (pMinus1, p, t, pqDigits); BI_Sub (qMinus1, q, t, pqDigits); BI_Mod (dP, d, nDigits, pMinus1, pqDigits); BI_Mod (dQ, d, nDigits, qMinus1, pqDigits); privateKey->public_part.bits = nBits; BI_Encode (privateKey->public_part.modulus, MAX_RSA_MODULUS_LEN, n, nDigits); BI_ASSIGN_DIGIT (t, 2, 1); BI_Encode (privateKey->public_part.exponent, MAX_RSA_PUBLIC_EXP_LEN, t, 1); BI_Encode (privateKey->private_part.exponent, MAX_RSA_MODULUS_LEN, d, nDigits); BI_Encode (privateKey->private_part.prime[0], MAX_RSA_PRIME_LEN, p, pqDigits); BI_Encode (privateKey->private_part.prime[1], MAX_RSA_PRIME_LEN, q, pqDigits); BI_Encode (privateKey->private_part.primeExponent[0], MAX_RSA_PRIME_LEN, dP, pqDigits); BI_Encode (privateKey->private_part.primeExponent[1], MAX_RSA_PRIME_LEN, dQ, pqDigits); BI_Encode (privateKey->private_part.coefficient, MAX_RSA_PRIME_LEN, qInv, pqDigits); /* Zeroize sensitive information. */ memset (d, 0, sizeof (d)); memset (dP, 0, sizeof (dP)); memset (dQ, 0, sizeof (dQ)); memset (phiN, 0, sizeof (phiN)); memset (pMinus1, 0, sizeof (pMinus1)); memset (qInv, 0, sizeof (qInv)); memset (qMinus1, 0, sizeof (qMinus1)); memset (t, 0, sizeof (t)); return TRUE; }
/* * Compute s as 2.s - 1 = 1/2 GCM(p-1;q-1) * --------------------------------------- */ BOOL RABIN_ComputePrivateKey_BI(BI_DIGIT *s, DWORD nDigits, BI_DIGIT *p, BI_DIGIT *q, DWORD pqDigits) { int k; BI_DIGIT phi[MAX_BI_DIGITS], GCD[MAX_BI_DIGITS], GCM[MAX_BI_DIGITS]; BI_DIGIT pM1[MAX_BI_DIGITS/2], qM1[MAX_BI_DIGITS/2]; BI_DIGIT t[MAX_BI_DIGITS], u[2*MAX_BI_DIGITS], v[MAX_BI_DIGITS]; BI_ASSIGN_DIGIT (t, 1, pqDigits); /* Compute p-1 */ BI_Sub (pM1, p, t, pqDigits); /* Compute q-1 */ BI_Sub (qM1, q, t, pqDigits); /* Compute phi=(p-1)(q-1) */ BI_ASSIGN_ZERO(phi, pqDigits); /* JDA */ BI_Mult(phi, pM1, qM1, pqDigits); /* Compute GCM(p-1;q-1) = (p-1).(q-1)/GCD(p-1;q-1) = phi/GCD(p-1;q-1) */ BI_ASSIGN_ZERO(GCD, pqDigits); /* JDA */ BI_Gcd(GCD, pM1, qM1, pqDigits); BI_ASSIGN_ZERO(GCM, nDigits); /* JDA */ BI_Div(GCM, t, phi, nDigits, GCD, pqDigits); /* Find the smallest s */ for (k=1; k<256; k++) { BI_ASSIGN_DIGIT(t, k, nDigits); /* t = k */ BI_Mult(u, GCM, t, nDigits); /* u = t.GCM = k.GCM */ BI_ASSIGN_DIGIT(t, 2, nDigits); /* t = 2 */ BI_Div(v, t, u, nDigits, t, nDigits); /* v = k.GCM/2 , modulus is t */ if (BI_Zero(t, nDigits)) { /* modulus is zero -> I can choose this k */ BI_ASSIGN_DIGIT(t, 1, nDigits); /* t = 1 */ BI_Add(v, v, t, nDigits); /* v = v + t = v + 1 = k.GCM/2 + 1 */ BI_ASSIGN_DIGIT(t, 2, nDigits); /* t = 2 */ BI_Div(s, t, v, nDigits, t, nDigits); /* this is s, modulus is t */ if (BI_Zero(t, nDigits)) { /* modulus is zero -> I have found s ! */ return TRUE; } } } return FALSE; }
int main(void) { printf("BigInteger Testing:\n\n"); printf("#1- Creating a BigInteger:\n"); BI* b = BI_Create(1087491031,1); BI_PrintDeci(b); printf("\n"); printf("#2- Trying different prints:\n"); BI_PrintHex(b); BI_PrintBits(b); BI_PrintDeci(b); printf("\n"); printf("#3- Mulitply it with a word:\n"); BI_MultOneWord(b,b,3215728912); BI_PrintDeci(b); printf("\n"); printf("#4- Multiply it with 0:\n"); BI_MultOneWord(b,b,0); BI_PrintDeci(b); printf("\n"); printf("#5- Adding it with a word:\n"); BI_AddOneWord(b,b,1239112); BI_PrintDeci(b); printf("\n"); printf("#6- Adding it with 0:\n"); BI_AddOneWord(b,b,0); BI_PrintDeci(b); BI_PrintHex(b); printf("\n"); printf("#7- Adding it with 4,294,967,295:\n"); BI_AddOneWord(b,b,4294967295); BI_PrintDeci(b); BI_PrintHex(b); printf("\n"); printf("#8- Set to 0 and add it 1024 times: \n"); BI_MultOneWord(b,b,0); for(int i=0; i<1024; i++) BI_AddOneWord(b,b,4294967295); BI_PrintDeci(b); BI_PrintHex(b); printf("\n"); printf("#9- Double it by adding to itself: \n"); BI_Add(b,b,b); BI_PrintDeci(b); BI_PrintHex(b); printf("\n"); printf("#10- Double it 85 more times and add words: \n"); for(int i=0; i<84; i++){ BI_Add(b,b,b); BI_AddOneWord(b,b,-1); } BI_PrintDeci(b); BI_PrintHex(b); printf("\n"); printf("#11- Add lots of words:\n"); for(int i=0; i<50121; i++) { BI_AddOneWord(b,b,i*12342); } BI_AddOneWord(b,b,1); BI_PrintDeci(b); BI_PrintHex(b); printf("\n"); printf("#12- Resting BI to 2:\n"); BI_Free(b); b = BI_Create(2,1); BI_PrintDeci(b); printf("\n"); printf("#13- Testing BI_USubOneWord:\n"); BI_USubOneWord(b,b,1); BI_PrintDeci(b); printf("\n"); printf("#14- Testing carry of subtracting a word: \n"); for(int i=0; i<64; i++) { BI_Add(b,b,b); } printf("Before: \n"); BI_PrintHex(b); BI_USubOneWord(b,b,-1); printf("After: "); BI_PrintHex(b); BI_AddOneWord(b,b,-1); printf("Rest: "); BI_PrintHex(b); printf("\n"); printf("#15- Testing BI_USub: \n"); BI* a = BI_Create(-1,1); printf("A: "); BI_PrintHex(a); printf("B: "); BI_PrintHex(b); BI_USub(b,b,a); printf("Sub: "); BI_PrintHex(b); BI_Add(b,b,a); printf("Rest: "); BI_PrintHex(b); printf("\n"); printf("#16- Testing BI_USub: \n"); for(int i=0; i<16; i++){ BI_Add(a,a,a); } printf("A: "); BI_PrintHex(a); printf("B: "); BI_PrintHex(b); BI_USub(b,b,a); printf("Sub: "); BI_PrintHex(b); BI_Add(b,b,a); printf("Rest: "); BI_PrintHex(b); printf("\n"); BI* c = BI_Create(-1,-1); printf("#17- Creating negative numbers: \n"); BI_PrintDeci(c); printf("\n"); printf("#18- Testing BI_AddOneWord:\n"); BI_AddOneWord(c,c,-1); BI_PrintDeci(c); printf("\n"); BI_Set(c,-1,-1); printf("#19- Testing BI_Add of negative numbers:\n"); BI_Add(c,c,c); BI_PrintDeci(c); printf("\n"); BI_Set(b,9183451,1); BI_Add(c,c,b); BI_PrintDeci(c); printf("\n"); printf("#20- Testing creation from string:\n"); BI_Free(c); c = BI_StringCreate("-12345678901234567890"); BI_PrintDeci(c); BI_Free(c); c = BI_StringCreate("0"); BI_PrintDeci(c); BI_Free(c); c = BI_StringCreate("12345678900987654321"); BI_PrintDeci(c); BI_Free(b); b = BI_StringCreate("-123123123123123"); BI_PrintDeci(b); BI_Copy(a,c); BI_Neg(a); BI_PrintDeci(a); BI* d = BI_Create(0,0); BI_PrintDeci(d); printf("\n"); printf("#21- Testing Add: \n"); BI* out = BI_StringCreate("0"); // b = -123123123123123 // c = 12345678900987654321 // a = -12345678900987654321 // mag are added BI_Add(out,c,c); BI_PrintDeci(out); // mag are sub src > op BI_Add(out,c,b); BI_PrintDeci(out); // mag are sub src < op BI_Add(out,b,c); BI_PrintDeci(out); // mag are sub eq src == op BI_Add(out,a,c); BI_PrintDeci(out); BI_Add(out,a,d); BI_PrintDeci(out); BI_Add(out,d,a); BI_PrintDeci(out); printf("\n"); printf("#22- Testing Sub:\n"); // b = -123123123123123 // c = 12345678900987654321 // a = -12345678900987654321 // mag are added BI_Sub(out,c,a); BI_PrintDeci(out); // mag are sub, src > op BI_Sub(out,a,b); BI_PrintDeci(out); // mag are sub, op > src BI_Sub(out,b,a); BI_PrintDeci(out); // mag are eq BI_Sub(out,a,a); BI_PrintDeci(out); BI_Sub(out,a,d); BI_PrintDeci(out); BI_Sub(out,d,a); BI_PrintDeci(out); printf("\n"); BI_Free(a); BI_Free(b); BI_Free(c); printf("StringCreate is funny\n"); a = BI_StringCreate("2oijfw1029oi"); b = BI_StringCreate("-Alji319oifw"); c = BI_StringCreate("-100000"); BI_PrintDeci(a); BI_PrintDeci(b); BI_PrintDeci(c); printf("\n"); printf("#23- Testing AddOneWord:\n"); // a = 893411103587 // b = -236373259311 // c = 100000 BI_AddOneWord(out,a,10); BI_PrintDeci(out); BI_AddOneWord(out,b,10); BI_PrintDeci(out); BI_AddOneWord(out,c,110000); BI_PrintDeci(out); BI_AddOneWord(out,d,10); BI_PrintDeci(out); printf("\n"); BI_Set(c,1000,1); printf("#24- Testing SubOneWord: \n"); // a = 893411103587 // b = -236373259311 // c = 100000 BI_SubOneWord(out,a,10); BI_PrintDeci(out); BI_SubOneWord(out,b,10); BI_PrintDeci(out); BI_SubOneWord(out,c,99); BI_PrintDeci(out); BI_SubOneWord(out,d,10); BI_PrintDeci(out); printf("\n"); BI_Free(out); printf("#END- Free BigInteger(s):\n"); BI_Free(b); BI_Free(a); BI_Free(c); BI_Free(d); printf("Free'd\n\n"); }
/* * Generation de P et Q utilisables en Rabin * ----------------------------------------- */ BOOL RABIN_GeneratePrimes_BI(BI_DIGIT *p, BI_DIGIT *q, DWORD nDigits, DWORD nBits) { BI_DIGIT t[MAX_BI_DIGITS]; BI_DIGIT u[MAX_BI_DIGITS]; BI_DIGIT v[MAX_BI_DIGITS]; BI_DIGIT n[MAX_BI_DIGITS]; DWORD pqBits, pqDigits; BYTE p_mod_8, q_mod_8; pqDigits = nDigits / 2; pqBits = nBits / 2; /* * Generate prime p between 3*2^(pqBits-2) and 2^pqBits-1, searching * in steps of 2, until one satisfies p mod 8 = 3 or p mod 8 = 7 */ BI_Assign2Exp(t, (WORD) (pqBits-1), pqDigits); BI_Assign2Exp(u, (WORD) (pqBits-2), pqDigits); BI_Add(t, t, u, pqDigits); BI_ASSIGN_DIGIT(v, 1, pqDigits); BI_Sub(v, t, v, pqDigits); BI_Add(u, u, v, pqDigits); BI_ASSIGN_DIGIT(v, 2, pqDigits); for (;;) { if (!GeneratePrime(p, t, u, v, pqDigits)) return FALSE; p_mod_8 = (BYTE) BI_MOD_DIGIT(p, 8, pqDigits); if (p_mod_8 == 3) break; if (p_mod_8 == 7) break; } if (BI_Bits(p, pqDigits) != pqBits) return FALSE; /* * Generate prime q between 3*2^(pqBits-2) and 2^pqBits-1, searching * in steps of 2, until one satisfies q mod 8 = 3 or q mod 8 = 7 and * q mod 8 != p mod 8 */ BI_Assign2Exp(t, (WORD) (pqBits-1), pqDigits); BI_Assign2Exp(u, (WORD) (pqBits-2), pqDigits); BI_Add(t, t, u, pqDigits); BI_ASSIGN_DIGIT(v, 1, pqDigits); BI_Sub(v, t, v, pqDigits); BI_Add(u, u, v, pqDigits); BI_ASSIGN_DIGIT(v, 2, pqDigits); for (;;) { if (!GeneratePrime(q, t, u, v, pqDigits)) return FALSE; q_mod_8 = (BYTE) BI_MOD_DIGIT(q, 8, pqDigits); if (q_mod_8 == p_mod_8) continue; if (q_mod_8 == 3) break; if (q_mod_8 == 7) break; } if (BI_Bits(q, pqDigits) != pqBits) return FALSE; /* * Check size of generated n=p.q */ BI_Mult(n, p, q, pqDigits); if (BI_Bits(n, nDigits) != nBits) return FALSE; /* * Sort so that p > q. (p = q case is extremely unlikely.) */ if (BI_Cmp (p, q, pqDigits) < 0) { BI_Assign (t, p, pqDigits); BI_Assign (p, q, pqDigits); BI_Assign (q, t, pqDigits); } return TRUE; }