:NGUYỄN HỮU MẠNH Bài toán elgamal Phát biểu bài toán : Cho số nguyên tố p, gọi α thuộc Z*p là phần tử sinh và β thuộc Z*p , Cần xác định số nguyên dương a thuộc Z*p-1 sao cho ◦ αa = β(mod p ) Khi đó , a được ký hiệu là logα β XÁC ĐỊNH BÀI TOÁN Input: số nguyên tố p, 2 số nguyên tố nhỏ hơn p là α (phần tử nguyên thủy của Z*p ) và a (khóa bí mật của người nhận) Output: β là khóa công khai Thuật toán chung B1: Chọn số nguyên tố p sao cho bài toán logarit rời rạc trong Z*p là “khó” giải. B2: Cho phần tử nguyên thuỷ α thuộc Zp* B3: Chọn khóa bí mật là a thuộc Zp* B4: Tính khóa công khai β = αa mod p. B5: Khóa công khai là (p, α, β) và khóa bí mật là (a). Thuật toán chung B1: Chọn số nguyên tố p sao cho bài toán logarit rời rạc trong Z*p là “khó” giải. Ý tưởng: em sẽ chọn số nguyên tố p bằng cách sử dụng 1 hàm random() để chọn ngẫu nhiên 1 số trong khoảng đã xét ◦ : sau đó em sẽ kiểm tra số đã cho ở trên có phải số nguyên tố không nếu đúng thì in ra còn sai thì chọn random lại Thuật toán chung B2: Cho phần tử nguyên thuỷ α thuộc Zp* Ý tưởng: sử dụng 1 hàm liệt kê ra các số nguyên tố trong khoảng từ 2 đến p ◦ : sau tính mỗi số nguyên tố bằng cách lũy thừa mỗi nguyên tố với các số tang dần từ 1 đến p ◦ : kiểm tra mỗi phép tính có bằng với các số nguyên tố trong mảng ở trên ◦ : Nếu đúng tăng count lên 1 lần, Ngược lại thì kiểm tra số khác ◦ : Sau đó so sách số count của mỗi số nguyên tố , nếu số nguyên tố nào có số count lớn nhất thì là phần tử sinh Thuật toán chung B3: Chọn khóa bí mật là a thuộc Zp* Ý tưởng: em sẽ chọn số nguyên a bằng cách sử dụng 1 hàm random() để chọn ngẫu nhiên 1 số trong khoảng đã xét ◦ : sau đó em sẽ kiểm tra số đã cho ở trên có phải số nguyên tố không nếu đúng thì in ra còn sai thì chọn random lại Các hàm trong chương trình int PhanTuSinh(int dem, int mangnguyento[Max], int khoa_1, int k); int SinhKhoa(int khoa_1, int key, int pt_sinh, unsigned long int khoa_3); int random(int minN, int maxN); bool KTsnt(int n); void mangsonguyento(int dem, int khoa_2[Max],int soluongmang,int mangnguyento[Max] ,int khoa_1); int random(int minN, int maxN); Input: số min và số max (khoảng cách để chọn ngẫu nhiên trong khoảng từ min đến max) Output: số ngẫu nhiên được chọn trong khoảng min đến max bool KTsnt(int n); Input: một số n bất kỳ Output: đưa ra kết quả true nếu n là số nguyên tố, ngược lại không phải số nguyên tố thì false Thuật toán: khởi tạo biến count = 0 : nếu n = 1 thì return false; : Cho for có i=2 chạy trong khoảng từ i <= √n : Nếu n % I ==0 thì tăng count++ : Nếu count == 0 thì true, còn ngược lại thì false void mangsonguyento(int dem, int mang[Max], mangnguyento[Max] ,int khoa_1);
Input: Cho một mảng là mang , số nguyên tố khoa_1
Output: Một mảng chứa số nguyên tố từ 2 đến khoa_1 và biến dem là số lượng số nguyên tố trong mảng đó Thuật toán: khởi tạo mảng là mang và gán mỗi giá trị trong mang đó từ 1 đến khoa_1 :Dùng for để kiểm tra xem những số nào trong mang[] là số nguyên tố , nếu đúng thì gán số nguyên tố đó vào mangnguyento[] và tang biến đếm : Còn sai thì thôi int PhanTuSinh(int dem, int mangnguyento[Max], int khoa_1,int k); Input: Biến dem chứa số lượng nguyên tố, mangnguyento[] chứa các số nguyên tố trong khoảng từ 2 đến khoa_1, số nguyên tố khoa_1 Output: đưa ra k là phần tử sinh Thuật toán: khởi tạo biến count = 0 và mảng dem1 để chứa các lớp đồng dư của mỗi số nguyên tố : dùng for để kiểm tra xem mỗi số nguyên tố có lớp đồng dư không, nếu có thì tăng biến count++ của từng số nguyên tố : Xem số count của số nguyên tố nào nhiều hơn thì đó là phần tử sinh k int SinhKhoa(int khoa_1, int key, int pt_sinh, unsigned long int khoa_3); Input: số nguyên tố khoa_1 và 2 số nguyên key và pt_sinh Output: khóa công khai khoa_3 Thuật toán: Tính khoa_3 = pt_sinh key mod khoa_1 rồi return khoa_3 ra