. EMK: {KC }→ EKM0(KC)
o Other user
1.4. Các tập tin nguồn (*.c): 1 R_random.c
1.4.1. R_random.c
- Giới thiệu:
Các hàm khác nhau trong RSATOOL yêu cầu data ngẫu nhiên (cơ bản để tạo khóa). Một dòng dta ngẫu nhiên (random data stream) được tạo sử dụng giải thuật chữ ký MD5 và giá trị “seed” được cung cấp trong form của cấu trúc random.
Trước khi sử dụng, cấu trúc random phải được khởi tạo và chính bản thân nó phải được seed bằng cách trôn vào một lượng ngẫu nhiên thật.
Thủ tục để chuẩn bị một cấu trúc random mới như sau:
1. Để dành (reserve) sizeof (R_RANDOM_STRUCT) bộ nhớ.
2. Khởi tạo cấu trúc mới sử dụng R_RandomInit. Thiết lập random -> bytesNeeded, số byte ngẫu nhiên yêu cầu để seed cấu trúc trước khi sử dụng, để RANDOM_BYTES_RQ và zero data.
3. Trộn một lượng data random thích hợp sử dụng R_RandomUpdate. Nó lấy một khối data được cung cấp bởi người gọi và kết hợp nó với cấu trúc random có sẵn MD5. Đồng thời nó cũng giảm random -> butesNeeded mà chỉ ra lượng data random còn yêu cầu (hàm R_GetRandomBytesNeeded và trả về trị bytesNeeded của cấu trúc random đã cho). R_RandomUpdate sẽ được lặp lại cho đến khi R_GetRandomBytesNeeded trả về 0.
R_RandomUpdate: có thể được gọi một khi cấu trúc cấu trúc đã được khởi tạo (VD: bytesNeeded = 0). RANDOM_BYTES_RQ sẽ được điều chỉnh theo "purity" của nguồn data random.
R_RandomCreate: tạo và khởi tạo một cấu trúc random tươi (fresh) sử dụng data từ đồng hồ hệ thống hiện tại, thông qua hàm gmtime của ANSI (hàm này chủ yếu sử dụng biến tách biệt RANDOM_BYTES_INT để chỉ lượng byte tổng hợp, hiện tại thiết lập ở
512). Trên hệ thống tương thích ANSI, R_RandomCreate có thể được sử dụng như cửa hàng một trạm (one_stop) cho việc tạo một cấu trúc random dễ dàng để sử dụng. Các nguồn data random khác như số lần gõ bàn phím, số lần truy xuất đĩa,…
Một khi cấu trúc random đã được khởi tạo, việc khởi tạo và seed nó có thể được sử dụng bởi R_GenerateBytes để tạo ra dòng data random giả. R_GenerateBytes trả về một lỗi nếu cấu trúc random không hợp lệ (không được seed) được tham khảo.
Hàm R_RandomMix: sử dụng hàm đồng hồ và thời gian ANSI để lấy ngẫu nhiên trạng thái hiện tại của cấu trúc random có sẵn, đã được khởi tạo. Sau đó, lấy đi output nào đang chờ từ trạng thái output.
Hàm R_RandomFinal: xóa cấu trúc random. - Các hàm random:
R_RandomInit
Int R_RandomInit(random) R_RANDOM_STRUCT *random;
Khởi tạo một cấu trúc random mới. Zero vùng data và thiết lập random -> bytesNeeded tới default của hệ thống (RANDOM_BYTES_RQ). Lu6n trả về IDOK (=0).
R_RandomUpdate
Int R_RandomUpdate(random, block, len) R_RANDOM_STRUCT *random;
unsigned char *block; unsigned int len;
Cập nhật cấu trúc random đã được khởi tạo trước đây bằng cách trộn khối data được cung cấp bởi người gọi (sử dụng MD5). Cập nhật random -> bytesNeeded khi thích hợp. Luôn trả về IDOK.
R_GetRandomBytesNeeded
Int R_GetRandomBytesNeeded(bytesNeeded, random) R_RANDOM_STRUCT *random;
Unsigned int bytesNeeded; (số byte trộn cần thiết)
Trả về số byte seed vẫn còn yêu cầu cho cấu trúc random. Khi thoát, bytesNeeded chứa số byte yêu cầu bởi cấu trúc random. Luôn trả về IDOK.
R_GenerateBytes
Int R_GenerateBytes(block, len, random) unsigned char *block; (khối data)
unsigned int len; (chiều dài khối)
Tạo khối data cần thiết với chiề dài số byte giả random (len) dẫn xuất từ random sử dụng MD5. Trả về RE_NEED_RANDOM nếu random không được khởi tạo một cách đầy đủ, ngược lại trả về IDOK.
R_RandomFinal
void R_RandomFinal(random) R_RANDOM_STRUCT *random;
Xóa cấu trúc random, thiết lập tất cả giá trị và data bằng zero.
R_RandomCreate
void R_RandomCreate(random) R_RANDOM_STRUCT *random;
Khởi tạo cấu trúc random và seed nó với data được dẫn xuất từ việc sử dụng hàm gmtime và clock của ANSI. Lượng data seed được xác định bởi RANDOM_BYTES_RQINT.
R_RandomMix
void R_RandomMix(random) R_RANDOM_STRUCT *random
Ngẫu nhiên hóa (randomises) trạng thái bên trong của cấu trúc random được cung cấp, sử dụng data từ các hàm clock và time của ANSI, sau đó lấy đi bất kỳ output chờ.
1.4.2. NN.c
- Giới thiệu: tập tin này chứa các giải thuật liên quan đến số tự nhiên (số kiểu NN_DIGIT: 4 byte) đã định nghĩa trong nn.h được sử dụng bởi các hàm khác nhau trong RSATOOL.
- Các hàm:
NN_Decode
NN_DIGIT *a; Unsigned char *b;
Unsigned int digits, len;
Biến đổi xâu b có chiều dài len thành số tự nhiên a có chiều dài digits.Digits phải đủ lớn để chứa len byte biến đổi, nếu digits nhỏ thì các byte MSB của số sẽ bị cắt. Các phép toán thực hiện việc biến đổi là: phép toán and và phép toán dịch trái.
NN_Encode
Void NN_Encode (b, len, a, digits) NN_DIGIT *a;
Unsigned char *b;
Unsigned int digits, len;
Biến đổi số tự nhiên a có chiều dài digits thành xâu b có chiều dài len. Len phải đủ lớn để chứa digits biến đổi từ a, nếu len nhỏ thì các byte MSB của số sẽ bị cắt. Các phép toán thực hiện việc biến đổi là: phép toán and và phép toán dịch phải.
NN_Assign
Void NN_Assign (b, a, digits) NN_DIGIT *a, *b; Unsigned int digits;
Thiết lập a = b (a, b là các số tự nhiên). Nếu a > b (NNDigits(a) > NNDigits(b)) thì digits MSB của a sẽ bị xóa.
NN_AssignZero
Void NN_AssignZero (a, digits) NN_DIGIT *a; Unsigned int digits;
Zero các chữ số (digits) của số tự nhiên a: a = 0.
NN_Assign2Exp
Void NN_Assign2Exp (a, b, digits) NN_DIGIT *a;
Thiết lập a = 2b với a là số tự nhiên có chiều dài digits và b số mũ nguyên bằng cách dịch 1 qua trái b mod 32 bít. Kết quả sẽ không xác định nếu b > digits*32.
NN_Add
NN_DIGIT NN_Add (a, b, c, digits) NN_DIGIT *a, *b, *c; Unsigned int digits;
Tính a = b + c và trả về carry. a, b, c và giá trị trả về là các số tự nhiên, tất cả có chiều dài digits.
NN_Sub
NN_DIGIT NN_Sub (a, b, c, digits) NN_DIGIT *a, *b, *c; Unsigned int digits;
Tính a = b – c và trả về borrow. a, b, c và giá trị trả về là các số tự nhiên, tất cả có chiều dài digits.
NN_Mult
Void NN_Mult (a, b, c, digits) NN_DIGIT *a, *b, *c; Unsigned int digits;
Tính a = b * c. a, b, c và giá trị trả về là các số tự nhiên, tất cả có chiều dài digits. Kết quả không xác định nếu digits > MAX_NN_DIGITS.
NN_LShift
NN_DIGIT NN_LShift (a, b, c, digits) NN_DIGIT *a, *b;
Unsigned int c, digits;
Tính a = b * 2c (dịch b qua trái c bít, kết quả trả về trong a). a, b, c và giá trị trả về là các số tự nhiên, tất cả có chiều dài digits. Kết quả không xác định nếu c > 32.
NN_RShift
NN_DIGIT NN_RShift (a, b, c, digits) NN_DIGIT *a, *b;
Tính a = b div 2c (dịch b qua phải c bít, kết quả trả về trong a). a, b, c và giá trị trả về là các số tự nhiên, tất cả có chiều dài digits. Kết quả không xác định nếu c > 32.
NN_Div
Void NN_Div (a, b, c, cDigits, d, dDigits) NN_DIGIT *a, *b, *c, *d; Unsigned int cDigits, dDigits;
Tính a = c div d và b = c mod d. a, b, c và d là các số tự nhiên, a và c có chiều dài
cDigits, còn b và d có chiều dài dDigits. Kết quả không xác định nếu d = 0, cDigits > = 2*MAX_NN_DIGITS hay dDigits > MAX_NN_DIGITS.
NN_Mod
Void NN_Mod (a, b, bDigits, c, cDigits) NN_DIGIT *a, *b, *c;
Unsigned int bDigits, cDigits;
Tính a = b mod c. a, b và c là các số tự nhiên, a và c có chiều dài cDigits, còn b có chiều dài bDigits. Kết quả không xác định nếu c = 0, bDigits > = 2*MAX_NN_DIGITS hay
cDigits > MAX_NN_DIGITS.
NN_ModMult
Void NN_ModMult (a, b, c, d, digits) NN_DIGIT *a, *b, *c, *d; Unsigned int digits;
Tính a = b*c mod d. a, b, c và d là các số tự nhiên, tất cả có chiều dài digits. Kết quả không xác định nếu d = 0 hay digits > MAX_NN_DIGITS.
NN_ModExp
Void NN_ModExp (a, b, c, cDigits, d, dDigits) NN_DIGIT *a, *b, *c, *d;
Unsigned int cDigits, dDigits;
Tính a = bc mod d. a, b, c và d là các số tự nhiên, a, b và d có chiều dài dDigits, còn c có chiều dài cDigits. Kết quả không xác định nếu d = 0, cDigits = 0 hay dDigits > MAX_NN_DIGITS.
NN_ModInv
Void NN_ModInv (a, b, c, digits) NN_DIGIT *a, *b, *c; Unsigned int digits;
Tính a = b-1 mod c. a, b và c là các số tự nhiên, tất cả có chiều dài digits. Kết quả không xác định nếu b và c không có quan hệ nguyên tố (gcd(b, c) khác 1) hay digits > MAX_NN_DIGITS.
NN_Gcd
Void NN_Gcd (a, b, c, digits) NN_DIGIT *a, *b, *c; Unsigned int digits;
Tính ước số chung lớn nhất của b và c, kết quả trả về trong a. a, b và c là các số tự nhiên, tất cả có chiều dài digits. Kết quả không xác định nếu c < b hay digits > MAX_NN_DIGITS.
NN_Cmp
Int NN_Cmp (a, b, digits) NN_DIGIT *a, *b; Unsigned int digits;
So sánh a và b. a, b là các số tự nhiên, tất cả có chiều dài digits. Kết quả trả về 1 nếu a > b, 0 nếu a = b, -1 nếu a < b.
NN_Zero
Int NN_Zero (a, digits) NN_DIGIT *a; Unsigned int digits;
Trả về 1 nếu a = 0 ngược lại trả về 0. a là các số tự nhiên, có chiều dài digits.
NN_Digits
Unsigned int NN_Digits (a, digits) NN_DIGIT *a;
Trả về chiều dài (bằng digits) thật sự của a (bỏ các digits dẫn đầu bằng 0). a là các số tự nhiên, có chiều dài digits.
NN_Bits
Unsigned int NN_Bits (a, digits) NN_DIGIT *a;
Unsigned int digits;
Trả về chiều dài (bằng bít) của a (bỏ các bít dẫn đầu bằng 0). a là các số tự nhiên, có chiều dài digits.