XÂY DỰNG CHƯƠNG TRÌNH KIỂM TRA SỐ NGUYÊN TỐ BẰNG THUẬT TOÁN MILLER- RABIN
Trang 1XÂY DỰNG CHƯƠNG TRÌNH KIỂMTRA SỐ NGUYÊN TỐ BẰNG THUẬT
TOÁN MILLER- RABIN
MỤC LỤC
CHƯƠNG 1: CƠ SỞ THUẬT TOÁN CHƯƠNG 2: PHÂN TÍCH VÀ THIẾT KẾ CHƯƠNG 3: CÀI ĐẶT VÀ KIỂM THỬ
PHỤ LỤC
Trang 2Chương 1
CƠ SỞ THUẬT TOÁN 1.Giới thiệu
Bài toán kiểm tra số nguyên tố là một trong những bài toán cơ bản nhưng hết sức quan trong trọng lĩnh vực an toàn và bảo mật thông tin cụ thể là trong hệ mật RSA.Có rất nhiều phương pháp kiểm tra số nguyên tố như : phương pháp chứng minh theo định lý Fecma, phương pháp sàng số nguyên tố Eratosthenes, phương pháp kiểm tra theo xác suất Thuật toán Miller- Rabin là thuật toán dựa trên phương pháp chứng minh theo xác suất.Thuật toán này được thao tác trên số lớn.
2.Cơ sở thuật toán Miller-Rabin
Thuật toán này dựa trên một định lý quan trong sau:
”Nếu n là số nguyên tố thì (n-1 )!≡ (n-1) mod n”.
“Với mỗi số nguyên n, Ф(n) là số các số nguyên tố cùng nhau với n mà nhỏ hơn n Khi đó, với mọi x, x > 0, xФ(n) ≡ 1 mod n ”.
3.Thuật toán
Sơ đồ thuật toán:
Trang 3Thuật toán:
a.Đầu vào : Là một số nguyên n > 3, và một tham số an toàn t (là số lần thực hiện kiểm tra
n )
b.Đầu ra : Trả lời câu hỏi n có là số nguyên tố không ?Câu trả lời là “prime” nếu là số
nguyên tố ngược lại là “composite”
for( I =1 ; i<k ; i++)
if( b≡-1 mod n ) then return “prime”;
Trang 4An toàn và bảo mật thông tin trong lĩnh vực công nghệ thông tin ngày càng trở nên quan
+ great: là một mảng dữ liệu kiểu NN_DIGIT để biểu diễn số lớn.
+ one : là một mảng dữ liệu kiểu NN_DIGIT để biểu diễn số lớn dùng thao tác trung gian
b.Phương thức:
+ void Div (NN_DIGIT *a, NN_DIGIT *b, NN_DIGIT *c,UINT2 cDigits, NN_DIGIT *d,UINT2 dDigits);
Thực hiện phép chia a = c div d and b = c mod d.
+ NN_DIGIT LShift (NN_DIGIT *a, NN_DIGIT *b, UINT2 c,UINT2 digits);
Trang 6{
NN_DIGIT t; UINT2 i, j, u;
/* @##$ unsigned/signed bug fix added JSAK - Fri 31/05/96 18:09:11 */
for (i = 0, j = 0; i < digits && j < len; i++) { t = b[i];
for (u = 0; j < len && u < NN_DIGIT_BITS; j++, u += 8) a[j] = (UINT1)(t >> u);
/* @##$ unsigned/signed bug fix added JSAK - Fri 31/05/96 18:09:11 */ for (i = 0, j = 0; i < digits && j < len ; i++) {
Trang 8NN_DIGIT *d, UINT2 dDigits)
Assign (bPower[0], b, dDigits);
ModMult (bPower[1], bPower[0], b, d, dDigits); ModMult (bPower[2], bPower[1], b, d, dDigits); NN_ASSIGN_DIGIT (t, 1, dDigits);
cDigits = NN_Digits (c, cDigits); for (i = cDigits - 1; i >= 0; i ) {
Trang 9NN_DIGIT dhigh, dlow, carry; UINT2 bDigits, cDigits, i, j;
AssignZero ((UINT4*)t, (UINT2)(2 * digits)); bDigits = NN_Digits (b, digits);
cDigits = NN_Digits (c, digits);
for (i = 0; i < bDigits; i++) { carry = 0;
if(*(b+i) != 0) {
for(j = 0; j < cDigits; j++) {
dmult(*(b+i), *(c+j), &dhigh, &dlow);
if((*(t+(i+j)) = *(t+(i+j)) + carry) < carry)
Trang 10void bigNumber::dmult(NN_DIGIT a, NN_DIGIT b, NN_DIGIT *high, NN_DIGIT *low) *low = (NN_DIGIT) al*bl;
*high = (NN_DIGIT) ah*bh;
Trang 11NN_DIGIT temp, carry = 0;
NN_DIGIT bigNumber::subdigitmult(NN_DIGIT *a, NN_DIGIT *b, NN_DIGIT c, NN_DIGIT *d, unsignedint digits)
for(i = 0; i < digits; i++) {
dmult(c, d[i], &thigh, &tlow);
if((a[i] = b[i] - borrow) > (MAX_NN_DIGIT - borrow))
NN_DIGIT *d, UINT2 dDigits)
Trang 12UINT2 ddDigits, shift;
ddDigits = NN_Digits (d, dDigits);
if(ddDigits == 0)
shift = NN_DIGIT_BITS - NN_DigitBits (d[ddDigits-1]); AssignZero (cc, ddDigits);
cc[cDigits] = LShift (cc, c, shift, cDigits); LShift (dd, d, shift, ddDigits);
s = dd[ddDigits-1]; AssignZero (a, cDigits);
for (i = cDigits-ddDigits; i >= 0; i ) {
((*(t+1) == cHigh) && (*t >= TO_HIGH_HALF (cLow)))) {
TO_HIGH_HALF (cLow))
t[1] ; *(t+1) -= cHigh; aHigh++;
Trang 13cc[i+ddDigits] -= subdigitmult(&cc[i], &cc[i], ai, dd, ddDigits);
while (cc[i+ddDigits] || (Compare (&cc[i], dd, ddDigits) >= 0)) {
Trang 14} while (!veryLong.isPrime(veryLong.great, NN_SIZE2, 10)); printf("\rMot so nguyen to ngau nhien:\n\n");
for (i=NN_SIZE2;i>0; printf("%08lX",veryLong.great[ i]));