You are on page 1of 13

Sinh khóa chữ ký số Elgamal

NHÓM GỒM CÓ : NGUYỄN CHÍ NGUYÊN


: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

You might also like