-
Notifications
You must be signed in to change notification settings - Fork 0
/
RSA.asm
316 lines (287 loc) · 7.17 KB
/
RSA.asm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
TITLE RSA(RSA.asm)
COMMENT !
// .386
// .model flat, stdcall
// .stack 4096
// ExitProcess proto, dwExitCode:dword
!
INCLUDE Irvine32.inc
.DATA
Pvalue DWORD 0
Qvalue DWORD 0
Mvalue DWORD 0 ;// Modulus M = (P*Q)
Tvalue DWORD 0 ;// Totient ?(M) = (P-1)*(Q-1)
ExitLoop BYTE 0
CaseTable BYTE '1' ;// lookup value
DWORD Input ;// address of procedure
EntrySize = ($ - CaseTable)
BYTE '2'
DWORD PrintPQMT
BYTE '3'
DWORD CreatePrime
BYTE '4'
DWORD DispBigNum
BYTE '5'
DWORD Quit
NumberOfEntries = ($ - CaseTable) / EntrySize
mainmenu BYTE " ----- Main Menu -----", 0dh, 0ah
BYTE "1. Enter the values of P & Q", 0dh, 0ah
BYTE "2. Print the values of P, Q, M & T", 0dh, 0ah
BYTE "3. Generate a random large Prime for P", 0dh, 0ah
BYTE "4. Display large number test", 0dh, 0ah
BYTE "5. Exit", 0dh, 0ah
BYTE "Enter your selection: ", 0
bignum DWORD 4 DUP (0FFFFFFFFh) ;// 18,446,744,073,709,551,615
bigsize = LENGTHOF bignum
Parray DWORD 4 DUP (0) ;// 128 bits
primesize = LENGTHOF Parray
Qarray DWORD primesize DUP (0)
Marray DWORD primesize*2 DUP (0)
sz = TYPE Parray ;// Size of each array element
.CODE
main PROC
call Randomize
Start:
mov edx, OFFSET mainmenu ;// ask user for input
call WriteString
call ReadChar ;// read character into AL
call Crlf
call Crlf
mov ebx, OFFSET CaseTable ;// point EBX to the table
mov ecx, NumberOfEntries ;// loop counter
L1:
cmp al, [ebx] ;// match found ?
jne L2 ;// no: continue
call NEAR PTR [ebx + 1] ;// yes: call the procedure
cmp ExitLoop, 0
ja L3 ;// exit the search
jmp Start
L2:
add ebx, EntrySize ;// point to the next entry
loop L1 ;// repeat until ECX = 0
COMMENT !
// Just an experiment
CallInput:
call Input
jmp Return
CallPrintPQMT:
call PrintPQMT
jmp Return
CallCreatePrime:
call CreatePrime
jmp Return
CallDispBigNum:
call DispBigNum
jmp Return
CallQuit:
call Quit
jmp Return
!
L3:
exit
;// invoke ExitProcess, 0
main ENDP
;//---------------------------------------------------------
CreatePrime PROC USES eax ecx esi edi
;// Generates a large & random prime number
;// Receives: Nothing
;// Returns: Nothing
;// --------------------------------------------------------
call Clrscr
;// Generate a random number
mov ecx, primesize
RandomLoop:
call Random32
cmp ecx, primesize
jne NotFirst
or eax, 80000000h ;// Set the highest bit to ensure the number meets the required length
NotFirst:
cmp ecx, 1 ;// Skip the even test if it's not the last element
jne NotLast
or eax, 1 ;// Make sure the number is odd
NotLast:
mov Parray[ecx * sz - sz], eax
loop RandomLoop
;// For now, copy Parray to bignum, just to display it.
mov ecx, SIZEOF Parray
mov esi, OFFSET Parray
mov edi, OFFSET bignum
rep movsb
call DispBigNum
;push DWORD PTR [bignum] ;// Passing a pointer to the large prime
;call PrimeTest
;add esp, 4 ;// undoing the push
ret
CreatePrime ENDP
;//---------------------------------------------------------
PrimeTest PROC
;// Checks the primality of a number
;// Receives: Nothing
;// Returns: Nothing
;// --------------------------------------------------------
push ebp ;// |
mov ebp, esp ;// Same as "enter 0, 0"
mov esi, [ebp + 4] ;// Pointer to the prime we're testing
COMMENT !
/*
Here we will use the Rabin-Miller Primality test (40 iterations)
Input: n > 2, an odd integer to be tested for primality;
k, a parameter that determines the accuracy of the test
Output: composite if n is composite, otherwise probably prime
write n ? 1 as 2s�d with d odd by factoring powers of 2 from n ? 1
LOOP: repeat k times:
pick a randomly in the range [2, n ? 1]
x ? ad mod n
if x = 1 or x = n ? 1 then do next LOOP
for r = 1 .. s ? 1
x ? x2 mod n
if x = 1 then return composite
if x = n ? 1 then do next LOOP
return composite
return probably prime
*/
!
mov ecx, 40 ;// Perform the test 40 times
RMtest:
loop RMtest
mov esp, ebp ;// |
pop ebp ;// Same as "leave"
ret
PrimeTest ENDP
;//---------------------------------------------------------
DispBigNum PROC USES eax ebx ecx edx esi edi
;// Displays large decimal integers!
;// Receives: Nothing
;// Returns: Nothing
;// --------------------------------------------------------
.DATA
temparr DWORD bigsize DUP (0) ;// The working array
divby DWORD 10 ;// The number we want to divide by
decdigits = 39 ;// There are 39 decimal digits in a 128 bit integer
numdigits DWORD decdigits
digitarr DWORD decdigits DUP (0)
.CODE
call Clrscr
xor eax, eax
xor ecx, ecx
xor edx, edx
;// Copy bignum to temparr
mov ecx, SIZEOF bignum
mov esi, OFFSET bignum
mov edi, OFFSET temparr
rep movsb
mov ecx, numdigits
DigitLoop:
push ecx
;// Divide the big number by 10
xor eax, eax
xor edx, edx
mov ecx, LENGTHOF bignum
DivLoop:
mov eax, temparr[ecx * sz - sz] ;// TYPE temparr = 4
div divby
mov temparr[ecx * sz - sz], eax
loop DivLoop
pop ecx
mov digitarr[ecx * sz - sz], edx ;// Save the remainder to display later
loop DigitLoop
;// Now lets display the large number in decimal
xor eax, eax
xor esi, esi
mov ecx, numdigits
DispLoop:
mov eax, digitarr[esi * sz]
call WriteDec
inc esi
loop DispLoop
call Crlf
ret
DispBigNum ENDP
;//---------------------------------------------------------
Input PROC USES eax edx
;// Gathers input for the values of P & Q
;// Receives: Nothing
;// Returns: Pvalue, Qvalue, Mvalue, Tvalue ?
;// --------------------------------------------------------
.DATA
AskForP BYTE "Enter P (random prime): ", 0
AskForQ BYTE "Enter Q (random prime): ", 0
.CODE
push ebp ;// |
mov ebp, esp ;// Same as "enter 0, 0"
;// Only needed if local variables are used
mov edx, OFFSET AskForP
call WriteString
call ReadDec
mov Pvalue, eax
mov edx, OFFSET AskForQ
call WriteString
call ReadDec
mov Qvalue, eax
call Calculations
call Clrscr
mov esp, ebp ;// |
pop ebp ;// Same as "leave"
ret
Input ENDP
;//---------------------------------------------------------
Calculations PROC USES eax ebx
;// Calculates the values of P, Q, M, & T
;// Receives: EAX
;// Returns: Mvalue & Tvalue ?
;// --------------------------------------------------------
mul Pvalue
mov Mvalue, eax
mov eax, Pvalue
dec eax
mov ebx, Qvalue
dec ebx
mul ebx
mov Tvalue, eax
ret
Calculations ENDP
;//---------------------------------------------------------
PrintPQMT PROC USES eax edx
;// Prints the values of P, Q, M & T
;// Receives: Nothing
;// Returns: Nothing
;// --------------------------------------------------------
.data
Pdisplay BYTE "The value of P is: ", 0
Qdisplay BYTE "The value of Q is: ", 0
Mdisplay BYTE "The value of M (P*Q) is: ", 0
Tdisplay BYTE "The value of T (P-1)*(Q-1) is: ", 0
.code
call Clrscr
mov edx, OFFSET Pdisplay
mov eax, Pvalue
call Display
mov edx, OFFSET Qdisplay
mov eax, Qvalue
call Display
mov edx, OFFSET Mdisplay
mov eax, Mvalue
call Display
mov edx, OFFSET Tdisplay
mov eax, Tvalue
call Display
call Crlf
ret
PrintPQMT ENDP
Display PROC
call WriteString
call WriteDec
call Crlf
ret
Display ENDP
;//---------------------------------------------------------
Quit PROC
;// Exits the program
;// Receives: Nothing
;// Returns: Nothing
;// --------------------------------------------------------
inc ExitLoop
ret
Quit ENDP
END main
END main