summaryrefslogtreecommitdiffabout
path: root/pwmanager/libcrypt/mpi
authorzautrix <zautrix>2004-10-19 20:16:14 (UTC)
committer zautrix <zautrix>2004-10-19 20:16:14 (UTC)
commiteca49bb06a71980ef61d078904573f25890fc7f2 (patch) (unidiff)
treec5338e3b12430248979a9ac2c1c7e6646ea9ecdf /pwmanager/libcrypt/mpi
parent53cc32b6e7b1f672bf91b2baf2df6c1e8baf3e0a (diff)
downloadkdepimpi-eca49bb06a71980ef61d078904573f25890fc7f2.zip
kdepimpi-eca49bb06a71980ef61d078904573f25890fc7f2.tar.gz
kdepimpi-eca49bb06a71980ef61d078904573f25890fc7f2.tar.bz2
Initial revision
Diffstat (limited to 'pwmanager/libcrypt/mpi') (more/less context) (ignore whitespace changes)
-rw-r--r--pwmanager/libcrypt/mpi/ChangeLog572
-rw-r--r--pwmanager/libcrypt/mpi/Manifest41
-rw-r--r--pwmanager/libcrypt/mpi/asm-syntax.h71
-rw-r--r--pwmanager/libcrypt/mpi/generic/Manifest29
-rw-r--r--pwmanager/libcrypt/mpi/generic/distfiles11
-rw-r--r--pwmanager/libcrypt/mpi/generic/mpi-asm-defs.h10
-rw-r--r--pwmanager/libcrypt/mpi/generic/mpih-add1.c65
-rw-r--r--pwmanager/libcrypt/mpi/generic/mpih-lshift.c68
-rw-r--r--pwmanager/libcrypt/mpi/generic/mpih-mul1.c62
-rw-r--r--pwmanager/libcrypt/mpi/generic/mpih-mul2.c68
-rw-r--r--pwmanager/libcrypt/mpi/generic/mpih-mul3.c68
-rw-r--r--pwmanager/libcrypt/mpi/generic/mpih-rshift.c67
-rw-r--r--pwmanager/libcrypt/mpi/generic/mpih-sub1.c66
-rw-r--r--pwmanager/libcrypt/mpi/generic/udiv-w-sdiv.c133
-rw-r--r--pwmanager/libcrypt/mpi/longlong.h1561
-rw-r--r--pwmanager/libcrypt/mpi/mpi-add.c236
-rw-r--r--pwmanager/libcrypt/mpi/mpi-bit.c257
-rw-r--r--pwmanager/libcrypt/mpi/mpi-cmp.c74
-rw-r--r--pwmanager/libcrypt/mpi/mpi-div.c364
-rw-r--r--pwmanager/libcrypt/mpi/mpi-gcd.c54
-rw-r--r--pwmanager/libcrypt/mpi/mpi-inline.c36
-rw-r--r--pwmanager/libcrypt/mpi/mpi-inline.h154
-rw-r--r--pwmanager/libcrypt/mpi/mpi-internal.h275
-rw-r--r--pwmanager/libcrypt/mpi/mpi-inv.c275
-rw-r--r--pwmanager/libcrypt/mpi/mpi-mpow.c224
-rw-r--r--pwmanager/libcrypt/mpi/mpi-mul.c220
-rw-r--r--pwmanager/libcrypt/mpi/mpi-pow.c302
-rw-r--r--pwmanager/libcrypt/mpi/mpi-scan.c132
-rw-r--r--pwmanager/libcrypt/mpi/mpi.pro42
-rw-r--r--pwmanager/libcrypt/mpi/mpicoder.c643
-rw-r--r--pwmanager/libcrypt/mpi/mpih-div.c535
-rw-r--r--pwmanager/libcrypt/mpi/mpih-mul.c530
-rw-r--r--pwmanager/libcrypt/mpi/mpiutil.c431
-rw-r--r--pwmanager/libcrypt/mpi/sysdep.h2
34 files changed, 7678 insertions, 0 deletions
diff --git a/pwmanager/libcrypt/mpi/ChangeLog b/pwmanager/libcrypt/mpi/ChangeLog
new file mode 100644
index 0000000..777fc7b
--- a/dev/null
+++ b/pwmanager/libcrypt/mpi/ChangeLog
@@ -0,0 +1,572 @@
12004-03-02 Werner Koch <wk@gnupg.org>
2
3 * hppa1.1/udiv-qrnnd.S: Alignment fix from Lamont Jones for
4 Debian. Taken from gnupg-1.3.
5
6 * longlong.h: Added PowerPC 64 bit code from GPM-4.1.2 but didn't
7 enable it yet. Some whitespace changes in HPPA to fix assembler
8 problems on HP-UX. From gnupg 1.3
9
10 * mpiutil.c (_gcry_mpi_alloc_limb_space): Better allocate
11 something even if NLIMBS is passed as 0.
12
13 * config.links: Updated system list to match gnupg 1.3.
14
152003-12-19 Werner Koch <wk@gnupg.org>
16
17 * mpi-internal.h [M_DEBUG]: Removed this unused code.
18 (struct karatsuba_ctx): Added TSPACE_NLIMBS andTP_NLIMBS.
19 * mpiutil.c (_gcry_mpi_free_limb_space): Add arg NLIMBS and wipe
20 out the memory. Changed all callers.
21 * mpih-mul.c (_gcry_mpih_mul_karatsuba_case): Keep track of
22 allocated limbs.
23 * mpi-div.c (_gcry_mpi_tdiv_qr): Keep track of allocated limbs.
24 * mpi-mul.c (gcry_mpi_mul): Ditto.
25 * mpi-pow.c (gcry_mpi_powm): Ditto.
26
27 * Manifest: Empty new file. Also add Manifest files to all CPU
28 specific directories.
29 * Makefile.am: Added.
30
31 * mpiutil.c (gcry_mpi_randomize): Use gcry_create_nonce if WEAK
32 random has been requested.
33
342003-10-31 Werner Koch <wk@gnupg.org>
35
36 * i386/mpih-rshift.S, i386/mpih-lshift.S: Use %dl and not %edx for
37 testb; this avoids an assembler warning.
38
39 * mpi-pow.c (gcry_mpi_powm): s/exp/expo/ to avoid shadowing warning.
40
412003-08-19 Marcus Brinkmann <marcus@g10code.de>
42
43 * Makefile.am (SUFFIXES): New variable.
44 (.S.o, .S.lo, .S.obj): Rewritten.
45
462003-07-30 Moritz Schulte <moritz@g10code.com>
47
48 * longlong.h (__clz_tab): Renamed to _gcry_clz_tab.
49 * mpi-bit.c (__clz_tab): Likewise.
50
512003-07-27 Werner Koch <wk@gnupg.org>
52
53 * mpicoder.c (gcry_mpi_scan): New argument BUFLEN to replace the
54 use of the intial value of NBYTES. Changed BUFFER to unsigned.
55 (gcry_mpi_print): Likewise.
56 (gcry_mpi_dump): New.
57 (_gcry_log_mpidump): Make use of gcry_mpi_dump.
58 (mpi_print): Removed.
59 (gcry_mpi_scan): Allocated mpi in secure memory when required.
60 (gcry_mpi_aprint): Changed BUFFER to unsigned char*.
61
622003-07-14 Moritz Schulte <moritz@g10code.com>
63
64 * mpicoder.c: Used gcry_err* wrappers for libgpg-error symbols.
65
662003-06-16 Moritz Schulte <moritz@g10code.com>
67
68 * mpi-add.c: Replace last occurences of old type names with newer
69 names (i.e. replace MPI with gcry_mpi_t).
70 * mpi-bit.c: Likewise.
71 * mpi-cmp.c: Likewise.
72 * mpi-div.c: Likewise.
73 * mpi-gcd.c: Likewise.
74 * mpi-internal.h: Likewise.
75 * mpi-inv.c: Likewise.
76 * mpi-mpow.c: Likewise.
77 * mpi-mul.c: Likewise.
78 * mpi-pow.c: Likewise.
79 * mpi-scan.c: Likewise.
80 * mpicoder.c: Likewise.
81 * mpiutil.c: Likewise.
82
832003-06-09 Moritz Schulte <moritz@g10code.com>
84
85 * mpicoder.c (gcry_mpi_scan): Adjust for libgpg-error.
86 (gcry_mpi_print): Likewise.
87 (gcry_mpi_aprint): Likewise.
88
892003-06-07 Moritz Schulte <moritz@g10code.com>
90
91 * longlong.h, mpi-add.c, mpi-bit.c, mpi-cmp.c, mpi-div.c,
92 mpi-gcd.c, mpi-inline.c, mpi-inline.h, mpi-internal.h, mpi-inv.c,
93 mpi-mpow.c, mpi-mul.c, mpi-pow.c, mpi-scan.c, mpicoder.c,
94 mpih-div.c, mpih-mul.c, mpiutil.c, generic/mpi-asm-defs.h,
95 generic/mpih-add1.c, generic/mpih-lshift.c, generic/mpih-mul1.c,
96 generic/mpih-mul2.c, generic/mpih-mul3.c, generic/mpih-rshift.c,
97 generic/mpih-sub1.c, generic/udiv-w-sdiv.c, i386/syntax.h,
98 m68k/syntax.h, mips3/mpi-asm-defs.h, powerpc32/syntax.h: Edited
99 all preprocessor instructions to remove whitespace before the '#'.
100 This is not required by C89, but there are some compilers out
101 there that don't like it. Replaced any occurence of the now
102 deprecated type names with the new ones.
103
1042003-05-21 Moritz Schulte <moritz@g10code.com>
105
106 * mpiutil.c (_gcry_mpi_alloc_limb_space): Only try to allocate
107 memory in case the amount of bytes to allocate is non-zero.
108
1092003-04-27 Moritz Schulte <moritz@g10code.com>
110
111 * mpiutil.c (_gcry_mpi_resize): Allocate secure memory, in case
112 bit zero of `flags' is set.
113
114 * mpi-add.c (gcry_mpi_sub): Simplify function; always use a
115 temporary variable now.
116
1172003-04-15 Werner Koch <wk@gnupg.org>
118
119 * longlong.h (umul_ppmm): Support SH3 and SH4. Thanks to
120 kazuya.s@jp.yokogawa.com.
121
1222003-04-02 Werner Koch <wk@gnupg.org>
123
124 * mpicoder.c (gcry_mpi_print): Fixed testing against possible
125 uninitialized LEN. Valgrinded by Nikos Mavroyanopoulos.
126
1272003-01-15 Werner Koch <wk@gnupg.org>
128
129 * longlong.h: Removed some spaces between backslashes and newlines.
130
1312002-09-20 Werner Koch <wk@gnupg.org>
132
133 * mpi-mul.c (gcry_mpi_mul_2exp): New. This was declared in
134 gcrypt.h but only implemented as internal function. Noted by Timo
135 but a few minutes to late for today's release.
136
137 * Makefile.am (DISTCLEANFILES): Include mpi-asm-defs.h
138
1392002-09-18 Werner Koch <wk@gnupg.org>
140
141 * Makefile.am (.S.lo): Pass -DPIC. i386, PPC and Sparc code
142 require it. It worked for me because I am using the i586 code.
143
1442002-08-23 Werner Koch <wk@gnupg.org>
145
146 * Makefile.am (.S.lo): Fixed for libtool build with --disable-shared.
147
1482002-07-24 Werner Koch <wk@gnupg.org>
149
150 * longlong.h: Replaced all K&R multiline strings by ISO ones for
151 the sake of modern compilers. Suggested by Marco Parrone.
152
1532002-06-24 Werner Koch <wk@gnupg.org>
154
155 * mpiutil.c (gcry_mpi_swap): New.
156
157 * mpi-div.c (gcry_mpi_div): New.
158 (gcry_mpi_mod): New.
159 * mpi-inv.c (gcry_mpi_invm): New.
160
161 * mpicoder.c (do_get_buffer): Make sure that we allocate at least
162 one byte.
163
1642002-06-12 Werner Koch <wk@gnupg.org>
165
166 * hppa1.1/udiv-qrnnd.S: Changes for PIC by Randolph Chung.
167
1682002-05-15 Werner Koch <wk@gnupg.org>
169
170 * config.links: Chnage the way the mpi modules are determined.
171 * Makefile.am: Revamped to better handle modules
172
1732002-05-14 Werner Koch <wk@gnupg.org>
174
175 Changed license of all files to the LGPL.
176
1772002-04-18 Werner Koch <wk@gnupg.org>
178
179 * mpicoder.c (gcry_mpi_scan): Don't use normalize on a NULL MPI.
180
1812002-03-20 Werner Koch <wk@gnupg.org>
182
183 * mpicoder.c (mpi_read_from_buffer): Bail out on a zero length
184 buffer because we can't eventually do an malloc of this size.
185 Reported by Timo.
186
1872002-01-14 Werner Koch <wk@gnupg.org>
188
189 * mpi-inv.c (_gcry_mpi_invm): Typo fixes, noted by Carlo Perassi.
190
1912001-11-01 Werner Koch <wk@gnupg.org>
192
193 * mpicoder.c (gcry_mpi_scan): Allow to pass a nbytes as NULL or
194 with value 0 for format GCRY_FMT_SSH, so that the length is not
195 used for any checks, only the length stored in the bufer is used.
196 This is a nice format becuase we can just pass a buffer around and
197 don't need to care about its length.
198
1992001-08-03 Werner Koch <wk@gnupg.org>
200
201 * config.links: Changed the way the list of files to be
202 symlinked is returned.
203
2042001-05-31 Werner Koch <wk@gnupg.org>
205
206 * mpih-cmp.c: Removed and moved mpihelp_cmp to ..
207 * mpi-inline.h: .. here.
208
209 Major function renaming. All global functions are now prefixed
210 with _gcry_ or gcry_. Renamed also all mpihelp_ to just mpih_ so
211 that functions names are not getting to long an unreadable and for
212 better matching with the filenames.
213
2142001-05-28 Werner Koch <wk@gnupg.org>
215
216 * mpicoder.c (mpi_fromstr): Made static and assume that all input
217 is in hexformat.
218
219 Updated all CPU specific code with the one from GnuPG-1.0.5. This
220 is just a change of text formatting and the use of .label
221 instead of labels for hppa and pa7100.
222
223 * longlong.h: Fixes for ARM by Phil Blundell.
224
2252001-03-29 Werner Koch <wk@gnupg.org>
226
227 * mpi-mul.c (mpi_mul): Make sure that secret temporary results are
228 not stored in w. Suggested by Florian Weimer.
229
230 * config.links: Use i386 code for i386. According to tests by
231 Kevin Ryde the i586 code runs slow on i386 CPUs. Ditto for i786.
232
2332001-01-11 Werner Koch <wk@gnupg.org>
234
235 * Makefile.am: Removed mpi.h.
236
2372000-12-19 Werner Koch <wk@gnupg.org>
238
239 * mpi-internal.h: Put limb_t definition in an ifdef.
240
241 Major change:
242 Removed all GnuPG stuff and renamed this piece of software
243 to gcrypt.
244
2452000-11-14 Werner Koch <wk@gnupg.org>
246
247 * mpi-internal.h, mpi.h: Changed the way they are called and
248 introduced DID_MPI_LIMP_TYPEDEF hack. Very ugly, should all be
249 revamped.
250
251 * Makefile.am (OMIT_DEPENDENCIES): Hack to work around dependency
252 problems.
253
2542000-10-11 Werner Koch <wk@gnupg.org>
255
256 * generic/mpi-asm-defs.h: New.
257 * mips3/mpi-asm-defs.h: New.
258 * config.links: Create a link to one of the above files.
259
260Fri Jul 28 18:19:11 CEST 2000 Werner Koch <wk@openit.de>
261
262 * mpicoder.c (gcry_mpi_scan): Normalize the returned MPI.
263
264Tue Jul 25 17:44:15 CEST 2000 Werner Koch <wk@openit.de>
265
266 * config.links: Support for powerpc--netbsd by Gabriel Rosenkoetter.
267
268Mon Jul 17 16:35:47 CEST 2000 Werner Koch <wk@>
269
270 * power/: Add all files from GMP for this CPU. Converted comments to
271 CPP comments because some ASes complain about ' in comments.
272
273 * config.links: Support for BSDI 4.x; by Wayne Chapeskie. Add support
274 for FreeBSD 5 and made the case stmt looking nicer; by Jun Kuriyama.
275 Add support for NetBSD.
276 (sparc8): Made the search path the same as sparc9
277 (sparc64-unknown-linux-gnu): use udiv module; by Adam Mitchell.
278
279 * Makefile.am: c/SFLAGS/ASFLAGS/. This has only been used by the
280 powerpc and actually never passed the -Wa,foo to the cc.
281
282 * mpih-div.c (mpihelp_divrem): The MPN_COPY_DECR copied one element
283 too many. This is a gmp2.0.2p9.txt patch.
284
285 * longlong.h (umul_ppmm): Fixes for ARM-4. By Sean MacLennan.
286
287 * mpi-internal.h (karatsuba_ctx): New.
288 * mpih-mul.c (mpihelp_release_karatsuba_ctx): New.
289 (mpihelp_mul_karatsuba_case): New.
290 (mpihelp_mul): Splitted to make use of the new functions.
291 * mpi-pow.c (mpi_powm): Make use of the new splitted function to avoid
292 multiple allocation of temporary memory during the karatsuba operations.
293 * mpi_mpow.c: Removed the unused Barrett code.
294
2952000-03-21 16:17:30 Werner Koch (wk@habibti.openit.de)
296
297 * config.links: Add support for FreeBSD 5.
298
299Mon Jan 24 22:24:38 CET 2000 Werner Koch <wk@gnupg.de>
300
301 * mpicoder.c (gcry_mpi_aprint): Now really returns the length.
302
303Mon Jan 24 13:04:28 CET 2000 Werner Koch <wk@gnupg.de>
304
305 * mpiutil.c: Removed all memory debugging code.
306
307 * mpicoder.c (gcry_mpi_aprint): New.
308
309 * Replaced all m_ memory functions by g10_ ones.
310
311Fri Dec 31 14:06:56 CET 1999 Werner Koch <wk@gnupg.de>
312
313 * mpi-bit.c (gcry_mpi_get_nbits): New.
314
315 * mpiutil.c (mpi_set_secure): made static.
316 (gcry_mpi_get_flag): New.
317 (gcry_mpi_set_flag): New.
318 (gcry_mpi_clear_flag): New.
319 (mpi_set_opaque): renamed to gcry_mpi_set_opaque.
320 (mpi_get_opaque): renamed to gcry_mpi_get_opaque.
321
322Fri Dec 31 12:48:31 CET 1999 Werner Koch <wk@gnupg.de>
323
324 * mpicoder.c (mpi_read_from_buffer): Made static.
325 (gcry_mpi_print): A buffer of NULL is now allowed to get the required
326 length back.
327 (mpi_get_keyid): Removed.
328 (mpi_print): Made static - should be removed.
329
330Wed Dec 8 21:58:32 CET 1999 Werner Koch <wk@gnupg.de>
331
332 * Makefile.am (INCLUDES): Add ../gcrypt.
333
334 * g10m.c : Removed.
335
336 * mpicoder.c (mpi_write): Removed.
337 (mpi_read): Removed.
338 (gcry_mpi_scan): New. Taken from ../gcrypt/mpiapi.c.
339 (gcry_mpi_print): Ditto.
340
341 * mpi-pow.c (mpi_powm): Renamed to ...
342 (gcry_mpi_powm): ... this.
343
344 * mpiutil.c (gcry_mpi_new): New as a wrapper around the old function.
345 Taken from ../gcrypt/mpiapi.c.
346 (gcry_mpi_snew): Ditto.
347 (gcry_mpi_release): Ditto.
348 (gcry_mpi_copy): Ditto.
349 (gcry_mpi_set): Ditto.
350 (gcry_mpi_set_ui): Ditto.
351 (gcry_mpi_cmp): Ditto.
352 (gcry_mpi_cmp_ui): Ditto.
353 (gcry_mpi_randomize): Ditto.
354
355 * mpicoder.c (mpi_print): Removed the nbit_info kludge.
356 * mpi-bits.c (mpi_get_nbits): Replaced the is_protected stuff by
357 checking whether it is an opaque mpi and then returns it's length
358 in bits.
359 * mpiutil.c (mpi_set_opaque): Changed the interface to take a number
360 of bits for the length. Adjusted all users.
361 (mpi_get_opaque): Ditto.
362
363Fri Nov 19 17:15:20 CET 1999 Werner Koch <wk@gnupg.de>
364
365 * mpicoder.c (g10_log_mpidump): Add a temporary workaround
366
367 * mpih-mul.c (mpihelp_mul_n): s/m_is_ecure/g10_is_secure/
368
369 * mpiutil.c (mpi_alloc): Remved the debug mode because it has turned
370 out, that this feature was not very useful in the past. Use the
371 new alloc functions.
372 (mpi_alloc_secure): Ditto.
373 (mpi_alloc_limb_space): Ditto.
374 (mpi_free_limb_space): Ditto.
375 (mpi_resize): Ditto.
376 (mpi_free): Ditto.
377 (mpi_set_secure): Removed the debug stuff.
378 (mpi_set_opaque): Ditto.
379 (mpi_copy): Ditto.
380 (mpi_alloc_set_ui): Ditto.
381 (mpi_m_check): Use g10_ wrapper.
382
383Mon Aug 30 20:38:33 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
384
385
386 * config.links: Add case label for DJGPP
387
388Wed Jul 14 19:42:08 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
389
390
391 * Makefile.am: Use .s files as temporaries, disabled other .S rules.
392
393Wed Jul 7 13:08:40 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
394
395
396 * mpicoder.c (g10_log_mpidump): New.
397
398 * Makefile.am: Support for libtool.
399
400Fri Jul 2 11:45:54 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
401
402
403 * mpi-bit.c (mpi_lshift_limbs,mpi_rshift_limbs): New.
404 * mpi-mpow.c (barrett_mulm): New but diabled.
405
406Tue Jun 1 16:01:46 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
407
408 * config.links (i[56]86*-*-freebsdelf*): New.
409
410Sun May 23 14:20:22 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
411
412 * config.links (sysdep.h): Not any more conditionally created.
413
414Tue May 4 15:47:53 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
415
416 * mpiutil.c (mpi_alloc_like): New.
417
418Mon Apr 26 17:48:15 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
419
420 * mpih-add.c, mpih-sub.c: Removed
421 * mpi-inline.c: New.
422 * mpi-inline.h: Make it usable by mpi-inline.c.
423
424Sun Apr 18 10:11:28 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
425
426 * mpih-mul.c (mpihelp_mul_n): Fixed use of memory region.
427 (mpihelp_mul): Ditto.
428
429Wed Apr 7 20:51:39 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
430
431 * Makefile.am: Explicit rules to invoke cpp on *.S
432
433Mon Mar 8 20:47:17 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
434
435 * config.links: Take advantage of the with_symbol_underscore macro.
436 Add support for freebsd 4.
437
438Wed Feb 24 11:07:27 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
439
440 * mips3/mpih-sub1.S: Removed left over junk in last line. (Should I
441 blame me or my editor?).
442
443Sat Feb 13 12:04:43 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
444
445 * Makefile.am: Removed the +=. Add MPI_OPT_FLAGS.
446
447Sat Jan 9 16:02:23 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
448
449 * mpi-cmp.c (mpi_cmp_ui): Normalized the arg.
450
451Thu Jan 7 18:00:58 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
452
453 * mpi-bit.c (mpi_normalize): New.
454 (mpi_get_nbits): Normalize the MPI.
455 * mpi-bit.c (mpi_cmp): Normalize the MPI before the compare.
456
457
458Tue Dec 8 13:15:16 CET 1998 Werner Koch <wk@isil.d.shuttle.de>
459
460 * config.links: Moved the case for powerpc*linux
461 * powerpcp32/*.S: Removed some underscores.
462
463Thu Nov 26 07:27:52 1998 Werner Koch <werner.koch@guug.de>
464
465 * config.links: Support for ppc with ELF
466 * powerpc32/syntax.h: New.
467 * powerpc32/*.S: Applied ELF patches (glibc patches)
468
469Tue Nov 10 19:31:37 1998 Werner Koch (wk@isil.d.shuttle.de)
470
471 * power*/ : Started with stuff for PPC
472 * config.links: Some stuff for PPC.
473 * generic/udiv-w-sdiv.c: New but disabled.
474
475Tue Oct 27 12:37:46 1998 Werner Koch (wk@isil.d.shuttle.de)
476
477 * config.links (freebsd): Fixes for FreeBSD 3.0
478
479Wed Oct 14 09:59:30 1998 Werner Koch (wk@isil.d.shuttle.de)
480
481 * config.links (freebsd): ELF patches from Jun Kuriyama.
482
483Thu Oct 8 13:28:17 1998 Werner Koch (wk@isil.d.shuttle.de)
484
485 * mpi-mpow.c (mpi_mulpowm): Fixed mem leak (m_free/mpi_free).
486
487Thu Sep 17 18:08:50 1998 Werner Koch (wk@(none))
488
489 * hppa1.1/udiv-qrnnd.S: Fix from Steffen Zahn for HPUX 10.20
490
491 Thu Aug 6 16:39:28 1998 Werner Koch,mobil,,,(wk@tobold)
492
493 * mpi-bit.c (mpi_set_bytes): Removed.
494
495Wed Aug 5 15:11:12 1998 Werner Koch (wk@(none))
496
497 * mpicoder.c (mpi_read_from_buffer): New.
498
499 * mpiutil.c (mpi_set_opaque): New.
500 (mpi_get_opaque): New.
501 (mpi_copy): Changed to support opauqe flag
502 (mpi_free): Ditto.
503
504Sat Jul 4 10:11:11 1998 Werner Koch (wk@isil.d.shuttle.de)
505
506 * mpiutil.c (mpi_clear): Reset flags.
507 (mpi_set): Ditto.
508 (mpi_alloc_secure): Set flag to 1 and not ored the 1 in, tsss..
509
510Fri Jun 26 11:19:06 1998 Werner Koch (wk@isil.d.shuttle.de)
511
512 * mpiutil.c (mpi_alloc): set nbits to 0.
513 (mpi_alloc_secure): Ditto.
514 (mpi_clear): Ditto.
515
516Thu Jun 25 11:50:01 1998 Werner Koch (wk@isil.d.shuttle.de)
517
518 * mips3/*.S: New
519
520Mon May 18 13:47:06 1998 Werner Koch (wk@isil.d.shuttle.de)
521
522 * config.links: split mpih-shift into mpih-[lr]shift and
523 changed all implementations.
524 * mpi/alpha: add some new assembler stuff.
525
526Wed May 13 11:04:29 1998 Werner Koch (wk@isil.d.shuttle.de)
527
528 * config.links: Add support for MIPS
529
530Thu Apr 9 11:31:36 1998 Werner Koch (wk@isil.d.shuttle.de)
531
532 * mpicoder.c (mpi_get_secure_buffer): New.
533
534Wed Apr 8 09:44:33 1998 Werner Koch (wk@isil.d.shuttle.de)
535
536 * config.links: Applied small fix from Ulf Möller.
537
538Mon Apr 6 12:38:52 1998 Werner Koch (wk@isil.d.shuttle.de)
539
540 * mpicoder.c (mpi_get_buffer): Removed returned leading zeroes
541 and changed all callers.
542
543Tue Mar 10 13:40:34 1998 Werner Koch (wk@isil.d.shuttle.de)
544
545 * mpi-bit.c (mpi_clear_highbit): New.
546
547Mon Mar 2 19:29:00 1998 Werner Koch (wk@isil.d.shuttle.de)
548
549 * Makefile.am (DISTCLEANFILES): New
550
551Thu Feb 26 06:48:54 1998 Werner Koch (wk@isil.d.shuttle.de)
552
553 * config.links (X86_BROKEN_ALIGN): Added for some systems.
554
555Mon Feb 23 12:21:40 1998 Werner Koch (wk@isil.d.shuttle.de)
556
557 * mpi/m68k/mpih-shift.S (Lspecial): Changed duplicate symbol.
558
559Mon Feb 16 13:00:27 1998 Werner Koch (wk@isil.d.shuttle.de)
560
561 * config.links : Add detection of m68k cpus
562
563
564 Copyright 1998,1999,2000,2001,2002,2003 Free Software Foundation, Inc.
565
566 This file is free software; as a special exception the author gives
567 unlimited permission to copy and/or distribute it, with or without
568 modifications, as long as this notice is preserved.
569
570 This file is distributed in the hope that it will be useful, but
571 WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
572 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
diff --git a/pwmanager/libcrypt/mpi/Manifest b/pwmanager/libcrypt/mpi/Manifest
new file mode 100644
index 0000000..3b0d673
--- a/dev/null
+++ b/pwmanager/libcrypt/mpi/Manifest
@@ -0,0 +1,41 @@
1# Manifest - checksums of the mpi directory
2# Copyright 2003 Free Software Foundation, Inc.
3#
4# This file is part of Libgcrypt.
5#
6# Libgcrypt is free software; you can redistribute it and/or modify
7# it under the terms of the GNU Lesser general Public License as
8# published by the Free Software Foundation; either version 2.1 of
9# the License, or (at your option) any later version.
10#
11# Libgcrypt is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU Lesser General Public License for more details.
15#
16# You should have received a copy of the GNU Lesser General Public
17# License along with this program; if not, write to the Free Software
18# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19
20Makefile.am
21config.links
22longlong.h
23mpi-add.c
24mpi-bit.c
25mpi-cmp.c
26mpi-div.c
27mpi-gcd.c
28mpi-inline.c
29mpi-inline.h
30mpi-internal.h
31mpi-inv.c
32mpi-mpow.c
33mpi-mul.c
34mpi-pow.c
35mpi-scan.c
36mpicoder.c
37mpih-div.c
38mpih-mul.c
39mpiutil.c
40$names$ iQCVAwUAP+LmfDEAnp832S/7AQKZJQQAkR/gQITUM+6Ygy9WAOAO17btyKAlCtGTXp5XSZ+J3X0o/rYneRdSCW89IJvwFRJjAOcFJd52MXs6ZVFF/RQBC8MvJzuQChbEzvihK8o2VgK34YWjU+6XH9sFgRMIgzkHs/51ZZxeQUOPy1XF7TyKB0WE7YBUVisFiRaqB1qGIOs==Z3qB
41
diff --git a/pwmanager/libcrypt/mpi/asm-syntax.h b/pwmanager/libcrypt/mpi/asm-syntax.h
new file mode 100644
index 0000000..ca94a8e
--- a/dev/null
+++ b/pwmanager/libcrypt/mpi/asm-syntax.h
@@ -0,0 +1,71 @@
1/* created by config.links - do not edit */
2/* Target: i686-pc-linux-gnu */
3#define ELF_SYNTAX
4/* syntax.h -- Definitions for x86 syntax variations.
5 *
6 * Copyright (C) 1992, 1994, 1995, 1998,
7 * 2001, 2002 Free Software Foundation, Inc.
8 *
9 * This file is part of Libgcrypt.
10 *
11 * Libgcrypt is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License as
13 * published by the Free Software Foundation; either version 2.1 of
14 * the License, or (at your option) any later version.
15 *
16 * Libgcrypt is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License for more details.
20 *
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
24 *
25 * Note: This code is heavily based on the GNU MP Library.
26 * Actually it's the same code with only minor changes in the
27 * way the data is stored; this is to support the abstraction
28 * of an optional secure memory allocation which may be used
29 * to avoid revealing of sensitive data due to paging etc.
30 */
31
32#undef ALIGN
33
34#if defined (BSD_SYNTAX) || defined (ELF_SYNTAX)
35#define R(r) %r
36#define MEM(base)(base)
37#define MEM_DISP(base,displacement)displacement(R(base))
38#define MEM_INDEX(base,index,size)(R(base),R(index),size)
39#ifdef __STDC__
40#define INSN1(mnemonic,size_suffix,dst)mnemonic##size_suffix dst
41#define INSN2(mnemonic,size_suffix,dst,src)mnemonic##size_suffix src,dst
42#else
43#define INSN1(mnemonic,size_suffix,dst)mnemonic/**/size_suffix dst
44#define INSN2(mnemonic,size_suffix,dst,src)mnemonic/**/size_suffix src,dst
45#endif
46#define TEXT .text
47#if defined (BSD_SYNTAX)
48#define ALIGN(log) .align log
49#endif
50#if defined (ELF_SYNTAX)
51#define ALIGN(log) .align 1<<(log)
52#endif
53#define GLOBL .globl
54#endif
55
56#ifdef INTEL_SYNTAX
57#define R(r) r
58#define MEM(base)[base]
59#define MEM_DISP(base,displacement)[base+(displacement)]
60#define MEM_INDEX(base,index,size)[base+index*size]
61#define INSN1(mnemonic,size_suffix,dst)mnemonic dst
62#define INSN2(mnemonic,size_suffix,dst,src)mnemonic dst,src
63#define TEXT .text
64#define ALIGN(log) .align log
65#define GLOBL .globl
66#endif
67
68#ifdef X86_BROKEN_ALIGN
69#undef ALIGN
70#define ALIGN(log) .align log,0x90
71#endif
diff --git a/pwmanager/libcrypt/mpi/generic/Manifest b/pwmanager/libcrypt/mpi/generic/Manifest
new file mode 100644
index 0000000..c429fde
--- a/dev/null
+++ b/pwmanager/libcrypt/mpi/generic/Manifest
@@ -0,0 +1,29 @@
1# Manifest - checksums
2# Copyright 2003 Free Software Foundation, Inc.
3#
4# This file is part of Libgcrypt.
5#
6# Libgcrypt is free software; you can redistribute it and/or modify
7# it under the terms of the GNU Lesser general Public License as
8# published by the Free Software Foundation; either version 2.1 of
9# the License, or (at your option) any later version.
10#
11# Libgcrypt is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU Lesser General Public License for more details.
15#
16# You should have received a copy of the GNU Lesser General Public
17# License along with this program; if not, write to the Free Software
18# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19
20mpih-add1.c iQCVAwUAP+Lj2DEAnp832S/7AQKn/AQAwQLWggl6zNQ5EZ+lE+jKV8W3FsogW3/6tp9T5rrSR5JnlWyoHQ9/Pu4knOcLjS6nIfVOiAEifu3nuIysQr9jDSSSJA2LylSUBSXKLKDamPsOCwXOLxiZODslJT3CCGAUtLvXJrWDbTZQrkEuwnLnjQFDzuA7iY9JLrG9kAoXD6Q==WoWm
21mpih-mul1.c iQCVAwUAP+LkCTEAnp832S/7AQKFVQP+MhBNjcY73JtnsHZfnaVZq3TiKwN151cWV51nDc1RnTaMhSIFeuNlj3vNML2W0Gn8n+GnyiWE2XXdQEaik6BL02eekUn9aq7I/rdpnTHuOjQPK1uwjuNl8RuJ9YrERBAxq4oB71f+iwMab8dsMSUlVC+NdeAocRqLLgnR/efkdLc==2Tkb
22mpih-mul2.c iQCVAwUAP+LkMjEAnp832S/7AQLPeAQAqmRzxFe/mDqTdZr/pTXT8RVyB1vKB0Ei2THV05BxmI4OPv39uysfFpLMt/INsX7AGqdOlj4jOZ/qNaFXR1ceMrlSXvo8u/epk6rCXFp82kM7Qs983LjoP//PrMCkYkXwblaVrgUGiBUCbuPMliWTK6qKkxxXtEfqZ7nVbEWdBx8==Kwhl
23mpih-mul3.c iQCVAwUAP+LkVDEAnp832S/7AQL91gP/Qd5iZWxRiN5DdEIVHAedoNvl23NPrT2UUdXvnSK49DpplTxkLiMBj0WqCayG/YIET2NpMRCeLvAZNcSt6lOm0bSZDYo1Hv/N+UoqD3V1McjY16REBv/nnPaMWMZcx7rl5yKTVZiX2PgV6oQOL7Yfrt5ZIOlrHBRs9S2/zcCaVz0==9BQe
24mpih-lshift.c iQCVAwUAP+LlATEAnp832S/7AQIACAQAhMrpx0SRXE/LN1NkjMO9n74nMrvmzYJyru0gw2O4BYrUPvD/LWGju2FZaggKV0IBjmi0cDoCrNeK9EGjKOO1lfgODbX2IZ1LUhr9jDuMj0QRqj6T9YkAFYTNUk4GfpwIf7T6Ybo7c78Jx93PidCJt7d39eMMEalooC7LZ4IU3NM==nZ4k
25mpih-rshift.c iQCVAwUAP+LlIjEAnp832S/7AQKiuAP/eYC2ZScd+taBx/kNzRvGjA0eAXvORMkMLV6Ot+OXVzVUi04eoP2yXdxSNFKwUj12p8GWXkdoMG3aOGBKg2a7bY5Q5RUho3hUWb9UsVYVUfXLf7IOTt/3a6MLh2CmV5dFPWJmSlbCyQRcn6n/fLDeJ3A2bWTS/BhqGfpOXUIU1ws==jCf8
26mpih-sub1.c iQCVAwUAP+LlZzEAnp832S/7AQIEPgP/dLHTDRbPrYJhsLp9SjGstU1M8/IC5XytcDtO3NQeu4mx6vaXjpujtsTvKIbX4QL5IahNntVVKv1xFLEm2yFg7L2ns0uD/mfwGgOhCG1j2o/SaTAWP5KxP7ae5UDcZl2w6NWvEuMj9t32zmziAZjP8W73A37FUspeRDYiL9sQzkI==QQzk
27udiv-w-sdiv.c iQCVAwUAP+Lk0TEAnp832S/7AQICXAQAsxe1SQD4+xZaZTqBC0V9Cyuo0mrdccnRFzthOtm0ARwKFXU2cuLW/ZBOkmeWOVmOFhBp22/I8dEGYnMA3gcfmOMCpNu9i9zk/XHfptdunA1MnOe3GsoWgfHL0rhpAyPhp/X043ICB41NElnnuxADuQQlD4Z1fca5ygYxMr2crJg==EI/6
28mpi-asm-defs.h iQCVAwUAP+LkgDEAnp832S/7AQK0FgQAxJZ7xvXhoZa33GWe23LRb3asrno/loZSyAIXrntqtVH8M3pEsCY0OyW4ry4hX2RnxpuhRCM/PdRNLG3xXyMSVIhkHU8WVRLqzF2LLjEkyU3cAmHnnTQ9aO/XpUWtJGTZ8q2bv7ZsAEi4aPl0p6KhPXcPgM9vQ2XcyOPn3Dl0d6Q==xpjI
29$names$ iQCVAwUAP+LmNDEAnp832S/7AQJa+gP+KQNJpbNOgc+s2UX+Ya2gDaOFcAROImIllhg3ej8EaBF8xxdHmWT1zaKwTwi3moEEleykMR104YAGWyQeMbFYiuPPBW+ohrT6KxRBVJpIA9auOOqqJMyglZyoR3Hv7gduVYUW1h/DebnqiKXKEfzQDFqYuT0ayuteoOR4B5NICbE==nLSh
diff --git a/pwmanager/libcrypt/mpi/generic/distfiles b/pwmanager/libcrypt/mpi/generic/distfiles
new file mode 100644
index 0000000..9810eef
--- a/dev/null
+++ b/pwmanager/libcrypt/mpi/generic/distfiles
@@ -0,0 +1,11 @@
1Manifest
2mpih-add1.c
3mpih-mul1.c
4mpih-mul2.c
5mpih-mul3.c
6mpih-lshift.c
7mpih-rshift.c
8mpih-sub1.c
9udiv-w-sdiv.c
10mpi-asm-defs.h
11
diff --git a/pwmanager/libcrypt/mpi/generic/mpi-asm-defs.h b/pwmanager/libcrypt/mpi/generic/mpi-asm-defs.h
new file mode 100644
index 0000000..13424e2
--- a/dev/null
+++ b/pwmanager/libcrypt/mpi/generic/mpi-asm-defs.h
@@ -0,0 +1,10 @@
1/* This file defines some basic constants for the MPI machinery. We
2 * need to define the types on a per-CPU basis, so it is done with
3 * this file here. */
4#define BYTES_PER_MPI_LIMB (SIZEOF_UNSIGNED_LONG)
5
6
7
8
9
10
diff --git a/pwmanager/libcrypt/mpi/generic/mpih-add1.c b/pwmanager/libcrypt/mpi/generic/mpih-add1.c
new file mode 100644
index 0000000..4a84df6
--- a/dev/null
+++ b/pwmanager/libcrypt/mpi/generic/mpih-add1.c
@@ -0,0 +1,65 @@
1/* mpihelp-add_1.c - MPI helper functions
2 * Copyright (C) 1994, 1996, 1997, 1998,
3 * 2000, 2002 Free Software Foundation, Inc.
4 *
5 * This file is part of Libgcrypt.
6 *
7 * Libgcrypt is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * Libgcrypt is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20 *
21 * Note: This code is heavily based on the GNU MP Library.
22 * Actually it's the same code with only minor changes in the
23 * way the data is stored; this is to support the abstraction
24 * of an optional secure memory allocation which may be used
25 * to avoid revealing of sensitive data due to paging etc.
26 */
27
28#include <config.h>
29#include <stdio.h>
30#include <stdlib.h>
31#include "mpi-internal.h"
32#include "longlong.h"
33
34mpi_limb_t
35_gcry_mpih_add_n (mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
36 mpi_ptr_t s2_ptr, mpi_size_t size)
37{
38 mpi_limb_t x, y, cy;
39 mpi_size_t j;
40
41 /* The loop counter and index J goes from -SIZE to -1. This way
42 the loop becomes faster. */
43 j = -size;
44
45 /* Offset the base pointers to compensate for the negative indices. */
46 s1_ptr -= j;
47 s2_ptr -= j;
48 res_ptr -= j;
49
50 cy = 0;
51 do
52 {
53 y = s2_ptr[j];
54 x = s1_ptr[j];
55 y += cy; /* add previous carry to one addend */
56 cy = y < cy; /* get out carry from that addition */
57 y += x; /* add other addend */
58 cy += y < x; /* get out carry from that add, combine */
59 res_ptr[j] = y;
60 }
61 while ( ++j );
62
63 return cy;
64}
65
diff --git a/pwmanager/libcrypt/mpi/generic/mpih-lshift.c b/pwmanager/libcrypt/mpi/generic/mpih-lshift.c
new file mode 100644
index 0000000..f48c12c
--- a/dev/null
+++ b/pwmanager/libcrypt/mpi/generic/mpih-lshift.c
@@ -0,0 +1,68 @@
1/* mpi-lshift.c - MPI helper functions
2 * Copyright (C) 1994, 1996, 1998, 2001, 2002 Free Software Foundation, Inc.
3 *
4 * This file is part of Libgcrypt.
5 *
6 * Libgcrypt is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License as
8 * published by the Free Software Foundation; either version 2.1 of
9 * the License, or (at your option) any later version.
10 *
11 * Libgcrypt is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19 *
20 * Note: This code is heavily based on the GNU MP Library.
21 * Actually it's the same code with only minor changes in the
22 * way the data is stored; this is to support the abstraction
23 * of an optional secure memory allocation which may be used
24 * to avoid revealing of sensitive data due to paging etc.
25 */
26
27#include <config.h>
28#include <stdio.h>
29#include <stdlib.h>
30#include "mpi-internal.h"
31
32/* Shift U (pointed to by UP and USIZE digits long) CNT bits to the left
33 * and store the USIZE least significant digits of the result at WP.
34 * Return the bits shifted out from the most significant digit.
35 *
36 * Argument constraints:
37 * 1. 0 < CNT < BITS_PER_MP_LIMB
38 * 2. If the result is to be written over the input, WP must be >= UP.
39 */
40
41mpi_limb_t
42_gcry_mpih_lshift( mpi_ptr_t wp, mpi_ptr_t up, mpi_size_t usize,
43 unsigned int cnt)
44{
45 mpi_limb_t high_limb, low_limb;
46 unsigned sh_1, sh_2;
47 mpi_size_t i;
48 mpi_limb_t retval;
49
50 sh_1 = cnt;
51 wp += 1;
52 sh_2 = BITS_PER_MPI_LIMB - sh_1;
53 i = usize - 1;
54 low_limb = up[i];
55 retval = low_limb >> sh_2;
56 high_limb = low_limb;
57 while ( --i >= 0 )
58 {
59 low_limb = up[i];
60 wp[i] = (high_limb << sh_1) | (low_limb >> sh_2);
61 high_limb = low_limb;
62 }
63 wp[i] = high_limb << sh_1;
64
65 return retval;
66}
67
68
diff --git a/pwmanager/libcrypt/mpi/generic/mpih-mul1.c b/pwmanager/libcrypt/mpi/generic/mpih-mul1.c
new file mode 100644
index 0000000..0e8197d
--- a/dev/null
+++ b/pwmanager/libcrypt/mpi/generic/mpih-mul1.c
@@ -0,0 +1,62 @@
1/* mpihelp-mul_1.c - MPI helper functions
2 * Copyright (C) 1994, 1996, 1997, 1998, 2001,
3 * 2002 Free Software Foundation, Inc.
4 *
5 * This file is part of Libgcrypt.
6 *
7 * Libgcrypt is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * Libgcrypt is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20 *
21 * Note: This code is heavily based on the GNU MP Library.
22 * Actually it's the same code with only minor changes in the
23 * way the data is stored; this is to support the abstraction
24 * of an optional secure memory allocation which may be used
25 * to avoid revealing of sensitive data due to paging etc.
26 */
27
28#include <config.h>
29#include <stdio.h>
30#include <stdlib.h>
31#include "mpi-internal.h"
32#include "longlong.h"
33
34mpi_limb_t
35_gcry_mpih_mul_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size,
36 mpi_limb_t s2_limb)
37{
38 mpi_limb_t cy_limb;
39 mpi_size_t j;
40 mpi_limb_t prod_high, prod_low;
41
42 /* The loop counter and index J goes from -S1_SIZE to -1. This way
43 * the loop becomes faster. */
44 j = -s1_size;
45
46 /* Offset the base pointers to compensate for the negative indices. */
47 s1_ptr -= j;
48 res_ptr -= j;
49
50 cy_limb = 0;
51 do
52 {
53 umul_ppmm( prod_high, prod_low, s1_ptr[j], s2_limb );
54 prod_low += cy_limb;
55 cy_limb = (prod_low < cy_limb?1:0) + prod_high;
56 res_ptr[j] = prod_low;
57 }
58 while( ++j );
59
60 return cy_limb;
61}
62
diff --git a/pwmanager/libcrypt/mpi/generic/mpih-mul2.c b/pwmanager/libcrypt/mpi/generic/mpih-mul2.c
new file mode 100644
index 0000000..3b75496
--- a/dev/null
+++ b/pwmanager/libcrypt/mpi/generic/mpih-mul2.c
@@ -0,0 +1,68 @@
1/* mpih-mul2.c - MPI helper functions
2 * Copyright (C) 1994, 1996, 1997, 1998, 2001,
3 * 2002 Free Software Foundation, Inc.
4 *
5 * This file is part of Libgcrypt.
6 *
7 * Libgcrypt is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * Libgcrypt is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20 *
21 * Note: This code is heavily based on the GNU MP Library.
22 * Actually it's the same code with only minor changes in the
23 * way the data is stored; this is to support the abstraction
24 * of an optional secure memory allocation which may be used
25 * to avoid revealing of sensitive data due to paging etc.
26 */
27
28#include <config.h>
29#include <stdio.h>
30#include <stdlib.h>
31#include "mpi-internal.h"
32#include "longlong.h"
33
34
35mpi_limb_t
36_gcry_mpih_addmul_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
37 mpi_size_t s1_size, mpi_limb_t s2_limb)
38{
39 mpi_limb_t cy_limb;
40 mpi_size_t j;
41 mpi_limb_t prod_high, prod_low;
42 mpi_limb_t x;
43
44 /* The loop counter and index J goes from -SIZE to -1. This way
45 * the loop becomes faster. */
46 j = -s1_size;
47 res_ptr -= j;
48 s1_ptr -= j;
49
50 cy_limb = 0;
51 do
52 {
53 umul_ppmm( prod_high, prod_low, s1_ptr[j], s2_limb );
54
55 prod_low += cy_limb;
56 cy_limb = (prod_low < cy_limb?1:0) + prod_high;
57
58 x = res_ptr[j];
59 prod_low = x + prod_low;
60 cy_limb += prod_low < x?1:0;
61 res_ptr[j] = prod_low;
62 }
63 while ( ++j );
64
65 return cy_limb;
66}
67
68
diff --git a/pwmanager/libcrypt/mpi/generic/mpih-mul3.c b/pwmanager/libcrypt/mpi/generic/mpih-mul3.c
new file mode 100644
index 0000000..5e84f94
--- a/dev/null
+++ b/pwmanager/libcrypt/mpi/generic/mpih-mul3.c
@@ -0,0 +1,68 @@
1/* mpih-mul3.c - MPI helper functions
2 * Copyright (C) 1994, 1996, 1997, 1998, 2001,
3 * 2002 Free Software Foundation, Inc.
4 *
5 * This file is part of Libgcrypt.
6 *
7 * Libgcrypt is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * Libgcrypt is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20 *
21 * Note: This code is heavily based on the GNU MP Library.
22 * Actually it's the same code with only minor changes in the
23 * way the data is stored; this is to support the abstraction
24 * of an optional secure memory allocation which may be used
25 * to avoid revealing of sensitive data due to paging etc.
26 */
27
28#include <config.h>
29#include <stdio.h>
30#include <stdlib.h>
31#include "mpi-internal.h"
32#include "longlong.h"
33
34
35mpi_limb_t
36_gcry_mpih_submul_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
37 mpi_size_t s1_size, mpi_limb_t s2_limb)
38{
39 mpi_limb_t cy_limb;
40 mpi_size_t j;
41 mpi_limb_t prod_high, prod_low;
42 mpi_limb_t x;
43
44 /* The loop counter and index J goes from -SIZE to -1. This way
45 * the loop becomes faster. */
46 j = -s1_size;
47 res_ptr -= j;
48 s1_ptr -= j;
49
50 cy_limb = 0;
51 do
52 {
53 umul_ppmm( prod_high, prod_low, s1_ptr[j], s2_limb);
54
55 prod_low += cy_limb;
56 cy_limb = (prod_low < cy_limb?1:0) + prod_high;
57
58 x = res_ptr[j];
59 prod_low = x - prod_low;
60 cy_limb += prod_low > x?1:0;
61 res_ptr[j] = prod_low;
62 }
63 while( ++j );
64
65 return cy_limb;
66}
67
68
diff --git a/pwmanager/libcrypt/mpi/generic/mpih-rshift.c b/pwmanager/libcrypt/mpi/generic/mpih-rshift.c
new file mode 100644
index 0000000..e40794f
--- a/dev/null
+++ b/pwmanager/libcrypt/mpi/generic/mpih-rshift.c
@@ -0,0 +1,67 @@
1/* mpih-rshift.c - MPI helper functions
2 * Copyright (C) 1994, 1996, 1998, 1999,
3 * 2000, 2001, 2002 Free Software Foundation, Inc.
4 *
5 * This file is part of Libgcrypt.
6 *
7 * Libgcrypt is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * Libgcrypt is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20 *
21 * Note: This code is heavily based on the GNU MP Library.
22 * Actually it's the same code with only minor changes in the
23 * way the data is stored; this is to support the abstraction
24 * of an optional secure memory allocation which may be used
25 * to avoid revealing of sensitive data due to paging etc.
26 */
27
28#include <config.h>
29#include <stdio.h>
30#include <stdlib.h>
31#include "mpi-internal.h"
32
33
34/* Shift U (pointed to by UP and USIZE limbs long) CNT bits to the right
35 * and store the USIZE least significant limbs of the result at WP.
36 * The bits shifted out to the right are returned.
37 *
38 * Argument constraints:
39 * 1. 0 < CNT < BITS_PER_MP_LIMB
40 * 2. If the result is to be written over the input, WP must be <= UP.
41 */
42
43mpi_limb_t
44_gcry_mpih_rshift( mpi_ptr_t wp, mpi_ptr_t up, mpi_size_t usize, unsigned cnt)
45{
46 mpi_limb_t high_limb, low_limb;
47 unsigned sh_1, sh_2;
48 mpi_size_t i;
49 mpi_limb_t retval;
50
51 sh_1 = cnt;
52 wp -= 1;
53 sh_2 = BITS_PER_MPI_LIMB - sh_1;
54 high_limb = up[0];
55 retval = high_limb << sh_2;
56 low_limb = high_limb;
57 for (i=1; i < usize; i++)
58 {
59 high_limb = up[i];
60 wp[i] = (low_limb >> sh_1) | (high_limb << sh_2);
61 low_limb = high_limb;
62 }
63 wp[i] = low_limb >> sh_1;
64
65 return retval;
66}
67
diff --git a/pwmanager/libcrypt/mpi/generic/mpih-sub1.c b/pwmanager/libcrypt/mpi/generic/mpih-sub1.c
new file mode 100644
index 0000000..e88821b
--- a/dev/null
+++ b/pwmanager/libcrypt/mpi/generic/mpih-sub1.c
@@ -0,0 +1,66 @@
1/* mpihelp-add_2.c - MPI helper functions
2 * Copyright (C) 1994, 1996, 1997, 1998, 2001,
3 * 2002 Free Software Foundation, Inc.
4 *
5 * This file is part of Libgcrypt.
6 *
7 * Libgcrypt is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * Libgcrypt is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20 *
21 * Note: This code is heavily based on the GNU MP Library.
22 * Actually it's the same code with only minor changes in the
23 * way the data is stored; this is to support the abstraction
24 * of an optional secure memory allocation which may be used
25 * to avoid revealing of sensitive data due to paging etc.
26 */
27
28#include <config.h>
29#include <stdio.h>
30#include <stdlib.h>
31#include "mpi-internal.h"
32#include "longlong.h"
33
34mpi_limb_t
35_gcry_mpih_sub_n( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
36 mpi_ptr_t s2_ptr, mpi_size_t size)
37{
38 mpi_limb_t x, y, cy;
39 mpi_size_t j;
40
41 /* The loop counter and index J goes from -SIZE to -1. This way
42 the loop becomes faster. */
43 j = -size;
44
45 /* Offset the base pointers to compensate for the negative indices. */
46 s1_ptr -= j;
47 s2_ptr -= j;
48 res_ptr -= j;
49
50 cy = 0;
51 do
52 {
53 y = s2_ptr[j];
54 x = s1_ptr[j];
55 y += cy; /* add previous carry to subtrahend */
56 cy = y < cy; /* get out carry from that addition */
57 y = x - y; /* main subtract */
58 cy += y > x; /* get out carry from the subtract, combine */
59 res_ptr[j] = y;
60 }
61 while( ++j );
62
63 return cy;
64}
65
66
diff --git a/pwmanager/libcrypt/mpi/generic/udiv-w-sdiv.c b/pwmanager/libcrypt/mpi/generic/udiv-w-sdiv.c
new file mode 100644
index 0000000..e80d98b
--- a/dev/null
+++ b/pwmanager/libcrypt/mpi/generic/udiv-w-sdiv.c
@@ -0,0 +1,133 @@
1/* mpih-w-sdiv -- implement udiv_qrnnd on machines with only signed
2 * division.
3 * Copyright (C) 1992, 1994, 1996, 1998, 2002 Free Software Foundation, Inc.
4 * Contributed by Peter L. Montgomery.
5 *
6 * This file is part of Libgcrypt.
7 *
8 * Libgcrypt is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU Lesser General Public License as
10 * published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * Libgcrypt is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
21 */
22
23#include <config.h>
24#include <stdio.h>
25#include <stdlib.h>
26#include "mpi-internal.h"
27#include "longlong.h"
28
29
30#if 0 /* not yet ported to MPI */
31
32mpi_limb_t
33mpihelp_udiv_w_sdiv( mpi_limp_t *rp,
34 mpi_limp_t *a1,
35 mpi_limp_t *a0,
36 mpi_limp_t *d )
37{
38 mp_limb_t q, r;
39 mp_limb_t c0, c1, b1;
40
41 if ((mpi_limb_signed_t) d >= 0)
42 {
43 if (a1 < d - a1 - (a0 >> (BITS_PER_MP_LIMB - 1)))
44 {
45 /* dividend, divisor, and quotient are nonnegative */
46 sdiv_qrnnd (q, r, a1, a0, d);
47 }
48 else
49 {
50 /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d */
51 sub_ddmmss (c1, c0, a1, a0, d >> 1, d << (BITS_PER_MP_LIMB - 1));
52 /* Divide (c1*2^32 + c0) by d */
53 sdiv_qrnnd (q, r, c1, c0, d);
54 /* Add 2^31 to quotient */
55 q += (mp_limb_t) 1 << (BITS_PER_MP_LIMB - 1);
56 }
57 }
58 else
59 {
60 b1 = d >> 1; /* d/2, between 2^30 and 2^31 - 1 */
61 c1 = a1 >> 1; /* A/2 */
62 c0 = (a1 << (BITS_PER_MP_LIMB - 1)) + (a0 >> 1);
63
64 if (a1 < b1) /* A < 2^32*b1, so A/2 < 2^31*b1 */
65 {
66 sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
67
68 r = 2*r + (a0 & 1); /* Remainder from A/(2*b1) */
69 if ((d & 1) != 0)
70 {
71 if (r >= q)
72 r = r - q;
73 else if (q - r <= d)
74 {
75 r = r - q + d;
76 q--;
77 }
78 else
79 {
80 r = r - q + 2*d;
81 q -= 2;
82 }
83 }
84 }
85 else if (c1 < b1) /* So 2^31 <= (A/2)/b1 < 2^32 */
86 {
87 c1 = (b1 - 1) - c1;
88 c0 = ~c0; /* logical NOT */
89
90 sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
91
92 q = ~q; /* (A/2)/b1 */
93 r = (b1 - 1) - r;
94
95 r = 2*r + (a0 & 1); /* A/(2*b1) */
96
97 if ((d & 1) != 0)
98 {
99 if (r >= q)
100 r = r - q;
101 else if (q - r <= d)
102 {
103 r = r - q + d;
104 q--;
105 }
106 else
107 {
108 r = r - q + 2*d;
109 q -= 2;
110 }
111 }
112 }
113 else /* Implies c1 = b1 */
114 { /* Hence a1 = d - 1 = 2*b1 - 1 */
115 if (a0 >= -d)
116 {
117 q = -1;
118 r = a0 + d;
119 }
120 else
121 {
122 q = -2;
123 r = a0 + 2*d;
124 }
125 }
126 }
127
128 *rp = r;
129 return q;
130}
131
132#endif
133
diff --git a/pwmanager/libcrypt/mpi/longlong.h b/pwmanager/libcrypt/mpi/longlong.h
new file mode 100644
index 0000000..34bd50c
--- a/dev/null
+++ b/pwmanager/libcrypt/mpi/longlong.h
@@ -0,0 +1,1561 @@
1/* longlong.h -- definitions for mixed size 32/64 bit arithmetic.
2 Note: I added some stuff for use with gnupg
3
4Copyright (C) 1991, 1992, 1993, 1994, 1996, 1998,
5 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
6
7This file is free software; you can redistribute it and/or modify
8it under the terms of the GNU Lesser General Public License as published by
9the Free Software Foundation; either version 2.1 of the License, or (at your
10option) any later version.
11
12This file is distributed in the hope that it will be useful, but
13WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15License for more details.
16
17You should have received a copy of the GNU Library General Public License
18along with this file; see the file COPYING.LIB. If not, write to
19the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
20MA 02111-1307, USA. */
21
22/* You have to define the following before including this file:
23
24 UWtype -- An unsigned type, default type for operations (typically a "word")
25 UHWtype -- An unsigned type, at least half the size of UWtype.
26 UDWtype -- An unsigned type, at least twice as large a UWtype
27 W_TYPE_SIZE -- size in bits of UWtype
28
29 SItype, USItype -- Signed and unsigned 32 bit types.
30 DItype, UDItype -- Signed and unsigned 64 bit types.
31
32 On a 32 bit machine UWtype should typically be USItype;
33 on a 64 bit machine, UWtype should typically be UDItype.
34*/
35
36#define __BITS4 (W_TYPE_SIZE / 4)
37#define __ll_B ((UWtype) 1 << (W_TYPE_SIZE / 2))
38#define __ll_lowpart(t) ((UWtype) (t) & (__ll_B - 1))
39#define __ll_highpart(t) ((UWtype) (t) >> (W_TYPE_SIZE / 2))
40
41/* This is used to make sure no undesirable sharing between different libraries
42 that use this file takes place. */
43#ifndef __MPN
44#define __MPN(x) __##x
45#endif
46
47/* Define auxiliary asm macros.
48
49 1) umul_ppmm(high_prod, low_prod, multipler, multiplicand) multiplies two
50 UWtype integers MULTIPLER and MULTIPLICAND, and generates a two UWtype
51 word product in HIGH_PROD and LOW_PROD.
52
53 2) __umulsidi3(a,b) multiplies two UWtype integers A and B, and returns a
54 UDWtype product. This is just a variant of umul_ppmm.
55
56 3) udiv_qrnnd(quotient, remainder, high_numerator, low_numerator,
57 denominator) divides a UDWtype, composed by the UWtype integers
58 HIGH_NUMERATOR and LOW_NUMERATOR, by DENOMINATOR and places the quotient
59 in QUOTIENT and the remainder in REMAINDER.HIGH_NUMERATOR must be less
60 than DENOMINATOR for correct operation. If, in addition, the most
61 significant bit of DENOMINATOR must be 1, then the pre-processor symbol
62 UDIV_NEEDS_NORMALIZATION is defined to 1.
63
64 4) sdiv_qrnnd(quotient, remainder, high_numerator, low_numerator,
65 denominator). Like udiv_qrnnd but the numbers are signed. The quotient
66 is rounded towards 0.
67
68 5) count_leading_zeros(count, x) counts the number of zero-bits from the
69 msb to the first non-zero bit in the UWtype X. This is the number of
70 steps X needs to be shifted left to set the msb. Undefined for X == 0,
71 unless the symbol COUNT_LEADING_ZEROS_0 is defined to some value.
72
73 6) count_trailing_zeros(count, x) like count_leading_zeros, but counts
74 from the least significant end.
75
76 7) add_ssaaaa(high_sum, low_sum, high_addend_1, low_addend_1,
77 high_addend_2, low_addend_2) adds two UWtype integers, composed by
78 HIGH_ADDEND_1 and LOW_ADDEND_1, and HIGH_ADDEND_2 and LOW_ADDEND_2
79 respectively. The result is placed in HIGH_SUM and LOW_SUM. Overflow
80 (i.e. carry out) is not stored anywhere, and is lost.
81
82 8) sub_ddmmss(high_difference, low_difference, high_minuend, low_minuend,
83 high_subtrahend, low_subtrahend) subtracts two two-word UWtype integers,
84 composed by HIGH_MINUEND_1 and LOW_MINUEND_1, and HIGH_SUBTRAHEND_2 and
85 LOW_SUBTRAHEND_2 respectively. The result is placed in HIGH_DIFFERENCE
86 and LOW_DIFFERENCE.Overflow (i.e. carry out) is not stored anywhere,
87 and is lost.
88
89 If any of these macros are left undefined for a particular CPU,
90 C macros are used. */
91
92/* The CPUs come in alphabetical order below.
93
94 Please add support for more CPUs here, or improve the current support
95 for the CPUs below!*/
96
97#ifdef __riscos__
98#pragma continue_after_hash_error
99#else /* !__riscos__ */
100#if defined (__GNUC__) && !defined (NO_ASM)
101
102/* We sometimes need to clobber "cc" with gcc2, but that would not be
103 understood by gcc1.Use cpp to avoid major code duplication. */
104#if __GNUC__ < 2
105#define __CLOBBER_CC
106#define __AND_CLOBBER_CC
107#else /* __GNUC__ >= 2 */
108#define __CLOBBER_CC : "cc"
109#define __AND_CLOBBER_CC , "cc"
110#endif /* __GNUC__ < 2 */
111
112
113/***************************************
114 ************** A29K *****************
115 ***************************************/
116#if (defined (__a29k__) || defined (_AM29K)) && W_TYPE_SIZE == 32
117#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
118 __asm__ ("add %1,%4,%5\n" \
119 "addc %0,%2,%3" \
120 : "=r" ((USItype)(sh)), \
121 "=&r" ((USItype)(sl)) \
122 : "%r" ((USItype)(ah)), \
123 "rI" ((USItype)(bh)), \
124 "%r" ((USItype)(al)), \
125 "rI" ((USItype)(bl)))
126#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
127 __asm__ ("sub %1,%4,%5\n" \
128 "subc %0,%2,%3" \
129 : "=r" ((USItype)(sh)), \
130 "=&r" ((USItype)(sl)) \
131 : "r" ((USItype)(ah)), \
132 "rI" ((USItype)(bh)), \
133 "r" ((USItype)(al)), \
134 "rI" ((USItype)(bl)))
135#define umul_ppmm(xh, xl, m0, m1) \
136 do { \
137 USItype __m0 = (m0), __m1 = (m1); \
138 __asm__ ("multiplu %0,%1,%2" \
139 : "=r" ((USItype)(xl)) \
140 : "r" (__m0), \
141 "r" (__m1)); \
142 __asm__ ("multmu %0,%1,%2" \
143 : "=r" ((USItype)(xh)) \
144 : "r" (__m0), \
145 "r" (__m1)); \
146 } while (0)
147#define udiv_qrnnd(q, r, n1, n0, d) \
148 __asm__ ("dividu %0,%3,%4" \
149 : "=r" ((USItype)(q)), \
150 "=q" ((USItype)(r)) \
151 : "1" ((USItype)(n1)), \
152 "r" ((USItype)(n0)), \
153 "r" ((USItype)(d)))
154#define count_leading_zeros(count, x) \
155 __asm__ ("clz %0,%1" \
156 : "=r" ((USItype)(count)) \
157 : "r" ((USItype)(x)))
158#define COUNT_LEADING_ZEROS_0 32
159#endif /* __a29k__ */
160
161
162#if defined (__alpha) && W_TYPE_SIZE == 64
163#define umul_ppmm(ph, pl, m0, m1) \
164 do { \
165 UDItype __m0 = (m0), __m1 = (m1); \
166 __asm__ ("umulh %r1,%2,%0" \
167 : "=r" ((UDItype) ph) \
168 : "%rJ" (__m0), \
169 "rI" (__m1)); \
170 (pl) = __m0 * __m1; \
171 } while (0)
172#define UMUL_TIME 46
173#ifndef LONGLONG_STANDALONE
174#define udiv_qrnnd(q, r, n1, n0, d) \
175 do { UDItype __r; \
176 (q) = __udiv_qrnnd (&__r, (n1), (n0), (d)); \
177 (r) = __r; \
178 } while (0)
179extern UDItype __udiv_qrnnd ();
180#define UDIV_TIME 220
181#endif /* LONGLONG_STANDALONE */
182#endif /* __alpha */
183
184/***************************************
185 ************** ARM ******************
186 ***************************************/
187#if defined (__arm__) && W_TYPE_SIZE == 32
188#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
189 __asm__ ("adds %1, %4, %5\n" \
190 "adc %0, %2, %3" \
191 : "=r" ((USItype)(sh)), \
192 "=&r" ((USItype)(sl)) \
193 : "%r" ((USItype)(ah)), \
194 "rI" ((USItype)(bh)), \
195 "%r" ((USItype)(al)), \
196 "rI" ((USItype)(bl)))
197#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
198 __asm__ ("subs %1, %4, %5\n" \
199 "sbc %0, %2, %3" \
200 : "=r" ((USItype)(sh)), \
201 "=&r" ((USItype)(sl)) \
202 : "r" ((USItype)(ah)), \
203 "rI" ((USItype)(bh)), \
204 "r" ((USItype)(al)), \
205 "rI" ((USItype)(bl)))
206#if defined __ARM_ARCH_2__ || defined __ARM_ARCH_3__
207#define umul_ppmm(xh, xl, a, b) \
208 __asm__ ("%@ Inlined umul_ppmm\n" \
209 "mov %|r0, %2, lsr #16 @ AAAA\n" \
210 "mov %|r2, %3, lsr #16 @ BBBB\n" \
211 "bic %|r1, %2, %|r0, lsl #16 @ aaaa\n" \
212 "bic %0, %3, %|r2, lsl #16 @ bbbb\n" \
213 "mul %1, %|r1, %|r2 @ aaaa * BBBB\n" \
214 "mul %|r2, %|r0, %|r2 @ AAAA * BBBB\n" \
215 "mul %|r1, %0, %|r1 @ aaaa * bbbb\n" \
216 "mul %0, %|r0, %0 @ AAAA * bbbb\n" \
217 "adds %|r0, %1, %0 @ central sum\n" \
218 "addcs%|r2, %|r2, #65536\n" \
219 "adds%1, %|r1, %|r0, lsl #16\n" \
220 "adc%0, %|r2, %|r0, lsr #16" \
221 : "=&r" ((USItype)(xh)), \
222 "=r" ((USItype)(xl)) \
223 : "r" ((USItype)(a)), \
224 "r" ((USItype)(b)) \
225 : "r0", "r1", "r2")
226#else
227#define umul_ppmm(xh, xl, a, b) \
228 __asm__ ("%@ Inlined umul_ppmm\n" \
229 "umull %r1, %r0, %r2, %r3" \
230 : "=&r" ((USItype)(xh)), \
231 "=r" ((USItype)(xl)) \
232 : "r" ((USItype)(a)), \
233 "r" ((USItype)(b)) \
234 : "r0", "r1")
235#endif
236#define UMUL_TIME 20
237#define UDIV_TIME 100
238#endif /* __arm__ */
239
240/***************************************
241 ************** CLIPPER **************
242 ***************************************/
243#if defined (__clipper__) && W_TYPE_SIZE == 32
244#define umul_ppmm(w1, w0, u, v) \
245 ({union {UDItype __ll; \
246 struct {USItype __l, __h;} __i; \
247 } __xx; \
248 __asm__ ("mulwux %2,%0" \
249 : "=r" (__xx.__ll) \
250 : "%0" ((USItype)(u)), \
251 "r" ((USItype)(v))); \
252 (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;})
253#define smul_ppmm(w1, w0, u, v) \
254 ({union {DItype __ll; \
255 struct {SItype __l, __h;} __i; \
256 } __xx; \
257 __asm__ ("mulwx %2,%0" \
258 : "=r" (__xx.__ll) \
259 : "%0" ((SItype)(u)), \
260 "r" ((SItype)(v))); \
261 (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;})
262#define __umulsidi3(u, v) \
263 ({UDItype __w; \
264 __asm__ ("mulwux %2,%0" \
265 : "=r" (__w) \
266 : "%0" ((USItype)(u)), \
267 "r" ((USItype)(v))); \
268 __w; })
269#endif /* __clipper__ */
270
271
272/***************************************
273 ************** GMICRO ***************
274 ***************************************/
275#if defined (__gmicro__) && W_TYPE_SIZE == 32
276#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
277 __asm__ ("add.w %5,%1\n" \
278 "addx %3,%0" \
279 : "=g" ((USItype)(sh)), \
280 "=&g" ((USItype)(sl)) \
281 : "%0" ((USItype)(ah)), \
282 "g" ((USItype)(bh)), \
283 "%1" ((USItype)(al)), \
284 "g" ((USItype)(bl)))
285#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
286 __asm__ ("sub.w %5,%1\n" \
287 "subx %3,%0" \
288 : "=g" ((USItype)(sh)), \
289 "=&g" ((USItype)(sl)) \
290 : "0" ((USItype)(ah)), \
291 "g" ((USItype)(bh)), \
292 "1" ((USItype)(al)), \
293 "g" ((USItype)(bl)))
294#define umul_ppmm(ph, pl, m0, m1) \
295 __asm__ ("mulx %3,%0,%1" \
296 : "=g" ((USItype)(ph)), \
297 "=r" ((USItype)(pl)) \
298 : "%0" ((USItype)(m0)), \
299 "g" ((USItype)(m1)))
300#define udiv_qrnnd(q, r, nh, nl, d) \
301 __asm__ ("divx %4,%0,%1" \
302 : "=g" ((USItype)(q)), \
303 "=r" ((USItype)(r)) \
304 : "1" ((USItype)(nh)), \
305 "0" ((USItype)(nl)), \
306 "g" ((USItype)(d)))
307#define count_leading_zeros(count, x) \
308 __asm__ ("bsch/1 %1,%0" \
309 : "=g" (count) \
310 : "g" ((USItype)(x)), \
311 "0" ((USItype)0))
312#endif
313
314
315/***************************************
316 ************** HPPA *****************
317 ***************************************/
318#if defined (__hppa) && W_TYPE_SIZE == 32
319#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
320 __asm__ ("add %4,%5,%1\n" \
321 "addc %2,%3,%0" \
322 : "=r" ((USItype)(sh)), \
323 "=&r" ((USItype)(sl)) \
324 : "%rM" ((USItype)(ah)), \
325 "rM" ((USItype)(bh)), \
326 "%rM" ((USItype)(al)), \
327 "rM" ((USItype)(bl)))
328#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
329 __asm__ ("sub %4,%5,%1\n" \
330 "subb %2,%3,%0" \
331 : "=r" ((USItype)(sh)), \
332 "=&r" ((USItype)(sl)) \
333 : "rM" ((USItype)(ah)), \
334 "rM" ((USItype)(bh)), \
335 "rM" ((USItype)(al)), \
336 "rM" ((USItype)(bl)))
337#if defined (_PA_RISC1_1)
338#define umul_ppmm(wh, wl, u, v) \
339 do { \
340 union {UDItype __ll; \
341 struct {USItype __h, __l;} __i; \
342 } __xx; \
343 __asm__ ("xmpyu %1,%2,%0" \
344 : "=*f" (__xx.__ll) \
345 : "*f" ((USItype)(u)), \
346 "*f" ((USItype)(v))); \
347 (wh) = __xx.__i.__h; \
348 (wl) = __xx.__i.__l; \
349 } while (0)
350#define UMUL_TIME 8
351#define UDIV_TIME 60
352#else
353#define UMUL_TIME 40
354#define UDIV_TIME 80
355#endif
356#ifndef LONGLONG_STANDALONE
357#define udiv_qrnnd(q, r, n1, n0, d) \
358 do { USItype __r; \
359 (q) = __udiv_qrnnd (&__r, (n1), (n0), (d)); \
360 (r) = __r; \
361 } while (0)
362extern USItype __udiv_qrnnd ();
363#endif /* LONGLONG_STANDALONE */
364#define count_leading_zeros(count, x) \
365 do { \
366 USItype __tmp; \
367 __asm__ ( \
368 "ldi 1,%0 \n" \
369 " extru,= %1,15,16,%%r0 ; Bits 31..16 zero? \n" \
370 " extru,tr%1,15,16,%1 ; No. Shift down, skip add.\n" \
371 " ldo 16(%0),%0 ; Yes.Perform add. \n" \
372 " extru,= %1,23,8,%%r0 ; Bits 15..8 zero? \n" \
373 " extru,tr%1,23,8,%1 ; No. Shift down, skip add.\n" \
374 " ldo 8(%0),%0 ; Yes.Perform add. \n" \
375 " extru,= %1,27,4,%%r0 ; Bits 7..4 zero? \n" \
376 " extru,tr%1,27,4,%1 ; No. Shift down, skip add.\n" \
377 " ldo 4(%0),%0 ; Yes.Perform add. \n" \
378 " extru,= %1,29,2,%%r0 ; Bits 3..2 zero? \n" \
379 " extru,tr%1,29,2,%1 ; No. Shift down, skip add.\n" \
380 " ldo 2(%0),%0 ; Yes.Perform add. \n" \
381 " extru %1,30,1,%1 ; Extract bit 1. \n" \
382 " sub %0,%1,%0 ; Subtract it. " \
383 : "=r" (count), "=r" (__tmp) : "1" (x)); \
384 } while (0)
385#endif /* hppa */
386
387
388/***************************************
389 ************** I370 *****************
390 ***************************************/
391#if (defined (__i370__) || defined (__mvs__)) && W_TYPE_SIZE == 32
392#define umul_ppmm(xh, xl, m0, m1) \
393 do { \
394 union {UDItype __ll; \
395 struct {USItype __h, __l;} __i; \
396 } __xx; \
397 USItype __m0 = (m0), __m1 = (m1); \
398 __asm__ ("mr %0,%3" \
399 : "=r" (__xx.__i.__h), \
400 "=r" (__xx.__i.__l) \
401 : "%1" (__m0), \
402 "r" (__m1)); \
403 (xh) = __xx.__i.__h; (xl) = __xx.__i.__l; \
404 (xh) += ((((SItype) __m0 >> 31) & __m1) \
405 + (((SItype) __m1 >> 31) & __m0)); \
406 } while (0)
407#define smul_ppmm(xh, xl, m0, m1) \
408 do { \
409 union {DItype __ll; \
410 struct {USItype __h, __l;} __i; \
411 } __xx; \
412 __asm__ ("mr %0,%3" \
413 : "=r" (__xx.__i.__h), \
414 "=r" (__xx.__i.__l) \
415 : "%1" (m0), \
416 "r" (m1)); \
417 (xh) = __xx.__i.__h; (xl) = __xx.__i.__l; \
418 } while (0)
419#define sdiv_qrnnd(q, r, n1, n0, d) \
420 do { \
421 union {DItype __ll; \
422 struct {USItype __h, __l;} __i; \
423 } __xx; \
424 __xx.__i.__h = n1; __xx.__i.__l = n0; \
425 __asm__ ("dr %0,%2" \
426 : "=r" (__xx.__ll) \
427 : "0" (__xx.__ll), "r" (d)); \
428 (q) = __xx.__i.__l; (r) = __xx.__i.__h; \
429 } while (0)
430#endif
431
432
433/***************************************
434 ************** I386 *****************
435 ***************************************/
436#if (defined (__i386__) || defined (__i486__)) && W_TYPE_SIZE == 32
437#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
438 __asm__ ("addl %5,%1\n" \
439 "adcl %3,%0" \
440 : "=r" ((USItype)(sh)), \
441 "=&r" ((USItype)(sl)) \
442 : "%0" ((USItype)(ah)), \
443 "g" ((USItype)(bh)), \
444 "%1" ((USItype)(al)), \
445 "g" ((USItype)(bl)))
446#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
447 __asm__ ("subl %5,%1\n" \
448 "sbbl %3,%0" \
449 : "=r" ((USItype)(sh)), \
450 "=&r" ((USItype)(sl)) \
451 : "0" ((USItype)(ah)), \
452 "g" ((USItype)(bh)), \
453 "1" ((USItype)(al)), \
454 "g" ((USItype)(bl)))
455#define umul_ppmm(w1, w0, u, v) \
456 __asm__ ("mull %3" \
457 : "=a" ((USItype)(w0)), \
458 "=d" ((USItype)(w1)) \
459 : "%0" ((USItype)(u)), \
460 "rm" ((USItype)(v)))
461#define udiv_qrnnd(q, r, n1, n0, d) \
462 __asm__ ("divl %4" \
463 : "=a" ((USItype)(q)), \
464 "=d" ((USItype)(r)) \
465 : "0" ((USItype)(n0)), \
466 "1" ((USItype)(n1)), \
467 "rm" ((USItype)(d)))
468#define count_leading_zeros(count, x) \
469 do { \
470 USItype __cbtmp; \
471 __asm__ ("bsrl %1,%0" \
472 : "=r" (__cbtmp) : "rm" ((USItype)(x))); \
473 (count) = __cbtmp ^ 31; \
474 } while (0)
475#define count_trailing_zeros(count, x) \
476 __asm__ ("bsfl %1,%0" : "=r" (count) : "rm" ((USItype)(x)))
477#ifndef UMUL_TIME
478#define UMUL_TIME 40
479#endif
480#ifndef UDIV_TIME
481#define UDIV_TIME 40
482#endif
483#endif /* 80x86 */
484
485
486/***************************************
487 ************** I860 *****************
488 ***************************************/
489#if defined (__i860__) && W_TYPE_SIZE == 32
490#define rshift_rhlc(r,h,l,c) \
491 __asm__ ("shr %3,r0,r0\n" \
492 "shrd %1,%2,%0" \
493 "=r" (r) : "r" (h), "r" (l), "rn" (c))
494#endif /* i860 */
495
496/***************************************
497 ************** I960 *****************
498 ***************************************/
499#if defined (__i960__) && W_TYPE_SIZE == 32
500#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
501 __asm__ ("cmpo 1,0\n" \
502 "addc %5,%4,%1\n" \
503 "addc %3,%2,%0" \
504 : "=r" ((USItype)(sh)), \
505 "=&r" ((USItype)(sl)) \
506 : "%dI" ((USItype)(ah)), \
507 "dI" ((USItype)(bh)), \
508 "%dI" ((USItype)(al)), \
509 "dI" ((USItype)(bl)))
510#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
511 __asm__ ("cmpo 0,0\n" \
512 "subc %5,%4,%1\n" \
513 "subc %3,%2,%0" \
514 : "=r" ((USItype)(sh)), \
515 "=&r" ((USItype)(sl)) \
516 : "dI" ((USItype)(ah)), \
517 "dI" ((USItype)(bh)), \
518 "dI" ((USItype)(al)), \
519 "dI" ((USItype)(bl)))
520#define umul_ppmm(w1, w0, u, v) \
521 ({union {UDItype __ll; \
522 struct {USItype __l, __h;} __i; \
523 } __xx; \
524 __asm__ ("emul %2,%1,%0" \
525 : "=d" (__xx.__ll) \
526 : "%dI" ((USItype)(u)), \
527 "dI" ((USItype)(v))); \
528 (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;})
529#define __umulsidi3(u, v) \
530 ({UDItype __w; \
531 __asm__ ("emul %2,%1,%0" \
532 : "=d" (__w) \
533 : "%dI" ((USItype)(u)), \
534 "dI" ((USItype)(v))); \
535 __w; })
536#define udiv_qrnnd(q, r, nh, nl, d) \
537 do { \
538 union {UDItype __ll; \
539 struct {USItype __l, __h;} __i; \
540 } __nn; \
541 __nn.__i.__h = (nh); __nn.__i.__l = (nl); \
542 __asm__ ("ediv %d,%n,%0" \
543 : "=d" (__rq.__ll) \
544 : "dI" (__nn.__ll), \
545 "dI" ((USItype)(d))); \
546 (r) = __rq.__i.__l; (q) = __rq.__i.__h; \
547 } while (0)
548#define count_leading_zeros(count, x) \
549 do { \
550 USItype __cbtmp; \
551 __asm__ ("scanbit %1,%0" \
552 : "=r" (__cbtmp) \
553 : "r" ((USItype)(x))); \
554 (count) = __cbtmp ^ 31; \
555 } while (0)
556#define COUNT_LEADING_ZEROS_0 (-32) /* sic */
557 #if defined (__i960mx) /* what is the proper symbol to test??? */
558#define rshift_rhlc(r,h,l,c) \
559 do { \
560 union {UDItype __ll; \
561 struct {USItype __l, __h;} __i; \
562 } __nn; \
563 __nn.__i.__h = (h); __nn.__i.__l = (l); \
564 __asm__ ("shre %2,%1,%0" \
565 : "=d" (r) : "dI" (__nn.__ll), "dI" (c)); \
566 }
567#endif /* i960mx */
568#endif /* i960 */
569
570
571/***************************************
572 ************** 68000****************
573 ***************************************/
574#if (defined (__mc68000__) || defined (__mc68020__) || defined (__NeXT__) || defined(mc68020)) && W_TYPE_SIZE == 32
575#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
576 __asm__ ("add%.l %5,%1\n" \
577 "addx%.l %3,%0" \
578 : "=d" ((USItype)(sh)), \
579 "=&d" ((USItype)(sl)) \
580 : "%0" ((USItype)(ah)), \
581 "d" ((USItype)(bh)), \
582 "%1" ((USItype)(al)), \
583 "g" ((USItype)(bl)))
584#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
585 __asm__ ("sub%.l %5,%1\n" \
586 "subx%.l %3,%0" \
587 : "=d" ((USItype)(sh)), \
588 "=&d" ((USItype)(sl)) \
589 : "0" ((USItype)(ah)), \
590 "d" ((USItype)(bh)), \
591 "1" ((USItype)(al)), \
592 "g" ((USItype)(bl)))
593#if (defined (__mc68020__) || defined (__NeXT__) || defined(mc68020))
594#define umul_ppmm(w1, w0, u, v) \
595 __asm__ ("mulu%.l %3,%1:%0" \
596 : "=d" ((USItype)(w0)), \
597 "=d" ((USItype)(w1)) \
598 : "%0" ((USItype)(u)), \
599 "dmi" ((USItype)(v)))
600#define UMUL_TIME 45
601#define udiv_qrnnd(q, r, n1, n0, d) \
602 __asm__ ("divu%.l %4,%1:%0" \
603 : "=d" ((USItype)(q)), \
604 "=d" ((USItype)(r)) \
605 : "0" ((USItype)(n0)), \
606 "1" ((USItype)(n1)), \
607 "dmi" ((USItype)(d)))
608#define UDIV_TIME 90
609#define sdiv_qrnnd(q, r, n1, n0, d) \
610 __asm__ ("divs%.l %4,%1:%0" \
611 : "=d" ((USItype)(q)), \
612 "=d" ((USItype)(r)) \
613 : "0" ((USItype)(n0)), \
614 "1" ((USItype)(n1)), \
615 "dmi" ((USItype)(d)))
616#define count_leading_zeros(count, x) \
617 __asm__ ("bfffo %1{%b2:%b2},%0" \
618 : "=d" ((USItype)(count)) \
619 : "od" ((USItype)(x)), "n" (0))
620#define COUNT_LEADING_ZEROS_0 32
621#else /* not mc68020 */
622#define umul_ppmm(xh, xl, a, b) \
623 do { USItype __umul_tmp1, __umul_tmp2; \
624 __asm__ ("| Inlined umul_ppmm \n" \
625 " move%.l %5,%3 \n" \
626 " move%.l %2,%0 \n" \
627 " move%.w %3,%1 \n" \
628 " swap%3 \n" \
629 " swap%0 \n" \
630 " mulu%2,%1 \n" \
631 " mulu%3,%0 \n" \
632 " mulu%2,%3 \n" \
633 " swap%2 \n" \
634 " mulu%5,%2 \n" \
635 " add%.l%3,%2 \n" \
636 " jcc1f \n" \
637 " add%.l%#0x10000,%0 \n" \
638 "1:move%.l %2,%3 \n" \
639 " clr%.w%2 \n" \
640 " swap%2 \n" \
641 " swap%3 \n" \
642 " clr%.w%3 \n" \
643 " add%.l%3,%1 \n" \
644 " addx%.l %2,%0 \n" \
645 " | End inlined umul_ppmm" \
646 : "=&d" ((USItype)(xh)), "=&d" ((USItype)(xl)), \
647 "=d" (__umul_tmp1), "=&d" (__umul_tmp2) \
648 : "%2" ((USItype)(a)), "d" ((USItype)(b))); \
649 } while (0)
650#define UMUL_TIME 100
651#define UDIV_TIME 400
652#endif /* not mc68020 */
653#endif /* mc68000 */
654
655
656/***************************************
657 ************** 88000****************
658 ***************************************/
659#if defined (__m88000__) && W_TYPE_SIZE == 32
660#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
661 __asm__ ("addu.co %1,%r4,%r5\n" \
662 "addu.ci %0,%r2,%r3" \
663 : "=r" ((USItype)(sh)), \
664 "=&r" ((USItype)(sl)) \
665 : "%rJ" ((USItype)(ah)), \
666 "rJ" ((USItype)(bh)), \
667 "%rJ" ((USItype)(al)), \
668 "rJ" ((USItype)(bl)))
669#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
670 __asm__ ("subu.co %1,%r4,%r5\n" \
671 "subu.ci %0,%r2,%r3" \
672 : "=r" ((USItype)(sh)), \
673 "=&r" ((USItype)(sl)) \
674 : "rJ" ((USItype)(ah)), \
675 "rJ" ((USItype)(bh)), \
676 "rJ" ((USItype)(al)), \
677 "rJ" ((USItype)(bl)))
678#define count_leading_zeros(count, x) \
679 do { \
680 USItype __cbtmp; \
681 __asm__ ("ff1 %0,%1" \
682 : "=r" (__cbtmp) \
683 : "r" ((USItype)(x))); \
684 (count) = __cbtmp ^ 31; \
685 } while (0)
686#define COUNT_LEADING_ZEROS_0 63 /* sic */
687#if defined (__m88110__)
688#define umul_ppmm(wh, wl, u, v) \
689 do { \
690 union {UDItype __ll; \
691 struct {USItype __h, __l;} __i; \
692 } __x; \
693 __asm__ ("mulu.d %0,%1,%2" : "=r" (__x.__ll) : "r" (u), "r" (v)); \
694 (wh) = __x.__i.__h; \
695 (wl) = __x.__i.__l; \
696 } while (0)
697#define udiv_qrnnd(q, r, n1, n0, d) \
698 ({union {UDItype __ll; \
699 struct {USItype __h, __l;} __i; \
700 } __x, __q; \
701 __x.__i.__h = (n1); __x.__i.__l = (n0); \
702 __asm__ ("divu.d %0,%1,%2" \
703 : "=r" (__q.__ll) : "r" (__x.__ll), "r" (d)); \
704 (r) = (n0) - __q.__l * (d); (q) = __q.__l; })
705#define UMUL_TIME 5
706#define UDIV_TIME 25
707#else
708#define UMUL_TIME 17
709#define UDIV_TIME 150
710#endif /* __m88110__ */
711#endif /* __m88000__ */
712
713/***************************************
714 ************** MIPS *****************
715 ***************************************/
716#if defined (__mips__) && W_TYPE_SIZE == 32
717#if __GNUC__ > 2 || __GNUC_MINOR__ >= 7
718#define umul_ppmm(w1, w0, u, v) \
719 __asm__ ("multu %2,%3" \
720 : "=l" ((USItype)(w0)), \
721 "=h" ((USItype)(w1)) \
722 : "d" ((USItype)(u)), \
723 "d" ((USItype)(v)))
724#else
725#define umul_ppmm(w1, w0, u, v) \
726 __asm__ ("multu %2,%3 \n" \
727 "mflo %0 \n" \
728 "mfhi %1" \
729 : "=d" ((USItype)(w0)), \
730 "=d" ((USItype)(w1)) \
731 : "d" ((USItype)(u)), \
732 "d" ((USItype)(v)))
733#endif
734#define UMUL_TIME 10
735#define UDIV_TIME 100
736#endif /* __mips__ */
737
738/***************************************
739 ************** MIPS/64 **************
740 ***************************************/
741#if (defined (__mips) && __mips >= 3) && W_TYPE_SIZE == 64
742#if __GNUC__ > 2 || __GNUC_MINOR__ >= 7
743#define umul_ppmm(w1, w0, u, v) \
744 __asm__ ("dmultu %2,%3" \
745 : "=l" ((UDItype)(w0)), \
746 "=h" ((UDItype)(w1)) \
747 : "d" ((UDItype)(u)), \
748 "d" ((UDItype)(v)))
749#else
750#define umul_ppmm(w1, w0, u, v) \
751 __asm__ ("dmultu %2,%3 \n" \
752 "mflo %0 \n" \
753 "mfhi %1" \
754 : "=d" ((UDItype)(w0)), \
755 "=d" ((UDItype)(w1)) \
756 : "d" ((UDItype)(u)), \
757 "d" ((UDItype)(v)))
758#endif
759#define UMUL_TIME 20
760#define UDIV_TIME 140
761#endif /* __mips__ */
762
763
764/***************************************
765 ************** 32000****************
766 ***************************************/
767#if defined (__ns32000__) && W_TYPE_SIZE == 32
768#define umul_ppmm(w1, w0, u, v) \
769 ({union {UDItype __ll; \
770 struct {USItype __l, __h;} __i; \
771 } __xx; \
772 __asm__ ("meid %2,%0" \
773 : "=g" (__xx.__ll) \
774 : "%0" ((USItype)(u)), \
775 "g" ((USItype)(v))); \
776 (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;})
777#define __umulsidi3(u, v) \
778 ({UDItype __w; \
779 __asm__ ("meid %2,%0" \
780 : "=g" (__w) \
781 : "%0" ((USItype)(u)), \
782 "g" ((USItype)(v))); \
783 __w; })
784#define udiv_qrnnd(q, r, n1, n0, d) \
785 ({union {UDItype __ll; \
786 struct {USItype __l, __h;} __i; \
787 } __xx; \
788 __xx.__i.__h = (n1); __xx.__i.__l = (n0); \
789 __asm__ ("deid %2,%0" \
790 : "=g" (__xx.__ll) \
791 : "0" (__xx.__ll), \
792 "g" ((USItype)(d))); \
793 (r) = __xx.__i.__l; (q) = __xx.__i.__h; })
794#define count_trailing_zeros(count,x) \
795 do {
796 __asm__ ("ffsd %2,%0" \
797 : "=r" ((USItype) (count)) \
798 : "0" ((USItype) 0), \
799 "r" ((USItype) (x))); \
800 } while (0)
801#endif /* __ns32000__ */
802
803
804/***************************************
805 ************** PPC ******************
806 ***************************************/
807#if (defined (_ARCH_PPC) || defined (_IBMR2)) && W_TYPE_SIZE == 32
808#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
809 do { \
810 if (__builtin_constant_p (bh) && (bh) == 0) \
811 __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{aze|addze} %0,%2" \
812 : "=r" ((USItype)(sh)), \
813 "=&r" ((USItype)(sl)) \
814 : "%r" ((USItype)(ah)), \
815 "%r" ((USItype)(al)), \
816 "rI" ((USItype)(bl))); \
817 else if (__builtin_constant_p (bh) && (bh) ==~(USItype) 0) \
818 __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{ame|addme} %0,%2" \
819 : "=r" ((USItype)(sh)), \
820 "=&r" ((USItype)(sl)) \
821 : "%r" ((USItype)(ah)), \
822 "%r" ((USItype)(al)), \
823 "rI" ((USItype)(bl))); \
824 else \
825 __asm__ ("{a%I5|add%I5c} %1,%4,%5\n\t{ae|adde} %0,%2,%3" \
826 : "=r" ((USItype)(sh)), \
827 "=&r" ((USItype)(sl)) \
828 : "%r" ((USItype)(ah)), \
829 "r" ((USItype)(bh)), \
830 "%r" ((USItype)(al)), \
831 "rI" ((USItype)(bl))); \
832 } while (0)
833#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
834 do { \
835 if (__builtin_constant_p (ah) && (ah) == 0) \
836 __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfze|subfze} %0,%2" \
837 : "=r" ((USItype)(sh)), \
838 "=&r" ((USItype)(sl)) \
839 : "r" ((USItype)(bh)), \
840 "rI" ((USItype)(al)), \
841 "r" ((USItype)(bl))); \
842 else if (__builtin_constant_p (ah) && (ah) ==~(USItype) 0) \
843 __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfme|subfme} %0,%2" \
844 : "=r" ((USItype)(sh)), \
845 "=&r" ((USItype)(sl)) \
846 : "r" ((USItype)(bh)), \
847 "rI" ((USItype)(al)), \
848 "r" ((USItype)(bl))); \
849 else if (__builtin_constant_p (bh) && (bh) == 0) \
850 __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{ame|addme} %0,%2" \
851 : "=r" ((USItype)(sh)), \
852 "=&r" ((USItype)(sl)) \
853 : "r" ((USItype)(ah)), \
854 "rI" ((USItype)(al)), \
855 "r" ((USItype)(bl))); \
856 else if (__builtin_constant_p (bh) && (bh) ==~(USItype) 0) \
857 __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{aze|addze} %0,%2" \
858 : "=r" ((USItype)(sh)), \
859 "=&r" ((USItype)(sl)) \
860 : "r" ((USItype)(ah)), \
861 "rI" ((USItype)(al)), \
862 "r" ((USItype)(bl))); \
863 else \
864 __asm__ ("{sf%I4|subf%I4c} %1,%5,%4\n\t{sfe|subfe} %0,%3,%2" \
865 : "=r" ((USItype)(sh)), \
866 "=&r" ((USItype)(sl)) \
867 : "r" ((USItype)(ah)), \
868 "r" ((USItype)(bh)), \
869 "rI" ((USItype)(al)), \
870 "r" ((USItype)(bl))); \
871 } while (0)
872#define count_leading_zeros(count, x) \
873 __asm__ ("{cntlz|cntlzw} %0,%1" \
874 : "=r" ((USItype)(count)) \
875 : "r" ((USItype)(x)))
876#define COUNT_LEADING_ZEROS_0 32
877#if defined (_ARCH_PPC)
878#define umul_ppmm(ph, pl, m0, m1) \
879 do { \
880 USItype __m0 = (m0), __m1 = (m1); \
881 __asm__ ("mulhwu %0,%1,%2" \
882 : "=r" ((USItype) ph) \
883 : "%r" (__m0), \
884 "r" (__m1)); \
885 (pl) = __m0 * __m1; \
886 } while (0)
887#define UMUL_TIME 15
888#define smul_ppmm(ph, pl, m0, m1) \
889 do { \
890 SItype __m0 = (m0), __m1 = (m1); \
891 __asm__ ("mulhw %0,%1,%2" \
892 : "=r" ((SItype) ph) \
893 : "%r" (__m0), \
894 "r" (__m1)); \
895 (pl) = __m0 * __m1; \
896 } while (0)
897#define SMUL_TIME 14
898#define UDIV_TIME 120
899#else
900#define umul_ppmm(xh, xl, m0, m1) \
901 do { \
902 USItype __m0 = (m0), __m1 = (m1); \
903 __asm__ ("mul %0,%2,%3" \
904 : "=r" ((USItype)(xh)), \
905 "=q" ((USItype)(xl)) \
906 : "r" (__m0), \
907 "r" (__m1)); \
908 (xh) += ((((SItype) __m0 >> 31) & __m1) \
909 + (((SItype) __m1 >> 31) & __m0)); \
910 } while (0)
911#define UMUL_TIME 8
912#define smul_ppmm(xh, xl, m0, m1) \
913 __asm__ ("mul %0,%2,%3" \
914 : "=r" ((SItype)(xh)), \
915 "=q" ((SItype)(xl)) \
916 : "r" (m0), \
917 "r" (m1))
918#define SMUL_TIME 4
919#define sdiv_qrnnd(q, r, nh, nl, d) \
920 __asm__ ("div %0,%2,%4" \
921 : "=r" ((SItype)(q)), "=q" ((SItype)(r)) \
922 : "r" ((SItype)(nh)), "1" ((SItype)(nl)), "r" ((SItype)(d)))
923#define UDIV_TIME 100
924#endif
925 #endif /* Power architecture variants.*/
926
927/* Powerpc 64 bit support taken from gmp-4.1.2. */
928/* We should test _IBMR2 here when we add assembly support for the system
929 vendor compilers. */
930#if 0 /* Not yet enabled becuase we don't have hardware for a test. */
931#if (defined (_ARCH_PPC) || defined (__powerpc__)) && W_TYPE_SIZE == 64
932#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
933 do { \
934 if (__builtin_constant_p (bh) && (bh) == 0) \
935 __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{aze|addze} %0,%2" \
936 : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\
937 else if (__builtin_constant_p (bh) && (bh) == ~(UDItype) 0) \
938 __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{ame|addme} %0,%2" \
939 : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\
940 else \
941 __asm__ ("{a%I5|add%I5c} %1,%4,%5\n\t{ae|adde} %0,%2,%3" \
942 : "=r" (sh), "=&r" (sl) \
943 : "%r" (ah), "r" (bh), "%r" (al), "rI" (bl)); \
944 } while (0)
945#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
946 do { \
947 if (__builtin_constant_p (ah) && (ah) == 0) \
948 __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfze|subfze} %0,%2"\
949 : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\
950 else if (__builtin_constant_p (ah) && (ah) == ~(UDItype) 0) \
951 __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfme|subfme} %0,%2"\
952 : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\
953 else if (__builtin_constant_p (bh) && (bh) == 0) \
954 __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{ame|addme} %0,%2" \
955 : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\
956 else if (__builtin_constant_p (bh) && (bh) == ~(UDItype) 0) \
957 __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{aze|addze} %0,%2" \
958 : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\
959 else \
960 __asm__ ("{sf%I4|subf%I4c} %1,%5,%4\n\t{sfe|subfe} %0,%3,%2"\
961 : "=r" (sh), "=&r" (sl) \
962 : "r" (ah), "r" (bh), "rI" (al), "r" (bl)); \
963 } while (0)
964#define count_leading_zeros(count, x) \
965 __asm__ ("cntlzd %0,%1" : "=r" (count) : "r" (x))
966#define COUNT_LEADING_ZEROS_0 64
967#define umul_ppmm(ph, pl, m0, m1) \
968 do { \
969 UDItype __m0 = (m0), __m1 = (m1); \
970 __asm__ ("mulhdu %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1));\
971 (pl) = __m0 * __m1; \
972 } while (0)
973#define UMUL_TIME 15
974#define smul_ppmm(ph, pl, m0, m1) \
975 do { \
976 DItype __m0 = (m0), __m1 = (m1); \
977 __asm__ ("mulhd %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1));\
978 (pl) = __m0 * __m1; \
979 } while (0)
980#define SMUL_TIME 14 /* ??? */
981#define UDIV_TIME 120 /* ??? */
982#endif /* 64-bit PowerPC. */
983#endif /* if 0 */
984
985/***************************************
986 ************** PYR ******************
987 ***************************************/
988#if defined (__pyr__) && W_TYPE_SIZE == 32
989#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
990 __asm__ ("addw %5,%1 \n" \
991 "addwc%3,%0" \
992 : "=r" ((USItype)(sh)), \
993 "=&r" ((USItype)(sl)) \
994 : "%0" ((USItype)(ah)), \
995 "g" ((USItype)(bh)), \
996 "%1" ((USItype)(al)), \
997 "g" ((USItype)(bl)))
998#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
999 __asm__ ("subw %5,%1 \n" \
1000 "subwb%3,%0" \
1001 : "=r" ((USItype)(sh)), \
1002 "=&r" ((USItype)(sl)) \
1003 : "0" ((USItype)(ah)), \
1004 "g" ((USItype)(bh)), \
1005 "1" ((USItype)(al)), \
1006 "g" ((USItype)(bl)))
1007/* This insn works on Pyramids with AP, XP, or MI CPUs, but not with SP. */
1008#define umul_ppmm(w1, w0, u, v) \
1009 ({union {UDItype __ll; \
1010 struct {USItype __h, __l;} __i; \
1011 } __xx; \
1012 __asm__ ("movw %1,%R0 \n" \
1013 "uemul %2,%0" \
1014 : "=&r" (__xx.__ll) \
1015 : "g" ((USItype) (u)), \
1016 "g" ((USItype)(v))); \
1017 (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;})
1018#endif /* __pyr__ */
1019
1020
1021/***************************************
1022 ************** RT/ROMP **************
1023 ***************************************/
1024 #if defined (__ibm032__) /* RT/ROMP */&& W_TYPE_SIZE == 32
1025#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
1026 __asm__ ("a %1,%5 \n" \
1027 "ae %0,%3" \
1028 : "=r" ((USItype)(sh)), \
1029 "=&r" ((USItype)(sl)) \
1030 : "%0" ((USItype)(ah)), \
1031 "r" ((USItype)(bh)), \
1032 "%1" ((USItype)(al)), \
1033 "r" ((USItype)(bl)))
1034#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
1035 __asm__ ("s %1,%5\n" \
1036 "se %0,%3" \
1037 : "=r" ((USItype)(sh)), \
1038 "=&r" ((USItype)(sl)) \
1039 : "0" ((USItype)(ah)), \
1040 "r" ((USItype)(bh)), \
1041 "1" ((USItype)(al)), \
1042 "r" ((USItype)(bl)))
1043#define umul_ppmm(ph, pl, m0, m1) \
1044 do { \
1045 USItype __m0 = (m0), __m1 = (m1); \
1046 __asm__ ( \
1047 "s r2,r2 \n" \
1048 "mtsr10,%2 \n" \
1049 "mr2,%3 \n" \
1050 "mr2,%3 \n" \
1051 "mr2,%3 \n" \
1052 "mr2,%3 \n" \
1053 "mr2,%3 \n" \
1054 "mr2,%3 \n" \
1055 "mr2,%3 \n" \
1056 "mr2,%3 \n" \
1057 "mr2,%3 \n" \
1058 "mr2,%3 \n" \
1059 "mr2,%3 \n" \
1060 "mr2,%3 \n" \
1061 "mr2,%3 \n" \
1062 "mr2,%3 \n" \
1063 "mr2,%3 \n" \
1064 "mr2,%3 \n" \
1065 "cas%0,r2,r0 \n" \
1066 "mfsr10,%1" \
1067 : "=r" ((USItype)(ph)), \
1068 "=r" ((USItype)(pl)) \
1069 : "%r" (__m0), \
1070 "r" (__m1) \
1071 : "r2"); \
1072 (ph) += ((((SItype) __m0 >> 31) & __m1) \
1073 + (((SItype) __m1 >> 31) & __m0)); \
1074 } while (0)
1075#define UMUL_TIME 20
1076#define UDIV_TIME 200
1077#define count_leading_zeros(count, x) \
1078 do { \
1079 if ((x) >= 0x10000) \
1080 __asm__ ("clz %0,%1" \
1081 : "=r" ((USItype)(count)) \
1082 : "r" ((USItype)(x) >> 16)); \
1083 else \
1084 { \
1085 __asm__ ("clz %0,%1" \
1086 : "=r" ((USItype)(count)) \
1087 : "r" ((USItype)(x))); \
1088 (count) += 16; \
1089 } \
1090 } while (0)
1091#endif /* RT/ROMP */
1092
1093
1094/***************************************
1095 ************** SH2 ******************
1096 ***************************************/
1097#if (defined (__sh2__) || defined(__sh3__) || defined(__SH4__) ) \
1098 && W_TYPE_SIZE == 32
1099#define umul_ppmm(w1, w0, u, v) \
1100 __asm__ ( \
1101 "dmulu.l %2,%3\n" \
1102 "stsmacl,%1\n" \
1103 "stsmach,%0" \
1104 : "=r" ((USItype)(w1)), \
1105 "=r" ((USItype)(w0)) \
1106 : "r" ((USItype)(u)), \
1107 "r" ((USItype)(v)) \
1108 : "macl", "mach")
1109#define UMUL_TIME 5
1110#endif
1111
1112/***************************************
1113 ************** SPARC****************
1114 ***************************************/
1115#if defined (__sparc__) && W_TYPE_SIZE == 32
1116#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
1117 __asm__ ("addcc %r4,%5,%1\n" \
1118 "addx %r2,%3,%0" \
1119 : "=r" ((USItype)(sh)), \
1120 "=&r" ((USItype)(sl)) \
1121 : "%rJ" ((USItype)(ah)), \
1122 "rI" ((USItype)(bh)), \
1123 "%rJ" ((USItype)(al)), \
1124 "rI" ((USItype)(bl)) \
1125 __CLOBBER_CC)
1126#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
1127 __asm__ ("subcc %r4,%5,%1\n" \
1128 "subx %r2,%3,%0" \
1129 : "=r" ((USItype)(sh)), \
1130 "=&r" ((USItype)(sl)) \
1131 : "rJ" ((USItype)(ah)), \
1132 "rI" ((USItype)(bh)), \
1133 "rJ" ((USItype)(al)), \
1134 "rI" ((USItype)(bl)) \
1135 __CLOBBER_CC)
1136#if defined (__sparc_v8__)
1137/* Don't match immediate range because, 1) it is not often useful,
1138 2) the 'I' flag thinks of the range as a 13 bit signed interval,
1139 while we want to match a 13 bit interval, sign extended to 32 bits,
1140 but INTERPRETED AS UNSIGNED. */
1141#define umul_ppmm(w1, w0, u, v) \
1142 __asm__ ("umul %2,%3,%1;rd %%y,%0" \
1143 : "=r" ((USItype)(w1)), \
1144 "=r" ((USItype)(w0)) \
1145 : "r" ((USItype)(u)), \
1146 "r" ((USItype)(v)))
1147#define UMUL_TIME 5
1148 #ifndef SUPERSPARC/* SuperSPARC's udiv only handles 53 bit dividends */
1149#define udiv_qrnnd(q, r, n1, n0, d) \
1150 do { \
1151 USItype __q; \
1152 __asm__ ("mov %1,%%y;nop;nop;nop;udiv %2,%3,%0" \
1153 : "=r" ((USItype)(__q)) \
1154 : "r" ((USItype)(n1)), \
1155 "r" ((USItype)(n0)), \
1156 "r" ((USItype)(d))); \
1157 (r) = (n0) - __q * (d); \
1158 (q) = __q; \
1159 } while (0)
1160#define UDIV_TIME 25
1161#endif /* SUPERSPARC */
1162#else /* ! __sparc_v8__ */
1163#if defined (__sparclite__)
1164/* This has hardware multiply but not divide. It also has two additional
1165 instructions scan (ffs from high bit) and divscc. */
1166#define umul_ppmm(w1, w0, u, v) \
1167 __asm__ ("umul %2,%3,%1;rd %%y,%0" \
1168 : "=r" ((USItype)(w1)), \
1169 "=r" ((USItype)(w0)) \
1170 : "r" ((USItype)(u)), \
1171 "r" ((USItype)(v)))
1172#define UMUL_TIME 5
1173#define udiv_qrnnd(q, r, n1, n0, d) \
1174 __asm__ ("! Inlined udiv_qrnnd \n" \
1175 " wr %%g0,%2,%%y! Not a delayed write for sparclite \n" \
1176 " tst%%g0 \n" \
1177 " divscc%3,%4,%%g1 \n" \
1178 " divscc%%g1,%4,%%g1 \n" \
1179 " divscc%%g1,%4,%%g1 \n" \
1180 " divscc%%g1,%4,%%g1 \n" \
1181 " divscc%%g1,%4,%%g1 \n" \
1182 " divscc%%g1,%4,%%g1 \n" \
1183 " divscc%%g1,%4,%%g1 \n" \
1184 " divscc%%g1,%4,%%g1 \n" \
1185 " divscc%%g1,%4,%%g1 \n" \
1186 " divscc%%g1,%4,%%g1 \n" \
1187 " divscc%%g1,%4,%%g1 \n" \
1188 " divscc%%g1,%4,%%g1 \n" \
1189 " divscc%%g1,%4,%%g1 \n" \
1190 " divscc%%g1,%4,%%g1 \n" \
1191 " divscc%%g1,%4,%%g1 \n" \
1192 " divscc%%g1,%4,%%g1 \n" \
1193 " divscc%%g1,%4,%%g1 \n" \
1194 " divscc%%g1,%4,%%g1 \n" \
1195 " divscc%%g1,%4,%%g1 \n" \
1196 " divscc%%g1,%4,%%g1 \n" \
1197 " divscc%%g1,%4,%%g1 \n" \
1198 " divscc%%g1,%4,%%g1 \n" \
1199 " divscc%%g1,%4,%%g1 \n" \
1200 " divscc%%g1,%4,%%g1 \n" \
1201 " divscc%%g1,%4,%%g1 \n" \
1202 " divscc%%g1,%4,%%g1 \n" \
1203 " divscc%%g1,%4,%%g1 \n" \
1204 " divscc%%g1,%4,%%g1 \n" \
1205 " divscc%%g1,%4,%%g1 \n" \
1206 " divscc%%g1,%4,%%g1 \n" \
1207 " divscc%%g1,%4,%%g1 \n" \
1208 " divscc%%g1,%4,%0 \n" \
1209 " rd%%y,%1 \n" \
1210 " bl,a 1f \n" \
1211 " add%1,%4,%1 \n" \
1212 "1:! End of inline udiv_qrnnd" \
1213 : "=r" ((USItype)(q)), \
1214 "=r" ((USItype)(r)) \
1215 : "r" ((USItype)(n1)), \
1216 "r" ((USItype)(n0)), \
1217 "rI" ((USItype)(d)) \
1218 : "%g1" __AND_CLOBBER_CC)
1219#define UDIV_TIME 37
1220#define count_leading_zeros(count, x) \
1221 __asm__ ("scan %1,0,%0" \
1222 : "=r" ((USItype)(x)) \
1223 : "r" ((USItype)(count)))
1224/* Early sparclites return 63 for an argument of 0, but they warn that future
1225 implementations might change this. Therefore, leave COUNT_LEADING_ZEROS_0
1226 undefined. */
1227#endif /* __sparclite__ */
1228#endif /* __sparc_v8__ */
1229/* Default to sparc v7 versions of umul_ppmm and udiv_qrnnd. */
1230#ifndef umul_ppmm
1231#define umul_ppmm(w1, w0, u, v) \
1232 __asm__ ("! Inlined umul_ppmm \n" \
1233 " wr %%g0,%2,%%y! SPARC has 0-3 delay insn after a wr \n" \
1234 " sra %3,31,%%g2! Don't move this insn \n" \
1235 " and %2,%%g2,%%g2! Don't move this insn \n" \
1236 " andcc %%g0,0,%%g1! Don't move this insn \n" \
1237 " mulscc%%g1,%3,%%g1 \n" \
1238 " mulscc%%g1,%3,%%g1 \n" \
1239 " mulscc%%g1,%3,%%g1 \n" \
1240 " mulscc%%g1,%3,%%g1 \n" \
1241 " mulscc%%g1,%3,%%g1 \n" \
1242 " mulscc%%g1,%3,%%g1 \n" \
1243 " mulscc%%g1,%3,%%g1 \n" \
1244 " mulscc%%g1,%3,%%g1 \n" \
1245 " mulscc%%g1,%3,%%g1 \n" \
1246 " mulscc%%g1,%3,%%g1 \n" \
1247 " mulscc%%g1,%3,%%g1 \n" \
1248 " mulscc%%g1,%3,%%g1 \n" \
1249 " mulscc%%g1,%3,%%g1 \n" \
1250 " mulscc%%g1,%3,%%g1 \n" \
1251 " mulscc%%g1,%3,%%g1 \n" \
1252 " mulscc%%g1,%3,%%g1 \n" \
1253 " mulscc%%g1,%3,%%g1 \n" \
1254 " mulscc%%g1,%3,%%g1 \n" \
1255 " mulscc%%g1,%3,%%g1 \n" \
1256 " mulscc%%g1,%3,%%g1 \n" \
1257 " mulscc%%g1,%3,%%g1 \n" \
1258 " mulscc%%g1,%3,%%g1 \n" \
1259 " mulscc%%g1,%3,%%g1 \n" \
1260 " mulscc%%g1,%3,%%g1 \n" \
1261 " mulscc%%g1,%3,%%g1 \n" \
1262 " mulscc%%g1,%3,%%g1 \n" \
1263 " mulscc%%g1,%3,%%g1 \n" \
1264 " mulscc%%g1,%3,%%g1 \n" \
1265 " mulscc%%g1,%3,%%g1 \n" \
1266 " mulscc%%g1,%3,%%g1 \n" \
1267 " mulscc%%g1,%3,%%g1 \n" \
1268 " mulscc%%g1,%3,%%g1 \n" \
1269 " mulscc%%g1,0,%%g1 \n" \
1270 " add%%g1,%%g2,%0 \n" \
1271 " rd%%y,%1" \
1272 : "=r" ((USItype)(w1)), \
1273 "=r" ((USItype)(w0)) \
1274 : "%rI" ((USItype)(u)), \
1275 "r" ((USItype)(v)) \
1276 : "%g1", "%g2" __AND_CLOBBER_CC)
1277 #define UMUL_TIME 39 /* 39 instructions */
1278#endif
1279#ifndef udiv_qrnnd
1280#ifndef LONGLONG_STANDALONE
1281#define udiv_qrnnd(q, r, n1, n0, d) \
1282 do { USItype __r; \
1283 (q) = __udiv_qrnnd (&__r, (n1), (n0), (d)); \
1284 (r) = __r; \
1285 } while (0)
1286extern USItype __udiv_qrnnd ();
1287#define UDIV_TIME 140
1288#endif /* LONGLONG_STANDALONE */
1289#endif /* udiv_qrnnd */
1290#endif /* __sparc__ */
1291
1292
1293/***************************************
1294 ************** VAX ******************
1295 ***************************************/
1296#if defined (__vax__) && W_TYPE_SIZE == 32
1297#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
1298 __asm__ ("addl2 %5,%1\n" \
1299 "adwc %3,%0" \
1300 : "=g" ((USItype)(sh)), \
1301 "=&g" ((USItype)(sl)) \
1302 : "%0" ((USItype)(ah)), \
1303 "g" ((USItype)(bh)), \
1304 "%1" ((USItype)(al)), \
1305 "g" ((USItype)(bl)))
1306#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
1307 __asm__ ("subl2 %5,%1\n" \
1308 "sbwc %3,%0" \
1309 : "=g" ((USItype)(sh)), \
1310 "=&g" ((USItype)(sl)) \
1311 : "0" ((USItype)(ah)), \
1312 "g" ((USItype)(bh)), \
1313 "1" ((USItype)(al)), \
1314 "g" ((USItype)(bl)))
1315#define umul_ppmm(xh, xl, m0, m1) \
1316 do { \
1317 union {UDItype __ll; \
1318 struct {USItype __l, __h;} __i; \
1319 } __xx; \
1320 USItype __m0 = (m0), __m1 = (m1); \
1321 __asm__ ("emul %1,%2,$0,%0" \
1322 : "=g" (__xx.__ll) \
1323 : "g" (__m0), \
1324 "g" (__m1)); \
1325 (xh) = __xx.__i.__h; (xl) = __xx.__i.__l; \
1326 (xh) += ((((SItype) __m0 >> 31) & __m1) \
1327 + (((SItype) __m1 >> 31) & __m0)); \
1328 } while (0)
1329#define sdiv_qrnnd(q, r, n1, n0, d) \
1330 do { \
1331 union {DItype __ll; \
1332 struct {SItype __l, __h;} __i; \
1333 } __xx; \
1334 __xx.__i.__h = n1; __xx.__i.__l = n0; \
1335 __asm__ ("ediv %3,%2,%0,%1" \
1336 : "=g" (q), "=g" (r) \
1337 : "g" (__xx.__ll), "g" (d)); \
1338 } while (0)
1339#endif /* __vax__ */
1340
1341
1342/***************************************
1343 ************** Z8000****************
1344 ***************************************/
1345#if defined (__z8000__) && W_TYPE_SIZE == 16
1346#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
1347 __asm__ ("add %H1,%H5\n\tadc %H0,%H3" \
1348 : "=r" ((unsigned int)(sh)), \
1349 "=&r" ((unsigned int)(sl)) \
1350 : "%0" ((unsigned int)(ah)), \
1351 "r" ((unsigned int)(bh)), \
1352 "%1" ((unsigned int)(al)), \
1353 "rQR" ((unsigned int)(bl)))
1354#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
1355 __asm__ ("sub %H1,%H5\n\tsbc %H0,%H3" \
1356 : "=r" ((unsigned int)(sh)), \
1357 "=&r" ((unsigned int)(sl)) \
1358 : "0" ((unsigned int)(ah)), \
1359 "r" ((unsigned int)(bh)), \
1360 "1" ((unsigned int)(al)), \
1361 "rQR" ((unsigned int)(bl)))
1362#define umul_ppmm(xh, xl, m0, m1) \
1363 do { \
1364 union {long int __ll; \
1365 struct {unsigned int __h, __l;} __i; \
1366 } __xx; \
1367 unsigned int __m0 = (m0), __m1 = (m1); \
1368 __asm__ ("mult %S0,%H3" \
1369 : "=r" (__xx.__i.__h), \
1370 "=r" (__xx.__i.__l) \
1371 : "%1" (__m0), \
1372 "rQR" (__m1)); \
1373 (xh) = __xx.__i.__h; (xl) = __xx.__i.__l; \
1374 (xh) += ((((signed int) __m0 >> 15) & __m1) \
1375 + (((signed int) __m1 >> 15) & __m0)); \
1376 } while (0)
1377#endif /* __z8000__ */
1378
1379#endif /* __GNUC__ */
1380#endif /* !__riscos__ */
1381
1382
1383/***************************************
1384 *********** Generic Versions********
1385 ***************************************/
1386#if !defined (umul_ppmm) && defined (__umulsidi3)
1387#define umul_ppmm(ph, pl, m0, m1) \
1388 { \
1389 UDWtype __ll = __umulsidi3 (m0, m1); \
1390 ph = (UWtype) (__ll >> W_TYPE_SIZE); \
1391 pl = (UWtype) __ll; \
1392 }
1393#endif
1394
1395#if !defined (__umulsidi3)
1396#define __umulsidi3(u, v) \
1397 ({UWtype __hi, __lo; \
1398 umul_ppmm (__hi, __lo, u, v); \
1399 ((UDWtype) __hi << W_TYPE_SIZE) | __lo; })
1400#endif
1401
1402/* If this machine has no inline assembler, use C macros. */
1403
1404#if !defined (add_ssaaaa)
1405#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
1406 do { \
1407 UWtype __x; \
1408 __x = (al) + (bl); \
1409 (sh) = (ah) + (bh) + (__x < (al)); \
1410 (sl) = __x; \
1411 } while (0)
1412#endif
1413
1414#if !defined (sub_ddmmss)
1415#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
1416 do { \
1417 UWtype __x; \
1418 __x = (al) - (bl); \
1419 (sh) = (ah) - (bh) - (__x > (al)); \
1420 (sl) = __x; \
1421 } while (0)
1422#endif
1423
1424#if !defined (umul_ppmm)
1425 #define umul_ppmm(w1, w0, u, v) \
1426 do { \
1427 UWtype __x0, __x1, __x2, __x3; \
1428 UHWtype __ul, __vl, __uh, __vh; \
1429 UWtype __u = (u), __v = (v); \
1430 \
1431 __ul = __ll_lowpart (__u); \
1432 __uh = __ll_highpart (__u); \
1433 __vl = __ll_lowpart (__v); \
1434 __vh = __ll_highpart (__v); \
1435 \
1436 __x0 = (UWtype) __ul * __vl; \
1437 __x1 = (UWtype) __ul * __vh; \
1438 __x2 = (UWtype) __uh * __vl; \
1439 __x3 = (UWtype) __uh * __vh; \
1440 \
1441 __x1 += __ll_highpart (__x0);/* this can't give carry */ \
1442 __x1 += __x2; /* but this indeed can */ \
1443 if (__x1 < __x2) /* did we get it? */ \
1444 __x3 += __ll_B; /* yes, add it in the proper pos. */\
1445 \
1446 (w1) = __x3 + __ll_highpart (__x1); \
1447 (w0) = (__ll_lowpart (__x1) << W_TYPE_SIZE/2) + __ll_lowpart (__x0);\
1448 } while (0)
1449#endif
1450
1451#if !defined (umul_ppmm)
1452 #define smul_ppmm(w1, w0, u, v) \
1453 do { \
1454 UWtype __w1; \
1455 UWtype __m0 = (u), __m1 = (v); \
1456 umul_ppmm (__w1, w0, __m0, __m1); \
1457 (w1) = __w1 - (-(__m0 >> (W_TYPE_SIZE - 1)) & __m1) \
1458 - (-(__m1 >> (W_TYPE_SIZE - 1)) & __m0); \
1459 } while (0)
1460#endif
1461
1462/* Define this unconditionally, so it can be used for debugging. */
1463#define __udiv_qrnnd_c(q, r, n1, n0, d) \
1464 do { \
1465 UWtype __d1, __d0, __q1, __q0, __r1, __r0, __m; \
1466 __d1 = __ll_highpart (d); \
1467 __d0 = __ll_lowpart (d); \
1468 \
1469 __r1 = (n1) % __d1; \
1470 __q1 = (n1) / __d1; \
1471 __m = (UWtype) __q1 * __d0; \
1472 __r1 = __r1 * __ll_B | __ll_highpart (n0); \
1473 if (__r1 < __m) \
1474 { \
1475 __q1--, __r1 += (d); \
1476 if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\
1477 if (__r1 < __m) \
1478 __q1--, __r1 += (d); \
1479 } \
1480 __r1 -= __m; \
1481 \
1482 __r0 = __r1 % __d1; \
1483 __q0 = __r1 / __d1; \
1484 __m = (UWtype) __q0 * __d0; \
1485 __r0 = __r0 * __ll_B | __ll_lowpart (n0); \
1486 if (__r0 < __m) \
1487 { \
1488 __q0--, __r0 += (d); \
1489 if (__r0 >= (d)) \
1490 if (__r0 < __m) \
1491 __q0--, __r0 += (d); \
1492 } \
1493 __r0 -= __m; \
1494 \
1495 (q) = (UWtype) __q1 * __ll_B | __q0; \
1496 (r) = __r0; \
1497 } while (0)
1498
1499/* If the processor has no udiv_qrnnd but sdiv_qrnnd, go through
1500 __udiv_w_sdiv (defined in libgcc or elsewhere). */
1501#if !defined (udiv_qrnnd) && defined (sdiv_qrnnd)
1502#define udiv_qrnnd(q, r, nh, nl, d) \
1503 do { \
1504 UWtype __r; \
1505 (q) = __MPN(udiv_w_sdiv) (&__r, nh, nl, d); \
1506 (r) = __r; \
1507 } while (0)
1508#endif
1509
1510/* If udiv_qrnnd was not defined for this processor, use __udiv_qrnnd_c. */
1511#if !defined (udiv_qrnnd)
1512#define UDIV_NEEDS_NORMALIZATION 1
1513#define udiv_qrnnd __udiv_qrnnd_c
1514#endif
1515
1516#if !defined (count_leading_zeros)
1517extern
1518#ifdef __STDC__
1519const
1520#endif
1521unsigned char _gcry_clz_tab[];
1522#define MPI_INTERNAL_NEED_CLZ_TAB 1
1523#define count_leading_zeros(count, x) \
1524 do { \
1525 UWtype __xr = (x); \
1526 UWtype __a; \
1527 \
1528 if (W_TYPE_SIZE <= 32) \
1529 { \
1530 __a = __xr < ((UWtype) 1 << 2*__BITS4) \
1531 ? (__xr < ((UWtype) 1 << __BITS4) ? 0 : __BITS4) \
1532 : (__xr < ((UWtype) 1 << 3*__BITS4) ? 2*__BITS4 : 3*__BITS4);\
1533 } \
1534 else \
1535 { \
1536 for (__a = W_TYPE_SIZE - 8; __a > 0; __a -= 8) \
1537 if (((__xr >> __a) & 0xff) != 0) \
1538 break; \
1539 } \
1540 \
1541 (count) = W_TYPE_SIZE - (_gcry_clz_tab[__xr >> __a] + __a); \
1542 } while (0)
1543/* This version gives a well-defined value for zero. */
1544#define COUNT_LEADING_ZEROS_0 W_TYPE_SIZE
1545#endif
1546
1547#if !defined (count_trailing_zeros)
1548/* Define count_trailing_zeros using count_leading_zeros. The latter might be
1549 defined in asm, but if it is not, the C version above is good enough. */
1550#define count_trailing_zeros(count, x) \
1551 do { \
1552 UWtype __ctz_x = (x); \
1553 UWtype __ctz_c; \
1554 count_leading_zeros (__ctz_c, __ctz_x & -__ctz_x); \
1555 (count) = W_TYPE_SIZE - 1 - __ctz_c; \
1556 } while (0)
1557#endif
1558
1559#ifndef UDIV_NEEDS_NORMALIZATION
1560#define UDIV_NEEDS_NORMALIZATION 0
1561#endif
diff --git a/pwmanager/libcrypt/mpi/mpi-add.c b/pwmanager/libcrypt/mpi/mpi-add.c
new file mode 100644
index 0000000..ada257a
--- a/dev/null
+++ b/pwmanager/libcrypt/mpi/mpi-add.c
@@ -0,0 +1,236 @@
1/* mpi-add.c - MPI functions
2 * Copyright (C) 1994, 1996, 1998, 2001, 2002, 2003 Free Software Foundation, Inc.
3 *
4 * This file is part of Libgcrypt.
5 *
6 * Libgcrypt is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License as
8 * published by the Free Software Foundation; either version 2.1 of
9 * the License, or (at your option) any later version.
10 *
11 * Libgcrypt is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19 *
20 * Note: This code is heavily based on the GNU MP Library.
21 * Actually it's the same code with only minor changes in the
22 * way the data is stored; this is to support the abstraction
23 * of an optional secure memory allocation which may be used
24 * to avoid revealing of sensitive data due to paging etc.
25 */
26
27#include <config.h>
28#include <stdio.h>
29#include <stdlib.h>
30
31#include "mpi-internal.h"
32
33
34/****************
35 * Add the unsigned integer V to the mpi-integer U and store the
36 * result in W. U and V may be the same.
37 */
38void
39gcry_mpi_add_ui(gcry_mpi_t w, gcry_mpi_t u, unsigned long v )
40{
41 mpi_ptr_t wp, up;
42 mpi_size_t usize, wsize;
43 int usign, wsign;
44
45 usize = u->nlimbs;
46 usign = u->sign;
47 wsign = 0;
48
49 /* If not space for W (and possible carry), increase space. */
50 wsize = usize + 1;
51 if( w->alloced < wsize )
52 mpi_resize(w, wsize);
53
54 /* These must be after realloc (U may be the same as W). */
55 up = u->d;
56 wp = w->d;
57
58 if( !usize ) { /* simple */
59 wp[0] = v;
60 wsize = v? 1:0;
61 }
62 else if( !usign ) { /* mpi is not negative */
63 mpi_limb_t cy;
64 cy = _gcry_mpih_add_1(wp, up, usize, v);
65 wp[usize] = cy;
66 wsize = usize + cy;
67 }
68 else { /* The signs are different. Need exact comparison to determine
69 * which operand to subtract from which. */
70 if( usize == 1 && up[0] < v ) {
71 wp[0] = v - up[0];
72 wsize = 1;
73 }
74 else {
75 _gcry_mpih_sub_1(wp, up, usize, v);
76 /* Size can decrease with at most one limb. */
77 wsize = usize - (wp[usize-1]==0);
78 wsign = 1;
79 }
80 }
81
82 w->nlimbs = wsize;
83 w->sign = wsign;
84}
85
86
87void
88gcry_mpi_add(gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v)
89{
90 mpi_ptr_t wp, up, vp;
91 mpi_size_t usize, vsize, wsize;
92 int usign, vsign, wsign;
93
94 if( u->nlimbs < v->nlimbs ) { /* Swap U and V. */
95 usize = v->nlimbs;
96 usign = v->sign;
97 vsize = u->nlimbs;
98 vsign = u->sign;
99 wsize = usize + 1;
100 RESIZE_IF_NEEDED(w, wsize);
101 /* These must be after realloc (u or v may be the same as w). */
102 up = v->d;
103 vp = u->d;
104 }
105 else {
106 usize = u->nlimbs;
107 usign = u->sign;
108 vsize = v->nlimbs;
109 vsign = v->sign;
110 wsize = usize + 1;
111 RESIZE_IF_NEEDED(w, wsize);
112 /* These must be after realloc (u or v may be the same as w). */
113 up = u->d;
114 vp = v->d;
115 }
116 wp = w->d;
117 wsign = 0;
118
119 if( !vsize ) { /* simple */
120 MPN_COPY(wp, up, usize );
121 wsize = usize;
122 wsign = usign;
123 }
124 else if( usign != vsign ) { /* different sign */
125 /* This test is right since USIZE >= VSIZE */
126 if( usize != vsize ) {
127 _gcry_mpih_sub(wp, up, usize, vp, vsize);
128 wsize = usize;
129 MPN_NORMALIZE(wp, wsize);
130 wsign = usign;
131 }
132 else if( _gcry_mpih_cmp(up, vp, usize) < 0 ) {
133 _gcry_mpih_sub_n(wp, vp, up, usize);
134 wsize = usize;
135 MPN_NORMALIZE(wp, wsize);
136 if( !usign )
137 wsign = 1;
138 }
139 else {
140 _gcry_mpih_sub_n(wp, up, vp, usize);
141 wsize = usize;
142 MPN_NORMALIZE(wp, wsize);
143 if( usign )
144 wsign = 1;
145 }
146 }
147 else { /* U and V have same sign. Add them. */
148 mpi_limb_t cy = _gcry_mpih_add(wp, up, usize, vp, vsize);
149 wp[usize] = cy;
150 wsize = usize + cy;
151 if( usign )
152 wsign = 1;
153 }
154
155 w->nlimbs = wsize;
156 w->sign = wsign;
157}
158
159
160/****************
161 * Subtract the unsigned integer V from the mpi-integer U and store the
162 * result in W.
163 */
164void
165gcry_mpi_sub_ui(gcry_mpi_t w, gcry_mpi_t u, unsigned long v )
166{
167 mpi_ptr_t wp, up;
168 mpi_size_t usize, wsize;
169 int usign, wsign;
170
171 usize = u->nlimbs;
172 usign = u->sign;
173 wsign = 0;
174
175 /* If not space for W (and possible carry), increase space. */
176 wsize = usize + 1;
177 if( w->alloced < wsize )
178 mpi_resize(w, wsize);
179
180 /* These must be after realloc (U may be the same as W). */
181 up = u->d;
182 wp = w->d;
183
184 if( !usize ) { /* simple */
185 wp[0] = v;
186 wsize = v? 1:0;
187 wsign = 1;
188 }
189 else if( usign ) {/* mpi and v are negative */
190 mpi_limb_t cy;
191 cy = _gcry_mpih_add_1(wp, up, usize, v);
192 wp[usize] = cy;
193 wsize = usize + cy;
194 }
195 else { /* The signs are different. Need exact comparison to determine
196 * which operand to subtract from which. */
197 if( usize == 1 && up[0] < v ) {
198 wp[0] = v - up[0];
199 wsize = 1;
200 wsign = 1;
201 }
202 else {
203 _gcry_mpih_sub_1(wp, up, usize, v);
204 /* Size can decrease with at most one limb. */
205 wsize = usize - (wp[usize-1]==0);
206 }
207 }
208
209 w->nlimbs = wsize;
210 w->sign = wsign;
211}
212
213void
214gcry_mpi_sub(gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v)
215{
216 gcry_mpi_t vv = mpi_copy (v);
217 vv->sign = ! vv->sign;
218 gcry_mpi_add (w, u, vv);
219 mpi_free (vv);
220}
221
222
223void
224gcry_mpi_addm( gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m)
225{
226 gcry_mpi_add(w, u, v);
227 _gcry_mpi_fdiv_r( w, w, m );
228}
229
230void
231gcry_mpi_subm( gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m)
232{
233 gcry_mpi_sub(w, u, v);
234 _gcry_mpi_fdiv_r( w, w, m );
235}
236
diff --git a/pwmanager/libcrypt/mpi/mpi-bit.c b/pwmanager/libcrypt/mpi/mpi-bit.c
new file mode 100644
index 0000000..26853ef
--- a/dev/null
+++ b/pwmanager/libcrypt/mpi/mpi-bit.c
@@ -0,0 +1,257 @@
1/* mpi-bit.c - MPI bit level fucntions
2 * Copyright (C) 1998, 1999, 2001, 2002 Free Software Foundation, Inc.
3 *
4 * This file is part of Libgcrypt.
5 *
6 * Libgcrypt is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License as
8 * published by the Free Software Foundation; either version 2.1 of
9 * the License, or (at your option) any later version.
10 *
11 * Libgcrypt is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19 */
20
21#include <config.h>
22#include <stdio.h>
23#include <stdlib.h>
24#include <assert.h>
25#include "mpi-internal.h"
26#include "longlong.h"
27
28
29#ifdef MPI_INTERNAL_NEED_CLZ_TAB
30#ifdef __STDC__
31const
32#endif
33unsigned char
34_gcry_clz_tab[] =
35{
36 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
37 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
38 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
39 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
40 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
41 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
42 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
43 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
44};
45#endif
46
47
48#define A_LIMB_1 ((mpi_limb_t)1)
49
50
51/****************
52 * Sometimes we have MSL (most significant limbs) which are 0;
53 * this is for some reasons not good, so this function removes them.
54 */
55void
56_gcry_mpi_normalize( gcry_mpi_t a )
57{
58 if( mpi_is_opaque(a) )
59 return;
60
61 for( ; a->nlimbs && !a->d[a->nlimbs-1]; a->nlimbs-- )
62 ;
63}
64
65
66
67/****************
68 * Return the number of bits in A.
69 */
70unsigned int
71gcry_mpi_get_nbits( gcry_mpi_t a )
72{
73 unsigned n;
74
75 if( mpi_is_opaque(a) ) {
76 return a->sign; /* which holds the number of bits */
77 }
78
79 _gcry_mpi_normalize( a );
80 if( a->nlimbs ) {
81 mpi_limb_t alimb = a->d[a->nlimbs-1];
82 if( alimb )
83 count_leading_zeros( n, alimb );
84 else
85 n = BITS_PER_MPI_LIMB;
86 n = BITS_PER_MPI_LIMB - n + (a->nlimbs-1) * BITS_PER_MPI_LIMB;
87 }
88 else
89 n = 0;
90 return n;
91}
92
93
94/****************
95 * Test whether bit N is set.
96 */
97int
98gcry_mpi_test_bit( gcry_mpi_t a, unsigned int n )
99{
100 unsigned int limbno, bitno;
101 mpi_limb_t limb;
102
103 limbno = n / BITS_PER_MPI_LIMB;
104 bitno = n % BITS_PER_MPI_LIMB;
105
106 if( limbno >= a->nlimbs )
107 return 0; /* too far left: this is a 0 */
108 limb = a->d[limbno];
109 return (limb & (A_LIMB_1 << bitno))? 1: 0;
110}
111
112
113/****************
114 * Set bit N of A.
115 */
116void
117gcry_mpi_set_bit( gcry_mpi_t a, unsigned int n )
118{
119 unsigned int limbno, bitno;
120
121 limbno = n / BITS_PER_MPI_LIMB;
122 bitno = n % BITS_PER_MPI_LIMB;
123
124 if( limbno >= a->nlimbs ) { /* resize */
125 if( a->alloced >= limbno )
126 mpi_resize(a, limbno+1 );
127 a->nlimbs = limbno+1;
128 }
129 a->d[limbno] |= (A_LIMB_1<<bitno);
130}
131
132/****************
133 * Set bit N of A. and clear all bits above
134 */
135void
136gcry_mpi_set_highbit( gcry_mpi_t a, unsigned int n )
137{
138 unsigned int limbno, bitno;
139
140 limbno = n / BITS_PER_MPI_LIMB;
141 bitno = n % BITS_PER_MPI_LIMB;
142
143 if( limbno >= a->nlimbs ) { /* resize */
144 if( a->alloced >= limbno )
145 mpi_resize(a, limbno+1 );
146 a->nlimbs = limbno+1;
147 }
148 a->d[limbno] |= (A_LIMB_1<<bitno);
149 for( bitno++; bitno < BITS_PER_MPI_LIMB; bitno++ )
150 a->d[limbno] &= ~(A_LIMB_1 << bitno);
151 a->nlimbs = limbno+1;
152}
153
154/****************
155 * clear bit N of A and all bits above
156 */
157void
158gcry_mpi_clear_highbit( gcry_mpi_t a, unsigned int n )
159{
160 unsigned int limbno, bitno;
161
162 limbno = n / BITS_PER_MPI_LIMB;
163 bitno = n % BITS_PER_MPI_LIMB;
164
165 if( limbno >= a->nlimbs )
166 return; /* not allocated, so need to clear bits :-) */
167
168 for( ; bitno < BITS_PER_MPI_LIMB; bitno++ )
169 a->d[limbno] &= ~(A_LIMB_1 << bitno);
170 a->nlimbs = limbno+1;
171}
172
173/****************
174 * Clear bit N of A.
175 */
176void
177gcry_mpi_clear_bit( gcry_mpi_t a, unsigned int n )
178{
179 unsigned int limbno, bitno;
180
181 limbno = n / BITS_PER_MPI_LIMB;
182 bitno = n % BITS_PER_MPI_LIMB;
183
184 if( limbno >= a->nlimbs )
185 return; /* don't need to clear this bit, it's to far to left */
186 a->d[limbno] &= ~(A_LIMB_1 << bitno);
187}
188
189
190/****************
191 * Shift A by N bits to the right
192 * FIXME: should use alloc_limb if X and A are same.
193 */
194void
195gcry_mpi_rshift( gcry_mpi_t x, gcry_mpi_t a, unsigned n )
196{
197 mpi_ptr_t xp;
198 mpi_size_t xsize;
199
200 xsize = a->nlimbs;
201 x->sign = a->sign;
202 RESIZE_IF_NEEDED(x, xsize);
203 xp = x->d;
204
205 if( xsize ) {
206 _gcry_mpih_rshift( xp, a->d, xsize, n);
207 MPN_NORMALIZE( xp, xsize);
208 }
209 x->nlimbs = xsize;
210}
211
212
213/****************
214 * Shift A by COUNT limbs to the left
215 * This is used only within the MPI library
216 */
217void
218_gcry_mpi_lshift_limbs( gcry_mpi_t a, unsigned int count )
219{
220 mpi_ptr_t ap = a->d;
221 int n = a->nlimbs;
222 int i;
223
224 if( !count || !n )
225 return;
226
227 RESIZE_IF_NEEDED( a, n+count );
228
229 for( i = n-1; i >= 0; i-- )
230 ap[i+count] = ap[i];
231 for(i=0; i < count; i++ )
232 ap[i] = 0;
233 a->nlimbs += count;
234}
235
236
237/****************
238 * Shift A by COUNT limbs to the right
239 * This is used only within the MPI library
240 */
241void
242_gcry_mpi_rshift_limbs( gcry_mpi_t a, unsigned int count )
243{
244 mpi_ptr_t ap = a->d;
245 mpi_size_t n = a->nlimbs;
246 unsigned int i;
247
248 if( count >= n ) {
249 a->nlimbs = 0;
250 return;
251 }
252
253 for( i = 0; i < n - count; i++ )
254 ap[i] = ap[i+count];
255 ap[i] = 0;
256 a->nlimbs -= count;
257}
diff --git a/pwmanager/libcrypt/mpi/mpi-cmp.c b/pwmanager/libcrypt/mpi/mpi-cmp.c
new file mode 100644
index 0000000..6036255
--- a/dev/null
+++ b/pwmanager/libcrypt/mpi/mpi-cmp.c
@@ -0,0 +1,74 @@
1/* mpi-cmp.c - MPI functions
2 * Copyright (C) 1998, 1999, 2001, 2002 Free Software Foundation, Inc.
3 *
4 * This file is part of Libgcrypt.
5 *
6 * Libgcrypt is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License as
8 * published by the Free Software Foundation; either version 2.1 of
9 * the License, or (at your option) any later version.
10 *
11 * Libgcrypt is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19 */
20
21#include <config.h>
22#include <stdio.h>
23#include <stdlib.h>
24#include "mpi-internal.h"
25
26int
27gcry_mpi_cmp_ui( gcry_mpi_t u, unsigned long v )
28{
29 mpi_limb_t limb = v;
30
31 _gcry_mpi_normalize( u );
32 if( !u->nlimbs && !limb )
33 return 0;
34 if( u->sign )
35 return -1;
36 if( u->nlimbs > 1 )
37 return 1;
38
39 if( u->d[0] == limb )
40 return 0;
41 else if( u->d[0] > limb )
42 return 1;
43 else
44 return -1;
45}
46
47int
48gcry_mpi_cmp( gcry_mpi_t u, gcry_mpi_t v )
49{
50 mpi_size_t usize, vsize;
51 int cmp;
52
53 _gcry_mpi_normalize( u );
54 _gcry_mpi_normalize( v );
55 usize = u->nlimbs;
56 vsize = v->nlimbs;
57 if( !u->sign && v->sign )
58 return 1;
59 if( u->sign && !v->sign )
60 return -1;
61 if( usize != vsize && !u->sign && !v->sign )
62 return usize - vsize;
63 if( usize != vsize && u->sign && v->sign )
64 return vsize + usize;
65 if( !usize )
66 return 0;
67 if( !(cmp = _gcry_mpih_cmp( u->d, v->d, usize )) )
68 return 0;
69 if( (cmp < 0?1:0) == (u->sign?1:0))
70 return 1;
71 return -1;
72}
73
74
diff --git a/pwmanager/libcrypt/mpi/mpi-div.c b/pwmanager/libcrypt/mpi/mpi-div.c
new file mode 100644
index 0000000..6172eb4
--- a/dev/null
+++ b/pwmanager/libcrypt/mpi/mpi-div.c
@@ -0,0 +1,364 @@
1/* mpi-div.c - MPI functions
2 * Copyright (C) 1994, 1996, 1998, 2001, 2002,
3 * 2003 Free Software Foundation, Inc.
4 *
5 * This file is part of Libgcrypt.
6 *
7 * Libgcrypt is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * Libgcrypt is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20 *
21 * Note: This code is heavily based on the GNU MP Library.
22 * Actually it's the same code with only minor changes in the
23 * way the data is stored; this is to support the abstraction
24 * of an optional secure memory allocation which may be used
25 * to avoid revealing of sensitive data due to paging etc.
26 */
27
28#include <config.h>
29#include <stdio.h>
30#include <stdlib.h>
31#include "mpi-internal.h"
32#include "longlong.h"
33#include "g10lib.h"
34
35
36void
37_gcry_mpi_fdiv_r( gcry_mpi_t rem, gcry_mpi_t dividend, gcry_mpi_t divisor )
38{
39 int divisor_sign = divisor->sign;
40 gcry_mpi_t temp_divisor = NULL;
41
42 /* We need the original value of the divisor after the remainder has been
43 * preliminary calculated.We have to copy it to temporary space if it's
44 * the same variable as REM. */
45 if( rem == divisor ) {
46 temp_divisor = mpi_copy( divisor );
47 divisor = temp_divisor;
48 }
49
50 _gcry_mpi_tdiv_r( rem, dividend, divisor );
51
52 if( ((divisor_sign?1:0) ^ (dividend->sign?1:0)) && rem->nlimbs )
53 gcry_mpi_add( rem, rem, divisor);
54
55 if( temp_divisor )
56 mpi_free(temp_divisor);
57}
58
59
60
61/****************
62 * Division rounding the quotient towards -infinity.
63 * The remainder gets the same sign as the denominator.
64 * rem is optional
65 */
66
67ulong
68_gcry_mpi_fdiv_r_ui( gcry_mpi_t rem, gcry_mpi_t dividend, ulong divisor )
69{
70 mpi_limb_t rlimb;
71
72 rlimb = _gcry_mpih_mod_1( dividend->d, dividend->nlimbs, divisor );
73 if( rlimb && dividend->sign )
74 rlimb = divisor - rlimb;
75
76 if( rem ) {
77 rem->d[0] = rlimb;
78 rem->nlimbs = rlimb? 1:0;
79 }
80 return rlimb;
81}
82
83
84void
85_gcry_mpi_fdiv_q( gcry_mpi_t quot, gcry_mpi_t dividend, gcry_mpi_t divisor )
86{
87 gcry_mpi_t tmp = mpi_alloc( mpi_get_nlimbs(quot) );
88 _gcry_mpi_fdiv_qr( quot, tmp, dividend, divisor);
89 mpi_free(tmp);
90}
91
92void
93_gcry_mpi_fdiv_qr( gcry_mpi_t quot, gcry_mpi_t rem, gcry_mpi_t dividend, gcry_mpi_t divisor )
94{
95 int divisor_sign = divisor->sign;
96 gcry_mpi_t temp_divisor = NULL;
97
98 if( quot == divisor || rem == divisor ) {
99 temp_divisor = mpi_copy( divisor );
100 divisor = temp_divisor;
101 }
102
103 _gcry_mpi_tdiv_qr( quot, rem, dividend, divisor );
104
105 if( (divisor_sign ^ dividend->sign) && rem->nlimbs ) {
106 gcry_mpi_sub_ui( quot, quot, 1 );
107 gcry_mpi_add( rem, rem, divisor);
108 }
109
110 if( temp_divisor )
111 mpi_free(temp_divisor);
112}
113
114
115/* If den == quot, den needs temporary storage.
116 * If den == rem, den needs temporary storage.
117 * If num == quot, num needs temporary storage.
118 * If den has temporary storage, it can be normalized while being copied,
119 * i.e no extra storage should be allocated.
120 */
121
122void
123_gcry_mpi_tdiv_r( gcry_mpi_t rem, gcry_mpi_t num, gcry_mpi_t den)
124{
125 _gcry_mpi_tdiv_qr(NULL, rem, num, den );
126}
127
128void
129_gcry_mpi_tdiv_qr( gcry_mpi_t quot, gcry_mpi_t rem, gcry_mpi_t num, gcry_mpi_t den)
130{
131 mpi_ptr_t np, dp;
132 mpi_ptr_t qp, rp;
133 mpi_size_t nsize = num->nlimbs;
134 mpi_size_t dsize = den->nlimbs;
135 mpi_size_t qsize, rsize;
136 mpi_size_t sign_remainder = num->sign;
137 mpi_size_t sign_quotient = num->sign ^ den->sign;
138 unsigned normalization_steps;
139 mpi_limb_t q_limb;
140 mpi_ptr_t marker[5];
141 unsigned int marker_nlimbs[5];
142 int markidx=0;
143
144 /* Ensure space is enough for quotient and remainder.
145 * We need space for an extra limb in the remainder, because it's
146 * up-shifted (normalized) below. */
147 rsize = nsize + 1;
148 mpi_resize( rem, rsize);
149
150 qsize = rsize - dsize; /* qsize cannot be bigger than this.*/
151 if( qsize <= 0 ) {
152 if( num != rem ) {
153 rem->nlimbs = num->nlimbs;
154 rem->sign = num->sign;
155 MPN_COPY(rem->d, num->d, nsize);
156 }
157 if( quot ) {
158 /* This needs to follow the assignment to rem, in case the
159 * numerator and quotient are the same. */
160 quot->nlimbs = 0;
161 quot->sign = 0;
162 }
163 return;
164 }
165
166 if( quot )
167 mpi_resize( quot, qsize);
168
169 /* Read pointers here, when reallocation is finished. */
170 np = num->d;
171 dp = den->d;
172 rp = rem->d;
173
174 /* Optimize division by a single-limb divisor. */
175 if( dsize == 1 ) {
176 mpi_limb_t rlimb;
177 if( quot ) {
178 qp = quot->d;
179 rlimb = _gcry_mpih_divmod_1( qp, np, nsize, dp[0] );
180 qsize -= qp[qsize - 1] == 0;
181 quot->nlimbs = qsize;
182 quot->sign = sign_quotient;
183 }
184 else
185 rlimb = _gcry_mpih_mod_1( np, nsize, dp[0] );
186 rp[0] = rlimb;
187 rsize = rlimb != 0?1:0;
188 rem->nlimbs = rsize;
189 rem->sign = sign_remainder;
190 return;
191 }
192
193
194 if( quot ) {
195 qp = quot->d;
196 /* Make sure QP and NP point to different objects. Otherwise the
197 * numerator would be gradually overwritten by the quotient limbs. */
198 if(qp == np) { /* Copy NP object to temporary space. */
199 marker_nlimbs[markidx] = nsize;
200 np = marker[markidx++] = mpi_alloc_limb_space(nsize,
201 mpi_is_secure(quot));
202 MPN_COPY(np, qp, nsize);
203 }
204 }
205 else /* Put quotient at top of remainder. */
206 qp = rp + dsize;
207
208 count_leading_zeros( normalization_steps, dp[dsize - 1] );
209
210 /* Normalize the denominator, i.e. make its most significant bit set by
211 * shifting it NORMALIZATION_STEPS bits to the left. Also shift the
212 * numerator the same number of steps (to keep the quotient the same!).
213 */
214 if( normalization_steps ) {
215 mpi_ptr_t tp;
216 mpi_limb_t nlimb;
217
218 /* Shift up the denominator setting the most significant bit of
219 * the most significant word. Use temporary storage not to clobber
220 * the original contents of the denominator. */
221 marker_nlimbs[markidx] = dsize;
222 tp = marker[markidx++] = mpi_alloc_limb_space(dsize,mpi_is_secure(den));
223 _gcry_mpih_lshift( tp, dp, dsize, normalization_steps );
224 dp = tp;
225
226 /* Shift up the numerator, possibly introducing a new most
227 * significant word. Move the shifted numerator in the remainder
228 * meanwhile. */
229 nlimb = _gcry_mpih_lshift(rp, np, nsize, normalization_steps);
230 if( nlimb ) {
231 rp[nsize] = nlimb;
232 rsize = nsize + 1;
233 }
234 else
235 rsize = nsize;
236 }
237 else {
238 /* The denominator is already normalized, as required.Copy it to
239 * temporary space if it overlaps with the quotient or remainder. */
240 if( dp == rp || (quot && (dp == qp))) {
241 mpi_ptr_t tp;
242
243 marker_nlimbs[markidx] = dsize;
244 tp = marker[markidx++] = mpi_alloc_limb_space(dsize,
245 mpi_is_secure(den));
246 MPN_COPY( tp, dp, dsize );
247 dp = tp;
248 }
249
250 /* Move the numerator to the remainder. */
251 if( rp != np )
252 MPN_COPY(rp, np, nsize);
253
254 rsize = nsize;
255 }
256
257 q_limb = _gcry_mpih_divrem( qp, 0, rp, rsize, dp, dsize );
258
259 if( quot ) {
260 qsize = rsize - dsize;
261 if(q_limb) {
262 qp[qsize] = q_limb;
263 qsize += 1;
264 }
265
266 quot->nlimbs = qsize;
267 quot->sign = sign_quotient;
268 }
269
270 rsize = dsize;
271 MPN_NORMALIZE (rp, rsize);
272
273 if( normalization_steps && rsize ) {
274 _gcry_mpih_rshift(rp, rp, rsize, normalization_steps);
275 rsize -= rp[rsize - 1] == 0?1:0;
276 }
277
278 rem->nlimbs = rsize;
279 rem->sign= sign_remainder;
280 while( markidx )
281 {
282 markidx--;
283 _gcry_mpi_free_limb_space (marker[markidx], marker_nlimbs[markidx]);
284 }
285}
286
287void
288_gcry_mpi_tdiv_q_2exp( gcry_mpi_t w, gcry_mpi_t u, unsigned int count )
289{
290 mpi_size_t usize, wsize;
291 mpi_size_t limb_cnt;
292
293 usize = u->nlimbs;
294 limb_cnt = count / BITS_PER_MPI_LIMB;
295 wsize = usize - limb_cnt;
296 if( limb_cnt >= usize )
297 w->nlimbs = 0;
298 else {
299 mpi_ptr_t wp;
300 mpi_ptr_t up;
301
302 RESIZE_IF_NEEDED( w, wsize );
303 wp = w->d;
304 up = u->d;
305
306 count %= BITS_PER_MPI_LIMB;
307 if( count ) {
308 _gcry_mpih_rshift( wp, up + limb_cnt, wsize, count );
309 wsize -= !wp[wsize - 1];
310 }
311 else {
312 MPN_COPY_INCR( wp, up + limb_cnt, wsize);
313 }
314
315 w->nlimbs = wsize;
316 }
317}
318
319/****************
320 * Check whether dividend is divisible by divisor
321 * (note: divisor must fit into a limb)
322 */
323int
324_gcry_mpi_divisible_ui(gcry_mpi_t dividend, ulong divisor )
325{
326 return !_gcry_mpih_mod_1( dividend->d, dividend->nlimbs, divisor );
327}
328
329
330void
331gcry_mpi_div (gcry_mpi_t quot, gcry_mpi_t rem, gcry_mpi_t dividend, gcry_mpi_t divisor, int round)
332{
333 if (!round)
334 {
335 if (!rem)
336 {
337 gcry_mpi_t tmp = mpi_alloc (mpi_get_nlimbs(quot));
338 _gcry_mpi_tdiv_qr (quot, tmp, dividend, divisor);
339 mpi_free (tmp);
340 }
341 else
342 _gcry_mpi_tdiv_qr (quot, rem, dividend, divisor);
343 }
344 else if (round < 0)
345 {
346 if (!rem)
347 _gcry_mpi_fdiv_q (quot, dividend, divisor);
348 else if (!quot)
349 _gcry_mpi_fdiv_r (rem, dividend, divisor);
350 else
351 _gcry_mpi_fdiv_qr (quot, rem, dividend, divisor);
352 }
353 else
354 log_bug ("mpi rounding to ceiling not yet implemented\n");
355}
356
357
358void
359gcry_mpi_mod (gcry_mpi_t rem, gcry_mpi_t dividend, gcry_mpi_t divisor)
360{
361 _gcry_mpi_fdiv_r (rem, dividend, divisor);
362 rem->sign = 0;
363}
364
diff --git a/pwmanager/libcrypt/mpi/mpi-gcd.c b/pwmanager/libcrypt/mpi/mpi-gcd.c
new file mode 100644
index 0000000..51841e7
--- a/dev/null
+++ b/pwmanager/libcrypt/mpi/mpi-gcd.c
@@ -0,0 +1,54 @@
1/* mpi-gcd.c - MPI functions
2 *Copyright (C) 1998, 2001, 2002, 2003 Free Software Foundation, Inc.
3 *
4 * This file is part of Libgcrypt.
5 *
6 * Libgcrypt is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License as
8 * published by the Free Software Foundation; either version 2.1 of
9 * the License, or (at your option) any later version.
10 *
11 * Libgcrypt is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19 */
20
21#include <config.h>
22#include <stdio.h>
23#include <stdlib.h>
24#include "mpi-internal.h"
25
26/****************
27 * Find the greatest common divisor G of A and B.
28 * Return: true if this 1, false in all other cases
29 */
30int
31gcry_mpi_gcd( gcry_mpi_t g, gcry_mpi_t xa, gcry_mpi_t xb )
32{
33 gcry_mpi_t a, b;
34
35 a = mpi_copy(xa);
36 b = mpi_copy(xb);
37
38 /* TAOCP Vol II, 4.5.2, Algorithm A */
39 a->sign = 0;
40 b->sign = 0;
41 while( gcry_mpi_cmp_ui( b, 0 ) ) {
42 _gcry_mpi_fdiv_r( g, a, b ); /* g used as temorary variable */
43 mpi_set(a,b);
44 mpi_set(b,g);
45 }
46 mpi_set(g, a);
47
48 mpi_free(a);
49 mpi_free(b);
50 return !gcry_mpi_cmp_ui( g, 1);
51}
52
53
54
diff --git a/pwmanager/libcrypt/mpi/mpi-inline.c b/pwmanager/libcrypt/mpi/mpi-inline.c
new file mode 100644
index 0000000..a196946
--- a/dev/null
+++ b/pwmanager/libcrypt/mpi/mpi-inline.c
@@ -0,0 +1,36 @@
1/* mpi-inline.c
2 *Copyright (C) 1999, 2002 Free Software Foundation, Inc.
3 *
4 * This file is part of Libgcrypt.
5 *
6 * Libgcrypt is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License as
8 * published by the Free Software Foundation; either version 2.1 of
9 * the License, or (at your option) any later version.
10 *
11 * Libgcrypt is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19 */
20
21#include <config.h>
22#include <stdio.h>
23#include <stdlib.h>
24
25/* put the inline functions as real functions into the lib */
26#define G10_MPI_INLINE_DECL
27
28#include "mpi-internal.h"
29
30/* always include the header becuase it is only
31 * included by mpi-internal if __GCC__ is defined but we
32 * need it here in all cases and the above definition of
33 * of the macro allows us to do so
34 */
35#include "mpi-inline.h"
36
diff --git a/pwmanager/libcrypt/mpi/mpi-inline.h b/pwmanager/libcrypt/mpi/mpi-inline.h
new file mode 100644
index 0000000..88d9f56
--- a/dev/null
+++ b/pwmanager/libcrypt/mpi/mpi-inline.h
@@ -0,0 +1,154 @@
1/* mpi-inline.h - Internal to the Multi Precision Integers
2 * Copyright (C) 1994, 1996, 1998, 1999,
3 * 2001, 2002 Free Software Foundation, Inc.
4 *
5 * This file is part of Libgcrypt.
6 *
7 * Libgcrypt is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * Libgcrypt is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20 *
21 * Note: This code is heavily based on the GNU MP Library.
22 * Actually it's the same code with only minor changes in the
23 * way the data is stored; this is to support the abstraction
24 * of an optional secure memory allocation which may be used
25 * to avoid revealing of sensitive data due to paging etc.
26 */
27
28#ifndef G10_MPI_INLINE_H
29#define G10_MPI_INLINE_H
30
31#ifndef G10_MPI_INLINE_DECL
32#define G10_MPI_INLINE_DECL extern __inline__
33#endif
34
35G10_MPI_INLINE_DECL mpi_limb_t
36_gcry_mpih_add_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
37 mpi_size_t s1_size, mpi_limb_t s2_limb)
38{
39 mpi_limb_t x;
40
41 x = *s1_ptr++;
42 s2_limb += x;
43 *res_ptr++ = s2_limb;
44 if( s2_limb < x ) { /* sum is less than the left operand: handle carry */
45 while( --s1_size ) {
46 x = *s1_ptr++ + 1;/* add carry */
47 *res_ptr++ = x;/* and store */
48 if( x ) /* not 0 (no overflow): we can stop */
49 goto leave;
50 }
51 return 1; /* return carry (size of s1 to small) */
52 }
53
54 leave:
55 if( res_ptr != s1_ptr ) { /* not the same variable */
56 mpi_size_t i; /* copy the rest */
57 for( i=0; i < s1_size-1; i++ )
58 res_ptr[i] = s1_ptr[i];
59 }
60 return 0; /* no carry */
61}
62
63
64
65G10_MPI_INLINE_DECL mpi_limb_t
66_gcry_mpih_add(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size,
67 mpi_ptr_t s2_ptr, mpi_size_t s2_size)
68{
69 mpi_limb_t cy = 0;
70
71 if( s2_size )
72 cy = _gcry_mpih_add_n( res_ptr, s1_ptr, s2_ptr, s2_size );
73
74 if( s1_size - s2_size )
75 cy = _gcry_mpih_add_1( res_ptr + s2_size, s1_ptr + s2_size,
76 s1_size - s2_size, cy);
77 return cy;
78}
79
80
81G10_MPI_INLINE_DECL mpi_limb_t
82_gcry_mpih_sub_1(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
83 mpi_size_t s1_size, mpi_limb_t s2_limb )
84{
85 mpi_limb_t x;
86
87 x = *s1_ptr++;
88 s2_limb = x - s2_limb;
89 *res_ptr++ = s2_limb;
90 if( s2_limb > x ) {
91 while( --s1_size ) {
92 x = *s1_ptr++;
93 *res_ptr++ = x - 1;
94 if( x )
95 goto leave;
96 }
97 return 1;
98 }
99
100 leave:
101 if( res_ptr != s1_ptr ) {
102 mpi_size_t i;
103 for( i=0; i < s1_size-1; i++ )
104 res_ptr[i] = s1_ptr[i];
105 }
106 return 0;
107}
108
109
110
111G10_MPI_INLINE_DECL mpi_limb_t
112_gcry_mpih_sub( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size,
113 mpi_ptr_t s2_ptr, mpi_size_t s2_size)
114{
115 mpi_limb_t cy = 0;
116
117 if( s2_size )
118 cy = _gcry_mpih_sub_n(res_ptr, s1_ptr, s2_ptr, s2_size);
119
120 if( s1_size - s2_size )
121 cy = _gcry_mpih_sub_1(res_ptr + s2_size, s1_ptr + s2_size,
122 s1_size - s2_size, cy);
123 return cy;
124}
125
126/****************
127 * Compare OP1_PTR/OP1_SIZE with OP2_PTR/OP2_SIZE.
128 * There are no restrictions on the relative sizes of
129 * the two arguments.
130 * Return 1 if OP1 > OP2, 0 if they are equal, and -1 if OP1 < OP2.
131 */
132G10_MPI_INLINE_DECL int
133_gcry_mpih_cmp( mpi_ptr_t op1_ptr, mpi_ptr_t op2_ptr, mpi_size_t size )
134{
135 mpi_size_t i;
136 mpi_limb_t op1_word, op2_word;
137
138 for( i = size - 1; i >= 0 ; i--) {
139 op1_word = op1_ptr[i];
140 op2_word = op2_ptr[i];
141 if( op1_word != op2_word )
142 goto diff;
143 }
144 return 0;
145
146 diff:
147 /* This can *not* be simplified to
148 * op2_word - op2_word
149 * since that expression might give signed overflow. */
150 return (op1_word > op2_word) ? 1 : -1;
151}
152
153
154#endif /*G10_MPI_INLINE_H*/
diff --git a/pwmanager/libcrypt/mpi/mpi-internal.h b/pwmanager/libcrypt/mpi/mpi-internal.h
new file mode 100644
index 0000000..d78c180
--- a/dev/null
+++ b/pwmanager/libcrypt/mpi/mpi-internal.h
@@ -0,0 +1,275 @@
1/* mpi-internal.h - Internal to the Multi Precision Integers
2 * Copyright (C) 1994, 1996, 1998, 2000, 2002,
3 * 2003 Free Software Foundation, Inc.
4 *
5 * This file is part of Libgcrypt.
6 *
7 * Libgcrypt is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * Libgcrypt is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20 *
21 * Note: This code is heavily based on the GNU MP Library.
22 * Actually it's the same code with only minor changes in the
23 * way the data is stored; this is to support the abstraction
24 * of an optional secure memory allocation which may be used
25 * to avoid revealing of sensitive data due to paging etc.
26 */
27
28#ifndef G10_MPI_INTERNAL_H
29#define G10_MPI_INTERNAL_H
30
31#include "mpi-asm-defs.h"
32
33#ifndef BITS_PER_MPI_LIMB
34#if BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_INT
35 typedef unsigned int mpi_limb_t;
36 typedef signed int mpi_limb_signed_t;
37#elif BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_LONG
38 typedef unsigned long int mpi_limb_t;
39 typedef signed long int mpi_limb_signed_t;
40#elif BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_LONG_LONG
41 typedef unsigned long long int mpi_limb_t;
42 typedef signed long long int mpi_limb_signed_t;
43#elif BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_SHORT
44 typedef unsigned short int mpi_limb_t;
45 typedef signed short int mpi_limb_signed_t;
46#else
47#error BYTES_PER_MPI_LIMB does not match any C type
48#endif
49#define BITS_PER_MPI_LIMB (8*BYTES_PER_MPI_LIMB)
50#endif /*BITS_PER_MPI_LIMB*/
51
52#include "mpi.h"
53
54/* If KARATSUBA_THRESHOLD is not already defined, define it to a
55 * value which is good on most machines. */
56
57/* tested 4, 16, 32 and 64, where 16 gave the best performance when
58 * checking a 768 and a 1024 bit ElGamal signature.
59 * (wk 22.12.97) */
60#ifndef KARATSUBA_THRESHOLD
61#define KARATSUBA_THRESHOLD 16
62#endif
63
64/* The code can't handle KARATSUBA_THRESHOLD smaller than 2. */
65#if KARATSUBA_THRESHOLD < 2
66#undef KARATSUBA_THRESHOLD
67#define KARATSUBA_THRESHOLD 2
68#endif
69
70
71typedef mpi_limb_t *mpi_ptr_t; /* pointer to a limb */
72typedef int mpi_size_t; /* (must be a signed type) */
73
74#define ABS(x) (x >= 0 ? x : -x)
75#define MIN(l,o) ((l) < (o) ? (l) : (o))
76#define MAX(h,i) ((h) > (i) ? (h) : (i))
77#define RESIZE_IF_NEEDED(a,b) \
78 do { \
79 if( (a)->alloced < (b) ) \
80 mpi_resize((a), (b)); \
81 } while(0)
82
83/* Copy N limbs from S to D. */
84#define MPN_COPY( d, s, n) \
85 do { \
86 mpi_size_t _i; \
87 for( _i = 0; _i < (n); _i++ )\
88 (d)[_i] = (s)[_i]; \
89 } while(0)
90
91 #define MPN_COPY_INCR( d, s, n) \
92 do { \
93 mpi_size_t _i; \
94 for( _i = 0; _i < (n); _i++ )\
95 (d)[_i] = (d)[_i]; \
96 } while (0)
97
98#define MPN_COPY_DECR( d, s, n ) \
99 do { \
100 mpi_size_t _i; \
101 for( _i = (n)-1; _i >= 0; _i--) \
102 (d)[_i] = (s)[_i]; \
103 } while(0)
104
105/* Zero N limbs at D */
106#define MPN_ZERO(d, n) \
107 do { \
108 int _i; \
109 for( _i = 0; _i < (n); _i++ ) \
110 (d)[_i] = 0; \
111 } while (0)
112
113#define MPN_NORMALIZE(d, n) \
114 do { \
115 while( (n) > 0 ) { \
116 if( (d)[(n)-1] ) \
117 break; \
118 (n)--; \
119 } \
120 } while(0)
121
122#define MPN_NORMALIZE_NOT_ZERO(d, n) \
123 do { \
124 for(;;) { \
125 if( (d)[(n)-1] ) \
126 break; \
127 (n)--; \
128 } \
129 } while(0)
130
131#define MPN_MUL_N_RECURSE(prodp, up, vp, size, tspace) \
132 do { \
133 if( (size) < KARATSUBA_THRESHOLD ) \
134 mul_n_basecase (prodp, up, vp, size);\
135 else \
136 mul_n (prodp, up, vp, size, tspace);\
137 } while (0);
138
139
140/* Divide the two-limb number in (NH,,NL) by D, with DI being the largest
141 * limb not larger than (2**(2*BITS_PER_MP_LIMB))/D - (2**BITS_PER_MP_LIMB).
142 * If this would yield overflow, DI should be the largest possible number
143 * (i.e., only ones). For correct operation, the most significant bit of D
144 * has to be set. Put the quotient in Q and the remainder in R.
145 */
146#define UDIV_QRNND_PREINV(q, r, nh, nl, d, di) \
147 do { \
148 mpi_limb_t _q, _ql, _r; \
149 mpi_limb_t _xh, _xl; \
150 umul_ppmm (_q, _ql, (nh), (di)); \
151 _q += (nh);/* DI is 2**BITS_PER_MPI_LIMB too small */ \
152 umul_ppmm (_xh, _xl, _q, (d)); \
153 sub_ddmmss (_xh, _r, (nh), (nl), _xh, _xl); \
154 if( _xh ) { \
155 sub_ddmmss (_xh, _r, _xh, _r, 0, (d)); \
156 _q++; \
157 if( _xh) { \
158 sub_ddmmss (_xh, _r, _xh, _r, 0, (d)); \
159 _q++; \
160 } \
161 } \
162 if( _r >= (d) ) { \
163 _r -= (d); \
164 _q++; \
165 } \
166 (r) = _r; \
167 (q) = _q; \
168 } while (0)
169
170
171/*-- mpiutil.c --*/
172#define mpi_alloc_limb_space(n,f) _gcry_mpi_alloc_limb_space((n),(f))
173mpi_ptr_t _gcry_mpi_alloc_limb_space( unsigned nlimbs, int sec );
174void _gcry_mpi_free_limb_space( mpi_ptr_t a, unsigned int nlimbs );
175void _gcry_mpi_assign_limb_space( gcry_mpi_t a, mpi_ptr_t ap, unsigned nlimbs );
176
177/*-- mpi-bit.c --*/
178void _gcry_mpi_rshift_limbs( gcry_mpi_t a, unsigned int count );
179void _gcry_mpi_lshift_limbs( gcry_mpi_t a, unsigned int count );
180
181
182/*-- mpih-add.c --*/
183mpi_limb_t _gcry_mpih_add_1(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
184 mpi_size_t s1_size, mpi_limb_t s2_limb );
185mpi_limb_t _gcry_mpih_add_n( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
186 mpi_ptr_t s2_ptr, mpi_size_t size);
187mpi_limb_t _gcry_mpih_add(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size,
188 mpi_ptr_t s2_ptr, mpi_size_t s2_size);
189
190/*-- mpih-sub.c --*/
191mpi_limb_t _gcry_mpih_sub_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
192 mpi_size_t s1_size, mpi_limb_t s2_limb );
193mpi_limb_t _gcry_mpih_sub_n( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
194 mpi_ptr_t s2_ptr, mpi_size_t size);
195mpi_limb_t _gcry_mpih_sub(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size,
196 mpi_ptr_t s2_ptr, mpi_size_t s2_size);
197
198/*-- mpih-cmp.c --*/
199int _gcry_mpih_cmp( mpi_ptr_t op1_ptr, mpi_ptr_t op2_ptr, mpi_size_t size );
200
201/*-- mpih-mul.c --*/
202
203struct karatsuba_ctx {
204 struct karatsuba_ctx *next;
205 mpi_ptr_t tspace;
206 unsigned int tspace_nlimbs;
207 mpi_size_t tspace_size;
208 mpi_ptr_t tp;
209 unsigned int tp_nlimbs;
210 mpi_size_t tp_size;
211};
212
213void _gcry_mpih_release_karatsuba_ctx( struct karatsuba_ctx *ctx );
214
215mpi_limb_t _gcry_mpih_addmul_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
216 mpi_size_t s1_size, mpi_limb_t s2_limb);
217mpi_limb_t _gcry_mpih_submul_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
218 mpi_size_t s1_size, mpi_limb_t s2_limb);
219void _gcry_mpih_mul_n( mpi_ptr_t prodp, mpi_ptr_t up, mpi_ptr_t vp,
220 mpi_size_t size);
221mpi_limb_t _gcry_mpih_mul( mpi_ptr_t prodp, mpi_ptr_t up, mpi_size_t usize,
222 mpi_ptr_t vp, mpi_size_t vsize);
223void _gcry_mpih_sqr_n_basecase( mpi_ptr_t prodp, mpi_ptr_t up, mpi_size_t size );
224void _gcry_mpih_sqr_n( mpi_ptr_t prodp, mpi_ptr_t up, mpi_size_t size,
225 mpi_ptr_t tspace);
226
227void _gcry_mpih_mul_karatsuba_case( mpi_ptr_t prodp,
228 mpi_ptr_t up, mpi_size_t usize,
229 mpi_ptr_t vp, mpi_size_t vsize,
230 struct karatsuba_ctx *ctx );
231
232
233/*-- mpih-mul_1.c (or xxx/cpu/ *.S) --*/
234mpi_limb_t _gcry_mpih_mul_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
235 mpi_size_t s1_size, mpi_limb_t s2_limb);
236
237/*-- mpih-div.c --*/
238mpi_limb_t _gcry_mpih_mod_1(mpi_ptr_t dividend_ptr, mpi_size_t dividend_size,
239 mpi_limb_t divisor_limb);
240mpi_limb_t _gcry_mpih_divrem( mpi_ptr_t qp, mpi_size_t qextra_limbs,
241 mpi_ptr_t np, mpi_size_t nsize,
242 mpi_ptr_t dp, mpi_size_t dsize);
243mpi_limb_t _gcry_mpih_divmod_1( mpi_ptr_t quot_ptr,
244 mpi_ptr_t dividend_ptr, mpi_size_t dividend_size,
245 mpi_limb_t divisor_limb);
246
247/*-- mpih-shift.c --*/
248mpi_limb_t _gcry_mpih_lshift( mpi_ptr_t wp, mpi_ptr_t up, mpi_size_t usize,
249 unsigned cnt);
250mpi_limb_t _gcry_mpih_rshift( mpi_ptr_t wp, mpi_ptr_t up, mpi_size_t usize,
251 unsigned cnt);
252
253
254/* Define stuff for longlong.h. */
255#define W_TYPE_SIZE BITS_PER_MPI_LIMB
256 typedef mpi_limb_t UWtype;
257 typedef unsigned int UHWtype;
258#if defined (__GNUC__)
259 typedef unsigned int UQItype __attribute__ ((mode (QI)));
260 typedef int SItype __attribute__ ((mode (SI)));
261 typedef unsigned int USItype __attribute__ ((mode (SI)));
262 typedef int DItype __attribute__ ((mode (DI)));
263 typedef unsigned int UDItype __attribute__ ((mode (DI)));
264#else
265 typedef unsigned char UQItype;
266 typedef long SItype;
267 typedef unsigned long USItype;
268#endif
269
270#ifdef __GNUC__
271#include "mpi-inline.h"
272#endif
273
274#endif /*G10_MPI_INTERNAL_H*/
275
diff --git a/pwmanager/libcrypt/mpi/mpi-inv.c b/pwmanager/libcrypt/mpi/mpi-inv.c
new file mode 100644
index 0000000..2e737b8
--- a/dev/null
+++ b/pwmanager/libcrypt/mpi/mpi-inv.c
@@ -0,0 +1,275 @@
1/* mpi-inv.c - MPI functions
2 *Copyright (C) 1998, 2001, 2002, 2003 Free Software Foundation, Inc.
3 *
4 * This file is part of Libgcrypt.
5 *
6 * Libgcrypt is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License as
8 * published by the Free Software Foundation; either version 2.1 of
9 * the License, or (at your option) any later version.
10 *
11 * Libgcrypt is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19 */
20
21#include <config.h>
22#include <stdio.h>
23#include <stdlib.h>
24#include "mpi-internal.h"
25#include "g10lib.h"
26
27/****************
28 * Calculate the multiplicative inverse X of A mod N
29 * That is: Find the solution x for
30 * 1 = (a*x) mod n
31 */
32void
33_gcry_mpi_invm( gcry_mpi_t x, gcry_mpi_t a, gcry_mpi_t n )
34{
35#if 0
36 gcry_mpi_t u, v, u1, u2, u3, v1, v2, v3, q, t1, t2, t3;
37 gcry_mpi_t ta, tb, tc;
38
39 u = mpi_copy(a);
40 v = mpi_copy(n);
41 u1 = mpi_alloc_set_ui(1);
42 u2 = mpi_alloc_set_ui(0);
43 u3 = mpi_copy(u);
44 v1 = mpi_alloc_set_ui(0);
45 v2 = mpi_alloc_set_ui(1);
46 v3 = mpi_copy(v);
47 q = mpi_alloc( mpi_get_nlimbs(u)+1 );
48 t1 = mpi_alloc( mpi_get_nlimbs(u)+1 );
49 t2 = mpi_alloc( mpi_get_nlimbs(u)+1 );
50 t3 = mpi_alloc( mpi_get_nlimbs(u)+1 );
51 while( mpi_cmp_ui( v3, 0 ) ) {
52 mpi_fdiv_q( q, u3, v3 );
53 mpi_mul(t1, v1, q); mpi_mul(t2, v2, q); mpi_mul(t3, v3, q);
54 mpi_sub(t1, u1, t1); mpi_sub(t2, u2, t2); mpi_sub(t3, u3, t3);
55 mpi_set(u1, v1); mpi_set(u2, v2); mpi_set(u3, v3);
56 mpi_set(v1, t1); mpi_set(v2, t2); mpi_set(v3, t3);
57 }
58 /*log_debug("result:\n");
59 log_mpidump("q =", q );
60 log_mpidump("u1=", u1);
61 log_mpidump("u2=", u2);
62 log_mpidump("u3=", u3);
63 log_mpidump("v1=", v1);
64 log_mpidump("v2=", v2); */
65 mpi_set(x, u1);
66
67 mpi_free(u1);
68 mpi_free(u2);
69 mpi_free(u3);
70 mpi_free(v1);
71 mpi_free(v2);
72 mpi_free(v3);
73 mpi_free(q);
74 mpi_free(t1);
75 mpi_free(t2);
76 mpi_free(t3);
77 mpi_free(u);
78 mpi_free(v);
79#elif 0
80 /* Extended Euclid's algorithm (See TAOCP Vol II, 4.5.2, Alg X)
81 * modified according to Michael Penk's solution for Exercise 35 */
82
83 /* FIXME: we can simplify this in most cases (see Knuth) */
84 gcry_mpi_t u, v, u1, u2, u3, v1, v2, v3, t1, t2, t3;
85 unsigned k;
86 int sign;
87
88 u = mpi_copy(a);
89 v = mpi_copy(n);
90 for(k=0; !mpi_test_bit(u,0) && !mpi_test_bit(v,0); k++ ) {
91 mpi_rshift(u, u, 1);
92 mpi_rshift(v, v, 1);
93 }
94
95
96 u1 = mpi_alloc_set_ui(1);
97 u2 = mpi_alloc_set_ui(0);
98 u3 = mpi_copy(u);
99 v1 = mpi_copy(v); /* !-- used as const 1 */
100 v2 = mpi_alloc( mpi_get_nlimbs(u) ); mpi_sub( v2, u1, u );
101 v3 = mpi_copy(v);
102 if( mpi_test_bit(u, 0) ) { /* u is odd */
103 t1 = mpi_alloc_set_ui(0);
104 t2 = mpi_alloc_set_ui(1); t2->sign = 1;
105 t3 = mpi_copy(v); t3->sign = !t3->sign;
106 goto Y4;
107 }
108 else {
109 t1 = mpi_alloc_set_ui(1);
110 t2 = mpi_alloc_set_ui(0);
111 t3 = mpi_copy(u);
112 }
113 do {
114 do {
115 if( mpi_test_bit(t1, 0) || mpi_test_bit(t2, 0) ) { /* one is odd */
116 mpi_add(t1, t1, v);
117 mpi_sub(t2, t2, u);
118 }
119 mpi_rshift(t1, t1, 1);
120 mpi_rshift(t2, t2, 1);
121 mpi_rshift(t3, t3, 1);
122 Y4:
123 ;
124 } while( !mpi_test_bit( t3, 0 ) ); /* while t3 is even */
125
126 if( !t3->sign ) {
127 mpi_set(u1, t1);
128 mpi_set(u2, t2);
129 mpi_set(u3, t3);
130 }
131 else {
132 mpi_sub(v1, v, t1);
133 sign = u->sign; u->sign = !u->sign;
134 mpi_sub(v2, u, t2);
135 u->sign = sign;
136 sign = t3->sign; t3->sign = !t3->sign;
137 mpi_set(v3, t3);
138 t3->sign = sign;
139 }
140 mpi_sub(t1, u1, v1);
141 mpi_sub(t2, u2, v2);
142 mpi_sub(t3, u3, v3);
143 if( t1->sign ) {
144 mpi_add(t1, t1, v);
145 mpi_sub(t2, t2, u);
146 }
147 } while( mpi_cmp_ui( t3, 0 ) ); /* while t3 != 0 */
148 /* mpi_lshift( u3, k ); */
149 mpi_set(x, u1);
150
151 mpi_free(u1);
152 mpi_free(u2);
153 mpi_free(u3);
154 mpi_free(v1);
155 mpi_free(v2);
156 mpi_free(v3);
157 mpi_free(t1);
158 mpi_free(t2);
159 mpi_free(t3);
160#else
161 /* Extended Euclid's algorithm (See TAOCP Vol II, 4.5.2, Alg X)
162 * modified according to Michael Penk's solution for Exercise 35
163 * with further enhancement */
164 gcry_mpi_t u, v, u1, u2=NULL, u3, v1, v2=NULL, v3, t1, t2=NULL, t3;
165 unsigned k;
166 int sign;
167 int odd ;
168
169 u = mpi_copy(a);
170 v = mpi_copy(n);
171
172 for(k=0; !mpi_test_bit(u,0) && !mpi_test_bit(v,0); k++ ) {
173 mpi_rshift(u, u, 1);
174 mpi_rshift(v, v, 1);
175 }
176 odd = mpi_test_bit(v,0);
177
178 u1 = mpi_alloc_set_ui(1);
179 if( !odd )
180 u2 = mpi_alloc_set_ui(0);
181 u3 = mpi_copy(u);
182 v1 = mpi_copy(v);
183 if( !odd ) {
184 v2 = mpi_alloc( mpi_get_nlimbs(u) );
185 mpi_sub( v2, u1, u ); /* U is used as const 1 */
186 }
187 v3 = mpi_copy(v);
188 if( mpi_test_bit(u, 0) ) { /* u is odd */
189 t1 = mpi_alloc_set_ui(0);
190 if( !odd ) {
191 t2 = mpi_alloc_set_ui(1); t2->sign = 1;
192 }
193 t3 = mpi_copy(v); t3->sign = !t3->sign;
194 goto Y4;
195 }
196 else {
197 t1 = mpi_alloc_set_ui(1);
198 if( !odd )
199 t2 = mpi_alloc_set_ui(0);
200 t3 = mpi_copy(u);
201 }
202 do {
203 do {
204 if( !odd ) {
205 if( mpi_test_bit(t1, 0) || mpi_test_bit(t2, 0) ) { /* one is odd */
206 mpi_add(t1, t1, v);
207 mpi_sub(t2, t2, u);
208 }
209 mpi_rshift(t1, t1, 1);
210 mpi_rshift(t2, t2, 1);
211 mpi_rshift(t3, t3, 1);
212 }
213 else {
214 if( mpi_test_bit(t1, 0) )
215 mpi_add(t1, t1, v);
216 mpi_rshift(t1, t1, 1);
217 mpi_rshift(t3, t3, 1);
218 }
219 Y4:
220 ;
221 } while( !mpi_test_bit( t3, 0 ) ); /* while t3 is even */
222
223 if( !t3->sign ) {
224 mpi_set(u1, t1);
225 if( !odd )
226 mpi_set(u2, t2);
227 mpi_set(u3, t3);
228 }
229 else {
230 mpi_sub(v1, v, t1);
231 sign = u->sign; u->sign = !u->sign;
232 if( !odd )
233 mpi_sub(v2, u, t2);
234 u->sign = sign;
235 sign = t3->sign; t3->sign = !t3->sign;
236 mpi_set(v3, t3);
237 t3->sign = sign;
238 }
239 mpi_sub(t1, u1, v1);
240 if( !odd )
241 mpi_sub(t2, u2, v2);
242 mpi_sub(t3, u3, v3);
243 if( t1->sign ) {
244 mpi_add(t1, t1, v);
245 if( !odd )
246 mpi_sub(t2, t2, u);
247 }
248 } while( mpi_cmp_ui( t3, 0 ) ); /* while t3 != 0 */
249 /* mpi_lshift( u3, k ); */
250 mpi_set(x, u1);
251
252 mpi_free(u1);
253 mpi_free(v1);
254 mpi_free(t1);
255 if( !odd ) {
256 mpi_free(u2);
257 mpi_free(v2);
258 mpi_free(t2);
259 }
260 mpi_free(u3);
261 mpi_free(v3);
262 mpi_free(t3);
263
264 mpi_free(u);
265 mpi_free(v);
266#endif
267}
268
269
270int
271gcry_mpi_invm (gcry_mpi_t x, gcry_mpi_t a, gcry_mpi_t n)
272{
273 _gcry_mpi_invm (x, a, n);
274 return 1;
275}
diff --git a/pwmanager/libcrypt/mpi/mpi-mpow.c b/pwmanager/libcrypt/mpi/mpi-mpow.c
new file mode 100644
index 0000000..f37c6f9
--- a/dev/null
+++ b/pwmanager/libcrypt/mpi/mpi-mpow.c
@@ -0,0 +1,224 @@
1/* mpi-mpow.c - MPI functions
2 *Copyright (C) 1998, 1999, 2001, 2002, 2003 Free Software Foundation, Inc.
3 *
4 * This file is part of Libgcrypt.
5 *
6 * Libgcrypt is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License as
8 * published by the Free Software Foundation; either version 2.1 of
9 * the License, or (at your option) any later version.
10 *
11 * Libgcrypt is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19 */
20
21#include <config.h>
22#include <stdio.h>
23#include <stdlib.h>
24#include "mpi-internal.h"
25#include "longlong.h"
26#include "g10lib.h"
27#include <assert.h>
28
29
30/* Barrett is slower than the classical way. It can be tweaked by
31 * using partial multiplications
32 */
33/*#define USE_BARRETT*/
34
35
36
37#ifdef USE_BARRETT
38static void barrett_mulm( gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m, gcry_mpi_t y, int k, gcry_mpi_t r1, gcry_mpi_t r2 );
39static gcry_mpi_t init_barrett( gcry_mpi_t m, int *k, gcry_mpi_t *r1, gcry_mpi_t *r2 );
40static int calc_barrett( gcry_mpi_t r, gcry_mpi_t x, gcry_mpi_t m, gcry_mpi_t y, int k, gcry_mpi_t r1, gcry_mpi_t r2 );
41#else
42#define barrett_mulm( w, u, v, m, y, k, r1, r2 ) gcry_mpi_mulm( (w), (u), (v), (m) )
43#endif
44
45
46static int
47build_index( gcry_mpi_t *exparray, int k, int i, int t )
48{
49 int j, bitno;
50 int idx = 0;
51
52 bitno = t-i;
53 for(j=k-1; j >= 0; j-- ) {
54 idx <<= 1;
55 if( mpi_test_bit( exparray[j], bitno ) )
56 idx |= 1;
57 }
58 /*log_debug("t=%d i=%d idx=%d\n", t, i, idx );*/
59 return idx;
60}
61
62/****************
63 * RES = (BASE[0] ^ EXP[0]) * (BASE[1] ^ EXP[1]) * ... * mod M
64 */
65void
66_gcry_mpi_mulpowm( gcry_mpi_t res, gcry_mpi_t *basearray, gcry_mpi_t *exparray, gcry_mpi_t m)
67{
68 int k;/* number of elements */
69 int t;/* bit size of largest exponent */
70 int i, j, idx;
71 gcry_mpi_t *G;/* table with precomputed values of size 2^k */
72 gcry_mpi_t tmp;
73#ifdef USE_BARRETT
74 gcry_mpi_t barrett_y, barrett_r1, barrett_r2;
75 int barrett_k;
76#endif
77
78 for(k=0; basearray[k]; k++ )
79 ;
80 assert(k);
81 for(t=0, i=0; (tmp=exparray[i]); i++ ) {
82 /*log_mpidump("exp: ", tmp );*/
83 j = mpi_get_nbits(tmp);
84 if( j > t )
85 t = j;
86 }
87 /*log_mpidump("mod: ", m );*/
88 assert(i==k);
89 assert(t);
90 assert( k < 10 );
91
92 G = gcry_xcalloc( (1<<k) , sizeof *G );
93#ifdef USE_BARRETT
94 barrett_y = init_barrett( m, &barrett_k, &barrett_r1, &barrett_r2 );
95#endif
96 /* and calculate */
97 tmp = mpi_alloc( mpi_get_nlimbs(m)+1 );
98 mpi_set_ui( res, 1 );
99 for(i = 1; i <= t; i++ ) {
100 barrett_mulm(tmp, res, res, m, barrett_y, barrett_k,
101 barrett_r1, barrett_r2 );
102 idx = build_index( exparray, k, i, t );
103 assert( idx >= 0 && idx < (1<<k) );
104 if( !G[idx] ) {
105 if( !idx )
106 G[0] = mpi_alloc_set_ui( 1 );
107 else {
108 for(j=0; j < k; j++ ) {
109 if( (idx & (1<<j) ) ) {
110 if( !G[idx] )
111 G[idx] = mpi_copy( basearray[j] );
112 else
113 barrett_mulm( G[idx], G[idx], basearray[j],
114 m, barrett_y, barrett_k, barrett_r1, barrett_r2);
115 }
116 }
117 if( !G[idx] )
118 G[idx] = mpi_alloc(0);
119 }
120 }
121 barrett_mulm(res, tmp, G[idx], m, barrett_y, barrett_k, barrett_r1, barrett_r2);
122 }
123
124 /* cleanup */
125 mpi_free(tmp);
126#ifdef USE_BARRETT
127 mpi_free(barrett_y);
128 mpi_free(barrett_r1);
129 mpi_free(barrett_r2);
130#endif
131 for(i=0; i < (1<<k); i++ )
132 mpi_free(G[i]);
133 gcry_free(G);
134}
135
136
137
138#ifdef USE_BARRETT
139static void
140 barrett_mulm( gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m, gcry_mpi_t y, int k, gcry_mpi_t r1, gcry_mpi_t r2)
141{
142 mpi_mul(w, u, v);
143 if( calc_barrett( w, w, m, y, k, r1, r2 ) )
144 mpi_fdiv_r( w, w, m );
145}
146
147/****************
148 * Barrett precalculation: y = floor(b^(2k) / m)
149 */
150static gcry_mpi_t
151init_barrett( gcry_mpi_t m, int *k, gcry_mpi_t *r1, gcry_mpi_t *r2 )
152{
153 gcry_mpi_t tmp;
154
155 mpi_normalize( m );
156 *k = mpi_get_nlimbs( m );
157 tmp = mpi_alloc( *k + 1 );
158 mpi_set_ui( tmp, 1 );
159 mpi_lshift_limbs( tmp, 2 * *k );
160 mpi_fdiv_q( tmp, tmp, m );
161 *r1 = mpi_alloc( 2* *k + 1 );
162 *r2 = mpi_alloc( 2* *k + 1 );
163 return tmp;
164}
165
166/****************
167 * Barrett reduction: We assume that these conditions are met:
168 * Given x =(x_2k-1 ...x_0)_b
169 * m =(m_k-1 ....m_0)_b with m_k-1 != 0
170 * Output r = x mod m
171 * Before using this function init_barret must be used to calucalte y and k.
172 * Returns: false = no error
173 * true = can't perform barret reduction
174 */
175static int
176calc_barrett( gcry_mpi_t r, gcry_mpi_t x, gcry_mpi_t m, gcry_mpi_t y, int k, gcry_mpi_t r1, gcry_mpi_t r2 )
177{
178 int xx = k > 3 ? k-3:0;
179
180 mpi_normalize( x );
181 if( mpi_get_nlimbs(x) > 2*k )
182 return 1; /* can't do it */
183
184 /* 1. q1 = floor( x / b^k-1)
185 * q2 = q1 * y
186 * q3 = floor( q2 / b^k+1 )
187 * Actually, we don't need qx, we can work direct on r2
188 */
189 mpi_set( r2, x );
190 mpi_rshift_limbs( r2, k-1 );
191 mpi_mul( r2, r2, y );
192 mpi_rshift_limbs( r2, k+1 );
193
194 /* 2. r1 = x mod b^k+1
195 * r2 = q3 * m mod b^k+1
196 * r = r1 - r2
197 * 3. if r < 0 then r = r + b^k+1
198 */
199 mpi_set( r1, x );
200 if( r1->nlimbs > k+1 ) /* quick modulo operation */
201 r1->nlimbs = k+1;
202 mpi_mul( r2, r2, m );
203 if( r2->nlimbs > k+1 ) /* quick modulo operation */
204 r2->nlimbs = k+1;
205 mpi_sub( r, r1, r2 );
206
207 if( mpi_is_neg( r ) ) {
208 gcry_mpi_t tmp;
209
210 tmp = mpi_alloc( k + 2 );
211 mpi_set_ui( tmp, 1 );
212 mpi_lshift_limbs( tmp, k+1 );
213 mpi_add( r, r, tmp );
214 mpi_free(tmp);
215 }
216
217 /* 4. while r >= m do r = r - m */
218 while( mpi_cmp( r, m ) >= 0 )
219 mpi_sub( r, r, m );
220
221 return 0;
222}
223#endif /* USE_BARRETT */
224
diff --git a/pwmanager/libcrypt/mpi/mpi-mul.c b/pwmanager/libcrypt/mpi/mpi-mul.c
new file mode 100644
index 0000000..23beee0
--- a/dev/null
+++ b/pwmanager/libcrypt/mpi/mpi-mul.c
@@ -0,0 +1,220 @@
1/* mpi-mul.c - MPI functions
2 * Copyright (C) 1994, 1996, 1998, 2001, 2002, 2003 Free Software Foundation, Inc.
3 *
4 * This file is part of Libgcrypt.
5 *
6 * Libgcrypt is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License as
8 * published by the Free Software Foundation; either version 2.1 of
9 * the License, or (at your option) any later version.
10 *
11 * Libgcrypt is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19 *
20 * Note: This code is heavily based on the GNU MP Library.
21 * Actually it's the same code with only minor changes in the
22 * way the data is stored; this is to support the abstraction
23 * of an optional secure memory allocation which may be used
24 * to avoid revealing of sensitive data due to paging etc.
25 */
26
27#include <config.h>
28#include <stdio.h>
29#include <stdlib.h>
30#include "mpi-internal.h"
31
32
33void
34gcry_mpi_mul_ui( gcry_mpi_t prod, gcry_mpi_t mult, unsigned long small_mult )
35{
36 mpi_size_t size, prod_size;
37 mpi_ptr_t prod_ptr;
38 mpi_limb_t cy;
39 int sign;
40
41 size = mult->nlimbs;
42 sign = mult->sign;
43
44 if( !size || !small_mult ) {
45 prod->nlimbs = 0;
46 prod->sign = 0;
47 return;
48 }
49
50 prod_size = size + 1;
51 if( prod->alloced < prod_size )
52 mpi_resize( prod, prod_size );
53 prod_ptr = prod->d;
54
55 cy = _gcry_mpih_mul_1( prod_ptr, mult->d, size, (mpi_limb_t)small_mult );
56 if( cy )
57 prod_ptr[size++] = cy;
58 prod->nlimbs = size;
59 prod->sign = sign;
60}
61
62
63void
64_gcry_mpi_mul_2exp( gcry_mpi_t w, gcry_mpi_t u, unsigned long cnt)
65{
66 mpi_size_t usize, wsize, limb_cnt;
67 mpi_ptr_t wp;
68 mpi_limb_t wlimb;
69 int usign, wsign;
70
71 usize = u->nlimbs;
72 usign = u->sign;
73
74 if( !usize ) {
75 w->nlimbs = 0;
76 w->sign = 0;
77 return;
78 }
79
80 limb_cnt = cnt / BITS_PER_MPI_LIMB;
81 wsize = usize + limb_cnt + 1;
82 if( w->alloced < wsize )
83 mpi_resize(w, wsize );
84 wp = w->d;
85 wsize = usize + limb_cnt;
86 wsign = usign;
87
88 cnt %= BITS_PER_MPI_LIMB;
89 if( cnt ) {
90 wlimb = _gcry_mpih_lshift( wp + limb_cnt, u->d, usize, cnt );
91 if( wlimb ) {
92 wp[wsize] = wlimb;
93 wsize++;
94 }
95 }
96 else {
97 MPN_COPY_DECR( wp + limb_cnt, u->d, usize );
98 }
99
100 /* Zero all whole limbs at low end. Do it here and not before calling
101 * mpn_lshift, not to lose for U == W. */
102 MPN_ZERO( wp, limb_cnt );
103
104 w->nlimbs = wsize;
105 w->sign = wsign;
106}
107
108
109void
110gcry_mpi_mul_2exp( gcry_mpi_t w, gcry_mpi_t u, unsigned long cnt)
111{
112 _gcry_mpi_mul_2exp (w, u, cnt);
113}
114
115
116void
117gcry_mpi_mul( gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v)
118{
119 mpi_size_t usize, vsize, wsize;
120 mpi_ptr_t up, vp, wp;
121 mpi_limb_t cy;
122 int usign, vsign, usecure, vsecure, sign_product;
123 int assign_wp=0;
124 mpi_ptr_t tmp_limb=NULL;
125 unsigned int tmp_limb_nlimbs = 0;
126
127 if( u->nlimbs < v->nlimbs ) { /* Swap U and V. */
128 usize = v->nlimbs;
129 usign = v->sign;
130 usecure = mpi_is_secure(v);
131 up = v->d;
132 vsize = u->nlimbs;
133 vsign = u->sign;
134 vsecure = mpi_is_secure(u);
135 vp = u->d;
136 }
137 else {
138 usize = u->nlimbs;
139 usign = u->sign;
140 usecure = mpi_is_secure(u);
141 up = u->d;
142 vsize = v->nlimbs;
143 vsign = v->sign;
144 vsecure = mpi_is_secure(v);
145 vp = v->d;
146 }
147 sign_product = usign ^ vsign;
148 wp = w->d;
149
150 /* Ensure W has space enough to store the result. */
151 wsize = usize + vsize;
152 if ( !mpi_is_secure (w) && (mpi_is_secure (u) || mpi_is_secure (v)) ) {
153 /* w is not allocated in secure space but u or v is. To make sure
154 * that no temporray results are stored in w, we temporary use
155 * a newly allocated limb space for w */
156 wp = mpi_alloc_limb_space( wsize, 1 );
157 assign_wp = 2; /* mark it as 2 so that we can later copy it back to
158 * mormal memory */
159 }
160 else if( w->alloced < wsize ) {
161 if( wp == up || wp == vp ) {
162 wp = mpi_alloc_limb_space( wsize, mpi_is_secure(w) );
163 assign_wp = 1;
164 }
165 else {
166 mpi_resize(w, wsize );
167 wp = w->d;
168 }
169 }
170 else { /* Make U and V not overlap with W.*/
171 if( wp == up ) {
172 /* W and U are identical. Allocate temporary space for U.*/
173 tmp_limb_nlimbs = usize;
174 up = tmp_limb = mpi_alloc_limb_space( usize, usecure );
175 /* Is V identical too? Keep it identical with U. */
176 if( wp == vp )
177 vp = up;
178 /* Copy to the temporary space. */
179 MPN_COPY( up, wp, usize );
180 }
181 else if( wp == vp ) {
182 /* W and V are identical. Allocate temporary space for V.*/
183 tmp_limb_nlimbs = vsize;
184 vp = tmp_limb = mpi_alloc_limb_space( vsize, vsecure );
185 /* Copy to the temporary space. */
186 MPN_COPY( vp, wp, vsize );
187 }
188 }
189
190 if( !vsize )
191 wsize = 0;
192 else {
193 cy = _gcry_mpih_mul( wp, up, usize, vp, vsize );
194 wsize -= cy? 0:1;
195 }
196
197 if( assign_wp ) {
198 if (assign_wp == 2) {
199 /* copy the temp wp from secure memory back to normal memory */
200 mpi_ptr_t tmp_wp = mpi_alloc_limb_space (wsize, 0);
201 MPN_COPY (tmp_wp, wp, wsize);
202 _gcry_mpi_free_limb_space (wp, 0);
203 wp = tmp_wp;
204 }
205 _gcry_mpi_assign_limb_space( w, wp, wsize );
206 }
207 w->nlimbs = wsize;
208 w->sign = sign_product;
209 if( tmp_limb )
210 _gcry_mpi_free_limb_space (tmp_limb, tmp_limb_nlimbs);
211}
212
213
214void
215gcry_mpi_mulm( gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m)
216{
217 gcry_mpi_mul(w, u, v);
218 _gcry_mpi_fdiv_r( w, w, m );
219}
220
diff --git a/pwmanager/libcrypt/mpi/mpi-pow.c b/pwmanager/libcrypt/mpi/mpi-pow.c
new file mode 100644
index 0000000..61a115f
--- a/dev/null
+++ b/pwmanager/libcrypt/mpi/mpi-pow.c
@@ -0,0 +1,302 @@
1/* mpi-pow.c - MPI functions
2 * Copyright (C) 1994, 1996, 1998, 2000, 2002, 2003 Free Software Foundation, Inc.
3 *
4 * This file is part of Libgcrypt.
5 *
6 * Libgcrypt is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License as
8 * published by the Free Software Foundation; either version 2.1 of
9 * the License, or (at your option) any later version.
10 *
11 * Libgcrypt is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19 *
20 * Note: This code is heavily based on the GNU MP Library.
21 * Actually it's the same code with only minor changes in the
22 * way the data is stored; this is to support the abstraction
23 * of an optional secure memory allocation which may be used
24 * to avoid revealing of sensitive data due to paging etc.
25 */
26
27#include <config.h>
28#include <stdio.h>
29#include <stdlib.h>
30#include <string.h>
31#include "mpi-internal.h"
32#include "longlong.h"
33#include <assert.h>
34
35
36/****************
37 * RES = BASE ^ EXPO mod MOD
38 */
39void
40gcry_mpi_powm( gcry_mpi_t res, gcry_mpi_t base, gcry_mpi_t expo, gcry_mpi_t mod)
41{
42 mpi_ptr_t rp, ep, mp, bp;
43 mpi_size_t esize, msize, bsize, rsize;
44 int esign, msign, bsign, rsign;
45 int esec, msec, bsec, rsec;
46 mpi_size_t size;
47 int mod_shift_cnt;
48 int negative_result;
49 mpi_ptr_t mp_marker=NULL, bp_marker=NULL, ep_marker=NULL;
50 mpi_ptr_t xp_marker=NULL;
51 unsigned int mp_nlimbs = 0, bp_nlimbs = 0, ep_nlimbs = 0;
52 unsigned int xp_nlimbs = 0;
53 int assign_rp = 0;
54 mpi_ptr_t tspace = NULL;
55 mpi_size_t tsize=0; /* to avoid compiler warning */
56 /* fixme: we should check that the warning is void*/
57
58 esize = expo->nlimbs;
59 msize = mod->nlimbs;
60 size = 2 * msize;
61 esign = expo->sign;
62 msign = mod->sign;
63
64 esec = mpi_is_secure(expo);
65 msec = mpi_is_secure(mod);
66 bsec = mpi_is_secure(base);
67 rsec = mpi_is_secure(res);
68
69 rp = res->d;
70 ep = expo->d;
71
72 if( !msize )
73 msize = 1 / msize; /* provoke a signal */
74
75 if( !esize ) {
76 /* Exponent is zero, result is 1 mod MOD, i.e., 1 or 0
77 * depending on if MOD equals 1. */
78 rp[0] = 1;
79 res->nlimbs = (msize == 1 && mod->d[0] == 1) ? 0 : 1;
80 res->sign = 0;
81 goto leave;
82 }
83
84 /* Normalize MOD (i.e. make its most significant bit set) as required by
85 * mpn_divrem. This will make the intermediate values in the calculation
86 * slightly larger, but the correct result is obtained after a final
87 * reduction using the original MOD value.*/
88 mp_nlimbs = msec? msize:0;
89 mp = mp_marker = mpi_alloc_limb_space(msize, msec);
90 count_leading_zeros( mod_shift_cnt, mod->d[msize-1] );
91 if( mod_shift_cnt )
92 _gcry_mpih_lshift( mp, mod->d, msize, mod_shift_cnt );
93 else
94 MPN_COPY( mp, mod->d, msize );
95
96 bsize = base->nlimbs;
97 bsign = base->sign;
98 if( bsize > msize ) { /* The base is larger than the module. Reduce it. */
99 /* Allocate (BSIZE + 1) with space for remainder and quotient.
100 * (The quotient is (bsize - msize + 1) limbs.) */
101 bp_nlimbs = bsec ? (bsize + 1):0;
102 bp = bp_marker = mpi_alloc_limb_space( bsize + 1, bsec );
103 MPN_COPY( bp, base->d, bsize );
104 /* We don't care about the quotient, store it above the remainder,
105 * at BP + MSIZE. */
106 _gcry_mpih_divrem( bp + msize, 0, bp, bsize, mp, msize );
107 bsize = msize;
108 /* Canonicalize the base, since we are going to multiply with it
109 * quite a few times. */
110 MPN_NORMALIZE( bp, bsize );
111 }
112 else
113 bp = base->d;
114
115 if( !bsize ) {
116 res->nlimbs = 0;
117 res->sign = 0;
118 goto leave;
119 }
120
121 if( res->alloced < size ) {
122 /* We have to allocate more space for RES. If any of the input
123 * parameters are identical to RES, defer deallocation of the old
124 * space. */
125 if( rp == ep || rp == mp || rp == bp ) {
126 rp = mpi_alloc_limb_space( size, rsec );
127 assign_rp = 1;
128 }
129 else {
130 mpi_resize( res, size );
131 rp = res->d;
132 }
133 }
134 else { /* Make BASE, EXPO and MOD not overlap with RES. */
135 if( rp == bp ) {
136 /* RES and BASE are identical. Allocate temp. space for BASE. */
137 assert( !bp_marker );
138 bp_nlimbs = bsec? bsize:0;
139 bp = bp_marker = mpi_alloc_limb_space( bsize, bsec );
140 MPN_COPY(bp, rp, bsize);
141 }
142 if( rp == ep ) {
143 /* RES and EXPO are identical. Allocate temp. space for EXPO. */
144 ep_nlimbs = esec? esize:0;
145 ep = ep_marker = mpi_alloc_limb_space( esize, esec );
146 MPN_COPY(ep, rp, esize);
147 }
148 if( rp == mp ) {
149 /* RES and MOD are identical. Allocate temporary space for MOD.*/
150 assert( !mp_marker );
151 mp_nlimbs = msec?msize:0;
152 mp = mp_marker = mpi_alloc_limb_space( msize, msec );
153 MPN_COPY(mp, rp, msize);
154 }
155 }
156
157 MPN_COPY( rp, bp, bsize );
158 rsize = bsize;
159 rsign = bsign;
160
161 {
162 mpi_size_t i;
163 mpi_ptr_t xp;
164 int c;
165 mpi_limb_t e;
166 mpi_limb_t carry_limb;
167 struct karatsuba_ctx karactx;
168
169 xp_nlimbs = msec? (2 * (msize + 1)):0;
170 xp = xp_marker = mpi_alloc_limb_space( 2 * (msize + 1), msec );
171
172 memset( &karactx, 0, sizeof karactx );
173 negative_result = (ep[0] & 1) && base->sign;
174
175 i = esize - 1;
176 e = ep[i];
177 count_leading_zeros (c, e);
178 e = (e << c) << 1; /* shift the expo bits to the left, lose msb */
179 c = BITS_PER_MPI_LIMB - 1 - c;
180
181 /* Main loop.
182 *
183 * Make the result be pointed to alternately by XP and RP. This
184 * helps us avoid block copying, which would otherwise be necessary
185 * with the overlap restrictions of _gcry_mpih_divmod. With 50% probability
186 * the result after this loop will be in the area originally pointed
187 * by RP (==RES->d), and with 50% probability in the area originally
188 * pointed to by XP.
189 */
190
191 for(;;) {
192 while( c ) {
193 mpi_ptr_t tp;
194 mpi_size_t xsize;
195
196 /*mpih_mul_n(xp, rp, rp, rsize);*/
197 if( rsize < KARATSUBA_THRESHOLD )
198 _gcry_mpih_sqr_n_basecase( xp, rp, rsize );
199 else {
200 if( !tspace ) {
201 tsize = 2 * rsize;
202 tspace = mpi_alloc_limb_space( tsize, 0 );
203 }
204 else if( tsize < (2*rsize) ) {
205 _gcry_mpi_free_limb_space (tspace, 0);
206 tsize = 2 * rsize;
207 tspace = mpi_alloc_limb_space( tsize, 0 );
208 }
209 _gcry_mpih_sqr_n( xp, rp, rsize, tspace );
210 }
211
212 xsize = 2 * rsize;
213 if( xsize > msize ) {
214 _gcry_mpih_divrem(xp + msize, 0, xp, xsize, mp, msize);
215 xsize = msize;
216 }
217
218 tp = rp; rp = xp; xp = tp;
219 rsize = xsize;
220
221 if( (mpi_limb_signed_t)e < 0 ) {
222 /*mpih_mul( xp, rp, rsize, bp, bsize );*/
223 if( bsize < KARATSUBA_THRESHOLD ) {
224 _gcry_mpih_mul( xp, rp, rsize, bp, bsize );
225 }
226 else {
227 _gcry_mpih_mul_karatsuba_case(
228 xp, rp, rsize, bp, bsize, &karactx );
229 }
230
231 xsize = rsize + bsize;
232 if( xsize > msize ) {
233 _gcry_mpih_divrem(xp + msize, 0, xp, xsize, mp, msize);
234 xsize = msize;
235 }
236
237 tp = rp; rp = xp; xp = tp;
238 rsize = xsize;
239 }
240 e <<= 1;
241 c--;
242 }
243
244 i--;
245 if( i < 0 )
246 break;
247 e = ep[i];
248 c = BITS_PER_MPI_LIMB;
249 }
250
251 /* We shifted MOD, the modulo reduction argument, left MOD_SHIFT_CNT
252 * steps. Adjust the result by reducing it with the original MOD.
253 *
254 * Also make sure the result is put in RES->d (where it already
255 * might be, see above).
256 */
257 if( mod_shift_cnt ) {
258 carry_limb = _gcry_mpih_lshift( res->d, rp, rsize, mod_shift_cnt);
259 rp = res->d;
260 if( carry_limb ) {
261 rp[rsize] = carry_limb;
262 rsize++;
263 }
264 }
265 else {
266 MPN_COPY( res->d, rp, rsize);
267 rp = res->d;
268 }
269
270 if( rsize >= msize ) {
271 _gcry_mpih_divrem(rp + msize, 0, rp, rsize, mp, msize);
272 rsize = msize;
273 }
274
275 /* Remove any leading zero words from the result. */
276 if( mod_shift_cnt )
277 _gcry_mpih_rshift( rp, rp, rsize, mod_shift_cnt);
278 MPN_NORMALIZE (rp, rsize);
279
280 _gcry_mpih_release_karatsuba_ctx( &karactx );
281 }
282
283 if( negative_result && rsize ) {
284 if( mod_shift_cnt )
285 _gcry_mpih_rshift( mp, mp, msize, mod_shift_cnt);
286 _gcry_mpih_sub( rp, mp, msize, rp, rsize);
287 rsize = msize;
288 rsign = msign;
289 MPN_NORMALIZE(rp, rsize);
290 }
291 res->nlimbs = rsize;
292 res->sign = rsign;
293
294 leave:
295 if( assign_rp ) _gcry_mpi_assign_limb_space( res, rp, size );
296 if( mp_marker ) _gcry_mpi_free_limb_space( mp_marker, mp_nlimbs );
297 if( bp_marker ) _gcry_mpi_free_limb_space( bp_marker, bp_nlimbs );
298 if( ep_marker ) _gcry_mpi_free_limb_space( ep_marker, ep_nlimbs );
299 if( xp_marker ) _gcry_mpi_free_limb_space( xp_marker, xp_nlimbs );
300 if( tspace ) _gcry_mpi_free_limb_space( tspace, 0 );
301}
302
diff --git a/pwmanager/libcrypt/mpi/mpi-scan.c b/pwmanager/libcrypt/mpi/mpi-scan.c
new file mode 100644
index 0000000..90699cd
--- a/dev/null
+++ b/pwmanager/libcrypt/mpi/mpi-scan.c
@@ -0,0 +1,132 @@
1/* mpi-scan.c - MPI functions
2 *Copyright (C) 1998, 2001, 2002, 2003 Free Software Foundation, Inc.
3 *
4 * This file is part of Libgcrypt.
5 *
6 * Libgcrypt is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License as
8 * published by the Free Software Foundation; either version 2.1 of
9 * the License, or (at your option) any later version.
10 *
11 * Libgcrypt is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19 */
20
21#include <config.h>
22#include <stdio.h>
23#include <stdlib.h>
24#include "mpi-internal.h"
25#include "longlong.h"
26
27/****************
28 * Scan through an mpi and return byte for byte. a -1 is returned to indicate
29 * the end of the mpi. Scanning is done from the lsb to the msb, returned
30 * values are in the range of 0 .. 255.
31 *
32 * FIXME: This code is VERY ugly!
33 */
34int
35_gcry_mpi_getbyte( gcry_mpi_t a, unsigned idx )
36{
37 int i, j;
38 unsigned n;
39 mpi_ptr_t ap;
40 mpi_limb_t limb;
41
42 ap = a->d;
43 for(n=0,i=0; i < a->nlimbs; i++ ) {
44 limb = ap[i];
45 for( j=0; j < BYTES_PER_MPI_LIMB; j++, n++ )
46 if( n == idx )
47 return (limb >> j*8) & 0xff;
48 }
49 return -1;
50}
51
52
53/****************
54 * Put a value at position IDX into A. idx counts from lsb to msb
55 */
56void
57_gcry_mpi_putbyte( gcry_mpi_t a, unsigned idx, int xc )
58{
59 int i, j;
60 unsigned n;
61 mpi_ptr_t ap;
62 mpi_limb_t limb, c;
63
64 c = xc & 0xff;
65 ap = a->d;
66 for(n=0,i=0; i < a->alloced; i++ ) {
67 limb = ap[i];
68 for( j=0; j < BYTES_PER_MPI_LIMB; j++, n++ )
69 if( n == idx ) {
70 #if BYTES_PER_MPI_LIMB == 4
71 if( j == 0 )
72 limb = (limb & 0xffffff00) | c;
73 else if( j == 1 )
74 limb = (limb & 0xffff00ff) | (c<<8);
75 else if( j == 2 )
76 limb = (limb & 0xff00ffff) | (c<<16);
77 else
78 limb = (limb & 0x00ffffff) | (c<<24);
79 #elif BYTES_PER_MPI_LIMB == 8
80 if( j == 0 )
81 limb = (limb & 0xffffffffffffff00) | c;
82 else if( j == 1 )
83 limb = (limb & 0xffffffffffff00ff) | (c<<8);
84 else if( j == 2 )
85 limb = (limb & 0xffffffffff00ffff) | (c<<16);
86 else if( j == 3 )
87 limb = (limb & 0xffffffff00ffffff) | (c<<24);
88 else if( j == 4 )
89 limb = (limb & 0xffffff00ffffffff) | (c<<32);
90 else if( j == 5 )
91 limb = (limb & 0xffff00ffffffffff) | (c<<40);
92 else if( j == 6 )
93 limb = (limb & 0xff00ffffffffffff) | (c<<48);
94 else
95 limb = (limb & 0x00ffffffffffffff) | (c<<56);
96 #else
97 #error please enhance this function, its ugly - i know.
98 #endif
99 if( a->nlimbs <= i )
100 a->nlimbs = i+1;
101 ap[i] = limb;
102 return;
103 }
104 }
105 abort(); /* index out of range */
106}
107
108
109/****************
110 * Count the number of zerobits at the low end of A
111 */
112unsigned
113_gcry_mpi_trailing_zeros( gcry_mpi_t a )
114{
115 unsigned n, count = 0;
116
117 for(n=0; n < a->nlimbs; n++ ) {
118 if( a->d[n] ) {
119 unsigned nn;
120 mpi_limb_t alimb = a->d[n];
121
122 count_trailing_zeros( nn, alimb );
123 count += nn;
124 break;
125 }
126 count += BITS_PER_MPI_LIMB;
127 }
128 return count;
129
130}
131
132
diff --git a/pwmanager/libcrypt/mpi/mpi.pro b/pwmanager/libcrypt/mpi/mpi.pro
new file mode 100644
index 0000000..cf750ec
--- a/dev/null
+++ b/pwmanager/libcrypt/mpi/mpi.pro
@@ -0,0 +1,42 @@
1######################################################################
2# Automatically generated by qmake (1.07a) Tue Oct 19 15:37:52 2004
3######################################################################
4
5TEMPLATE = lib
6CONFIG += staticlib
7DEPENDPATH += generic
8INCLUDEPATH += . .. ../crypt
9OBJECTS_DIR = obj/$(PLATFORM)
10MOC_DIR = moc/$(PLATFORM)
11DESTDIR= ../$(PLATFORM)
12 TARGET = kpmicrompi
13# Input
14HEADERS += asm-syntax.h \
15 longlong.h \
16 generic/mpi-asm-defs.h \
17 mpi-inline.h \
18 mpi-internal.h \
19 sysdep.h
20SOURCES += mpi-add.c \
21 mpi-bit.c \
22 mpi-cmp.c \
23 mpi-div.c \
24 mpi-gcd.c \
25 mpi-inline.c \
26 mpi-inv.c \
27 mpi-mpow.c \
28 mpi-mul.c \
29 mpi-pow.c \
30 mpi-scan.c \
31 mpicoder.c \
32 mpih-div.c \
33 mpih-mul.c \
34 mpiutil.c \
35 generic/mpih-add1.c \
36 generic/mpih-lshift.c \
37 generic/mpih-mul1.c \
38 generic/mpih-mul2.c \
39 generic/mpih-mul3.c \
40 generic/mpih-rshift.c \
41 generic/mpih-sub1.c \
42 generic/udiv-w-sdiv.c
diff --git a/pwmanager/libcrypt/mpi/mpicoder.c b/pwmanager/libcrypt/mpi/mpicoder.c
new file mode 100644
index 0000000..d501fe4
--- a/dev/null
+++ b/pwmanager/libcrypt/mpi/mpicoder.c
@@ -0,0 +1,643 @@
1/* mpicoder.c - Coder for the external representation of MPIs
2 * Copyright (C) 1998, 1999, 2000, 2001, 2002,
3 * 2003 Free Software Foundation, Inc.
4 *
5 * This file is part of Libgcrypt.
6 *
7 * Libgcrypt is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * Libgcrypt is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20 */
21
22#include <config.h>
23#include <stdio.h>
24#include <string.h>
25#include <stdlib.h>
26#include <assert.h>
27
28#include "mpi-internal.h"
29#include "g10lib.h"
30
31#define MAX_EXTERN_MPI_BITS 16384
32
33
34static gcry_mpi_t
35mpi_read_from_buffer(byte *buffer, unsigned *ret_nread, int secure)
36{
37 int i, j;
38 unsigned int nbits, nbytes, nlimbs, nread=0;
39 mpi_limb_t a;
40 gcry_mpi_t val = MPI_NULL;
41
42 if( *ret_nread < 2 )
43 goto leave;
44 nbits = buffer[0] << 8 | buffer[1];
45 if( nbits > MAX_EXTERN_MPI_BITS ) {
46 log_error("mpi too large (%u bits)\n", nbits);
47 goto leave;
48 }
49 else if( !nbits ) {
50 log_error("an mpi of size 0 is not allowed\n");
51 goto leave;
52 }
53 buffer += 2;
54 nread = 2;
55
56 nbytes = (nbits+7) / 8;
57 nlimbs = (nbytes+BYTES_PER_MPI_LIMB-1) / BYTES_PER_MPI_LIMB;
58 val = secure? mpi_alloc_secure( nlimbs )
59 : mpi_alloc( nlimbs );
60 i = BYTES_PER_MPI_LIMB - nbytes % BYTES_PER_MPI_LIMB;
61 i %= BYTES_PER_MPI_LIMB;
62 j= val->nlimbs = nlimbs;
63 val->sign = 0;
64 for( ; j > 0; j-- ) {
65 a = 0;
66 for(; i < BYTES_PER_MPI_LIMB; i++ ) {
67 if( ++nread > *ret_nread )
68 log_bug("mpi larger than buffer");
69 a <<= 8;
70 a |= *buffer++;
71 }
72 i = 0;
73 val->d[j-1] = a;
74 }
75
76 leave:
77 *ret_nread = nread;
78 return val;
79}
80
81
82/****************
83 * Make an mpi from a hex character string.
84 */
85static int
86mpi_fromstr(gcry_mpi_t val, const char *str)
87{
88 int sign=0, prepend_zero=0, i, j, c, c1, c2;
89 unsigned nbits, nbytes, nlimbs;
90 mpi_limb_t a;
91
92 if( *str == '-' ) {
93 sign = 1;
94 str++;
95 }
96
97 /* skip optional hex prefix */
98 if ( *str == '0' && str[1] == 'x' ) {
99 str += 2;
100 }
101
102 nbits = strlen(str)*4;
103 if( nbits % 8 )
104 prepend_zero = 1;
105 nbytes = (nbits+7) / 8;
106 nlimbs = (nbytes+BYTES_PER_MPI_LIMB-1) / BYTES_PER_MPI_LIMB;
107 if( val->alloced < nlimbs )
108 mpi_resize(val, nlimbs );
109 i = BYTES_PER_MPI_LIMB - nbytes % BYTES_PER_MPI_LIMB;
110 i %= BYTES_PER_MPI_LIMB;
111 j= val->nlimbs = nlimbs;
112 val->sign = sign;
113 for( ; j > 0; j-- ) {
114 a = 0;
115 for(; i < BYTES_PER_MPI_LIMB; i++ ) {
116 if( prepend_zero ) {
117 c1 = '0';
118 prepend_zero = 0;
119 }
120 else
121 c1 = *str++;
122 assert(c1);
123 c2 = *str++;
124 assert(c2);
125 if( c1 >= '0' && c1 <= '9' )
126 c = c1 - '0';
127 else if( c1 >= 'a' && c1 <= 'f' )
128 c = c1 - 'a' + 10;
129 else if( c1 >= 'A' && c1 <= 'F' )
130 c = c1 - 'A' + 10;
131 else {
132 mpi_clear(val);
133 return 1;
134 }
135 c <<= 4;
136 if( c2 >= '0' && c2 <= '9' )
137 c |= c2 - '0';
138 else if( c2 >= 'a' && c2 <= 'f' )
139 c |= c2 - 'a' + 10;
140 else if( c2 >= 'A' && c2 <= 'F' )
141 c |= c2 - 'A' + 10;
142 else {
143 mpi_clear(val);
144 return 1;
145 }
146 a <<= 8;
147 a |= c;
148 }
149 i = 0;
150 val->d[j-1] = a;
151 }
152
153 return 0;
154}
155
156
157/* Dump the value of A in a format suitable for debugging to
158 Libgcrypt's logging stream. Note that one leading space but no
159 trailing space or linefeed will be printed. It is okay to pass
160 NULL for A. */
161void
162gcry_mpi_dump (const gcry_mpi_t a)
163{
164 int i;
165
166 log_printf (" ");
167 if (!a)
168 log_printf ("[MPI_NULL]");
169 else
170 {
171 if (a->sign)
172 log_printf ( "-");
173#if BYTES_PER_MPI_LIMB == 2
174# define X "4"
175#elif BYTES_PER_MPI_LIMB == 4
176# define X "8"
177#elif BYTES_PER_MPI_LIMB == 8
178# define X "16"
179#elif BYTES_PER_MPI_LIMB == 16
180# define X "32"
181#else
182# error please define the format here
183#endif
184 for (i=a->nlimbs; i > 0 ; i-- )
185 {
186 log_printf (i != a->nlimbs? "%0" X "lX":"%lX", (ulong)a->d[i-1]);
187 }
188#undef X
189 if (!a->nlimbs)
190 log_printf ("0");
191 }
192}
193
194/* Convience function used internally. */
195void
196_gcry_log_mpidump (const char *text, gcry_mpi_t a)
197{
198 log_printf ("%s:", text);
199 gcry_mpi_dump (a);
200 log_printf ("\n");
201}
202
203
204/****************
205 * Return an m_alloced buffer with the MPI (msb first).
206 * NBYTES receives the length of this buffer. Caller must free the
207 * return string (This function does return a 0 byte buffer with NBYTES
208 * set to zero if the value of A is zero. If sign is not NULL, it will
209 * be set to the sign of the A.
210 */
211static byte *
212do_get_buffer( gcry_mpi_t a, unsigned *nbytes, int *sign, int force_secure )
213{
214 byte *p, *buffer;
215 mpi_limb_t alimb;
216 int i;
217 size_t n;
218
219 if( sign )
220 *sign = a->sign;
221 *nbytes = a->nlimbs * BYTES_PER_MPI_LIMB;
222 n = *nbytes? *nbytes:1; /* allocate at least one byte */
223 p = buffer = force_secure || mpi_is_secure(a) ? gcry_xmalloc_secure(n)
224 : gcry_xmalloc(n);
225
226 for(i=a->nlimbs-1; i >= 0; i-- ) {
227 alimb = a->d[i];
228#if BYTES_PER_MPI_LIMB == 4
229 *p++ = alimb >> 24;
230 *p++ = alimb >> 16;
231 *p++ = alimb >> 8;
232 *p++ = alimb ;
233#elif BYTES_PER_MPI_LIMB == 8
234 *p++ = alimb >> 56;
235 *p++ = alimb >> 48;
236 *p++ = alimb >> 40;
237 *p++ = alimb >> 32;
238 *p++ = alimb >> 24;
239 *p++ = alimb >> 16;
240 *p++ = alimb >> 8;
241 *p++ = alimb ;
242#else
243 #error please implement for this limb size.
244#endif
245 }
246
247 /* this is sub-optimal but we need to do the shift oepration because
248 * the caller has to free the returned buffer */
249 for(p=buffer; !*p && *nbytes; p++, --*nbytes )
250 ;
251 if( p != buffer )
252 memmove(buffer,p, *nbytes);
253 return buffer;
254}
255
256
257byte *
258_gcry_mpi_get_buffer( gcry_mpi_t a, unsigned *nbytes, int *sign )
259{
260 return do_get_buffer( a, nbytes, sign, 0 );
261}
262
263byte *
264_gcry_mpi_get_secure_buffer( gcry_mpi_t a, unsigned *nbytes, int *sign )
265{
266 return do_get_buffer( a, nbytes, sign, 1 );
267}
268
269/****************
270 * Use BUFFER to update MPI.
271 */
272void
273_gcry_mpi_set_buffer( gcry_mpi_t a, const byte *buffer, unsigned nbytes, int sign )
274{
275 const byte *p;
276 mpi_limb_t alimb;
277 int nlimbs;
278 int i;
279
280 nlimbs = (nbytes + BYTES_PER_MPI_LIMB - 1) / BYTES_PER_MPI_LIMB;
281 RESIZE_IF_NEEDED(a, nlimbs);
282 a->sign = sign;
283
284 for(i=0, p = buffer+nbytes-1; p >= buffer+BYTES_PER_MPI_LIMB; ) {
285#if BYTES_PER_MPI_LIMB == 4
286 alimb = *p-- ;
287 alimb |= *p-- << 8 ;
288 alimb |= *p-- << 16 ;
289 alimb |= *p-- << 24 ;
290#elif BYTES_PER_MPI_LIMB == 8
291 alimb = (mpi_limb_t)*p--;
292 alimb |= (mpi_limb_t)*p-- << 8 ;
293 alimb |= (mpi_limb_t)*p-- << 16 ;
294 alimb |= (mpi_limb_t)*p-- << 24 ;
295 alimb |= (mpi_limb_t)*p-- << 32 ;
296 alimb |= (mpi_limb_t)*p-- << 40 ;
297 alimb |= (mpi_limb_t)*p-- << 48 ;
298 alimb |= (mpi_limb_t)*p-- << 56 ;
299#else
300 #error please implement for this limb size.
301#endif
302 a->d[i++] = alimb;
303 }
304 if( p >= buffer ) {
305#if BYTES_PER_MPI_LIMB == 4
306 alimb = *p-- ;
307 if( p >= buffer ) alimb |= *p-- << 8 ;
308 if( p >= buffer ) alimb |= *p-- << 16 ;
309 if( p >= buffer ) alimb |= *p-- << 24 ;
310#elif BYTES_PER_MPI_LIMB == 8
311 alimb = (mpi_limb_t)*p-- ;
312 if( p >= buffer ) alimb |= (mpi_limb_t)*p-- <<8 ;
313 if( p >= buffer ) alimb |= (mpi_limb_t)*p-- << 16 ;
314 if( p >= buffer ) alimb |= (mpi_limb_t)*p-- << 24 ;
315 if( p >= buffer ) alimb |= (mpi_limb_t)*p-- << 32 ;
316 if( p >= buffer ) alimb |= (mpi_limb_t)*p-- << 40 ;
317 if( p >= buffer ) alimb |= (mpi_limb_t)*p-- << 48 ;
318 if( p >= buffer ) alimb |= (mpi_limb_t)*p-- << 56 ;
319#else
320 #error please implement for this limb size.
321#endif
322 a->d[i++] = alimb;
323 }
324 a->nlimbs = i;
325 assert( i == nlimbs );
326}
327
328
329
330/* Convert the external representation of an integer stored in BUFFER
331 with a length of BUFLEN into a newly create MPI returned in
332 RET_MPI. If NBYTES is not NULL, it will receive the number of
333 bytes actually scanned after a successful operation. */
334gcry_error_t
335gcry_mpi_scan( struct gcry_mpi **ret_mpi, enum gcry_mpi_format format,
336 const unsigned char *buffer, size_t buflen, size_t *nscanned )
337{
338 struct gcry_mpi *a = NULL;
339 unsigned int len;
340 int secure = (buffer && gcry_is_secure (buffer));
341
342 if (format == GCRYMPI_FMT_SSH)
343 len = 0;
344 else
345 len = buflen;
346
347 if( format == GCRYMPI_FMT_STD ) {
348 const byte *s = buffer;
349
350 a = secure? mpi_alloc_secure ((len+BYTES_PER_MPI_LIMB-1)
351 /BYTES_PER_MPI_LIMB)
352 : mpi_alloc ((len+BYTES_PER_MPI_LIMB-1)/BYTES_PER_MPI_LIMB);
353 if( len ) { /* not zero */
354 a->sign = *s & 0x80;
355 if( a->sign ) {
356 /* FIXME: we have to convert from 2compl to magnitude format */
357 mpi_free(a);
358 return gcry_error (GPG_ERR_INTERNAL);
359 }
360 else
361 _gcry_mpi_set_buffer( a, s, len, 0 );
362 }
363 if( ret_mpi ) {
364 mpi_normalize ( a );
365 *ret_mpi = a;
366 }
367 else
368 mpi_free(a);
369 return gcry_error (GPG_ERR_NO_ERROR);
370 }
371 else if( format == GCRYMPI_FMT_USG ) {
372 a = secure? mpi_alloc_secure ((len+BYTES_PER_MPI_LIMB-1)
373 /BYTES_PER_MPI_LIMB)
374 : mpi_alloc ((len+BYTES_PER_MPI_LIMB-1)/BYTES_PER_MPI_LIMB);
375
376 if( len ) /* not zero */
377 _gcry_mpi_set_buffer( a, buffer, len, 0 );
378 if( ret_mpi ) {
379 mpi_normalize ( a );
380 *ret_mpi = a;
381 }
382 else
383 mpi_free(a);
384 return gcry_error (GPG_ERR_NO_ERROR);
385 }
386 else if( format == GCRYMPI_FMT_PGP ) {
387 a = mpi_read_from_buffer( (char*)buffer, &len, secure);
388 if( nscanned )
389 *nscanned = len;
390 if( ret_mpi && a ) {
391 mpi_normalize ( a );
392 *ret_mpi = a;
393 }
394 else
395 mpi_free(a);
396 return gcry_error (a ? GPG_ERR_NO_ERROR : GPG_ERR_INV_OBJ);
397 }
398 else if( format == GCRYMPI_FMT_SSH ) {
399 const byte *s = buffer;
400 size_t n;
401
402 if( len && len < 4 )
403 return gcry_error (GPG_ERR_TOO_SHORT);
404 n = s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3];
405 s += 4;
406 if (len)
407 len -= 4;
408 if( len && n > len )
409 return gcry_error (GPG_ERR_TOO_LARGE); /* or should it be
410 too_short */
411
412 a = secure? mpi_alloc_secure ((n+BYTES_PER_MPI_LIMB-1)
413 /BYTES_PER_MPI_LIMB)
414 : mpi_alloc ((n+BYTES_PER_MPI_LIMB-1)/BYTES_PER_MPI_LIMB);
415 if( n ) { /* not zero */
416 a->sign = *s & 0x80;
417 if( a->sign ) {
418 /* FIXME: we have to convert from 2compl to magnitude format */
419 mpi_free(a);
420 return gcry_error (GPG_ERR_INTERNAL);
421 }
422 else
423 _gcry_mpi_set_buffer( a, s, n, 0 );
424 }
425 if( nscanned )
426 *nscanned = n+4;
427 if( ret_mpi ) {
428 mpi_normalize ( a );
429 *ret_mpi = a;
430 }
431 else
432 mpi_free(a);
433 return gcry_error (GPG_ERR_NO_ERROR);
434 }
435 else if( format == GCRYMPI_FMT_HEX ) {
436 if( buflen )
437 return gcry_error (GPG_ERR_INV_ARG); /* can only handle C
438 strings for now */
439 a = secure? mpi_alloc_secure (0) : mpi_alloc(0);
440 if( mpi_fromstr( a, buffer ) )
441 return gcry_error (GPG_ERR_INV_OBJ);
442 if( ret_mpi ) {
443 mpi_normalize ( a );
444 *ret_mpi = a;
445 }
446 else
447 mpi_free(a);
448 return gcry_error (GPG_ERR_NO_ERROR);
449 }
450 else
451 return gcry_error (GPG_ERR_INV_ARG);
452}
453
454/* Convert the big integer A into the external representation
455 described by FORMAT and store it in the provided BUFFER which has
456 been allocated by the user with a size of BUFLEN bytes. NWRITTEN
457 receives the actual length of the external representation unless it
458 has been passed as NULL. BUFFER may be NULL to query the required
459 length.*/
460gcry_error_t
461gcry_mpi_print( enum gcry_mpi_format format,
462 unsigned char *buffer, size_t buflen,
463 size_t *nwritten, struct gcry_mpi *a)
464{
465 unsigned int nbits = mpi_get_nbits(a);
466 size_t len;
467 size_t dummy_nwritten;
468
469 if (!nwritten)
470 nwritten = &dummy_nwritten;
471
472 len = buflen;
473 *nwritten = 0;
474 if( format == GCRYMPI_FMT_STD ) {
475 char *tmp;
476 int extra = 0;
477 unsigned int n;
478
479 if( a->sign )
480 return gcry_error (GPG_ERR_INTERNAL); /* can't handle it yet */
481
482 tmp = _gcry_mpi_get_buffer( a, &n, NULL );
483 if( n && (*tmp & 0x80) ) {
484 n++;
485 extra=1;
486 }
487
488 if (buffer && n > len) {
489 gcry_free(tmp);
490 return gcry_error (GPG_ERR_TOO_SHORT); /* the provided buffer is too short */
491 }
492 if( buffer ) {
493 byte *s = buffer;
494 if( extra )
495 *s++ = 0;
496
497 memcpy( s, tmp, n-extra );
498 }
499 gcry_free(tmp);
500 *nwritten = n;
501 return gcry_error (GPG_ERR_NO_ERROR);
502 }
503 else if( format == GCRYMPI_FMT_USG ) {
504 unsigned int n = (nbits + 7)/8;
505
506 /* we ignore the sign for this format */
507 /* FIXME: for performance reasons we should put this into
508 * mpi_aprint becuase we can then use the buffer directly */
509 if (buffer && n > len)
510 return gcry_error (GPG_ERR_TOO_SHORT); /* the provided buffer is too short */
511 if( buffer ) {
512 char *tmp;
513 tmp = _gcry_mpi_get_buffer( a, &n, NULL );
514 memcpy( buffer, tmp, n );
515 gcry_free(tmp);
516 }
517 *nwritten = n;
518 return gcry_error (GPG_ERR_NO_ERROR);
519 }
520 else if( format == GCRYMPI_FMT_PGP ) {
521 unsigned int n = (nbits + 7)/8;
522
523 if( a->sign )
524 return gcry_error (GPG_ERR_INV_ARG); /* pgp format can only handle unsigned */
525
526 if (buffer && n+2 > len)
527 return gcry_error (GPG_ERR_TOO_SHORT); /* the provided buffer is too short */
528 if( buffer ) {
529 char *tmp;
530 byte *s = buffer;
531 s[0] = nbits >> 8;
532 s[1] = nbits;
533
534 tmp = _gcry_mpi_get_buffer( a, &n, NULL );
535 memcpy( s+2, tmp, n );
536 gcry_free(tmp);
537 }
538 *nwritten = n+2;
539 return gcry_error (GPG_ERR_NO_ERROR);
540 }
541 else if( format == GCRYMPI_FMT_SSH ) {
542 char *tmp;
543 int extra = 0;
544 unsigned int n;
545
546 if( a->sign )
547 return gcry_error (GPG_ERR_INTERNAL); /* can't handle it yet */
548
549 tmp = _gcry_mpi_get_buffer( a, &n, NULL );
550 if( n && (*tmp & 0x80) ) {
551 n++;
552 extra=1;
553 }
554
555 if (buffer && n+4 > len) {
556 gcry_free(tmp);
557 return gcry_error (GPG_ERR_TOO_SHORT); /* the provided buffer is too short */
558 }
559 if( buffer ) {
560 byte *s = buffer;
561 *s++ = n >> 24;
562 *s++ = n >> 16;
563 *s++ = n >> 8;
564 *s++ = n;
565 if( extra )
566 *s++ = 0;
567
568 memcpy( s, tmp, n-extra );
569 }
570 gcry_free(tmp);
571 *nwritten = 4+n;
572 return gcry_error (GPG_ERR_NO_ERROR);
573 }
574 else if( format == GCRYMPI_FMT_HEX ) {
575 byte *tmp;
576 int i;
577 int extra = 0;
578 unsigned int n=0;
579
580 tmp = _gcry_mpi_get_buffer( a, &n, NULL );
581 if( !n || (*tmp & 0x80) )
582 extra=2;
583
584 if(buffer && 2*n + extra + !!a->sign + 1 > len) {
585 gcry_free(tmp);
586 return gcry_error (GPG_ERR_TOO_SHORT); /* the provided buffer is too short */
587 }
588 if( buffer ) {
589 byte *s = buffer;
590 if( a->sign )
591 *s++ = '-';
592 if( extra ) {
593 *s++ = '0';
594 *s++ = '0';
595 }
596
597 for(i=0; i < n; i++ ) {
598 unsigned int c = tmp[i];
599 *s++ = (c >> 4) < 10? '0'+(c>>4) : 'A'+(c>>4)-10 ;
600 c &= 15;
601 *s++ = c < 10? '0'+c : 'A'+c-10 ;
602 }
603 *s++ = 0;
604 *nwritten = s - buffer;
605 }
606 else {
607 *nwritten = 2*n + extra + !!a->sign + 1;
608 }
609 gcry_free(tmp);
610 return gcry_error (GPG_ERR_NO_ERROR);
611 }
612 else
613 return gcry_error (GPG_ERR_INV_ARG);
614}
615
616/****************
617 * Like gcry_mpi_print but this function allocates the buffer itself.
618 * The caller has to supply the address of a pointer. NWRITTEN may be
619 * NULL.
620 */
621gcry_error_t
622gcry_mpi_aprint( enum gcry_mpi_format format,
623 unsigned char **buffer, size_t *nwritten,
624 struct gcry_mpi *a )
625{
626 size_t n;
627 gcry_error_t rc;
628
629 *buffer = NULL;
630 rc = gcry_mpi_print( format, NULL, 0, &n, a );
631 if( rc )
632 return rc;
633 *buffer = mpi_is_secure(a) ? gcry_xmalloc_secure( n ) : gcry_xmalloc( n );
634 rc = gcry_mpi_print( format, *buffer, n, &n, a );
635 if( rc ) {
636 gcry_free(*buffer);
637 *buffer = NULL;
638 }
639 else if( nwritten )
640 *nwritten = n;
641 return rc;
642}
643
diff --git a/pwmanager/libcrypt/mpi/mpih-div.c b/pwmanager/libcrypt/mpi/mpih-div.c
new file mode 100644
index 0000000..e41e205
--- a/dev/null
+++ b/pwmanager/libcrypt/mpi/mpih-div.c
@@ -0,0 +1,535 @@
1/* mpih-div.c - MPI helper functions
2 * Copyright (C) 1994, 1996, 1998, 2000,
3 * 2001, 2002 Free Software Foundation, Inc.
4 *
5 * This file is part of Libgcrypt.
6 *
7 * Libgcrypt is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * Libgcrypt is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20 *
21 * Note: This code is heavily based on the GNU MP Library.
22 * Actually it's the same code with only minor changes in the
23 * way the data is stored; this is to support the abstraction
24 * of an optional secure memory allocation which may be used
25 * to avoid revealing of sensitive data due to paging etc.
26 */
27
28#include <config.h>
29#include <stdio.h>
30#include <stdlib.h>
31#include "mpi-internal.h"
32#include "longlong.h"
33
34#ifndef UMUL_TIME
35#define UMUL_TIME 1
36#endif
37#ifndef UDIV_TIME
38#define UDIV_TIME UMUL_TIME
39#endif
40
41/* FIXME: We should be using invert_limb (or invert_normalized_limb)
42 * here (not udiv_qrnnd).
43 */
44
45mpi_limb_t
46_gcry_mpih_mod_1(mpi_ptr_t dividend_ptr, mpi_size_t dividend_size,
47 mpi_limb_t divisor_limb)
48{
49 mpi_size_t i;
50 mpi_limb_t n1, n0, r;
51 int dummy;
52
53 /* Botch: Should this be handled at all? Rely on callers?*/
54 if( !dividend_size )
55 return 0;
56
57 /* If multiplication is much faster than division, and the
58 * dividend is large, pre-invert the divisor, and use
59 * only multiplications in the inner loop.
60 *
61 * This test should be read:
62 * Does it ever help to use udiv_qrnnd_preinv?
63 * && Does what we save compensate for the inversion overhead?
64 */
65 if( UDIV_TIME > (2 * UMUL_TIME + 6)
66 && (UDIV_TIME - (2 * UMUL_TIME + 6)) * dividend_size > UDIV_TIME ) {
67 int normalization_steps;
68
69 count_leading_zeros( normalization_steps, divisor_limb );
70 if( normalization_steps ) {
71 mpi_limb_t divisor_limb_inverted;
72
73 divisor_limb <<= normalization_steps;
74
75 /* Compute (2**2N - 2**N * DIVISOR_LIMB) / DIVISOR_LIMB. The
76 * result is a (N+1)-bit approximation to 1/DIVISOR_LIMB, with the
77 * most significant bit (with weight 2**N) implicit.
78 *
79 * Special case for DIVISOR_LIMB == 100...000.
80 */
81 if( !(divisor_limb << 1) )
82 divisor_limb_inverted = ~(mpi_limb_t)0;
83 else
84 udiv_qrnnd(divisor_limb_inverted, dummy,
85 -divisor_limb, 0, divisor_limb);
86
87 n1 = dividend_ptr[dividend_size - 1];
88 r = n1 >> (BITS_PER_MPI_LIMB - normalization_steps);
89
90 /* Possible optimization:
91 * if (r == 0
92 * && divisor_limb > ((n1 << normalization_steps)
93 * | (dividend_ptr[dividend_size - 2] >> ...)))
94 * ...one division less...
95 */
96 for( i = dividend_size - 2; i >= 0; i--) {
97 n0 = dividend_ptr[i];
98 UDIV_QRNND_PREINV(dummy, r, r,
99 ((n1 << normalization_steps)
100 | (n0 >> (BITS_PER_MPI_LIMB - normalization_steps))),
101 divisor_limb, divisor_limb_inverted);
102 n1 = n0;
103 }
104 UDIV_QRNND_PREINV(dummy, r, r,
105 n1 << normalization_steps,
106 divisor_limb, divisor_limb_inverted);
107 return r >> normalization_steps;
108 }
109 else {
110 mpi_limb_t divisor_limb_inverted;
111
112 /* Compute (2**2N - 2**N * DIVISOR_LIMB) / DIVISOR_LIMB. The
113 * result is a (N+1)-bit approximation to 1/DIVISOR_LIMB, with the
114 * most significant bit (with weight 2**N) implicit.
115 *
116 * Special case for DIVISOR_LIMB == 100...000.
117 */
118 if( !(divisor_limb << 1) )
119 divisor_limb_inverted = ~(mpi_limb_t)0;
120 else
121 udiv_qrnnd(divisor_limb_inverted, dummy,
122 -divisor_limb, 0, divisor_limb);
123
124 i = dividend_size - 1;
125 r = dividend_ptr[i];
126
127 if( r >= divisor_limb )
128 r = 0;
129 else
130 i--;
131
132 for( ; i >= 0; i--) {
133 n0 = dividend_ptr[i];
134 UDIV_QRNND_PREINV(dummy, r, r,
135 n0, divisor_limb, divisor_limb_inverted);
136 }
137 return r;
138 }
139 }
140 else {
141 if( UDIV_NEEDS_NORMALIZATION ) {
142 int normalization_steps;
143
144 count_leading_zeros(normalization_steps, divisor_limb);
145 if( normalization_steps ) {
146 divisor_limb <<= normalization_steps;
147
148 n1 = dividend_ptr[dividend_size - 1];
149 r = n1 >> (BITS_PER_MPI_LIMB - normalization_steps);
150
151 /* Possible optimization:
152 * if (r == 0
153 * && divisor_limb > ((n1 << normalization_steps)
154 * | (dividend_ptr[dividend_size - 2] >> ...)))
155 * ...one division less...
156 */
157 for(i = dividend_size - 2; i >= 0; i--) {
158 n0 = dividend_ptr[i];
159 udiv_qrnnd (dummy, r, r,
160 ((n1 << normalization_steps)
161 | (n0 >> (BITS_PER_MPI_LIMB - normalization_steps))),
162 divisor_limb);
163 n1 = n0;
164 }
165 udiv_qrnnd (dummy, r, r,
166 n1 << normalization_steps,
167 divisor_limb);
168 return r >> normalization_steps;
169 }
170 }
171 /* No normalization needed, either because udiv_qrnnd doesn't require
172 * it, or because DIVISOR_LIMB is already normalized. */
173 i = dividend_size - 1;
174 r = dividend_ptr[i];
175
176 if(r >= divisor_limb)
177 r = 0;
178 else
179 i--;
180
181 for(; i >= 0; i--) {
182 n0 = dividend_ptr[i];
183 udiv_qrnnd (dummy, r, r, n0, divisor_limb);
184 }
185 return r;
186 }
187}
188
189/* Divide num (NP/NSIZE) by den (DP/DSIZE) and write
190 * the NSIZE-DSIZE least significant quotient limbs at QP
191 * and the DSIZE long remainder at NP.If QEXTRA_LIMBS is
192 * non-zero, generate that many fraction bits and append them after the
193 * other quotient limbs.
194 * Return the most significant limb of the quotient, this is always 0 or 1.
195 *
196 * Preconditions:
197 * 0. NSIZE >= DSIZE.
198 * 1. The most significant bit of the divisor must be set.
199 * 2. QP must either not overlap with the input operands at all, or
200 * QP + DSIZE >= NP must hold true.(This means that it's
201 * possible to put the quotient in the high part of NUM, right after the
202 * remainder in NUM.
203 * 3. NSIZE >= DSIZE, even if QEXTRA_LIMBS is non-zero.
204 */
205
206mpi_limb_t
207_gcry_mpih_divrem( mpi_ptr_t qp, mpi_size_t qextra_limbs,
208 mpi_ptr_t np, mpi_size_t nsize,
209 mpi_ptr_t dp, mpi_size_t dsize)
210{
211 mpi_limb_t most_significant_q_limb = 0;
212
213 switch(dsize) {
214 case 0:
215 /* We are asked to divide by zero, so go ahead and do it! (To make
216 the compiler not remove this statement, return the value.) */
217 return 1 / dsize;
218
219 case 1:
220 {
221 mpi_size_t i;
222 mpi_limb_t n1;
223 mpi_limb_t d;
224
225 d = dp[0];
226 n1 = np[nsize - 1];
227
228 if( n1 >= d ) {
229 n1 -= d;
230 most_significant_q_limb = 1;
231 }
232
233 qp += qextra_limbs;
234 for( i = nsize - 2; i >= 0; i--)
235 udiv_qrnnd( qp[i], n1, n1, np[i], d );
236 qp -= qextra_limbs;
237
238 for( i = qextra_limbs - 1; i >= 0; i-- )
239 udiv_qrnnd (qp[i], n1, n1, 0, d);
240
241 np[0] = n1;
242 }
243 break;
244
245 case 2:
246 {
247 mpi_size_t i;
248 mpi_limb_t n1, n0, n2;
249 mpi_limb_t d1, d0;
250
251 np += nsize - 2;
252 d1 = dp[1];
253 d0 = dp[0];
254 n1 = np[1];
255 n0 = np[0];
256
257 if( n1 >= d1 && (n1 > d1 || n0 >= d0) ) {
258 sub_ddmmss (n1, n0, n1, n0, d1, d0);
259 most_significant_q_limb = 1;
260 }
261
262 for( i = qextra_limbs + nsize - 2 - 1; i >= 0; i-- ) {
263 mpi_limb_t q;
264 mpi_limb_t r;
265
266 if( i >= qextra_limbs )
267 np--;
268 else
269 np[0] = 0;
270
271 if( n1 == d1 ) {
272 /* Q should be either 111..111 or 111..110. Need special
273 * treatment of this rare case as normal division would
274 * give overflow. */
275 q = ~(mpi_limb_t)0;
276
277 r = n0 + d1;
278 if( r < d1 ) { /* Carry in the addition? */
279 add_ssaaaa( n1, n0, r - d0, np[0], 0, d0 );
280 qp[i] = q;
281 continue;
282 }
283 n1 = d0 - (d0 != 0?1:0);
284 n0 = -d0;
285 }
286 else {
287 udiv_qrnnd (q, r, n1, n0, d1);
288 umul_ppmm (n1, n0, d0, q);
289 }
290
291 n2 = np[0];
292 q_test:
293 if( n1 > r || (n1 == r && n0 > n2) ) {
294 /* The estimated Q was too large. */
295 q--;
296 sub_ddmmss (n1, n0, n1, n0, 0, d0);
297 r += d1;
298 if( r >= d1 ) /* If not carry, test Q again. */
299 goto q_test;
300 }
301
302 qp[i] = q;
303 sub_ddmmss (n1, n0, r, n2, n1, n0);
304 }
305 np[1] = n1;
306 np[0] = n0;
307 }
308 break;
309
310 default:
311 {
312 mpi_size_t i;
313 mpi_limb_t dX, d1, n0;
314
315 np += nsize - dsize;
316 dX = dp[dsize - 1];
317 d1 = dp[dsize - 2];
318 n0 = np[dsize - 1];
319
320 if( n0 >= dX ) {
321 if(n0 > dX || _gcry_mpih_cmp(np, dp, dsize - 1) >= 0 ) {
322 _gcry_mpih_sub_n(np, np, dp, dsize);
323 n0 = np[dsize - 1];
324 most_significant_q_limb = 1;
325 }
326 }
327
328 for( i = qextra_limbs + nsize - dsize - 1; i >= 0; i--) {
329 mpi_limb_t q;
330 mpi_limb_t n1, n2;
331 mpi_limb_t cy_limb;
332
333 if( i >= qextra_limbs ) {
334 np--;
335 n2 = np[dsize];
336 }
337 else {
338 n2 = np[dsize - 1];
339 MPN_COPY_DECR (np + 1, np, dsize - 1);
340 np[0] = 0;
341 }
342
343 if( n0 == dX ) {
344 /* This might over-estimate q, but it's probably not worth
345 * the extra code here to find out. */
346 q = ~(mpi_limb_t)0;
347 }
348 else {
349 mpi_limb_t r;
350
351 udiv_qrnnd(q, r, n0, np[dsize - 1], dX);
352 umul_ppmm(n1, n0, d1, q);
353
354 while( n1 > r || (n1 == r && n0 > np[dsize - 2])) {
355 q--;
356 r += dX;
357 if( r < dX ) /* I.e. "carry in previous addition?" */
358 break;
359 n1 -= n0 < d1;
360 n0 -= d1;
361 }
362 }
363
364 /* Possible optimization: We already have (q * n0) and (1 * n1)
365 * after the calculation of q.Taking advantage of that, we
366 * could make this loop make two iterations less. */
367 cy_limb = _gcry_mpih_submul_1(np, dp, dsize, q);
368
369 if( n2 != cy_limb ) {
370 _gcry_mpih_add_n(np, np, dp, dsize);
371 q--;
372 }
373
374 qp[i] = q;
375 n0 = np[dsize - 1];
376 }
377 }
378 }
379
380 return most_significant_q_limb;
381}
382
383
384/****************
385 * Divide (DIVIDEND_PTR,,DIVIDEND_SIZE) by DIVISOR_LIMB.
386 * Write DIVIDEND_SIZE limbs of quotient at QUOT_PTR.
387 * Return the single-limb remainder.
388 * There are no constraints on the value of the divisor.
389 *
390 * QUOT_PTR and DIVIDEND_PTR might point to the same limb.
391 */
392
393mpi_limb_t
394_gcry_mpih_divmod_1( mpi_ptr_t quot_ptr,
395 mpi_ptr_t dividend_ptr, mpi_size_t dividend_size,
396 mpi_limb_t divisor_limb)
397{
398 mpi_size_t i;
399 mpi_limb_t n1, n0, r;
400 int dummy;
401
402 if( !dividend_size )
403 return 0;
404
405 /* If multiplication is much faster than division, and the
406 * dividend is large, pre-invert the divisor, and use
407 * only multiplications in the inner loop.
408 *
409 * This test should be read:
410 * Does it ever help to use udiv_qrnnd_preinv?
411 * && Does what we save compensate for the inversion overhead?
412 */
413 if( UDIV_TIME > (2 * UMUL_TIME + 6)
414 && (UDIV_TIME - (2 * UMUL_TIME + 6)) * dividend_size > UDIV_TIME ) {
415 int normalization_steps;
416
417 count_leading_zeros( normalization_steps, divisor_limb );
418 if( normalization_steps ) {
419 mpi_limb_t divisor_limb_inverted;
420
421 divisor_limb <<= normalization_steps;
422
423 /* Compute (2**2N - 2**N * DIVISOR_LIMB) / DIVISOR_LIMB. The
424 * result is a (N+1)-bit approximation to 1/DIVISOR_LIMB, with the
425 * most significant bit (with weight 2**N) implicit.
426 */
427 /* Special case for DIVISOR_LIMB == 100...000. */
428 if( !(divisor_limb << 1) )
429 divisor_limb_inverted = ~(mpi_limb_t)0;
430 else
431 udiv_qrnnd(divisor_limb_inverted, dummy,
432 -divisor_limb, 0, divisor_limb);
433
434 n1 = dividend_ptr[dividend_size - 1];
435 r = n1 >> (BITS_PER_MPI_LIMB - normalization_steps);
436
437 /* Possible optimization:
438 * if (r == 0
439 * && divisor_limb > ((n1 << normalization_steps)
440 * | (dividend_ptr[dividend_size - 2] >> ...)))
441 * ...one division less...
442 */
443 for( i = dividend_size - 2; i >= 0; i--) {
444 n0 = dividend_ptr[i];
445 UDIV_QRNND_PREINV( quot_ptr[i + 1], r, r,
446 ((n1 << normalization_steps)
447 | (n0 >> (BITS_PER_MPI_LIMB - normalization_steps))),
448 divisor_limb, divisor_limb_inverted);
449 n1 = n0;
450 }
451 UDIV_QRNND_PREINV( quot_ptr[0], r, r,
452 n1 << normalization_steps,
453 divisor_limb, divisor_limb_inverted);
454 return r >> normalization_steps;
455 }
456 else {
457 mpi_limb_t divisor_limb_inverted;
458
459 /* Compute (2**2N - 2**N * DIVISOR_LIMB) / DIVISOR_LIMB. The
460 * result is a (N+1)-bit approximation to 1/DIVISOR_LIMB, with the
461 * most significant bit (with weight 2**N) implicit.
462 */
463 /* Special case for DIVISOR_LIMB == 100...000. */
464 if( !(divisor_limb << 1) )
465 divisor_limb_inverted = ~(mpi_limb_t) 0;
466 else
467 udiv_qrnnd(divisor_limb_inverted, dummy,
468 -divisor_limb, 0, divisor_limb);
469
470 i = dividend_size - 1;
471 r = dividend_ptr[i];
472
473 if( r >= divisor_limb )
474 r = 0;
475 else
476 quot_ptr[i--] = 0;
477
478 for( ; i >= 0; i-- ) {
479 n0 = dividend_ptr[i];
480 UDIV_QRNND_PREINV( quot_ptr[i], r, r,
481 n0, divisor_limb, divisor_limb_inverted);
482 }
483 return r;
484 }
485 }
486 else {
487 if(UDIV_NEEDS_NORMALIZATION) {
488 int normalization_steps;
489
490 count_leading_zeros (normalization_steps, divisor_limb);
491 if( normalization_steps ) {
492 divisor_limb <<= normalization_steps;
493
494 n1 = dividend_ptr[dividend_size - 1];
495 r = n1 >> (BITS_PER_MPI_LIMB - normalization_steps);
496
497 /* Possible optimization:
498 * if (r == 0
499 * && divisor_limb > ((n1 << normalization_steps)
500 * | (dividend_ptr[dividend_size - 2] >> ...)))
501 * ...one division less...
502 */
503 for( i = dividend_size - 2; i >= 0; i--) {
504 n0 = dividend_ptr[i];
505 udiv_qrnnd (quot_ptr[i + 1], r, r,
506 ((n1 << normalization_steps)
507 | (n0 >> (BITS_PER_MPI_LIMB - normalization_steps))),
508 divisor_limb);
509 n1 = n0;
510 }
511 udiv_qrnnd (quot_ptr[0], r, r,
512 n1 << normalization_steps,
513 divisor_limb);
514 return r >> normalization_steps;
515 }
516 }
517 /* No normalization needed, either because udiv_qrnnd doesn't require
518 * it, or because DIVISOR_LIMB is already normalized. */
519 i = dividend_size - 1;
520 r = dividend_ptr[i];
521
522 if(r >= divisor_limb)
523 r = 0;
524 else
525 quot_ptr[i--] = 0;
526
527 for(; i >= 0; i--) {
528 n0 = dividend_ptr[i];
529 udiv_qrnnd( quot_ptr[i], r, r, n0, divisor_limb );
530 }
531 return r;
532 }
533}
534
535
diff --git a/pwmanager/libcrypt/mpi/mpih-mul.c b/pwmanager/libcrypt/mpi/mpih-mul.c
new file mode 100644
index 0000000..e1f6f58
--- a/dev/null
+++ b/pwmanager/libcrypt/mpi/mpih-mul.c
@@ -0,0 +1,530 @@
1/* mpih-mul.c - MPI helper functions
2 * Copyright (C) 1994, 1996, 1998, 1999, 2000,
3 * 2001, 2002 Free Software Foundation, Inc.
4 *
5 * This file is part of Libgcrypt.
6 *
7 * Libgcrypt is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * Libgcrypt is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20 *
21 * Note: This code is heavily based on the GNU MP Library.
22 * Actually it's the same code with only minor changes in the
23 * way the data is stored; this is to support the abstraction
24 * of an optional secure memory allocation which may be used
25 * to avoid revealing of sensitive data due to paging etc.
26 */
27
28#include <config.h>
29#include <stdio.h>
30#include <stdlib.h>
31#include <string.h>
32#include "mpi-internal.h"
33#include "longlong.h"
34#include "g10lib.h"
35
36#define MPN_MUL_N_RECURSE(prodp, up, vp, size, tspace) \
37 do { \
38 if( (size) < KARATSUBA_THRESHOLD ) \
39 mul_n_basecase (prodp, up, vp, size);\
40 else \
41 mul_n (prodp, up, vp, size, tspace);\
42 } while (0);
43
44#define MPN_SQR_N_RECURSE(prodp, up, size, tspace) \
45 do { \
46 if ((size) < KARATSUBA_THRESHOLD) \
47 _gcry_mpih_sqr_n_basecase (prodp, up, size); \
48 else \
49 _gcry_mpih_sqr_n (prodp, up, size, tspace); \
50 } while (0);
51
52
53
54
55/* Multiply the natural numbers u (pointed to by UP) and v (pointed to by VP),
56 * both with SIZE limbs, and store the result at PRODP. 2 * SIZE limbs are
57 * always stored. Return the most significant limb.
58 *
59 * Argument constraints:
60 * 1. PRODP != UP and PRODP != VP, i.e. the destination
61 * must be distinct from the multiplier and the multiplicand.
62 *
63 *
64 * Handle simple cases with traditional multiplication.
65 *
66 * This is the most critical code of multiplication. All multiplies rely
67 * on this, both small and huge. Small ones arrive here immediately. Huge
68 * ones arrive here as this is the base case for Karatsuba's recursive
69 * algorithm below.
70 */
71
72static mpi_limb_t
73mul_n_basecase( mpi_ptr_t prodp, mpi_ptr_t up,
74 mpi_ptr_t vp, mpi_size_t size)
75{
76 mpi_size_t i;
77 mpi_limb_t cy;
78 mpi_limb_t v_limb;
79
80 /* Multiply by the first limb in V separately, as the result can be
81 * stored (not added) to PROD. We also avoid a loop for zeroing. */
82 v_limb = vp[0];
83 if( v_limb <= 1 ) {
84 if( v_limb == 1 )
85 MPN_COPY( prodp, up, size );
86 else
87 MPN_ZERO( prodp, size );
88 cy = 0;
89 }
90 else
91 cy = _gcry_mpih_mul_1( prodp, up, size, v_limb );
92
93 prodp[size] = cy;
94 prodp++;
95
96 /* For each iteration in the outer loop, multiply one limb from
97 * U with one limb from V, and add it to PROD. */
98 for( i = 1; i < size; i++ ) {
99 v_limb = vp[i];
100 if( v_limb <= 1 ) {
101 cy = 0;
102 if( v_limb == 1 )
103 cy = _gcry_mpih_add_n(prodp, prodp, up, size);
104 }
105 else
106 cy = _gcry_mpih_addmul_1(prodp, up, size, v_limb);
107
108 prodp[size] = cy;
109 prodp++;
110 }
111
112 return cy;
113}
114
115
116static void
117mul_n( mpi_ptr_t prodp, mpi_ptr_t up, mpi_ptr_t vp,
118 mpi_size_t size, mpi_ptr_t tspace )
119{
120 if( size & 1 ) {
121 /* The size is odd, and the code below doesn't handle that.
122 * Multiply the least significant (size - 1) limbs with a recursive
123 * call, and handle the most significant limb of S1 and S2
124 * separately.
125 * A slightly faster way to do this would be to make the Karatsuba
126 * code below behave as if the size were even, and let it check for
127 * odd size in the end. I.e., in essence move this code to the end.
128 * Doing so would save us a recursive call, and potentially make the
129 * stack grow a lot less.
130 */
131 mpi_size_t esize = size - 1; /* even size */
132 mpi_limb_t cy_limb;
133
134 MPN_MUL_N_RECURSE( prodp, up, vp, esize, tspace );
135 cy_limb = _gcry_mpih_addmul_1( prodp + esize, up, esize, vp[esize] );
136 prodp[esize + esize] = cy_limb;
137 cy_limb = _gcry_mpih_addmul_1( prodp + esize, vp, size, up[esize] );
138 prodp[esize + size] = cy_limb;
139 }
140 else {
141 /* Anatolij Alekseevich Karatsuba's divide-and-conquer algorithm.
142 *
143 * Split U in two pieces, U1 and U0, such that
144 * U = U0 + U1*(B**n),
145 * and V in V1 and V0, such that
146 * V = V0 + V1*(B**n).
147 *
148 * UV is then computed recursively using the identity
149 *
150 * 2n n n n
151 * UV = (B + B )U V + B (U -U )(V -V ) + (B + 1)U V
152 * 1 1 1 0 0 1 0 0
153 *
154 * Where B = 2**BITS_PER_MP_LIMB.
155 */
156 mpi_size_t hsize = size >> 1;
157 mpi_limb_t cy;
158 int negflg;
159
160 /* Product H. ________________ ________________
161 * |_____U1 x V1____||____U0 x V0_____|
162 * Put result in upper part of PROD and pass low part of TSPACE
163 * as new TSPACE.
164 */
165 MPN_MUL_N_RECURSE(prodp + size, up + hsize, vp + hsize, hsize, tspace);
166
167 /* Product M. ________________
168 * |_(U1-U0)(V0-V1)_|
169 */
170 if( _gcry_mpih_cmp(up + hsize, up, hsize) >= 0 ) {
171 _gcry_mpih_sub_n(prodp, up + hsize, up, hsize);
172 negflg = 0;
173 }
174 else {
175 _gcry_mpih_sub_n(prodp, up, up + hsize, hsize);
176 negflg = 1;
177 }
178 if( _gcry_mpih_cmp(vp + hsize, vp, hsize) >= 0 ) {
179 _gcry_mpih_sub_n(prodp + hsize, vp + hsize, vp, hsize);
180 negflg ^= 1;
181 }
182 else {
183 _gcry_mpih_sub_n(prodp + hsize, vp, vp + hsize, hsize);
184 /* No change of NEGFLG. */
185 }
186 /* Read temporary operands from low part of PROD.
187 * Put result in low part of TSPACE using upper part of TSPACE
188 * as new TSPACE.
189 */
190 MPN_MUL_N_RECURSE(tspace, prodp, prodp + hsize, hsize, tspace + size);
191
192 /* Add/copy product H. */
193 MPN_COPY (prodp + hsize, prodp + size, hsize);
194 cy = _gcry_mpih_add_n( prodp + size, prodp + size,
195 prodp + size + hsize, hsize);
196
197 /* Add product M (if NEGFLG M is a negative number) */
198 if(negflg)
199 cy -= _gcry_mpih_sub_n(prodp + hsize, prodp + hsize, tspace, size);
200 else
201 cy += _gcry_mpih_add_n(prodp + hsize, prodp + hsize, tspace, size);
202
203 /* Product L. ________________ ________________
204 * |________________||____U0 x V0_____|
205 * Read temporary operands from low part of PROD.
206 * Put result in low part of TSPACE using upper part of TSPACE
207 * as new TSPACE.
208 */
209 MPN_MUL_N_RECURSE(tspace, up, vp, hsize, tspace + size);
210
211 /* Add/copy Product L (twice) */
212
213 cy += _gcry_mpih_add_n(prodp + hsize, prodp + hsize, tspace, size);
214 if( cy )
215 _gcry_mpih_add_1(prodp + hsize + size, prodp + hsize + size, hsize, cy);
216
217 MPN_COPY(prodp, tspace, hsize);
218 cy = _gcry_mpih_add_n(prodp + hsize, prodp + hsize, tspace + hsize, hsize);
219 if( cy )
220 _gcry_mpih_add_1(prodp + size, prodp + size, size, 1);
221 }
222}
223
224
225void
226_gcry_mpih_sqr_n_basecase( mpi_ptr_t prodp, mpi_ptr_t up, mpi_size_t size )
227{
228 mpi_size_t i;
229 mpi_limb_t cy_limb;
230 mpi_limb_t v_limb;
231
232 /* Multiply by the first limb in V separately, as the result can be
233 * stored (not added) to PROD. We also avoid a loop for zeroing. */
234 v_limb = up[0];
235 if( v_limb <= 1 ) {
236 if( v_limb == 1 )
237 MPN_COPY( prodp, up, size );
238 else
239 MPN_ZERO(prodp, size);
240 cy_limb = 0;
241 }
242 else
243 cy_limb = _gcry_mpih_mul_1( prodp, up, size, v_limb );
244
245 prodp[size] = cy_limb;
246 prodp++;
247
248 /* For each iteration in the outer loop, multiply one limb from
249 * U with one limb from V, and add it to PROD. */
250 for( i=1; i < size; i++) {
251 v_limb = up[i];
252 if( v_limb <= 1 ) {
253 cy_limb = 0;
254 if( v_limb == 1 )
255 cy_limb = _gcry_mpih_add_n(prodp, prodp, up, size);
256 }
257 else
258 cy_limb = _gcry_mpih_addmul_1(prodp, up, size, v_limb);
259
260 prodp[size] = cy_limb;
261 prodp++;
262 }
263}
264
265
266void
267_gcry_mpih_sqr_n( mpi_ptr_t prodp,
268 mpi_ptr_t up, mpi_size_t size, mpi_ptr_t tspace)
269{
270 if( size & 1 ) {
271 /* The size is odd, and the code below doesn't handle that.
272 * Multiply the least significant (size - 1) limbs with a recursive
273 * call, and handle the most significant limb of S1 and S2
274 * separately.
275 * A slightly faster way to do this would be to make the Karatsuba
276 * code below behave as if the size were even, and let it check for
277 * odd size in the end. I.e., in essence move this code to the end.
278 * Doing so would save us a recursive call, and potentially make the
279 * stack grow a lot less.
280 */
281 mpi_size_t esize = size - 1; /* even size */
282 mpi_limb_t cy_limb;
283
284 MPN_SQR_N_RECURSE( prodp, up, esize, tspace );
285 cy_limb = _gcry_mpih_addmul_1( prodp + esize, up, esize, up[esize] );
286 prodp[esize + esize] = cy_limb;
287 cy_limb = _gcry_mpih_addmul_1( prodp + esize, up, size, up[esize] );
288
289 prodp[esize + size] = cy_limb;
290 }
291 else {
292 mpi_size_t hsize = size >> 1;
293 mpi_limb_t cy;
294
295 /* Product H. ________________ ________________
296 * |_____U1 x U1____||____U0 x U0_____|
297 * Put result in upper part of PROD and pass low part of TSPACE
298 * as new TSPACE.
299 */
300 MPN_SQR_N_RECURSE(prodp + size, up + hsize, hsize, tspace);
301
302 /* Product M. ________________
303 * |_(U1-U0)(U0-U1)_|
304 */
305 if( _gcry_mpih_cmp( up + hsize, up, hsize) >= 0 )
306 _gcry_mpih_sub_n( prodp, up + hsize, up, hsize);
307 else
308 _gcry_mpih_sub_n (prodp, up, up + hsize, hsize);
309
310 /* Read temporary operands from low part of PROD.
311 * Put result in low part of TSPACE using upper part of TSPACE
312 * as new TSPACE. */
313 MPN_SQR_N_RECURSE(tspace, prodp, hsize, tspace + size);
314
315 /* Add/copy product H */
316 MPN_COPY(prodp + hsize, prodp + size, hsize);
317 cy = _gcry_mpih_add_n(prodp + size, prodp + size,
318 prodp + size + hsize, hsize);
319
320 /* Add product M (if NEGFLG M is a negative number). */
321 cy -= _gcry_mpih_sub_n (prodp + hsize, prodp + hsize, tspace, size);
322
323 /* Product L. ________________ ________________
324 * |________________||____U0 x U0_____|
325 * Read temporary operands from low part of PROD.
326 * Put result in low part of TSPACE using upper part of TSPACE
327 * as new TSPACE. */
328 MPN_SQR_N_RECURSE (tspace, up, hsize, tspace + size);
329
330 /* Add/copy Product L (twice).*/
331 cy += _gcry_mpih_add_n (prodp + hsize, prodp + hsize, tspace, size);
332 if( cy )
333 _gcry_mpih_add_1(prodp + hsize + size, prodp + hsize + size,
334 hsize, cy);
335
336 MPN_COPY(prodp, tspace, hsize);
337 cy = _gcry_mpih_add_n (prodp + hsize, prodp + hsize, tspace + hsize, hsize);
338 if( cy )
339 _gcry_mpih_add_1 (prodp + size, prodp + size, size, 1);
340 }
341}
342
343
344/* This should be made into an inline function in gmp.h. */
345void
346_gcry_mpih_mul_n( mpi_ptr_t prodp,
347 mpi_ptr_t up, mpi_ptr_t vp, mpi_size_t size)
348{
349 int secure;
350
351 if( up == vp ) {
352 if( size < KARATSUBA_THRESHOLD )
353 _gcry_mpih_sqr_n_basecase( prodp, up, size );
354 else {
355 mpi_ptr_t tspace;
356 secure = gcry_is_secure( up );
357 tspace = mpi_alloc_limb_space( 2 * size, secure );
358 _gcry_mpih_sqr_n( prodp, up, size, tspace );
359 _gcry_mpi_free_limb_space (tspace, 2 * size );
360 }
361 }
362 else {
363 if( size < KARATSUBA_THRESHOLD )
364 mul_n_basecase( prodp, up, vp, size );
365 else {
366 mpi_ptr_t tspace;
367 secure = gcry_is_secure( up ) || gcry_is_secure( vp );
368 tspace = mpi_alloc_limb_space( 2 * size, secure );
369 mul_n (prodp, up, vp, size, tspace);
370 _gcry_mpi_free_limb_space (tspace, 2 * size );
371 }
372 }
373}
374
375
376
377void
378_gcry_mpih_mul_karatsuba_case( mpi_ptr_t prodp,
379 mpi_ptr_t up, mpi_size_t usize,
380 mpi_ptr_t vp, mpi_size_t vsize,
381 struct karatsuba_ctx *ctx )
382{
383 mpi_limb_t cy;
384
385 if( !ctx->tspace || ctx->tspace_size < vsize ) {
386 if( ctx->tspace )
387 _gcry_mpi_free_limb_space( ctx->tspace, ctx->tspace_nlimbs );
388 ctx->tspace_nlimbs = 2 * vsize;
389 ctx->tspace = mpi_alloc_limb_space( 2 * vsize,
390 (gcry_is_secure( up )
391 || gcry_is_secure( vp )) );
392 ctx->tspace_size = vsize;
393 }
394
395 MPN_MUL_N_RECURSE( prodp, up, vp, vsize, ctx->tspace );
396
397 prodp += vsize;
398 up += vsize;
399 usize -= vsize;
400 if( usize >= vsize ) {
401 if( !ctx->tp || ctx->tp_size < vsize ) {
402 if( ctx->tp )
403 _gcry_mpi_free_limb_space( ctx->tp, ctx->tp_nlimbs );
404 ctx->tp_nlimbs = 2 * vsize;
405 ctx->tp = mpi_alloc_limb_space( 2 * vsize, gcry_is_secure( up )
406 || gcry_is_secure( vp ) );
407 ctx->tp_size = vsize;
408 }
409
410 do {
411 MPN_MUL_N_RECURSE( ctx->tp, up, vp, vsize, ctx->tspace );
412 cy = _gcry_mpih_add_n( prodp, prodp, ctx->tp, vsize );
413 _gcry_mpih_add_1( prodp + vsize, ctx->tp + vsize, vsize, cy );
414 prodp += vsize;
415 up += vsize;
416 usize -= vsize;
417 } while( usize >= vsize );
418 }
419
420 if( usize ) {
421 if( usize < KARATSUBA_THRESHOLD ) {
422 _gcry_mpih_mul( ctx->tspace, vp, vsize, up, usize );
423 }
424 else {
425 if( !ctx->next ) {
426 ctx->next = gcry_xcalloc( 1, sizeof *ctx );
427 }
428 _gcry_mpih_mul_karatsuba_case( ctx->tspace,
429 vp, vsize,
430 up, usize,
431 ctx->next );
432 }
433
434 cy = _gcry_mpih_add_n( prodp, prodp, ctx->tspace, vsize);
435 _gcry_mpih_add_1( prodp + vsize, ctx->tspace + vsize, usize, cy );
436 }
437}
438
439
440void
441_gcry_mpih_release_karatsuba_ctx( struct karatsuba_ctx *ctx )
442{
443 struct karatsuba_ctx *ctx2;
444
445 if( ctx->tp )
446 _gcry_mpi_free_limb_space( ctx->tp, ctx->tp_nlimbs );
447 if( ctx->tspace )
448 _gcry_mpi_free_limb_space( ctx->tspace, ctx->tspace_nlimbs );
449 for( ctx=ctx->next; ctx; ctx = ctx2 ) {
450 ctx2 = ctx->next;
451 if( ctx->tp )
452 _gcry_mpi_free_limb_space( ctx->tp, ctx->tp_nlimbs );
453 if( ctx->tspace )
454 _gcry_mpi_free_limb_space( ctx->tspace, ctx->tspace_nlimbs );
455 gcry_free( ctx );
456 }
457}
458
459/* Multiply the natural numbers u (pointed to by UP, with USIZE limbs)
460 * and v (pointed to by VP, with VSIZE limbs), and store the result at
461 * PRODP. USIZE + VSIZE limbs are always stored, but if the input
462 * operands are normalized. Return the most significant limb of the
463 * result.
464 *
465 * NOTE: The space pointed to by PRODP is overwritten before finished
466 * with U and V, so overlap is an error.
467 *
468 * Argument constraints:
469 * 1. USIZE >= VSIZE.
470 * 2. PRODP != UP and PRODP != VP, i.e. the destination
471 * must be distinct from the multiplier and the multiplicand.
472 */
473
474mpi_limb_t
475_gcry_mpih_mul( mpi_ptr_t prodp, mpi_ptr_t up, mpi_size_t usize,
476 mpi_ptr_t vp, mpi_size_t vsize)
477{
478 mpi_ptr_t prod_endp = prodp + usize + vsize - 1;
479 mpi_limb_t cy;
480 struct karatsuba_ctx ctx;
481
482 if( vsize < KARATSUBA_THRESHOLD ) {
483 mpi_size_t i;
484 mpi_limb_t v_limb;
485
486 if( !vsize )
487 return 0;
488
489 /* Multiply by the first limb in V separately, as the result can be
490 * stored (not added) to PROD.We also avoid a loop for zeroing. */
491 v_limb = vp[0];
492 if( v_limb <= 1 ) {
493 if( v_limb == 1 )
494 MPN_COPY( prodp, up, usize );
495 else
496 MPN_ZERO( prodp, usize );
497 cy = 0;
498 }
499 else
500 cy = _gcry_mpih_mul_1( prodp, up, usize, v_limb );
501
502 prodp[usize] = cy;
503 prodp++;
504
505 /* For each iteration in the outer loop, multiply one limb from
506 * U with one limb from V, and add it to PROD.*/
507 for( i = 1; i < vsize; i++ ) {
508 v_limb = vp[i];
509 if( v_limb <= 1 ) {
510 cy = 0;
511 if( v_limb == 1 )
512 cy = _gcry_mpih_add_n(prodp, prodp, up, usize);
513 }
514 else
515 cy = _gcry_mpih_addmul_1(prodp, up, usize, v_limb);
516
517 prodp[usize] = cy;
518 prodp++;
519 }
520
521 return cy;
522 }
523
524 memset( &ctx, 0, sizeof ctx );
525 _gcry_mpih_mul_karatsuba_case( prodp, up, usize, vp, vsize, &ctx );
526 _gcry_mpih_release_karatsuba_ctx( &ctx );
527 return *prod_endp;
528}
529
530
diff --git a/pwmanager/libcrypt/mpi/mpiutil.c b/pwmanager/libcrypt/mpi/mpiutil.c
new file mode 100644
index 0000000..2a0bafa
--- a/dev/null
+++ b/pwmanager/libcrypt/mpi/mpiutil.c
@@ -0,0 +1,431 @@
1/* mpiutil.ac - Utility functions for MPI
2 * Copyright (C) 1998, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
3 *
4 * This file is part of Libgcrypt.
5 *
6 * Libgcrypt is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License as
8 * published by the Free Software Foundation; either version 2.1 of
9 * the License, or (at your option) any later version.
10 *
11 * Libgcrypt is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19 */
20
21#include <config.h>
22#include <stdio.h>
23#include <stdlib.h>
24#include <string.h>
25#include <assert.h>
26
27#include "g10lib.h"
28#include "mpi-internal.h"
29#include "memory.h"
30
31/****************
32 * Note: It was a bad idea to use the number of limbs to allocate
33 * because on a alpha the limbs are large but we normally need
34 * integers of n bits - So we should chnage this to bits (or bytes).
35 *
36 * But mpi_alloc is used in a lot of places :-)
37 */
38gcry_mpi_t
39_gcry_mpi_alloc( unsigned nlimbs )
40{
41 gcry_mpi_t a;
42
43 a = gcry_xmalloc( sizeof *a );
44 a->d = nlimbs? mpi_alloc_limb_space( nlimbs, 0 ) : NULL;
45 a->alloced = nlimbs;
46 a->nlimbs = 0;
47 a->sign = 0;
48 a->flags = 0;
49 return a;
50}
51
52void
53_gcry_mpi_m_check( gcry_mpi_t a )
54{
55 _gcry_check_heap(a);
56 _gcry_check_heap(a->d);
57}
58
59gcry_mpi_t
60_gcry_mpi_alloc_secure( unsigned nlimbs )
61{
62 gcry_mpi_t a;
63
64 a = gcry_xmalloc( sizeof *a );
65 a->d = nlimbs? mpi_alloc_limb_space( nlimbs, 1 ) : NULL;
66 a->alloced = nlimbs;
67 a->flags = 1;
68 a->nlimbs = 0;
69 a->sign = 0;
70 return a;
71}
72
73
74
75mpi_ptr_t
76_gcry_mpi_alloc_limb_space( unsigned int nlimbs, int secure )
77{
78 size_t len = nlimbs * sizeof(mpi_limb_t);
79 mpi_ptr_t p = NULL;
80
81 if (!nlimbs)
82 {
83 p = secure? gcry_xmalloc_secure( 1 ) : gcry_xmalloc( 1 );
84 *p = 0;
85 }
86 else
87 p = secure? gcry_xmalloc_secure( len ) : gcry_xmalloc( len );
88
89 return p;
90}
91
92void
93_gcry_mpi_free_limb_space( mpi_ptr_t a, unsigned int nlimbs)
94{
95 if (a)
96 {
97 size_t len = nlimbs * sizeof(mpi_limb_t);
98
99 /* If we have information on the number of allocated limbs, we
100 better wipe that space out. This is a failsafe feature if
101 secure memory has been disabled or was not properly
102 implemented in user provided allocation functions. */
103 if (len)
104 wipememory (a, len);
105 gcry_free(a);
106 }
107}
108
109
110void
111_gcry_mpi_assign_limb_space( gcry_mpi_t a, mpi_ptr_t ap, unsigned int nlimbs )
112{
113 _gcry_mpi_free_limb_space (a->d, a->alloced);
114 a->d = ap;
115 a->alloced = nlimbs;
116}
117
118
119
120/****************
121 * Resize the array of A to NLIMBS. the additional space is cleared
122 * (set to 0) [done by gcry_realloc()]
123 */
124void
125_gcry_mpi_resize (gcry_mpi_t a, unsigned nlimbs)
126{
127 if (nlimbs <= a->alloced)
128 return; /* no need to do it */
129
130 if (a->d)
131 a->d = gcry_xrealloc (a->d, nlimbs * sizeof (mpi_limb_t));
132 else
133 {
134 if (a->flags & 1)
135 /* Secure memory is wanted. */
136 a->d = gcry_xcalloc_secure (nlimbs , sizeof (mpi_limb_t));
137 else
138 /* Standard memory. */
139 a->d = gcry_xcalloc (nlimbs , sizeof (mpi_limb_t));
140 }
141 a->alloced = nlimbs;
142}
143
144void
145_gcry_mpi_clear( gcry_mpi_t a )
146{
147 a->nlimbs = 0;
148 a->flags = 0;
149}
150
151
152void
153_gcry_mpi_free( gcry_mpi_t a )
154{
155 if (!a )
156 return;
157 if ((a->flags & 4))
158 gcry_free( a->d );
159 else
160 {
161 _gcry_mpi_free_limb_space(a->d, a->alloced);
162 }
163 if ((a->flags & ~7))
164 log_bug("invalid flag value in mpi\n");
165 gcry_free(a);
166}
167
168static void
169mpi_set_secure( gcry_mpi_t a )
170{
171 mpi_ptr_t ap, bp;
172
173 if ( (a->flags & 1) )
174 return;
175 a->flags |= 1;
176 ap = a->d;
177 if (!a->nlimbs)
178 {
179 assert(!ap);
180 return;
181 }
182 bp = mpi_alloc_limb_space (a->nlimbs, 1);
183 MPN_COPY( bp, ap, a->nlimbs );
184 a->d = bp;
185 _gcry_mpi_free_limb_space (ap, a->alloced);
186}
187
188
189gcry_mpi_t
190gcry_mpi_set_opaque( gcry_mpi_t a, void *p, unsigned int nbits )
191{
192 if (!a)
193 a = mpi_alloc(0);
194
195 if( a->flags & 4 )
196 gcry_free( a->d );
197 else
198 _gcry_mpi_free_limb_space (a->d, a->alloced);
199
200 a->d = p;
201 a->alloced = 0;
202 a->nlimbs = 0;
203 a->sign = nbits;
204 a->flags = 4;
205 return a;
206}
207
208
209void *
210gcry_mpi_get_opaque( gcry_mpi_t a, unsigned int *nbits )
211{
212 if( !(a->flags & 4) )
213 log_bug("mpi_get_opaque on normal mpi\n");
214 if( nbits )
215 *nbits = a->sign;
216 return a->d;
217}
218
219
220/****************
221 * Note: This copy function should not interpret the MPI
222 * but copy it transparently.
223 */
224gcry_mpi_t
225_gcry_mpi_copy( gcry_mpi_t a )
226{
227 int i;
228 gcry_mpi_t b;
229
230 if( a && (a->flags & 4) ) {
231 void *p = gcry_is_secure(a->d)? gcry_xmalloc_secure( (a->sign+7)/8 )
232 : gcry_xmalloc( (a->sign+7)/8 );
233 memcpy( p, a->d, (a->sign+7)/8 );
234 b = gcry_mpi_set_opaque( NULL, p, a->sign );
235 }
236 else if( a ) {
237 b = mpi_is_secure(a)? mpi_alloc_secure( a->nlimbs )
238 : mpi_alloc( a->nlimbs );
239 b->nlimbs = a->nlimbs;
240 b->sign = a->sign;
241 b->flags = a->flags;
242 for(i=0; i < b->nlimbs; i++ )
243 b->d[i] = a->d[i];
244 }
245 else
246 b = NULL;
247 return b;
248}
249
250
251/****************
252 * This function allocates an MPI which is optimized to hold
253 * a value as large as the one given in the argument and allocates it
254 * with the same flags as A.
255 */
256gcry_mpi_t
257_gcry_mpi_alloc_like( gcry_mpi_t a )
258{
259 gcry_mpi_t b;
260
261 if( a && (a->flags & 4) ) {
262 int n = (a->sign+7)/8;
263 void *p = gcry_is_secure(a->d)? gcry_malloc_secure( n )
264 : gcry_malloc( n );
265 memcpy( p, a->d, n );
266 b = gcry_mpi_set_opaque( NULL, p, a->sign );
267 }
268 else if( a ) {
269 b = mpi_is_secure(a)? mpi_alloc_secure( a->nlimbs )
270 : mpi_alloc( a->nlimbs );
271 b->nlimbs = 0;
272 b->sign = 0;
273 b->flags = a->flags;
274 }
275 else
276 b = NULL;
277 return b;
278}
279
280
281void
282_gcry_mpi_set( gcry_mpi_t w, gcry_mpi_t u)
283{
284 mpi_ptr_t wp, up;
285 mpi_size_t usize = u->nlimbs;
286 int usign = u->sign;
287
288 RESIZE_IF_NEEDED(w, usize);
289 wp = w->d;
290 up = u->d;
291 MPN_COPY( wp, up, usize );
292 w->nlimbs = usize;
293 w->flags = u->flags;
294 w->sign = usign;
295}
296
297
298void
299_gcry_mpi_set_ui( gcry_mpi_t w, unsigned long u)
300{
301 RESIZE_IF_NEEDED(w, 1);
302 w->d[0] = u;
303 w->nlimbs = u? 1:0;
304 w->sign = 0;
305 w->flags = 0;
306}
307
308
309gcry_mpi_t
310_gcry_mpi_alloc_set_ui( unsigned long u)
311{
312 gcry_mpi_t w = mpi_alloc(1);
313 w->d[0] = u;
314 w->nlimbs = u? 1:0;
315 w->sign = 0;
316 return w;
317}
318
319
320void
321_gcry_mpi_swap( gcry_mpi_t a, gcry_mpi_t b)
322{
323 struct gcry_mpi tmp;
324
325 tmp = *a; *a = *b; *b = tmp;
326}
327
328void
329gcry_mpi_swap( gcry_mpi_t a, gcry_mpi_t b)
330{
331 _gcry_mpi_swap (a, b);
332}
333
334
335gcry_mpi_t
336gcry_mpi_new( unsigned int nbits )
337{
338 return _gcry_mpi_alloc( (nbits+BITS_PER_MPI_LIMB-1) / BITS_PER_MPI_LIMB );
339}
340
341
342gcry_mpi_t
343gcry_mpi_snew( unsigned int nbits )
344{
345 return _gcry_mpi_alloc_secure( (nbits+BITS_PER_MPI_LIMB-1) / BITS_PER_MPI_LIMB );
346}
347
348void
349gcry_mpi_release( gcry_mpi_t a )
350{
351 _gcry_mpi_free( a );
352}
353
354gcry_mpi_t
355gcry_mpi_copy( const gcry_mpi_t a )
356{
357 return _gcry_mpi_copy( (gcry_mpi_t)a );
358}
359
360gcry_mpi_t
361gcry_mpi_set( gcry_mpi_t w, const gcry_mpi_t u )
362{
363 if( !w )
364 w = _gcry_mpi_alloc( mpi_get_nlimbs(u) );
365 _gcry_mpi_set( w, (gcry_mpi_t)u );
366 return w;
367}
368
369gcry_mpi_t
370gcry_mpi_set_ui( gcry_mpi_t w, unsigned long u )
371{
372 if( !w )
373 w = _gcry_mpi_alloc(1);
374 _gcry_mpi_set_ui( w, u );
375 return w;
376}
377
378
379void
380gcry_mpi_randomize( gcry_mpi_t w,
381 unsigned int nbits, enum gcry_random_level level )
382{
383 char *p;
384 size_t nbytes = (nbits+7)/8;
385
386 if (level == GCRY_WEAK_RANDOM)
387 {
388 p = mpi_is_secure(w) ? gcry_xmalloc (nbytes)
389 : gcry_xmalloc_secure (nbytes);
390 gcry_create_nonce (p, nbytes);
391 }
392 else
393 {
394 p = mpi_is_secure(w) ? gcry_random_bytes (nbytes, level)
395 : gcry_random_bytes_secure (nbytes, level);
396 }
397 _gcry_mpi_set_buffer( w, p, nbytes, 0 );
398 gcry_free (p);
399}
400
401
402void
403gcry_mpi_set_flag( gcry_mpi_t a, enum gcry_mpi_flag flag )
404{
405 switch( flag ) {
406 case GCRYMPI_FLAG_SECURE: mpi_set_secure(a); break;
407 case GCRYMPI_FLAG_OPAQUE:
408 default: log_bug("invalid flag value\n");
409 }
410}
411
412void
413gcry_mpi_clear_flag( gcry_mpi_t a, enum gcry_mpi_flag flag )
414{
415 switch( flag ) {
416 case GCRYMPI_FLAG_SECURE:
417 case GCRYMPI_FLAG_OPAQUE:
418 default: log_bug("invalid flag value\n");
419 }
420}
421
422int
423gcry_mpi_get_flag( gcry_mpi_t a, enum gcry_mpi_flag flag )
424{
425 switch( flag ) {
426 case GCRYMPI_FLAG_SECURE: return (a->flags & 1);
427 case GCRYMPI_FLAG_OPAQUE: return (a->flags & 4);
428 default: log_bug("invalid flag value\n");
429 }
430}
431
diff --git a/pwmanager/libcrypt/mpi/sysdep.h b/pwmanager/libcrypt/mpi/sysdep.h
new file mode 100644
index 0000000..9615e06
--- a/dev/null
+++ b/pwmanager/libcrypt/mpi/sysdep.h
@@ -0,0 +1,2 @@
1/* created by config.links - do not edit */
2#define C_SYMBOL_NAME(name) name