|
|
1.1 root 1: /*
2: **
3: ** 80386 assembly primitives for RSA library
4: ** GNU gas syntax, tested with gcc v1.39
5: **
6: ** Compile with UNIT32 defined, MULTUNIT must be unsigned long
7: ** assemble this file with gcc -c (file should have .S suffix)
8: **
9: ** Written by Branko Lankester ([email protected]) 11/18/91
10: ** Last revised: 12/01/92
11: ** Fixed macros to omit space before colon, 23 Jun 93
12: **
13: */
14:
1.1.1.2 ! root 15: #if defined(SYSV) || defined(__ELF__)
! 16: #define ENTRY(name) .align 4 ; .globl name ; name:
! 17: #else
1.1 root 18: #ifdef __STDC__
19: #define ENTRY(name) .align 4 ; .globl _##name ; _##name##:
20: #else
21: #define ENTRY(name) .align 4 ; .globl _/**/name ; _/**/name/**/:
22: #endif
23: #endif
24:
25: .text
26:
27: /*
28: ********************* set precision ********************
29: */
30: ENTRY (P_SETP)
31: pushl %ebp
32: movl %esp,%ebp
33: pushl %ebx
34: pushl %ecx
35: pushl %edx
36: movl 8(%ebp),%eax
37: addl $0x1f,%eax
38: shrl $5,%eax
39: movl %eax,%ebx
40: shrl $3,%eax
41: movl %eax,prec8
42: andl $7,%ebx
43:
44: movl $add_ref,%eax
45: movl %eax,%ecx
46: subl $add_1ref,%eax
47: mul %ebx
48: subl %eax,%ecx
49: movl %ecx,addp
50: movl $sub_ref,%ecx
51: subl %eax,%ecx
52: movl %ecx,subp
53:
54: movl $rot_ref,%eax
55: movl %eax,%ecx
56: subl $rot_1ref,%eax
57: mul %ebx
58: subl %eax,%ecx
59: movl %ecx,rotp
60:
61: movl $mul_ref,%eax
62: movl %eax,%ecx
63: subl $mul_1ref,%eax
64: mul %ebx
65: subl %eax,%ecx
66: movl %ecx,mulp
67:
68: popl %edx
69: popl %ecx
70: popl %ebx
71: leave
72: ret
73:
74:
75:
76: /*
77: ********************* mpi add with carry ********************
78: */
79:
80: #define ADDU lodsl ; adcl %eax,(%ebx,%esi)
81:
82: ENTRY (P_ADDC)
83: pushl %ebp
84: movl %esp,%ebp
85: pushl %ebx
86: pushl %ecx
87: pushl %esi
88: pushl %edi
89: movl 12(%ebp),%esi
90: movl 8(%ebp),%ebx
91: subl %esi,%ebx
92: subl $4,%ebx
93: cld
94: movl 16(%ebp),%eax
95: movl prec8,%ecx
96: orl %ecx,%ecx
97: rcrl $1,%eax /* set the carry flag */
98: jz add_units /* z-flag set by orl %ecx,%ecx */
99: add_8u:
100: ADDU ; ADDU ; ADDU ; ADDU ; ADDU ; ADDU ; ADDU ; ADDU
101: loop add_8u
102: add_units:
103: jmp *addp
104: ADDU ; ADDU ; ADDU ; ADDU ; ADDU ; ADDU
105: add_1ref: /* label to compute size of codes */
106: ADDU
107: add_ref:
108: rcll $1,%eax
109: andl $1,%eax
110:
111: popl %edi
112: popl %esi
113: popl %ecx
114: popl %ebx
115: leave
116: ret
117:
118:
119: /*
120: ********************* mpi subtract with borrow ********************
121: */
122:
123: #define SUBU lodsl ; sbbl %eax,(%ebx,%esi)
124:
125: ENTRY (P_SUBB)
126: pushl %ebp
127: movl %esp,%ebp
128: pushl %ebx
129: pushl %ecx
130: pushl %esi
131: pushl %edi
132: movl 12(%ebp),%esi
133: movl 8(%ebp),%ebx
134: subl %esi,%ebx
135: subl $4,%ebx
136: cld
137: movl 16(%ebp),%eax
138: movl prec8,%ecx
139: orl %ecx,%ecx
140: rcrl $1,%eax
141: jz sub_units
142: sub_8u:
143: SUBU ; SUBU ; SUBU ; SUBU ; SUBU ; SUBU ; SUBU ; SUBU
144: loop sub_8u
145: sub_units:
146: jmp *subp
147: SUBU ; SUBU ; SUBU ; SUBU ; SUBU ; SUBU ; SUBU
148: sub_ref:
149: rcll $1,%eax
150: andl $1,%eax
151:
152: popl %edi
153: popl %esi
154: popl %ecx
155: popl %ebx
156: leave
157: ret
158:
159:
160:
161: /*
162: ********************* mpi rotate left ********************
163: */
164:
165: #define ROTU rcll $1,(%ebx,%esi,4) ; incl %esi
166:
167: ENTRY (P_ROTL)
168: pushl %ebp
169: movl %esp,%ebp
170: pushl %ebx
171: pushl %ecx
172: pushl %esi
173: movl 8(%ebp),%ebx
174: movl 12(%ebp),%eax
175: xorl %esi,%esi
176: movl prec8,%ecx
177: orl %ecx,%ecx
178: rcrl $1,%eax /* set the carry flag */
179: jz rot_units /* z-flag set by orl %ecx,%ecx */
180: rot_8u:
181: rcll $1,(%ebx)
182: rcll $1,4(%ebx)
183: rcll $1,8(%ebx)
184: rcll $1,12(%ebx)
185: rcll $1,16(%ebx)
186: rcll $1,20(%ebx)
187: rcll $1,24(%ebx)
188: rcll $1,28(%ebx)
189: leal 32(%ebx),%ebx
190: loop rot_8u
191: rot_units:
192: jmp *rotp
193: ROTU ; ROTU ; ROTU ; ROTU ; ROTU ; ROTU ; ROTU
194: rot_1ref:
195: ROTU
196: rot_ref:
197: rcll $1,%eax
198: andl $1,%eax
199:
200: popl %esi
201: popl %ecx
202: popl %ebx
203: leave
204: ret
205:
206: /*
207: ********************* mpi multiply ********************
208: */
209: #define MULU \
210: lodsl ; \
211: mull %ebp ; \
212: addl %ebx,%eax ; \
213: adcl $0,%edx ; \
214: addl (%edi),%eax ; \
215: adcl $0,%edx ; \
216: movl %edx,%ebx ; \
217: stosl
218:
219: ENTRY (P_SMULA)
220: pushl %ebp
221: movl %esp,%ebp
222: pushl %ebx
223: pushl %ecx
224: pushl %edx
225: pushl %esi
226: pushl %edi
227:
228: xorl %ebx,%ebx
229: movl prec8,%ecx
230: movl 8(%ebp),%edi
231: movl 12(%ebp),%esi
232: movl 16(%ebp),%ebp
233: cld
234: orl %ecx,%ecx
235: jz mul_units
236: mul_8u:
237: MULU ; MULU ; MULU ; MULU ; MULU ; MULU ; MULU ; MULU
238: decl %ecx
239: jnz mul_8u /* offset too big for loop */
240: mul_units:
241: jmp *mulp
242: MULU ; MULU ; MULU ; MULU ; MULU ; MULU
243: mul_1ref:
244: MULU
245: mul_ref:
246: addl %ebx,(%edi)
247:
248: popl %edi
249: popl %esi
250: popl %edx
251: popl %ecx
252: popl %ebx
253: popl %ebp
254: ret
255:
256:
257: .lcomm _reciph,4
258: .lcomm _recipl,4
259: .lcomm _mshift,4
260:
261: ENTRY (p_setrecip)
262: movl 4(%esp),%eax
263: movl %eax,_reciph
264: movl 8(%esp),%eax
265: movl %eax,_recipl
266: movl 12(%esp),%eax
267: movl %eax,_mshift
268: ret
269:
270:
271: ENTRY (p_quo_digit)
272: pushl %ebp
273: pushl %ebx
274: pushl %esi
275: pushl %edi
276:
277: movl 20(%esp),%esi /* dividend */
278: movl -8(%esi),%eax /* dividend[-2] */
279: notl %eax
280: mull _reciph
281: addl _reciph,%eax
282: adcl $0,%edx
283: movl %eax,%ebx
284: movl %edx,%edi /* di:bx = q1 */
285:
286: movl -4(%esi),%eax /* dividend[-1] */
287: notl %eax
288: mull _recipl
289: incl %edx /* dx:ax = q2 */
290:
291: movl %edx,%ebp
292: andl %edi,%ebp
293: andl $1,%ebp /* bp = lsb_factor */
294:
295: addl %ebx,%eax
296: adcl %edx,%edi
297: rcrl $1,%edi /* di = MS word of q0 */
298:
299: movl -4(%esi),%eax /* dividend [-1] */
300: notl %eax
301: mull _reciph
302: movl %eax,%ebx
303: movl %edx,%ecx /* cx:bx = q1 */
304:
305: movl (%esi),%eax /* dividend[0] */
306: notl %eax
307: mull _recipl /* dx:ax = q2 */
308: xorl %ebx,%eax
309: andl %eax,%ebp /* lsb correction */
310: xorl %ebx,%eax /* restore ax */
311:
312: addl %ebx,%eax
313: adcl %ecx,%edx
314: rcrl $1,%edx
315: rcrl $1,%eax /* dx:ax = q */
316:
317: addl %edi,%eax /* + scaled q0 */
318: adcl $0,%edx
319: addl %ebp,%eax /* + lsb correction */
320: adcl $0,%edx /* q */
321:
322: shll $1,%eax
323: rcll $1,%edx
324: rcll $1,%eax
325: rcll $1,%edx
326: rcll $1,%eax
327: andl $3,%eax
328: movl %eax,%ecx
329: movl %edx,%ebx /* bx:cx = q >> 14 */
330:
331: movl (%esi),%eax /* dividend[0] */
332: notl %eax
333: mull _reciph
334: shll $1,%eax
335: rcll $1,%edx
336: addl %ebx,%eax
337: adcl %ecx,%edx /* q */
338:
339: movl _mshift,%ecx
340: cmpl $32,_mshift
341: je L2
342: #if 0
343: shrl %cl,%eax
344: movl %edx,%ebx
345: shrl %cl,%edx
346: negl %ecx
347: addl $32,%ecx
348: shll %cl,%ebx
349: addl %ebx,%eax /* dx:ax = q >> mshift */
350: #else
1.1.1.2 ! root 351: #if defined(SYSV) || defined(__ELF__)
1.1 root 352: shrdl %edx,%eax
353: #else
354: shrdl %cl,%edx,%eax
355: #endif
356: shrl %cl,%edx
357: #endif
358:
359: orl %edx,%edx
360: je L1
361: movl $-1,%eax
362: jmp L1
363: L2:
364: xchgl %edx,%eax
365: L1:
366: popl %edi
367: popl %esi
368: popl %ebx
369: popl %ebp
370: ret
371:
372: .lcomm prec8,4
373: .lcomm addp,4
374: .lcomm subp,4
375: .lcomm rotp,4
376: .lcomm mulp,4
377:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.