New script to create binop table for 2c operations.
[u/mdw/catacomb] / mp.h
CommitLineData
d03ab969 1/* -*-c-*-
2 *
397041a9 3 * $Id: mp.h,v 1.15 2002/10/15 19:18:31 mdw Exp $
d03ab969 4 *
d3409d5e 5 * Simple multiprecision arithmetic
d03ab969 6 *
7 * (c) 1999 Straylight/Edgeware
8 */
9
10/*----- Licensing notice --------------------------------------------------*
11 *
12 * This file is part of Catacomb.
13 *
14 * Catacomb is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU Library General Public License as
16 * published by the Free Software Foundation; either version 2 of the
17 * License, or (at your option) any later version.
18 *
19 * Catacomb is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU Library General Public License for more details.
23 *
24 * You should have received a copy of the GNU Library General Public
25 * License along with Catacomb; if not, write to the Free
26 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
27 * MA 02111-1307, USA.
28 */
29
30/*----- Revision history --------------------------------------------------*
31 *
32 * $Log: mp.h,v $
397041a9 33 * Revision 1.15 2002/10/15 19:18:31 mdw
34 * New operation to negate numbers.
35 *
09d00c6b 36 * Revision 1.14 2002/10/15 00:19:40 mdw
37 * Bit setting and clearing functions.
38 *
f09e814a 39 * Revision 1.13 2002/10/06 22:52:50 mdw
40 * Pile of changes for supporting two's complement properly.
41 *
3bc0a0fe 42 * Revision 1.12 2001/06/16 12:57:43 mdw
43 * Move the @mpmont_factor@ structure and rename it now that it's used for
44 * Barrett simultaneous exponentiation too.
45 *
0f32e0f8 46 * Revision 1.11 2001/04/03 19:36:05 mdw
47 * Add some simple bitwise operations so that Perl can use them.
48 *
740c9553 49 * Revision 1.10 2000/10/08 12:03:16 mdw
50 * Provide @mp_eq@ and @MP_EQ@ for rapidly testing equality of two
51 * integers.
52 *
5fbe3846 53 * Revision 1.9 2000/07/29 17:03:31 mdw
54 * Add support for left-to-right bitscanning, for use in modular
55 * exponentiation.
56 *
22a073c0 57 * Revision 1.8 2000/06/22 19:02:01 mdw
58 * Add new functions.
59 *
d34decd2 60 * Revision 1.7 2000/06/17 11:45:09 mdw
61 * Major memory management overhaul. Added arena support. Use the secure
62 * arena for secret integers. Replace and improve the MP management macros
63 * (e.g., replace MP_MODIFY by MP_DEST).
64 *
d9a8ae10 65 * Revision 1.6 1999/12/10 23:19:46 mdw
66 * Minor bugfixes. New interface for suggested destinations.
67 *
5b00a0ea 68 * Revision 1.5 1999/11/22 20:50:37 mdw
69 * Add support for computing Jacobi symbols.
70 *
24e1e862 71 * Revision 1.4 1999/11/21 22:13:02 mdw
72 * Add mp version of MPX_BITS.
73 *
a790733d 74 * Revision 1.3 1999/11/19 13:19:14 mdw
75 * Fix const annotation.
76 *
d3409d5e 77 * Revision 1.2 1999/11/17 18:02:16 mdw
78 * New multiprecision integer arithmetic suite.
d03ab969 79 *
80 */
81
d9a8ae10 82#ifndef CATACOMB_MP_H
83#define CATACOMB_MP_H
d03ab969 84
85#ifdef __cplusplus
86 extern "C" {
87#endif
88
89/*----- Header files ------------------------------------------------------*/
90
d3409d5e 91#include <assert.h>
d03ab969 92#include <string.h>
93
d3409d5e 94#include <mLib/sub.h>
95
d9a8ae10 96#ifndef CATACOMB_MPW_H
d3409d5e 97# include "mpw.h"
d03ab969 98#endif
99
d34decd2 100#ifndef CATACOMB_ARENA_H
101# include "arena.h"
102#endif
103
104#ifndef CATACOMB_MPARENA_H
105# include "mparena.h"
106#endif
107
d9a8ae10 108#ifndef CATACOMB_MPX_H
d03ab969 109# include "mpx.h"
110#endif
111
d03ab969 112/*----- Data structures ---------------------------------------------------*/
113
3bc0a0fe 114/* --- A multiprecision integer --- */
115
d03ab969 116typedef struct mp {
3bc0a0fe 117 mpw *v, *vl; /* Vector of digits, current limit */
118 size_t sz; /* Size of digit buffer in words */
119 mparena *a; /* Arena for buffer allocation */
120 unsigned f; /* Flags (see below) */
121 unsigned ref; /* Reference counter */
d03ab969 122} mp;
123
3bc0a0fe 124#define MP_NEG 1u /* Negative (signed magnitude) */
125#define MP_BURN 2u /* Secret (viral flag) */
126#define MP_CONST 4u /* Uses strange memory allocation */
127#define MP_UNDEF 8u /* Contains nothing interesting */
128#define MP_DESTROYED 16u /* Has been destroyed */
129
130/* --- A factor for simultaneous exponentation --- *
131 *
132 * Used by the Montgomery and Barrett exponentiators.
133 */
134
135typedef struct mp_expfactor {
136 mp *base;
137 mp *exp;
138} mp_expfactor;
d03ab969 139
d3409d5e 140/*----- Useful constants --------------------------------------------------*/
d03ab969 141
d3409d5e 142extern mp mp_const[];
d03ab969 143
d3409d5e 144#define MP_ZERO (&mp_const[0])
145#define MP_ONE (&mp_const[1])
146#define MP_TWO (&mp_const[2])
147#define MP_THREE (&mp_const[3])
148#define MP_FOUR (&mp_const[4])
149#define MP_FIVE (&mp_const[5])
150#define MP_TEN (&mp_const[6])
d34decd2 151#define MP_256 (&mp_const[7])
152#define MP_MONE (&mp_const[8])
d03ab969 153
d3409d5e 154#define MP_NEW ((mp *)0)
d34decd2 155#define MP_NEWSEC (&mp_const[9])
d03ab969 156
d34decd2 157/*----- Trivial macros ----------------------------------------------------*/
d03ab969 158
d34decd2 159/* --- @MP_LEN@ --- *
d03ab969 160 *
d34decd2 161 * Arguments: @mp *m@ = pointer to a multiprecision integer
d03ab969 162 *
d34decd2 163 * Returns: Length of the integer, in words.
d03ab969 164 */
165
d34decd2 166#define MP_LEN(m) ((m)->vl - ((m)->v))
d03ab969 167
d34decd2 168/*----- Memory management and reference counting --------------------------*/
d3409d5e 169
d34decd2 170/* --- @mp_new@ --- *
d03ab969 171 *
d34decd2 172 * Arguments: @size_t sz@ = size of vector required
173 * @unsigned f@ = flags to set
d03ab969 174 *
d34decd2 175 * Returns: Pointer to a new MP structure.
d03ab969 176 *
d34decd2 177 * Use: Allocates a new multiprecision integer. The data space is
178 * allocated from either the standard global or secret arena,
179 * depending on the initial flags requested.
d03ab969 180 */
181
d34decd2 182extern mp *mp_new(size_t /*sz*/, unsigned /*f*/);
d03ab969 183
d34decd2 184/* --- @mp_create@ --- *
d03ab969 185 *
d34decd2 186 * Arguments: @size_t sz@ = size of vector required
d03ab969 187 *
d34decd2 188 * Returns: Pointer to pristine new MP structure with enough memory
189 * bolted onto it.
190 *
191 * Use: Creates a new multiprecision integer with indeterminate
192 * contents. The integer has a single reference.
d03ab969 193 */
194
d34decd2 195extern mp *mp_create(size_t /*sz*/);
d3409d5e 196
d34decd2 197/* --- @mp_createsecure@ --- *
d03ab969 198 *
d3409d5e 199 * Arguments: @size_t sz@ = size of vector required
d03ab969 200 *
d3409d5e 201 * Returns: Pointer to pristine new MP structure with enough memory
202 * bolted onto it.
d03ab969 203 *
d3409d5e 204 * Use: Creates a new multiprecision integer with indeterminate
d34decd2 205 * contents. The integer has a single reference. The integer's
206 * data space is allocated from the secure arena. Its burn flag
207 * is set.
d03ab969 208 */
209
d34decd2 210extern mp *mp_createsecure(size_t /*sz*/);
d03ab969 211
d3409d5e 212/* --- @mp_build@ --- *
d03ab969 213 *
d3409d5e 214 * Arguments: @mp *m@ = pointer to an MP block to fill in
215 * @mpw *v@ = pointer to a word array
216 * @mpw *vl@ = pointer just past end of array
d03ab969 217 *
218 * Returns: ---
219 *
d3409d5e 220 * Use: Creates a multiprecision integer representing some smallish
221 * number. You must provide storage for the number and dispose
222 * of it when you've finished with it. The number is marked as
223 * constant while it exists.
d03ab969 224 */
225
d3409d5e 226extern void mp_build(mp */*m*/, mpw */*v*/, mpw */*vl*/);
d03ab969 227
d3409d5e 228/* --- @mp_destroy@ --- *
d03ab969 229 *
d3409d5e 230 * Arguments: @mp *m@ = pointer to a multiprecision integer
d03ab969 231 *
232 * Returns: ---
233 *
d3409d5e 234 * Use: Destroys a multiprecision integer. The reference count isn't
235 * checked. Don't use this function if you don't know what
236 * you're doing: use @mp_drop@ instead.
d03ab969 237 */
238
d3409d5e 239extern void mp_destroy(mp */*m*/);
d03ab969 240
d3409d5e 241/* --- @mp_copy@ --- *
d03ab969 242 *
d3409d5e 243 * Arguments: @mp *m@ = pointer to a multiprecision integer
d03ab969 244 *
d3409d5e 245 * Returns: A copy of the given multiprecision integer.
246 *
247 * Use: Copies the given integer. In fact you just get another
248 * reference to the same old one again.
d03ab969 249 */
250
d3409d5e 251extern mp *mp_copy(mp */*m*/);
d03ab969 252
d3409d5e 253#define MP_COPY(m) ((m)->ref++, (m))
254
255/* --- @mp_drop@ --- *
d03ab969 256 *
d3409d5e 257 * Arguments: @mp *m@ = pointer to a multiprecision integer
d03ab969 258 *
259 * Returns: ---
260 *
d3409d5e 261 * Use: Drops a reference to an integer which isn't wanted any more.
262 * If there are no more references, the integer is destroyed.
d03ab969 263 */
264
d3409d5e 265extern void mp_drop(mp */*m*/);
d03ab969 266
d3409d5e 267#define MP_DROP(m) do { \
268 mp *_mm = (m); \
d34decd2 269 _mm->ref--; \
270 if (_mm->ref == 0 && !(_mm->f & MP_CONST)) \
d3409d5e 271 mp_destroy(_mm); \
272} while (0)
273
274/* --- @mp_split@ --- *
d03ab969 275 *
d3409d5e 276 * Arguments: @mp *m@ = pointer to a multiprecision integer
d03ab969 277 *
d3409d5e 278 * Returns: A reference to the same integer, possibly with a different
279 * address.
d03ab969 280 *
d3409d5e 281 * Use: Splits off a modifiable version of the integer referred to.
d03ab969 282 */
283
d3409d5e 284extern mp *mp_split(mp */*m*/);
285
286#define MP_SPLIT(m) do { \
d34decd2 287 mp *_m = (m); \
288 if ((_m->f & MP_CONST) || _m->ref > 1) { \
289 size_t _len = MP_LEN(_m); \
290 mp *_mm = mp_new(_len, _m->f); \
291 if (!(_m->f & MP_UNDEF)) \
292 memcpy(_mm->v, _m->v, MPWS(_len)); \
293 _m->ref--; \
294 _m = _mm; \
d3409d5e 295 } \
d34decd2 296 (m) = _m; \
d3409d5e 297} while (0)
d03ab969 298
d3409d5e 299/* --- @mp_resize@ --- *
d03ab969 300 *
d3409d5e 301 * Arguments: @mp *m@ = pointer to a multiprecision integer
302 * @size_t sz@ = new size
d03ab969 303 *
d3409d5e 304 * Returns: ---
d03ab969 305 *
d3409d5e 306 * Use: Resizes the vector containing the integer's digits. The new
307 * size must be at least as large as the current integer's
d34decd2 308 * length. This isn't really intended for client use.
d03ab969 309 */
310
d3409d5e 311extern void mp_resize(mp */*m*/, size_t /*sz*/);
312
313#define MP_RESIZE(m, ssz) do { \
314 mp *_m = (m); \
315 size_t _sz = (ssz); \
d34decd2 316 mparena *_a = (_m->f & MP_BURN) ? MPARENA_SECURE : MPARENA_GLOBAL; \
317 mpw *_v; \
d3409d5e 318 size_t _len = MP_LEN(_m); \
d34decd2 319 assert(((void)"can't make size less than length", _sz >= _len)); \
320 _v = mpalloc(_a, _sz); \
d9a8ae10 321 if (!(_m->f & MP_UNDEF)) \
322 memcpy(_v, _m->v, MPWS(_len)); \
d3409d5e 323 if (_m->f & MP_BURN) \
324 memset(_m->v, 0, MPWS(_m->sz)); \
d34decd2 325 mpfree(_m->a, _m->v); \
326 _m->a = _a; \
d3409d5e 327 _m->v = _v; \
328 _m->vl = _v + _len; \
d3409d5e 329} while (0)
d03ab969 330
d3409d5e 331/* --- @mp_ensure@ --- *
d03ab969 332 *
d3409d5e 333 * Arguments: @mp *m@ = pointer to a multiprecision integer
334 * @size_t sz@ = required size
d03ab969 335 *
336 * Returns: ---
337 *
d3409d5e 338 * Use: Ensures that the integer has enough space for @sz@ digits.
339 * The value is not changed.
d03ab969 340 */
341
d3409d5e 342extern void mp_ensure(mp */*m*/, size_t /*sz*/);
343
344#define MP_ENSURE(m, ssz) do { \
d34decd2 345 mp *_m = (m); \
d3409d5e 346 size_t _ssz = (ssz); \
d34decd2 347 size_t _len = MP_LEN(_m); \
348 if (_ssz >= _len) { \
349 if (_ssz > _m->sz) \
350 mp_resize(_m, _ssz); \
351 if (!(_m->f & MP_UNDEF) && _ssz > _len) \
352 memset(_m->vl, 0, MPWS(_ssz - _len)); \
353 _m->vl = _m->v + _ssz; \
354 } \
d3409d5e 355} while (0)
d03ab969 356
d34decd2 357/* --- @mp_dest@ --- *
d03ab969 358 *
d34decd2 359 * Arguments: @mp *m@ = a suggested destination integer
360 * @size_t sz@ = size required for result, in digits
361 * @unsigned f@ = various flags
362 *
363 * Returns: A pointer to an appropriate destination.
364 *
365 * Use: Converts a suggested destination into a real destination with
366 * the required properties. If the real destination is @d@,
367 * then the following properties will hold:
368 *
369 * * @d@ will have exactly one reference.
d03ab969 370 *
d34decd2 371 * * If @m@ is not @MP_NEW@, then the contents of @m@ will not
372 * change, unless @f@ has the @MP_UNDEF@ flag set.
d03ab969 373 *
d34decd2 374 * * If @m@ is not @MP_NEW@, then he reference count of @m@ on
375 * entry is equal to the sum of the counts of @d@ and @m@ on
376 * exit.
377 *
378 * * The size of @d@ will be at least @sz@.
379 *
380 * * If @f@ has the @MP_BURN@ flag set, then @d@ will be
381 * allocated from @MPARENA_SECURE@.
382 *
383 * Understanding this function is crucial to using Catacomb's
384 * multiprecision integer library effectively.
d03ab969 385 */
386
d34decd2 387extern mp *mp_dest(mp */*m*/, size_t /*sz*/, unsigned /*f*/);
d03ab969 388
d34decd2 389#define MP_DEST(m, ssz, f) do { \
d3409d5e 390 mp *_m = (m); \
d34decd2 391 size_t _ssz = (ssz); \
392 unsigned _f = (f); \
393 _m = mp_dest(_m, _ssz, _f); \
d3409d5e 394 (m) = _m; \
395} while (0)
396
397/*----- Size manipulation -------------------------------------------------*/
398
399/* --- @mp_shrink@ --- *
d03ab969 400 *
d3409d5e 401 * Arguments: @mp *m@ = pointer to a multiprecision integer
d03ab969 402 *
403 * Returns: ---
404 *
d3409d5e 405 * Use: Reduces the recorded length of an integer. This doesn't
406 * reduce the amount of memory used, although it can improve
407 * performance a bit. To reduce memory, use @mp_minimize@
408 * instead. This can't change the value of an integer, and is
409 * therefore safe to use even when there are multiple
410 * references.
d03ab969 411 */
412
d3409d5e 413extern void mp_shrink(mp */*m*/);
d03ab969 414
d3409d5e 415#define MP_SHRINK(m) do { \
416 mp *_mm = (m); \
417 MPX_SHRINK(_mm->v, _mm->vl); \
418 if (!MP_LEN(_mm)) \
419 _mm->f &= ~MP_NEG; \
420} while (0)
421
422/* --- @mp_minimize@ --- *
d03ab969 423 *
d3409d5e 424 * Arguments: @mp *m@ = pointer to a multiprecision integer
d03ab969 425 *
426 * Returns: ---
427 *
d3409d5e 428 * Use: Reduces the amount of memory an integer uses. It's best to
429 * do this to numbers which aren't going to change in the
430 * future.
d03ab969 431 */
432
d3409d5e 433extern void mp_minimize(mp */*m*/);
d03ab969 434
d3409d5e 435/*----- Bit scanning ------------------------------------------------------*/
d03ab969 436
d9a8ae10 437#ifndef CATACOMB_MPSCAN_H
d3409d5e 438# include "mpscan.h"
439#endif
440
441/* --- @mp_scan@ --- *
d03ab969 442 *
d3409d5e 443 * Arguments: @mpscan *sc@ = pointer to bitscanner block
444 * @const mp *m@ = pointer to a multiprecision integer
d03ab969 445 *
446 * Returns: ---
447 *
d3409d5e 448 * Use: Initializes a bitscanner on a multiprecision integer.
d03ab969 449 */
450
d3409d5e 451extern void mp_scan(mpscan */*sc*/, const mp */*m*/);
452
453#define MP_SCAN(sc, m) do { \
a790733d 454 const mp *_mm = (m); \
d3409d5e 455 mpscan *_sc = (sc); \
456 MPSCAN_INITX(_sc, _mm->v, _mm->vl); \
457} while (0)
458
5fbe3846 459/* --- @mp_rscan@ --- *
460 *
461 * Arguments: @mpscan *sc@ = pointer to bitscanner block
462 * @const mp *m@ = pointer to a multiprecision integer
463 *
464 * Returns: ---
465 *
466 * Use: Initializes a reverse bitscanner on a multiprecision
467 * integer.
468 */
469
470extern void mp_rscan(mpscan */*sc*/, const mp */*m*/);
471
472#define MP_RSCAN(sc, m) do { \
473 const mp *_mm = (m); \
474 mpscan *_sc = (sc); \
475 MPSCAN_RINITX(_sc, _mm->v, _mm->vl); \
476} while (0)
477
d3409d5e 478/* --- Other bitscanning aliases --- */
479
480#define mp_step mpscan_step
481#define mp_bit mpscan_bit
5fbe3846 482#define mp_rstep mpscan_rstep
483#define mp_rbit mpscan_rbit
d3409d5e 484
485#define MP_STEP MPSCAN_STEP
486#define MP_BIT MPSCAN_BIT
5fbe3846 487#define MP_RSTEP MPSCAN_RSTEP
488#define MP_RBIT MPSCAN_RBIT
d3409d5e 489
490/*----- Loading and storing -----------------------------------------------*/
d03ab969 491
d3409d5e 492/* --- @mp_octets@ --- *
d03ab969 493 *
d3409d5e 494 * Arguments: @const mp *m@ = a multiprecision integer
d03ab969 495 *
d3409d5e 496 * Returns: The number of octets required to represent @m@.
d03ab969 497 *
d3409d5e 498 * Use: Calculates the external storage required for a multiprecision
499 * integer.
d03ab969 500 */
501
24e1e862 502extern size_t mp_octets(const mp */*m*/);
503
f09e814a 504/* --- @mp_octets2c@ --- *
505 *
506 * Arguments: @const mp *m@ = a multiprecision integer
507 *
508 * Returns: The number of octets required to represent @m@.
509 *
510 * Use: Calculates the external storage required for a multiprecision
511 * integer represented as two's complement.
512 */
513
514extern size_t mp_octets2c(const mp */*m*/);
515
24e1e862 516/* --- @mp_bits@ --- *
517 *
518 * Arguments: @const mp *m@ = a multiprecision integer
519 *
520 * Returns: The number of bits required to represent @m@.
521 *
522 * Use: Calculates the external storage required for a multiprecision
523 * integer.
524 */
525
526extern unsigned long mp_bits(const mp */*m*/);
d03ab969 527
d3409d5e 528/* --- @mp_loadl@ --- *
d03ab969 529 *
d3409d5e 530 * Arguments: @mp *d@ = destination
531 * @const void *pv@ = pointer to source data
532 * @size_t sz@ = size of the source data
d03ab969 533 *
d3409d5e 534 * Returns: Resulting multiprecision number.
d03ab969 535 *
d3409d5e 536 * Use: Loads a multiprecision number from an array of octets. The
537 * first byte in the array is the least significant. More
538 * formally, if the bytes are %$b_0, b_1, \ldots, b_{n-1}$%
539 * then the result is %$N = \sum_{0 \le i < n} b_i 2^{8i}$%.
d03ab969 540 */
541
d3409d5e 542extern mp *mp_loadl(mp */*d*/, const void */*pv*/, size_t /*sz*/);
d03ab969 543
d3409d5e 544/* --- @mp_storel@ --- *
545 *
546 * Arguments: @const mp *m@ = source
547 * @void *pv@ = pointer to output array
548 * @size_t sz@ = size of the output array
549 *
550 * Returns: ---
551 *
552 * Use: Stores a multiprecision number in an array of octets. The
553 * first byte in the array is the least significant. If the
554 * array is too small to represent the number, high-order bits
555 * are truncated; if the array is too large, high order bytes
556 * are filled with zeros. More formally, if the number is
557 * %$N = \sum{0 \le i} b_i 2^{8i}$% where %$0 \le b_i < 256$%,
558 * then the array is %$b_0, b_1, \ldots, b_{n-1}$%.
559 */
d03ab969 560
d3409d5e 561extern void mp_storel(const mp */*m*/, void */*pv*/, size_t /*sz*/);
d03ab969 562
d3409d5e 563/* --- @mp_loadb@ --- *
d03ab969 564 *
d3409d5e 565 * Arguments: @mp *d@ = destination
566 * @const void *pv@ = pointer to source data
567 * @size_t sz@ = size of the source data
d03ab969 568 *
d3409d5e 569 * Returns: Resulting multiprecision number.
d03ab969 570 *
d3409d5e 571 * Use: Loads a multiprecision number from an array of octets. The
572 * last byte in the array is the least significant. More
573 * formally, if the bytes are %$b_{n-1}, b_{n-2}, \ldots, b_0$%
574 * then the result is %$N = \sum_{0 \le i < n} b_i 2^{8i}$%.
d03ab969 575 */
576
d3409d5e 577extern mp *mp_loadb(mp */*d*/, const void */*pv*/, size_t /*sz*/);
d03ab969 578
d3409d5e 579/* --- @mp_storeb@ --- *
d03ab969 580 *
d3409d5e 581 * Arguments: @const mp *m@ = source
582 * @void *pv@ = pointer to output array
583 * @size_t sz@ = size of the output array
d03ab969 584 *
585 * Returns: ---
586 *
d3409d5e 587 * Use: Stores a multiprecision number in an array of octets. The
588 * last byte in the array is the least significant. If the
589 * array is too small to represent the number, high-order bits
590 * are truncated; if the array is too large, high order bytes
591 * are filled with zeros. More formally, if the number is
592 * %$N = \sum{0 \le i} b_i 2^{8i}$% where %$0 \le b_i < 256$%,
593 * then the array is %$b_{n-1}, b_{n-2}, \ldots, b_0$%.
d03ab969 594 */
595
d3409d5e 596extern void mp_storeb(const mp */*m*/, void */*pv*/, size_t /*sz*/);
d03ab969 597
f09e814a 598/* --- @mp_loadl2c@ --- *
d03ab969 599 *
d3409d5e 600 * Arguments: @mp *d@ = destination
f09e814a 601 * @const void *pv@ = pointer to source data
602 * @size_t sz@ = size of the source data
603 *
604 * Returns: Resulting multiprecision number.
d03ab969 605 *
f09e814a 606 * Use: Loads a multiprecision number from an array of octets as
607 * two's complement. The first byte in the array is the least
608 * significant.
d3409d5e 609 */
610
f09e814a 611extern mp *mp_loadl2c(mp */*d*/, const void */*pv*/, size_t /*sz*/);
d3409d5e 612
f09e814a 613/* --- @mp_storel2c@ --- *
614 *
615 * Arguments: @const mp *m@ = source
616 * @void *pv@ = pointer to output array
617 * @size_t sz@ = size of the output array
618 *
619 * Returns: ---
620 *
621 * Use: Stores a multiprecision number in an array of octets as two's
622 * complement. The first byte in the array is the least
623 * significant. If the array is too small to represent the
624 * number, high-order bits are truncated; if the array is too
625 * large, high order bytes are sign-extended.
626 */
627
628extern void mp_storel2c(const mp */*m*/, void */*pv*/, size_t /*sz*/);
629
630/* --- @mp_loadb2c@ --- *
d3409d5e 631 *
632 * Arguments: @mp *d@ = destination
f09e814a 633 * @const void *pv@ = pointer to source data
634 * @size_t sz@ = size of the source data
d03ab969 635 *
f09e814a 636 * Returns: Resulting multiprecision number.
637 *
638 * Use: Loads a multiprecision number from an array of octets as
639 * two's complement. The last byte in the array is the least
640 * significant.
d03ab969 641 */
642
f09e814a 643extern mp *mp_loadb2c(mp */*d*/, const void */*pv*/, size_t /*sz*/);
644
645/* --- @mp_storeb2c@ --- *
646 *
647 * Arguments: @const mp *m@ = source
648 * @void *pv@ = pointer to output array
649 * @size_t sz@ = size of the output array
650 *
651 * Returns: ---
652 *
653 * Use: Stores a multiprecision number in an array of octets, as
654 * two's complement. The last byte in the array is the least
655 * significant. If the array is too small to represent the
656 * number, high-order bits are truncated; if the array is too
657 * large, high order bytes are sign-extended.
658 */
659
660extern void mp_storeb2c(const mp */*m*/, void */*pv*/, size_t /*sz*/);
661
397041a9 662/*----- Bit operations ----------------------------------------------------*/
d03ab969 663
397041a9 664/* --- @mp_not@ --- *
d03ab969 665 *
d3409d5e 666 * Arguments: @mp *d@ = destination
d9a8ae10 667 * @mp *a@ = source
d03ab969 668 *
397041a9 669 * Returns: The bitwise complement of the source.
670 */
d3409d5e 671
397041a9 672extern mp *mp_not(mp */*d*/, mp */*a*/);
d3409d5e 673
397041a9 674/* --- @mp_bitop@ --- *
d3409d5e 675 *
676 * Arguments: @mp *d@ = destination
397041a9 677 * @mp *a, *b@ = sources
d03ab969 678 *
397041a9 679 * Returns: The result of the given bitwise operation. These functions
680 * don't handle negative numbers at all sensibly. For that, use
681 * the @...2c@ variants. The functions are named after the
682 * truth tables they generate:
683 *
684 * a: 0011
685 * b: 0101
686 * @mpx_bitXXXX@
d03ab969 687 */
688
397041a9 689#define MP_BITDECL(string) \
690 extern mp *mp_bit##string(mp */*d*/, mp */*a*/, mp */*b*/);
691MPX_DOBIN(MP_BITDECL)
f09e814a 692
397041a9 693/* --- @mp_[n]and@, @mp_[n]or@, @mp_[n]xor@, @mp_not@ --- *
f09e814a 694 *
397041a9 695 * Synonyms for the commonly-used functions.
f09e814a 696 */
697
397041a9 698#define mp_and mp_bit0001
699#define mp_or mp_bit0111
700#define mp_nand mp_bit1110
701#define mp_nor mp_bit1000
702#define mp_xor mp_bit0110
f09e814a 703
397041a9 704/* --- @mp_testbit@ --- *
f09e814a 705 *
706 * Arguments: @mp *x@ = a large integer
09d00c6b 707 * @unsigned long n@ = which bit to test
f09e814a 708 *
397041a9 709 * Returns: Nonzero if the bit is set, zero if not.
d3409d5e 710 */
711
397041a9 712extern int mp_testbit(mp */*x*/, unsigned long /*n*/);
d3409d5e 713
09d00c6b 714/* --- @mp_setbit@, @mp_clearbit@ --- *
715 *
716 * Arguments: @mp *d@ = a destination
717 * @mp *x@ = a large integer
718 * @unsigned long n@ = which bit to modify
719 *
720 * Returns: The argument @x@, with the appropriate bit set or cleared.
721 */
722
723extern mp *mp_setbit(mp */*d*/, mp */*x*/, unsigned long /*n*/);
724extern mp *mp_clearbit(mp */*d*/, mp */*x*/, unsigned long /*n*/);
725
397041a9 726/* --- @mp_lsl@, @mp_lsr@ --- *
0f32e0f8 727 *
728 * Arguments: @mp *d@ = destination
397041a9 729 * @mp *a@ = source
730 * @size_t n@ = number of bits to move
f09e814a 731 *
397041a9 732 * Returns: Result, @a@ shifted left or right by @n@.
f09e814a 733 */
734
397041a9 735extern mp *mp_lsl(mp */*d*/, mp */*a*/, size_t /*n*/);
736extern mp *mp_lsr(mp */*d*/, mp */*a*/, size_t /*n*/);
f09e814a 737
397041a9 738/* --- @mp_not2c@ --- *
f09e814a 739 *
740 * Arguments: @mp *d@ = destination
741 * @mp *a@ = source
742 *
397041a9 743 * Returns: The sign-extended complement of the argument.
744 */
f09e814a 745
397041a9 746extern mp *mp_not2c(mp */*d*/, mp */*a*/);
0f32e0f8 747
f09e814a 748/* --- @mp_bitop2c@ --- *
749 *
750 * Arguments: @mp *d@ = destination
751 * @mp *a, *b@ = sources
752 *
753 * Returns: The result of the given bitwise operation. Negative numbers
754 * are treated as two's complement, sign-extended infinitely to
755 * the left. The functions are named after the truth tables
756 * they generate:
757 *
758 * a: 0011
759 * b: 0101
760 * @mpx_bitXXXX@
761 */
762
763#define MP_BIT2CDECL(string) \
764 extern mp *mp_bit##string##2c(mp */*d*/, mp */*a*/, mp */*b*/);
765MPX_DOBIN(MP_BIT2CDECL)
766
767/* --- @mp_[n]and@, @mp_[n]or@, @mp_[n]xor@, @mp_not@ --- *
768 *
769 * Synonyms for the commonly-used functions.
770 */
771
772#define mp_and2c mp_bit00012c
773#define mp_or2c mp_bit01112c
774#define mp_nand2c mp_bit11102c
775#define mp_nor2c mp_bit10002c
776#define mp_xor2c mp_bit01102c
777
397041a9 778/* --- @mp_lsl2c@, @mp_lsr2c@ --- *
f09e814a 779 *
780 * Arguments: @mp *d@ = destination
781 * @mp *a@ = source
397041a9 782 * @size_t n@ = number of bits to move
f09e814a 783 *
397041a9 784 * Returns: Result, @a@ shifted left or right by @n@. Handles the
785 * pretence of sign-extension for negative numbers.
f09e814a 786 */
787
397041a9 788extern mp *mp_lsl2c(mp */*d*/, mp */*a*/, size_t /*n*/);
789extern mp *mp_lsr2c(mp */*d*/, mp */*a*/, size_t /*n*/);
790
791/* --- @mp_testbit2c@ --- *
792 *
793 * Arguments: @mp *x@ = a large integer
794 * @unsigned long n@ = which bit to test
795 *
796 * Returns: Nonzero if the bit is set, zero if not. Fakes up two's
797 * complement representation.
798 */
799
800extern int mp_testbit2c(mp */*x*/, unsigned long /*n*/);
801
802/* --- @mp_setbit2c@, @mp_clearbit2c@ --- *
803 *
804 * Arguments: @mp *d@ = a destination
805 * @mp *x@ = a large integer
806 * @unsigned long n@ = which bit to modify
807 *
808 * Returns: The argument @x@, with the appropriate bit set or cleared.
809 * Fakes up two's complement representation.
810 */
811
812extern mp *mp_setbit2c(mp */*d*/, mp */*x*/, unsigned long /*n*/);
813extern mp *mp_clearbit2c(mp */*d*/, mp */*x*/, unsigned long /*n*/);
814
815/*----- Comparisons -------------------------------------------------------*/
816
817/* --- @mp_eq@ --- *
818 *
819 * Arguments: @const mp *a, *b@ = two numbers
820 *
821 * Returns: Nonzero if the numbers are equal.
822 */
823
824extern int mp_eq(const mp */*a*/, const mp */*b*/);
825
826#define MP_EQ(a, b) \
827 ((((a)->f ^ (b)->f) & MP_NEG) == 0 && \
828 mpx_ueq((a)->v, (a)->vl, (b)->v, (b)->vl))
829
830/* --- @mp_cmp@ --- *
831 *
832 * Arguments: @const mp *a, *b@ = two numbers
833 *
834 * Returns: Less than, equal to or greater than zero, according to
835 * whether @a@ is less than, equal to or greater than @b@.
836 */
837
838extern int mp_cmp(const mp */*a*/, const mp */*b*/);
839
840#define MP_CMP(a, op, b) (mp_cmp((a), (b)) op 0)
841
842/*----- Arithmetic operations ---------------------------------------------*/
843
844/* --- @mp_neg@ --- *
845 *
846 * Arguments: @mp *d@ = destination
847 * @mp *a@ = argument
848 *
849 * Returns: The negation of the argument.
850 *
851 * Use: Negates its argument.
852 */
853
854extern mp *mp_neg(mp */*d*/, mp */*a*/);
f09e814a 855
d3409d5e 856/* --- @mp_add@ --- *
d03ab969 857 *
d3409d5e 858 * Arguments: @mp *d@ = destination
d9a8ae10 859 * @mp *a, *b@ = sources
d3409d5e 860 *
861 * Returns: Result, @a@ added to @b@.
d03ab969 862 */
863
d9a8ae10 864extern mp *mp_add(mp */*d*/, mp */*a*/, mp */*b*/);
d03ab969 865
d3409d5e 866/* --- @mp_sub@ --- *
867 *
868 * Arguments: @mp *d@ = destination
d9a8ae10 869 * @mp *a, *b@ = sources
d3409d5e 870 *
871 * Returns: Result, @b@ subtracted from @a@.
872 */
d03ab969 873
d9a8ae10 874extern mp *mp_sub(mp */*d*/, mp */*a*/, mp */*b*/);
d3409d5e 875
876/* --- @mp_mul@ --- *
d03ab969 877 *
d3409d5e 878 * Arguments: @mp *d@ = destination
d9a8ae10 879 * @mp *a, *b@ = sources
d03ab969 880 *
d3409d5e 881 * Returns: Result, @a@ multiplied by @b@.
882 */
883
d9a8ae10 884extern mp *mp_mul(mp */*d*/, mp */*a*/, mp */*b*/);
d3409d5e 885
886/* --- @mp_sqr@ --- *
887 *
888 * Arguments: @mp *d@ = destination
d9a8ae10 889 * @mp *a@ = source
d3409d5e 890 *
891 * Returns: Result, @a@ squared.
892 */
893
d9a8ae10 894extern mp *mp_sqr(mp */*d*/, mp */*a*/);
d3409d5e 895
896/* --- @mp_div@ --- *
d03ab969 897 *
d3409d5e 898 * Arguments: @mp **qq, **rr@ = destination, quotient and remainder
d9a8ae10 899 * @mp *a, *b@ = sources
d3409d5e 900 *
901 * Use: Calculates the quotient and remainder when @a@ is divided by
902 * @b@.
d03ab969 903 */
904
d9a8ae10 905extern void mp_div(mp **/*qq*/, mp **/*rr*/, mp */*a*/, mp */*b*/);
d3409d5e 906
22a073c0 907/* --- @mp_odd@ --- *
908 *
909 * Arguments: @mp *d@ = pointer to destination integer
910 * @mp *m@ = pointer to source integer
911 * @size_t *s@ = where to store the power of 2
912 *
913 * Returns: An odd integer integer %$t$% such that %$m = 2^s t$%.
914 *
915 * Use: Computes a power of two and an odd integer which, when
916 * multiplied, give a specified result. This sort of thing is
917 * useful in number theory quite often.
918 */
919
920extern mp *mp_odd(mp */*d*/, mp */*m*/, size_t */*s*/);
921
d3409d5e 922/*----- More advanced algorithms ------------------------------------------*/
d03ab969 923
22a073c0 924/* --- @mp_sqrt@ --- *
925 *
926 * Arguments: @mp *d@ = pointer to destination integer
927 * @mp *a@ = (nonnegative) integer to take square root of
928 *
929 * Returns: The largest integer %$x$% such that %$x^2 \le a$%.
930 *
931 * Use: Computes integer square roots.
932 *
933 * The current implementation isn't very good: it uses the
934 * Newton-Raphson method to find an approximation to %$a$%. If
935 * there's any demand for a better version, I'll write one.
936 */
937
938extern mp *mp_sqrt(mp */*d*/, mp */*a*/);
939
d3409d5e 940/* --- @mp_gcd@ --- *
d03ab969 941 *
d3409d5e 942 * Arguments: @mp **gcd, **xx, **yy@ = where to write the results
943 * @mp *a, *b@ = sources (must be nonzero)
d03ab969 944 *
945 * Returns: ---
946 *
d3409d5e 947 * Use: Calculates @gcd(a, b)@, and two numbers @x@ and @y@ such that
948 * @ax + by = gcd(a, b)@. This is useful for computing modular
d9a8ae10 949 * inverses. Neither @a@ nor @b@ may be zero.
d03ab969 950 */
951
d3409d5e 952extern void mp_gcd(mp **/*gcd*/, mp **/*xx*/, mp **/*yy*/,
953 mp */*a*/, mp */*b*/);
954
5b00a0ea 955/* --- @mp_jacobi@ --- *
956 *
957 * Arguments: @mp *a@ = an integer less than @n@
958 * @mp *n@ = an odd integer
959 *
960 * Returns: @-1@, @0@ or @1@ -- the Jacobi symbol %$J(a, n)$%.
961 *
962 * Use: Computes the Jacobi symbol. If @n@ is prime, this is the
963 * Legendre symbol and is equal to 1 if and only if @a@ is a
964 * quadratic residue mod @n@. The result is zero if and only if
965 * @a@ and @n@ have a common factor greater than one.
966 */
967
22a073c0 968extern int mp_jacobi(mp */*a*/, mp */*n*/);
969
970/* --- @mp_modsqrt@ --- *
971 *
972 * Arguments: @mp *d@ = destination integer
973 * @mp *a@ = source integer
974 * @mp *p@ = modulus (must be prime)
975 *
976 * Returns: If %$a$% is a quadratic residue, a square root of %$a$%; else
977 * a null pointer.
978 *
979 * Use: Returns an integer %$x$% such that %$x^2 \equiv a \pmod{p}$%,
980 * if one exists; else a null pointer. This function will not
981 * work if %$p$% is composite: you must factor the modulus, take
982 * a square root mod each factor, and recombine the results
983 * using the Chinese Remainder Theorem.
984 */
985
986extern mp *mp_modsqrt(mp */*d*/, mp */*a*/, mp */*p*/);
5b00a0ea 987
d3409d5e 988/*----- Test harness support ----------------------------------------------*/
989
990#include <mLib/testrig.h>
991
d9a8ae10 992#ifndef CATACOMB_MPTEXT_H
d3409d5e 993# include "mptext.h"
994#endif
995
996extern const test_type type_mp;
d03ab969 997
998/*----- That's all, folks -------------------------------------------------*/
999
1000#ifdef __cplusplus
1001 }
1002#endif
1003
1004#endif