1 /***************************************************************************
2                                                                            *
3 Copyright 2012 CertiVox IOM Ltd.                                           *
4                                                                            *
5 This file is part of CertiVox MIRACL Crypto SDK.                           *
6                                                                            *
7 The CertiVox MIRACL Crypto SDK provides developers with an                 *
8 extensive and efficient set of cryptographic functions.                    *
9 For further information about its features and functionalities please      *
10 refer to http://www.certivox.com                                           *
11                                                                            *
12 * The CertiVox MIRACL Crypto SDK is free software: you can                 *
13   redistribute it and/or modify it under the terms of the                  *
14   GNU Affero General Public License as published by the                    *
15   Free Software Foundation, either version 3 of the License,               *
16   or (at your option) any later version.                                   *
17                                                                            *
18 * The CertiVox MIRACL Crypto SDK is distributed in the hope                *
19   that it will be useful, but WITHOUT ANY WARRANTY; without even the       *
20   implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
21   See the GNU Affero General Public License for more details.              *
22                                                                            *
23 * You should have received a copy of the GNU Affero General Public         *
24   License along with CertiVox MIRACL Crypto SDK.                           *
25   If not, see <http://www.gnu.org/licenses/>.                              *
26                                                                            *
27 You can be released from the requirements of the license by purchasing     *
28 a commercial license. Buying such a license is mandatory as soon as you    *
29 develop commercial activities involving the CertiVox MIRACL Crypto SDK     *
30 without disclosing the source code of your own applications, or shipping   *
31 the CertiVox MIRACL Crypto SDK with a closed source product.               *
32                                                                            *
33 ***************************************************************************/
34 
35 #ifndef MIRACL_H
36 #define MIRACL_H
37 
38 /*
39  *   main MIRACL header - miracl.h.
40  */
41 
42 #include "mirdef.h"
43 
44 /* Some modifiable defaults... */
45 
46 /* Use a smaller buffer if space is limited, don't be so wasteful! */
47 
48 #ifdef MR_STATIC
49 #define MR_DEFAULT_BUFFER_SIZE 260
50 #else
51 #define MR_DEFAULT_BUFFER_SIZE 1024
52 #endif
53 
54 /* see mrgf2m.c */
55 
56 #ifndef MR_KARATSUBA
57 #define MR_KARATSUBA 2
58 #endif
59 
60 #ifndef MR_DOUBLE_BIG
61 
62 #ifdef MR_KCM
63   #ifdef MR_FLASH
64     #define MR_SPACES 32
65   #else
66     #define MR_SPACES 31
67   #endif
68 #else
69   #ifdef MR_FLASH
70     #define MR_SPACES 28
71   #else
72     #define MR_SPACES 27
73   #endif
74 #endif
75 
76 #else
77 
78 #ifdef MR_KCM
79   #ifdef MR_FLASH
80     #define MR_SPACES 44
81   #else
82     #define MR_SPACES 43
83   #endif
84 #else
85   #ifdef MR_FLASH
86     #define MR_SPACES 40
87   #else
88     #define MR_SPACES 39
89   #endif
90 #endif
91 
92 #endif
93 
94 /* To avoid name clashes - undefine this */
95 
96 #define compare mr_compare
97 
98 #ifdef MR_AVR
99 #include <avr/pgmspace.h>
100 #endif
101 
102 /* size of bigs and elliptic curve points for memory allocation from stack or heap */
103 
104 #define MR_ROUNDUP(a,b) ((a)-1)/(b)+1
105 
106 #define MR_SL sizeof(long)
107 
108 #ifdef MR_STATIC
109 
110 #define MR_SIZE (((sizeof(struct bigtype)+(MR_STATIC+2)*sizeof(mr_utype))-1)/MR_SL+1)*MR_SL
111 #define MR_BIG_RESERVE(n) ((n)*MR_SIZE+MR_SL)
112 
113 #ifdef MR_AFFINE_ONLY
114 #define MR_ESIZE (((sizeof(epoint)+MR_BIG_RESERVE(2))-1)/MR_SL+1)*MR_SL
115 #else
116 #define MR_ESIZE (((sizeof(epoint)+MR_BIG_RESERVE(3))-1)/MR_SL+1)*MR_SL
117 #endif
118 #define MR_ECP_RESERVE(n) ((n)*MR_ESIZE+MR_SL)
119 
120 #define MR_ESIZE_A (((sizeof(epoint)+MR_BIG_RESERVE(2))-1)/MR_SL+1)*MR_SL
121 #define MR_ECP_RESERVE_A(n) ((n)*MR_ESIZE_A+MR_SL)
122 
123 
124 #endif
125 
126 /* useful macro to convert size of big in words, to size of required structure */
127 
128 #define mr_size(n) (((sizeof(struct bigtype)+((n)+2)*sizeof(mr_utype))-1)/MR_SL+1)*MR_SL
129 #define mr_big_reserve(n,m) ((n)*mr_size(m)+MR_SL)
130 
131 #define mr_esize_a(n) (((sizeof(epoint)+mr_big_reserve(2,(n)))-1)/MR_SL+1)*MR_SL
132 #define mr_ecp_reserve_a(n,m) ((n)*mr_esize_a(m)+MR_SL)
133 
134 #ifdef MR_AFFINE_ONLY
135 #define mr_esize(n) (((sizeof(epoint)+mr_big_reserve(2,(n)))-1)/MR_SL+1)*MR_SL
136 #else
137 #define mr_esize(n) (((sizeof(epoint)+mr_big_reserve(3,(n)))-1)/MR_SL+1)*MR_SL
138 #endif
139 #define mr_ecp_reserve(n,m) ((n)*mr_esize(m)+MR_SL)
140 
141 
142 /* if basic library is static, make sure and use static C++ */
143 
144 #ifdef MR_STATIC
145  #ifndef BIGS
146   #define BIGS MR_STATIC
147  #endif
148  #ifndef ZZNS
149   #define ZZNS MR_STATIC
150  #endif
151  #ifndef GF2MS
152   #define GF2MS MR_STATIC
153  #endif
154 #endif
155 
156 #ifdef __ia64__
157 #if MIRACL==64
158 #define MR_ITANIUM
159 #include <ia64intrin.h>
160 #endif
161 #endif
162 
163 #ifdef _M_X64
164 #ifdef _WIN64
165 #if MIRACL==64
166 #define MR_WIN64
167 #endif
168 #endif
169 #endif
170 
171 #ifndef MR_NO_FILE_IO
172 #include <stdio.h>
173 #endif
174                /* error returns */
175 
176 #define MR_ERR_BASE_TOO_BIG       1
177 #define MR_ERR_DIV_BY_ZERO        2
178 #define MR_ERR_OVERFLOW           3
179 #define MR_ERR_NEG_RESULT         4
180 #define MR_ERR_BAD_FORMAT         5
181 #define MR_ERR_BAD_BASE           6
182 #define MR_ERR_BAD_PARAMETERS     7
183 #define MR_ERR_OUT_OF_MEMORY      8
184 #define MR_ERR_NEG_ROOT           9
185 #define MR_ERR_NEG_POWER         10
186 #define MR_ERR_BAD_ROOT          11
187 #define MR_ERR_INT_OP            12
188 #define MR_ERR_FLASH_OVERFLOW    13
189 #define MR_ERR_TOO_BIG           14
190 #define MR_ERR_NEG_LOG           15
191 #define MR_ERR_DOUBLE_FAIL       16
192 #define MR_ERR_IO_OVERFLOW       17
193 #define MR_ERR_NO_MIRSYS         18
194 #define MR_ERR_BAD_MODULUS       19
195 #define MR_ERR_NO_MODULUS        20
196 #define MR_ERR_EXP_TOO_BIG       21
197 #define MR_ERR_NOT_SUPPORTED     22
198 #define MR_ERR_NOT_DOUBLE_LEN    23
199 #define MR_ERR_NOT_IRREDUC       24
200 #define MR_ERR_NO_ROUNDING       25
201 #define MR_ERR_NOT_BINARY        26
202 #define MR_ERR_NO_BASIS          27
203 #define MR_ERR_COMPOSITE_MODULUS 28
204 #define MR_ERR_DEV_RANDOM        29
205 
206                /* some useful definitions */
207 
208 #define forever for(;;)
209 
210 #define mr_abs(x)  ((x)<0? (-(x)) : (x))
211 
212 #ifndef TRUE
213   #define TRUE 1
214 #endif
215 #ifndef FALSE
216   #define FALSE 0
217 #endif
218 
219 #define OFF 0
220 #define ON 1
221 #define PLUS 1
222 #define MINUS (-1)
223 
224 #define M1 (MIRACL-1)
225 #define M2 (MIRACL-2)
226 #define M3 (MIRACL-3)
227 #define M4 (MIRACL-4)
228 #define TOPBIT ((mr_small)1<<M1)
229 #define SECBIT ((mr_small)1<<M2)
230 #define THDBIT ((mr_small)1<<M3)
231 #define M8 (MIRACL-8)
232 
233 #define MR_MAXDEPTH 24
234                               /* max routine stack depth */
235 /* big and flash variables consist of an encoded length, *
236  * and an array of mr_smalls containing the digits       */
237 
238 #ifdef MR_COUNT_OPS
239 extern int fpm2,fpi2,fpc,fpa,fpx;
240 #endif
241 
242 typedef int BOOL;
243 
244 #define MR_BYTE unsigned char
245 
246 #ifdef MR_BITSINCHAR
247  #if MR_BITSINCHAR == 8
248   #define MR_TOBYTE(x) ((MR_BYTE)(x))
249  #else
250   #define MR_TOBYTE(x) ((MR_BYTE)((x)&0xFF))
251  #endif
252 #else
253  #define MR_TOBYTE(x) ((MR_BYTE)(x))
254 #endif
255 
256 #ifdef MR_FP
257 
258   typedef mr_utype mr_small;
259   #ifdef mr_dltype
260   typedef mr_dltype mr_large;
261   #endif
262 
263   #define MR_DIV(a,b)    (modf((a)/(b),&dres),dres)
264 
265   #ifdef MR_FP_ROUNDING
266 
267 /* slightly dicey - for example the optimizer might remove the MAGIC ! */
268 
269     #define MR_LROUND(a)   ( ( (a) + MR_MAGIC ) - MR_MAGIC )
270   #else
271     #define MR_LROUND(a)   (modfl((a),&ldres),ldres)
272   #endif
273 
274   #define MR_REMAIN(a,b) ((a)-(b)*MR_DIV((a),(b)))
275 
276 #else
277 
278   typedef unsigned mr_utype mr_small;
279   #ifdef mr_dltype
280     typedef unsigned mr_dltype mr_large;
281   #endif
282   #ifdef mr_qltype
283     typedef unsigned mr_qltype mr_vlarge;
284   #endif
285 
286   #define MR_DIV(a,b)    ((a)/(b))
287   #define MR_REMAIN(a,b) ((a)%(b))
288   #define MR_LROUND(a)   ((a))
289 #endif
290 
291 
292 /* It might be wanted to change this to unsigned long */
293 
294 typedef unsigned int mr_lentype;
295 
296 struct bigtype
297 {
298     mr_lentype len;
299     mr_small *w;
300 };
301 
302 typedef struct bigtype *big;
303 typedef big zzn;
304 
305 typedef big flash;
306 
307 #define MR_MSBIT ((mr_lentype)1<<(MR_IBITS-1))
308 
309 #define MR_OBITS (MR_MSBIT-1)
310 
311 #if MIRACL >= MR_IBITS
312 #define MR_TOOBIG (1<<(MR_IBITS-2))
313 #else
314 #define MR_TOOBIG (1<<(MIRACL-1))
315 #endif
316 
317 #ifdef  MR_FLASH
318 #define MR_EBITS (8*sizeof(double) - MR_FLASH)
319                                   /* no of Bits per double exponent */
320 #define MR_BTS 16
321 #define MR_MSK 0xFFFF
322 
323 #endif
324 
325 /* Default Hash function output size in bytes */
326 #define MR_HASH_BYTES     32
327 
328 /* Marsaglia & Zaman Random number generator */
329 /*         constants      alternatives       */
330 #define NK   37           /* 21 */
331 #define NJ   24           /*  6 */
332 #define NV   14           /*  8 */
333 
334 /* Use smaller values if memory is precious */
335 
336 #ifdef mr_dltype
337 
338 #ifdef MR_LITTLE_ENDIAN
339 #define MR_BOT 0
340 #define MR_TOP 1
341 #endif
342 #ifdef MR_BIG_ENDIAN
343 #define MR_BOT 1
344 #define MR_TOP 0
345 #endif
346 
347 union doubleword
348 {
349     mr_large d;
350     mr_small h[2];
351 };
352 
353 #endif
354 
355 /* chinese remainder theorem structures */
356 
357 typedef struct {
358 big *C;
359 big *V;
360 big *M;
361 int NP;
362 } big_chinese;
363 
364 typedef struct {
365 mr_utype *C;
366 mr_utype *V;
367 mr_utype *M;
368 int NP;
369 } small_chinese;
370 
371 /* Cryptographically strong pseudo-random number generator */
372 
373 typedef struct {
374 mr_unsign32 ira[NK];  /* random number...   */
375 int         rndptr;   /* ...array & pointer */
376 mr_unsign32 borrow;
377 int pool_ptr;
378 char pool[MR_HASH_BYTES];    /* random pool */
379 } csprng;
380 
381 /* secure hash Algorithm structure */
382 
383 typedef struct {
384 mr_unsign32 length[2];
385 mr_unsign32 h[8];
386 mr_unsign32 w[80];
387 } sha256;
388 
389 typedef sha256 sha;
390 
391 #ifdef mr_unsign64
392 
393 typedef struct {
394 mr_unsign64 length[2];
395 mr_unsign64 h[8];
396 mr_unsign64 w[80];
397 } sha512;
398 
399 typedef sha512 sha384;
400 
401 #endif
402 
403 /* Symmetric Encryption algorithm structure */
404 
405 #define MR_ECB   0
406 #define MR_CBC   1
407 #define MR_CFB1  2
408 #define MR_CFB2  3
409 #define MR_CFB4  5
410 #define MR_PCFB1 10
411 #define MR_PCFB2 11
412 #define MR_PCFB4 13
413 #define MR_OFB1  14
414 #define MR_OFB2  15
415 #define MR_OFB4  17
416 #define MR_OFB8  21
417 #define MR_OFB16 29
418 
419 typedef struct {
420 int Nk,Nr;
421 int mode;
422 mr_unsign32 fkey[60];
423 mr_unsign32 rkey[60];
424 char f[16];
425 } aes;
426 
427 /* AES-GCM suppport. See mrgcm.c */
428 
429 #define GCM_ACCEPTING_HEADER 0
430 #define GCM_ACCEPTING_CIPHER 1
431 #define GCM_NOT_ACCEPTING_MORE 2
432 #define GCM_FINISHED 3
433 #define GCM_ENCRYPTING 0
434 #define GCM_DECRYPTING 1
435 
436 typedef struct {
437 mr_unsign32 table[128][4]; /* 2k bytes */
438 MR_BYTE stateX[16];
439 MR_BYTE Y_0[16];
440 mr_unsign32 counter;
441 mr_unsign32 lenA[2],lenC[2];
442 int status;
443 aes a;
444 } gcm;
445 
446                /* Elliptic curve point status */
447 
448 #define MR_EPOINT_GENERAL    0
449 #define MR_EPOINT_NORMALIZED 1
450 #define MR_EPOINT_INFINITY   2
451 
452 #define MR_NOTSET     0
453 #define MR_PROJECTIVE 0
454 #define MR_AFFINE     1
455 #define MR_BEST       2
456 #define MR_TWIST      8
457 
458 #define MR_OVER       0
459 #define MR_ADD        1
460 #define MR_DOUBLE     2
461 
462 /* Twist type */
463 
464 #define MR_QUADRATIC 2
465 #define MR_CUBIC_M   0x3A
466 #define MR_CUBIC_D   0x3B
467 #define MR_QUARTIC_M 0x4A
468 #define MR_QUARTIC_D 0x4B
469 #define MR_SEXTIC_M  0x6A
470 #define MR_SEXTIC_D  0x6B
471 
472 
473 /* Fractional Sliding Windows for ECC - how much precomputation storage to use ? */
474 /* Note that for variable point multiplication there is an optimal value
475    which can be reduced if space is short. For fixed points its a matter of
476    how much ROM is available to store precomputed points.
477    We are storing the k points (P,3P,5P,7P,...,[2k-1].P) */
478 
479 /* These values can be manually tuned for optimal performance... */
480 
481 #ifdef MR_SMALL_EWINDOW
482 #define MR_ECC_STORE_N  3   /* point store for ecn  variable point multiplication */
483 #define MR_ECC_STORE_2M 3   /* point store for ec2m variable point multiplication */
484 #define MR_ECC_STORE_N2 3   /* point store for ecn2 variable point multiplication */
485 #else
486 #define MR_ECC_STORE_N  8   /* 8/9 is close to optimal for 256 bit exponents */
487 #define MR_ECC_STORE_2M 9
488 #define MR_ECC_STORE_N2 8
489 #endif
490 
491 /*#define MR_ECC_STORE_N2_PRECOMP MR_ECC_STORE_N2 */
492                             /* Might want to make this bigger.. */
493 
494 /* If multi-addition is of m points, and s precomputed values are required, this is max of m*s (=4.10?) */
495 #define MR_MAX_M_T_S 64
496 
497 /* Elliptic Curve epoint structure. Uses projective (X,Y,Z) co-ordinates */
498 
499 typedef struct {
500 int marker;
501 big X;
502 big Y;
503 #ifndef MR_AFFINE_ONLY
504 big Z;
505 #endif
506 } epoint;
507 
508 
509 /* Structure for Comb method for finite *
510    field exponentiation with precomputation */
511 
512 typedef struct {
513 #ifdef MR_STATIC
514     const mr_small *table;
515 #else
516     mr_small *table;
517 #endif
518     big n;
519     int window;
520     int max;
521 } brick;
522 
523 /* Structure for Comb method for elliptic *
524    curve exponentiation with precomputation  */
525 
526 typedef struct {
527 #ifdef MR_STATIC
528     const mr_small *table;
529 #else
530     mr_small *table;
531 #endif
532     big a,b,n;
533     int window;
534     int max;
535 } ebrick;
536 
537 typedef struct {
538 #ifdef MR_STATIC
539     const mr_small *table;
540 #else
541     mr_small *table;
542 #endif
543     big a6,a2;
544     int m,a,b,c;
545     int window;
546     int max;
547 } ebrick2;
548 
549 typedef struct
550 {
551     big a;
552     big b;
553 } zzn2;
554 
555 typedef struct
556 {
557     int marker;
558     zzn2 x;
559     zzn2 y;
560 #ifndef MR_AFFINE_ONLY
561     zzn2 z;
562 #endif
563 
564 } ecn2;
565 
566 typedef struct
567 {
568     big a;
569     big b;
570     big c;
571 } zzn3;
572 
573 typedef struct
574 {
575 	zzn2 a;
576 	zzn2 b;
577 	zzn2 c;
578 } zzn6_3x2;
579 
580 /* main MIRACL instance structure */
581 
582 /* ------------------------------------------------------------------------*/
583 
584 typedef struct {
585 mr_small base;       /* number base     */
586 mr_small apbase;     /* apparent base   */
587 int   pack;          /* packing density */
588 int   lg2b;          /* bits in base    */
589 mr_small base2;      /* 2^mr_lg2b          */
590 BOOL (*user)(void);  /* pointer to user supplied function */
591 
592 int   nib;           /* length of bigs  */
593 #ifndef MR_STRIPPED_DOWN
594 int   depth;                 /* error tracing ..*/
595 int   trace[MR_MAXDEPTH];    /* .. mechanism    */
596 #endif
597 BOOL  check;         /* overflow check  */
598 BOOL  fout;          /* Output to file   */
599 BOOL  fin;           /* Input from file  */
600 BOOL  active;
601 
602 #ifndef MR_NO_FILE_IO
603 
604 FILE  *infile;       /* Input file       */
605 FILE  *otfile;       /* Output file      */
606 
607 #endif
608 
609 
610 #ifndef MR_NO_RAND
611 mr_unsign32 ira[NK];  /* random number...   */
612 int         rndptr;   /* ...array & pointer */
613 mr_unsign32 borrow;
614 #endif
615 
616             /* Montgomery constants */
617 mr_small ndash;
618 big modulus;
619 big pR;
620 BOOL ACTIVE;
621 BOOL MONTY;
622 
623                        /* Elliptic Curve details   */
624 #ifndef MR_NO_SS
625 BOOL SS;               /* True for Super-Singular  */
626 #endif
627 #ifndef MR_NOKOBLITZ
628 BOOL KOBLITZ;          /* True for a Koblitz curve */
629 #endif
630 #ifndef MR_AFFINE_ONLY
631 int coord;
632 #endif
633 int Asize,Bsize;
634 
635 int M,AA,BB,CC;     /* for GF(2^m) curves */
636 
637 /*
638 mr_small pm,mask;
639 int e,k,Me,m;       for GF(p^m) curves */
640 
641 
642 #ifndef MR_STATIC
643 
644 int logN;           /* constants for fast fourier fft multiplication */
645 int nprimes,degree;
646 mr_utype *prime,*cr;
647 mr_utype *inverse,**roots;
648 small_chinese chin;
649 mr_utype const1,const2,const3;
650 mr_small msw,lsw;
651 mr_utype **s1,**s2;   /* pre-computed tables for polynomial reduction */
652 mr_utype **t;         /* workspace */
653 mr_utype *wa;
654 mr_utype *wb;
655 mr_utype *wc;
656 
657 #endif
658 
659 BOOL same;
660 BOOL first_one;
661 BOOL debug;
662 
663 big w0;            /* workspace bigs  */
664 big w1,w2,w3,w4;
665 big w5,w6,w7;
666 big w8,w9,w10,w11;
667 big w12,w13,w14,w15;
668 big sru;
669 big one;
670 
671 #ifdef MR_KCM
672 big big_ndash;
673 big ws,wt;
674 #endif
675 
676 big A,B;
677 
678 /* User modifiables */
679 
680 #ifndef MR_SIMPLE_IO
681 int  IOBSIZ;       /* size of i/o buffer */
682 #endif
683 BOOL ERCON;        /* error control   */
684 int  ERNUM;        /* last error code */
685 int  NTRY;         /* no. of tries for probablistic primality testing   */
686 #ifndef MR_SIMPLE_IO
687 int  INPLEN;       /* input length               */
688 #ifndef MR_SIMPLE_BASE
689 int  IOBASE;       /* base for input and output */
690 
691 #endif
692 #endif
693 #ifdef MR_FLASH
694 BOOL EXACT;        /* exact flag      */
695 BOOL RPOINT;       /* =ON for radix point, =OFF for fractions in output */
696 #endif
697 #ifndef MR_STRIPPED_DOWN
698 BOOL TRACER;       /* turns trace tracker on/off */
699 #endif
700 
701 #ifdef MR_STATIC
702 const int *PRIMES;                      /* small primes array         */
703 #ifndef MR_SIMPLE_IO
704 char IOBUFF[MR_DEFAULT_BUFFER_SIZE];    /* i/o buffer    */
705 #endif
706 #else
707 int *PRIMES;        /* small primes array         */
708 #ifndef MR_SIMPLE_IO
709 char *IOBUFF;       /* i/o buffer    */
710 #endif
711 #endif
712 
713 #ifdef MR_FLASH
714 int   workprec;
715 int   stprec;        /* start precision */
716 
717 int RS,RD;
718 double D;
719 
720 double db,n,p;
721 int a,b,c,d,r,q,oldn,ndig;
722 mr_small u,v,ku,kv;
723 
724 BOOL last,carryon;
725 flash pi;
726 
727 #endif
728 
729 #ifdef MR_FP_ROUNDING
730 mr_large inverse_base;
731 #endif
732 
733 #ifndef MR_STATIC
734 char *workspace;
735 #else
736 char workspace[MR_BIG_RESERVE(MR_SPACES)];
737 #endif
738 
739 int TWIST; /* set to twisted curve */
740 int qnr;    /* a QNR -1 for p=3 mod 4, -2 for p=5 mod 8, 0 otherwise */
741 int cnr;    /* a cubic non-residue */
742 int pmod8;
743 int pmod9;
744 BOOL NO_CARRY;
745 } miracl;
746 
747 /* ------------------------------------------------------------------------*/
748 
749 
750 #ifndef MR_GENERIC_MT
751 
752 #ifdef MR_WINDOWS_MT
753 #define MR_OS_THREADS
754 #endif
755 
756 #ifdef MR_UNIX_MT
757 #define MR_OS_THREADS
758 #endif
759 
760 #ifdef MR_OPENMP_MT
761 #define MR_OS_THREADS
762 #endif
763 
764 
765 #ifndef MR_OS_THREADS
766 
767 extern miracl *mr_mip;  /* pointer to MIRACL's only global variable */
768 
769 #endif
770 
771 #endif
772 
773 #ifdef MR_GENERIC_MT
774 
775 #ifdef MR_STATIC
776 #define MR_GENERIC_AND_STATIC
777 #endif
778 
779 #define _MIPT_  miracl *,
780 #define _MIPTO_ miracl *
781 #define _MIPD_  miracl *mr_mip,
782 #define _MIPDO_ miracl *mr_mip
783 #define _MIPP_  mr_mip,
784 #define _MIPPO_ mr_mip
785 
786 #else
787 
788 #define _MIPT_
789 #define _MIPTO_  void
790 #define _MIPD_
791 #define _MIPDO_  void
792 #define _MIPP_
793 #define _MIPPO_
794 
795 #endif
796 
797 /* Preamble and exit code for MIRACL routines. *
798  * Not used if MR_STRIPPED_DOWN is defined     */
799 
800 #ifdef MR_STRIPPED_DOWN
801 #define MR_OUT
802 #define MR_IN(N)
803 #else
804 #define MR_OUT  mr_mip->depth--;
805 #define MR_IN(N) mr_mip->depth++; if (mr_mip->depth<MR_MAXDEPTH) {mr_mip->trace[mr_mip->depth]=(N); if (mr_mip->TRACER) mr_track(_MIPPO_); }
806 #endif
807 
808 /* Function definitions  */
809 
810 /* Group 0 - Internal routines */
811 
812 extern void  mr_berror(_MIPT_ int);
813 extern mr_small mr_shiftbits(mr_small,int);
814 extern mr_small mr_setbase(_MIPT_ mr_small);
815 extern void  mr_track(_MIPTO_ );
816 extern void  mr_lzero(big);
817 extern BOOL  mr_notint(flash);
818 extern int   mr_lent(flash);
819 extern void  mr_padd(_MIPT_ big,big,big);
820 extern void  mr_psub(_MIPT_ big,big,big);
821 extern void  mr_pmul(_MIPT_ big,mr_small,big);
822 #ifdef MR_FP_ROUNDING
823 extern mr_large mr_invert(mr_small);
824 extern mr_small imuldiv(mr_small,mr_small,mr_small,mr_small,mr_large,mr_small *);
825 extern mr_small mr_sdiv(_MIPT_ big,mr_small,mr_large,big);
826 #else
827 extern mr_small mr_sdiv(_MIPT_ big,mr_small,big);
828 extern void mr_and(big,big,big);
829 extern void mr_xor(big,big,big);
830 #endif
831 extern void  mr_shift(_MIPT_ big,int,big);
832 extern miracl *mr_first_alloc(void);
833 extern void  *mr_alloc(_MIPT_ int,int);
834 extern void  mr_free(void *);
835 extern void  set_user_function(_MIPT_ BOOL (*)(void));
836 extern void  set_io_buffer_size(_MIPT_ int);
837 extern int   mr_testbit(_MIPT_ big,int);
838 extern void  mr_addbit(_MIPT_ big,int);
839 extern int   recode(_MIPT_ big ,int ,int ,int );
840 extern int   mr_window(_MIPT_ big,int,int *,int *,int);
841 extern int   mr_window2(_MIPT_ big,big,int,int *,int *);
842 extern int   mr_naf_window(_MIPT_ big,big,int,int *,int *,int);
843 
844 extern int   mr_fft_init(_MIPT_ int,big,big,BOOL);
845 extern void  mr_dif_fft(_MIPT_ int,int,mr_utype *);
846 extern void  mr_dit_fft(_MIPT_ int,int,mr_utype *);
847 extern void  fft_reset(_MIPTO_);
848 
849 extern int   mr_poly_mul(_MIPT_ int,big*,int,big*,big*);
850 extern int   mr_poly_sqr(_MIPT_ int,big*,big*);
851 extern void  mr_polymod_set(_MIPT_ int,big*,big*);
852 extern int   mr_poly_rem(_MIPT_ int,big *,big *);
853 
854 extern int   mr_ps_big_mul(_MIPT_ int,big *,big *,big *);
855 extern int   mr_ps_zzn_mul(_MIPT_ int,big *,big *,big *);
856 
857 extern mr_small muldiv(mr_small,mr_small,mr_small,mr_small,mr_small *);
858 extern mr_small muldvm(mr_small,mr_small,mr_small,mr_small *);
859 extern mr_small muldvd(mr_small,mr_small,mr_small,mr_small *);
860 extern void     muldvd2(mr_small,mr_small,mr_small *,mr_small *);
861 
862 extern flash mirvar_mem_variable(char *,int,int);
863 extern epoint* epoint_init_mem_variable(_MIPT_ char *,int,int);
864 
865 /* Group 1 - General purpose, I/O and basic arithmetic routines  */
866 
867 extern unsigned int   igcd(unsigned int,unsigned int);
868 extern unsigned long  lgcd(unsigned long,unsigned long);
869 extern mr_small sgcd(mr_small,mr_small);
870 extern unsigned int   isqrt(unsigned int,unsigned int);
871 extern unsigned long  mr_lsqrt(unsigned long,unsigned long);
872 extern void  irand(_MIPT_ mr_unsign32);
873 extern mr_small brand(_MIPTO_ );
874 extern void  zero(flash);
875 extern void  convert(_MIPT_ int,big);
876 extern void  uconvert(_MIPT_ unsigned int,big);
877 extern void  lgconv(_MIPT_ long,big);
878 extern void  ulgconv(_MIPT_ unsigned long,big);
879 extern void  tconvert(_MIPT_ mr_utype,big);
880 
881 #ifdef mr_dltype
882 extern void  dlconv(_MIPT_ mr_dltype,big);
883 #endif
884 
885 extern flash mirvar(_MIPT_ int);
886 extern flash mirvar_mem(_MIPT_ char *,int);
887 extern void  mirkill(big);
888 extern void  *memalloc(_MIPT_ int);
889 extern void  memkill(_MIPT_ char *,int);
890 extern void  mr_init_threading(void);
891 extern void  mr_end_threading(void);
892 extern miracl *get_mip(void );
893 extern void  set_mip(miracl *);
894 #ifdef MR_GENERIC_AND_STATIC
895 extern miracl *mirsys(miracl *,int,mr_small);
896 #else
897 extern miracl *mirsys(int,mr_small);
898 #endif
899 extern miracl *mirsys_basic(miracl *,int,mr_small);
900 extern void  mirexit(_MIPTO_ );
901 extern int   exsign(flash);
902 extern void  insign(int,flash);
903 extern int   getdig(_MIPT_ big,int);
904 extern int   numdig(_MIPT_ big);
905 extern void  putdig(_MIPT_ int,big,int);
906 extern void  copy(flash,flash);
907 extern void  negify(flash,flash);
908 extern void  absol(flash,flash);
909 extern int   size(big);
910 extern int   mr_compare(big,big);
911 extern void  add(_MIPT_ big,big,big);
912 extern void  subtract(_MIPT_ big,big,big);
913 extern void  incr(_MIPT_ big,int,big);
914 extern void  decr(_MIPT_ big,int,big);
915 extern void  premult(_MIPT_ big,int,big);
916 extern int   subdiv(_MIPT_ big,int,big);
917 extern BOOL  subdivisible(_MIPT_ big,int);
918 extern int   remain(_MIPT_ big,int);
919 extern void  bytes_to_big(_MIPT_ int,const char *,big);
920 extern int   big_to_bytes(_MIPT_ int,big,char *,BOOL);
921 extern mr_small normalise(_MIPT_ big,big);
922 extern void  multiply(_MIPT_ big,big,big);
923 extern void  fft_mult(_MIPT_ big,big,big);
924 extern BOOL  fastmultop(_MIPT_ int,big,big,big);
925 extern void  divide(_MIPT_ big,big,big);
926 extern BOOL  divisible(_MIPT_ big,big);
927 extern void  mad(_MIPT_ big,big,big,big,big,big);
928 extern int   instr(_MIPT_ flash,char *);
929 extern int   otstr(_MIPT_ flash,char *);
930 extern int   cinstr(_MIPT_ flash,char *);
931 extern int   cotstr(_MIPT_ flash,char *);
932 extern epoint* epoint_init(_MIPTO_ );
933 extern epoint* epoint_init_mem(_MIPT_ char *,int);
934 extern void* ecp_memalloc(_MIPT_ int);
935 void ecp_memkill(_MIPT_ char *,int);
936 BOOL init_big_from_rom(big,int,const mr_small *,int ,int *);
937 BOOL init_point_from_rom(epoint *,int,const mr_small *,int,int *);
938 
939 #ifndef MR_NO_FILE_IO
940 
941 extern int   innum(_MIPT_ flash,FILE *);
942 extern int   otnum(_MIPT_ flash,FILE *);
943 extern int   cinnum(_MIPT_ flash,FILE *);
944 extern int   cotnum(_MIPT_ flash,FILE *);
945 
946 #endif
947 
948 /* Group 2 - Advanced arithmetic routines */
949 
950 extern mr_small smul(mr_small,mr_small,mr_small);
951 extern mr_small spmd(mr_small,mr_small,mr_small);
952 extern mr_small invers(mr_small,mr_small);
953 extern mr_small sqrmp(mr_small,mr_small);
954 extern int      jac(mr_small,mr_small);
955 
956 extern void  gprime(_MIPT_ int);
957 extern int   jack(_MIPT_ big,big);
958 extern int   egcd(_MIPT_ big,big,big);
959 extern int   xgcd(_MIPT_ big,big,big,big,big);
960 extern int   invmodp(_MIPT_ big,big,big);
961 extern int   logb2(_MIPT_ big);
962 extern int   hamming(_MIPT_ big);
963 extern void  expb2(_MIPT_ int,big);
964 extern void  bigbits(_MIPT_ int,big);
965 extern void  expint(_MIPT_ int,int,big);
966 extern void  sftbit(_MIPT_ big,int,big);
967 extern void  power(_MIPT_ big,long,big,big);
968 extern void  powmod(_MIPT_ big,big,big,big);
969 extern void  powmod2(_MIPT_ big,big,big,big,big,big);
970 extern void  powmodn(_MIPT_ int,big *,big *,big,big);
971 extern int   powltr(_MIPT_ int,big,big,big);
972 extern BOOL  double_inverse(_MIPT_ big,big,big,big,big);
973 extern BOOL  multi_inverse(_MIPT_ int,big*,big,big*);
974 extern void  lucas(_MIPT_ big,big,big,big,big);
975 extern BOOL  nroot(_MIPT_ big,int,big);
976 extern BOOL  sqroot(_MIPT_ big,big,big);
977 extern void  bigrand(_MIPT_ big,big);
978 extern void  bigdig(_MIPT_ int,int,big);
979 extern int   trial_division(_MIPT_ big,big);
980 extern BOOL  isprime(_MIPT_ big);
981 extern BOOL  nxprime(_MIPT_ big,big);
982 extern BOOL  nxsafeprime(_MIPT_ int,int,big,big);
983 extern BOOL  crt_init(_MIPT_ big_chinese *,int,big *);
984 extern void  crt(_MIPT_ big_chinese *,big *,big);
985 extern void  crt_end(big_chinese *);
986 extern BOOL  scrt_init(_MIPT_ small_chinese *,int,mr_utype *);
987 extern void  scrt(_MIPT_ small_chinese*,mr_utype *,big);
988 extern void  scrt_end(small_chinese *);
989 #ifndef MR_STATIC
990 extern BOOL  brick_init(_MIPT_ brick *,big,big,int,int);
991 extern void  brick_end(brick *);
992 #else
993 extern void  brick_init(brick *,const mr_small *,big,int,int);
994 #endif
995 extern void  pow_brick(_MIPT_ brick *,big,big);
996 #ifndef MR_STATIC
997 extern BOOL  ebrick_init(_MIPT_ ebrick *,big,big,big,big,big,int,int);
998 extern void  ebrick_end(ebrick *);
999 #else
1000 extern void  ebrick_init(ebrick *,const mr_small *,big,big,big,int,int);
1001 #endif
1002 extern int   mul_brick(_MIPT_ ebrick*,big,big,big);
1003 #ifndef MR_STATIC
1004 extern BOOL  ebrick2_init(_MIPT_ ebrick2 *,big,big,big,big,int,int,int,int,int,int);
1005 extern void  ebrick2_end(ebrick2 *);
1006 #else
1007 extern void  ebrick2_init(ebrick2 *,const mr_small *,big,big,int,int,int,int,int,int);
1008 #endif
1009 extern int   mul2_brick(_MIPT_ ebrick2*,big,big,big);
1010 
1011 /* Montgomery stuff */
1012 
1013 extern mr_small prepare_monty(_MIPT_ big);
1014 extern void  kill_monty(_MIPTO_ );
1015 extern void  nres(_MIPT_ big,big);
1016 extern void  redc(_MIPT_ big,big);
1017 
1018 extern void  nres_negate(_MIPT_ big,big);
1019 extern void  nres_modadd(_MIPT_ big,big,big);
1020 extern void  nres_modsub(_MIPT_ big,big,big);
1021 extern void  nres_lazy(_MIPT_ big,big,big,big,big,big);
1022 extern void  nres_complex(_MIPT_ big,big,big,big);
1023 extern void  nres_double_modadd(_MIPT_ big,big,big);
1024 extern void  nres_double_modsub(_MIPT_ big,big,big);
1025 extern void  nres_premult(_MIPT_ big,int,big);
1026 extern void  nres_modmult(_MIPT_ big,big,big);
1027 extern int   nres_moddiv(_MIPT_ big,big,big);
1028 extern void  nres_dotprod(_MIPT_ int,big *,big *,big);
1029 extern void  nres_powmod(_MIPT_ big,big,big);
1030 extern void  nres_powltr(_MIPT_ int,big,big);
1031 extern void  nres_powmod2(_MIPT_ big,big,big,big,big);
1032 extern void  nres_powmodn(_MIPT_ int,big *,big *,big);
1033 extern BOOL  nres_sqroot(_MIPT_ big,big);
1034 extern void  nres_lucas(_MIPT_ big,big,big,big);
1035 extern BOOL  nres_double_inverse(_MIPT_ big,big,big,big);
1036 extern BOOL  nres_multi_inverse(_MIPT_ int,big *,big *);
1037 extern void  nres_div2(_MIPT_ big,big);
1038 extern void  nres_div3(_MIPT_ big,big);
1039 extern void  nres_div5(_MIPT_ big,big);
1040 
1041 extern void  shs_init(sha *);
1042 extern void  shs_process(sha *,int);
1043 extern void  shs_hash(sha *,char *);
1044 
1045 extern void  shs256_init(sha256 *);
1046 extern void  shs256_process(sha256 *,int);
1047 extern void  shs256_hash(sha256 *,char *);
1048 
1049 #ifdef mr_unsign64
1050 
1051 extern void  shs512_init(sha512 *);
1052 extern void  shs512_process(sha512 *,int);
1053 extern void  shs512_hash(sha512 *,char *);
1054 
1055 extern void  shs384_init(sha384 *);
1056 extern void  shs384_process(sha384 *,int);
1057 extern void  shs384_hash(sha384 *,char *);
1058 
1059 #endif
1060 
1061 extern BOOL  aes_init(aes *,int,int,char *,char *);
1062 extern void  aes_getreg(aes *,char *);
1063 extern void  aes_ecb_encrypt(aes *,MR_BYTE *);
1064 extern void  aes_ecb_decrypt(aes *,MR_BYTE *);
1065 extern mr_unsign32 aes_encrypt(aes *,char *);
1066 extern mr_unsign32 aes_decrypt(aes *,char *);
1067 extern void  aes_reset(aes *,int,char *);
1068 extern void  aes_end(aes *);
1069 
1070 extern void  gcm_init(gcm *,int,char *,int,char *);
1071 extern BOOL  gcm_add_header(gcm *,char *,int);
1072 extern BOOL  gcm_add_cipher(gcm *,int,char *,int,char *);
1073 extern void  gcm_finish(gcm *,char *);
1074 
1075 extern void  strong_init(csprng *,int,char *,mr_unsign32);
1076 extern int   strong_rng(csprng *);
1077 extern void  strong_bigrand(_MIPT_ csprng *,big,big);
1078 extern void  strong_bigdig(_MIPT_ csprng *,int,int,big);
1079 extern void  strong_kill(csprng *);
1080 
1081 /* special modular multipliers */
1082 
1083 extern void  comba_mult(big,big,big);
1084 extern void  comba_square(big,big);
1085 extern void  comba_redc(_MIPT_ big,big);
1086 extern void  comba_modadd(_MIPT_ big,big,big);
1087 extern void  comba_modsub(_MIPT_ big,big,big);
1088 extern void  comba_double_modadd(_MIPT_ big,big,big);
1089 extern void  comba_double_modsub(_MIPT_ big,big,big);
1090 extern void  comba_negate(_MIPT_ big,big);
1091 extern void  comba_add(big,big,big);
1092 extern void  comba_sub(big,big,big);
1093 extern void  comba_double_add(big,big,big);
1094 extern void  comba_double_sub(big,big,big);
1095 
1096 extern void  comba_mult2(_MIPT_ big,big,big);
1097 
1098 extern void  fastmodmult(_MIPT_ big,big,big);
1099 extern void  fastmodsquare(_MIPT_ big,big);
1100 
1101 extern void  kcm_mul(_MIPT_ big,big,big);
1102 extern void  kcm_sqr(_MIPT_ big,big);
1103 extern void  kcm_redc(_MIPT_ big,big);
1104 
1105 extern void  kcm_multiply(_MIPT_ int,big,big,big);
1106 extern void  kcm_square(_MIPT_ int,big,big);
1107 extern BOOL  kcm_top(_MIPT_ int,big,big,big);
1108 
1109 /* elliptic curve stuff */
1110 
1111 extern BOOL point_at_infinity(epoint *);
1112 
1113 extern void mr_jsf(_MIPT_ big,big,big,big,big,big);
1114 
1115 extern void ecurve_init(_MIPT_ big,big,big,int);
1116 extern int  ecurve_add(_MIPT_ epoint *,epoint *);
1117 extern int  ecurve_sub(_MIPT_ epoint *,epoint *);
1118 extern void ecurve_double_add(_MIPT_ epoint *,epoint *,epoint *,epoint *,big *,big *);
1119 extern void ecurve_multi_add(_MIPT_ int,epoint **,epoint **);
1120 extern void ecurve_double(_MIPT_ epoint*);
1121 extern int  ecurve_mult(_MIPT_ big,epoint *,epoint *);
1122 extern void ecurve_mult2(_MIPT_ big,epoint *,big,epoint *,epoint *);
1123 extern void ecurve_multn(_MIPT_ int,big *,epoint**,epoint *);
1124 
1125 extern BOOL epoint_x(_MIPT_ big);
1126 extern BOOL epoint_set(_MIPT_ big,big,int,epoint*);
1127 extern int  epoint_get(_MIPT_ epoint*,big,big);
1128 extern void epoint_getxyz(_MIPT_ epoint *,big,big,big);
1129 extern BOOL epoint_norm(_MIPT_ epoint *);
1130 extern BOOL epoint_multi_norm(_MIPT_ int,big *,epoint **);
1131 extern void epoint_free(epoint *);
1132 extern void epoint_copy(epoint *,epoint *);
1133 extern BOOL epoint_comp(_MIPT_ epoint *,epoint *);
1134 extern void epoint_negate(_MIPT_ epoint *);
1135 
1136 extern BOOL ecurve2_init(_MIPT_ int,int,int,int,big,big,BOOL,int);
1137 extern big  ecurve2_add(_MIPT_ epoint *,epoint *);
1138 extern big  ecurve2_sub(_MIPT_ epoint *,epoint *);
1139 extern void ecurve2_multi_add(_MIPT_ int,epoint **,epoint **);
1140 extern void ecurve2_mult(_MIPT_ big,epoint *,epoint *);
1141 extern void ecurve2_mult2(_MIPT_ big,epoint *,big,epoint *,epoint *);
1142 extern void ecurve2_multn(_MIPT_ int,big *,epoint**,epoint *);
1143 
1144 extern epoint* epoint2_init(_MIPTO_ );
1145 extern BOOL epoint2_set(_MIPT_ big,big,int,epoint*);
1146 extern int  epoint2_get(_MIPT_ epoint*,big,big);
1147 extern void epoint2_getxyz(_MIPT_ epoint *,big,big,big);
1148 extern int  epoint2_norm(_MIPT_ epoint *);
1149 extern void epoint2_free(epoint *);
1150 extern void epoint2_copy(epoint *,epoint *);
1151 extern BOOL epoint2_comp(_MIPT_ epoint *,epoint *);
1152 extern void epoint2_negate(_MIPT_ epoint *);
1153 
1154 /* GF(2) stuff */
1155 
1156 extern BOOL prepare_basis(_MIPT_ int,int,int,int,BOOL);
1157 extern int parity2(big);
1158 extern BOOL multi_inverse2(_MIPT_ int,big *,big *);
1159 extern void add2(big,big,big);
1160 extern void incr2(big,int,big);
1161 extern void reduce2(_MIPT_ big,big);
1162 extern void multiply2(_MIPT_ big,big,big);
1163 extern void modmult2(_MIPT_ big,big,big);
1164 extern void modsquare2(_MIPT_ big,big);
1165 extern void power2(_MIPT_ big,int,big);
1166 extern void sqroot2(_MIPT_ big,big);
1167 extern void halftrace2(_MIPT_ big,big);
1168 extern BOOL quad2(_MIPT_ big,big);
1169 extern BOOL inverse2(_MIPT_ big,big);
1170 extern void karmul2(int,mr_small *,mr_small *,mr_small *,mr_small *);
1171 extern void karmul2_poly(_MIPT_ int,big *,big *,big *,big *);
1172 extern void karmul2_poly_upper(_MIPT_ int,big *,big *,big *,big *);
1173 extern void gf2m_dotprod(_MIPT_ int,big *,big *,big);
1174 extern int  trace2(_MIPT_ big);
1175 extern void rand2(_MIPT_ big);
1176 extern void gcd2(_MIPT_ big,big,big);
1177 extern int degree2(big);
1178 
1179 /* zzn2 stuff */
1180 
1181 extern BOOL zzn2_iszero(zzn2 *);
1182 extern BOOL zzn2_isunity(_MIPT_ zzn2 *);
1183 extern void zzn2_from_int(_MIPT_ int,zzn2 *);
1184 extern void zzn2_from_ints(_MIPT_ int,int,zzn2 *);
1185 extern void zzn2_copy(zzn2 *,zzn2 *);
1186 extern void zzn2_zero(zzn2 *);
1187 extern void zzn2_negate(_MIPT_ zzn2 *,zzn2 *);
1188 extern void zzn2_conj(_MIPT_ zzn2 *,zzn2 *);
1189 extern void zzn2_add(_MIPT_ zzn2 *,zzn2 *,zzn2 *);
1190 extern void zzn2_sub(_MIPT_ zzn2 *,zzn2 *,zzn2 *);
1191 extern void zzn2_smul(_MIPT_ zzn2 *,big,zzn2 *);
1192 extern void zzn2_mul(_MIPT_ zzn2 *,zzn2 *,zzn2 *);
1193 extern void zzn2_sqr(_MIPT_ zzn2 *,zzn2 *);
1194 extern void zzn2_inv(_MIPT_ zzn2 *);
1195 extern void zzn2_timesi(_MIPT_ zzn2 *);
1196 extern void zzn2_powl(_MIPT_ zzn2 *,big,zzn2 *);
1197 extern void zzn2_from_zzns(big,big,zzn2 *);
1198 extern void zzn2_from_bigs(_MIPT_ big,big,zzn2 *);
1199 extern void zzn2_from_zzn(big,zzn2 *);
1200 extern void zzn2_from_big(_MIPT_ big, zzn2 *);
1201 extern void zzn2_sadd(_MIPT_ zzn2 *,big,zzn2 *);
1202 extern void zzn2_ssub(_MIPT_ zzn2 *,big,zzn2 *);
1203 extern void zzn2_div2(_MIPT_ zzn2 *);
1204 extern void zzn2_div3(_MIPT_ zzn2 *);
1205 extern void zzn2_div5(_MIPT_ zzn2 *);
1206 extern void zzn2_imul(_MIPT_ zzn2 *,int,zzn2 *);
1207 extern BOOL zzn2_compare(zzn2 *,zzn2 *);
1208 extern void zzn2_txx(_MIPT_ zzn2 *);
1209 extern void zzn2_txd(_MIPT_ zzn2 *);
1210 extern BOOL zzn2_sqrt(_MIPT_ zzn2 *,zzn2 *);
1211 extern BOOL zzn2_qr(_MIPT_ zzn2 *);
1212 extern BOOL zzn2_multi_inverse(_MIPT_ int,zzn2 *,zzn2 *);
1213 
1214 
1215 /* zzn3 stuff */
1216 
1217 extern void zzn3_set(_MIPT_ int,big);
1218 extern BOOL zzn3_iszero(zzn3 *);
1219 extern BOOL zzn3_isunity(_MIPT_ zzn3 *);
1220 extern void zzn3_from_int(_MIPT_ int,zzn3 *);
1221 extern void zzn3_from_ints(_MIPT_ int,int,int,zzn3 *);
1222 extern void zzn3_copy(zzn3 *,zzn3 *);
1223 extern void zzn3_zero(zzn3 *);
1224 extern void zzn3_negate(_MIPT_ zzn3 *,zzn3 *);
1225 extern void zzn3_powq(_MIPT_ zzn3 *,zzn3 *);
1226 extern void zzn3_add(_MIPT_ zzn3 *,zzn3 *,zzn3 *);
1227 extern void zzn3_sub(_MIPT_ zzn3 *,zzn3 *,zzn3 *);
1228 extern void zzn3_smul(_MIPT_ zzn3 *,big,zzn3 *);
1229 extern void zzn3_mul(_MIPT_ zzn3 *,zzn3 *,zzn3 *);
1230 extern void zzn3_inv(_MIPT_ zzn3 *);
1231 extern void zzn3_timesi(_MIPT_ zzn3 *);
1232 extern void zzn3_timesi2(_MIPT_ zzn3 *);
1233 extern void zzn3_powl(_MIPT_ zzn3 *,big,zzn3 *);
1234 extern void zzn3_from_zzns(big,big,big,zzn3 *);
1235 extern void zzn3_from_bigs(_MIPT_ big,big,big,zzn3 *);
1236 extern void zzn3_from_zzn(big,zzn3 *);
1237 extern void zzn3_from_zzn_1(big,zzn3 *);
1238 extern void zzn3_from_zzn_2(big,zzn3 *);
1239 extern void zzn3_from_big(_MIPT_ big, zzn3 *);
1240 extern void zzn3_sadd(_MIPT_ zzn3 *,big,zzn3 *);
1241 extern void zzn3_ssub(_MIPT_ zzn3 *,big,zzn3 *);
1242 extern void zzn3_div2(_MIPT_ zzn3 *);
1243 extern void zzn3_imul(_MIPT_ zzn3 *,int,zzn3 *);
1244 extern BOOL zzn3_compare(zzn3 *,zzn3 *);
1245 
1246 /* ecn2 stuff */
1247 
1248 extern BOOL ecn2_iszero(ecn2 *);
1249 extern void ecn2_copy(ecn2 *,ecn2 *);
1250 extern void ecn2_zero(ecn2 *);
1251 extern BOOL ecn2_compare(_MIPT_ ecn2 *,ecn2 *);
1252 extern void ecn2_norm(_MIPT_ ecn2 *);
1253 extern void ecn2_get(_MIPT_ ecn2 *,zzn2 *,zzn2 *,zzn2 *);
1254 extern void ecn2_getxy(ecn2 *,zzn2 *,zzn2 *);
1255 extern void ecn2_getx(ecn2 *,zzn2 *);
1256 extern void ecn2_getz(_MIPT_ ecn2 *,zzn2 *);
1257 extern void ecn2_rhs(_MIPT_ zzn2 *,zzn2 *);
1258 extern BOOL ecn2_set(_MIPT_ zzn2 *,zzn2 *,ecn2 *);
1259 extern BOOL ecn2_setx(_MIPT_ zzn2 *,ecn2 *);
1260 extern void ecn2_setxyz(_MIPT_ zzn2 *,zzn2 *,zzn2 *,ecn2 *);
1261 extern void ecn2_negate(_MIPT_ ecn2 *,ecn2 *);
1262 extern BOOL ecn2_add3(_MIPT_ ecn2 *,ecn2 *,zzn2 *,zzn2 *,zzn2 *);
1263 extern BOOL ecn2_add2(_MIPT_ ecn2 *,ecn2 *,zzn2 *,zzn2 *);
1264 extern BOOL ecn2_add1(_MIPT_ ecn2 *,ecn2 *,zzn2 *);
1265 extern BOOL ecn2_add(_MIPT_ ecn2 *,ecn2 *);
1266 extern BOOL ecn2_sub(_MIPT_ ecn2 *,ecn2 *);
1267 extern BOOL ecn2_add_sub(_MIPT_ ecn2 *,ecn2 *,ecn2 *,ecn2 *);
1268 extern int ecn2_mul2_jsf(_MIPT_ big,ecn2 *,big,ecn2 *,ecn2 *);
1269 extern int ecn2_mul(_MIPT_ big,ecn2 *);
1270 extern void ecn2_psi(_MIPT_ zzn2 *,ecn2 *);
1271 extern BOOL ecn2_multi_norm(_MIPT_ int ,zzn2 *,ecn2 *);
1272 extern int ecn2_mul4_gls_v(_MIPT_ big *,int,ecn2 *,big *,ecn2 *,zzn2 *,ecn2 *);
1273 extern int ecn2_muln_engine(_MIPT_ int,int,int,int,big *,big *,big *,big *,ecn2 *,ecn2 *,ecn2 *);
1274 extern void ecn2_precomp_gls(_MIPT_ int,BOOL,ecn2 *,zzn2 *,ecn2 *);
1275 extern int ecn2_mul2_gls(_MIPT_ big *,ecn2 *,zzn2 *,ecn2 *);
1276 extern void ecn2_precomp(_MIPT_ int,BOOL,ecn2 *,ecn2 *);
1277 extern int ecn2_mul2(_MIPT_ big,int,ecn2 *,big,ecn2 *,ecn2 *);
1278 #ifndef MR_STATIC
1279 extern BOOL ecn2_brick_init(_MIPT_ ebrick *,zzn2 *,zzn2 *,big,big,big,int,int);
1280 extern void ecn2_brick_end(ebrick *);
1281 #else
1282 extern void ebrick_init(ebrick *,const mr_small *,big,big,big,int,int);
1283 #endif
1284 extern void ecn2_mul_brick_gls(_MIPT_ ebrick *B,big *,zzn2 *,zzn2 *,zzn2 *);
1285 extern void ecn2_multn(_MIPT_ int,big *,ecn2 *,ecn2 *);
1286 /* Group 3 - Floating-slash routines      */
1287 
1288 #ifdef MR_FLASH
1289 extern void  fpack(_MIPT_ big,big,flash);
1290 extern void  numer(_MIPT_ flash,big);
1291 extern void  denom(_MIPT_ flash,big);
1292 extern BOOL  fit(big,big,int);
1293 extern void  build(_MIPT_ flash,int (*)(_MIPT_ big,int));
1294 extern void  mround(_MIPT_ big,big,flash);
1295 extern void  flop(_MIPT_ flash,flash,int *,flash);
1296 extern void  fmul(_MIPT_ flash,flash,flash);
1297 extern void  fdiv(_MIPT_ flash,flash,flash);
1298 extern void  fadd(_MIPT_ flash,flash,flash);
1299 extern void  fsub(_MIPT_ flash,flash,flash);
1300 extern int   fcomp(_MIPT_ flash,flash);
1301 extern void  fconv(_MIPT_ int,int,flash);
1302 extern void  frecip(_MIPT_ flash,flash);
1303 extern void  ftrunc(_MIPT_ flash,big,flash);
1304 extern void  fmodulo(_MIPT_ flash,flash,flash);
1305 extern void  fpmul(_MIPT_ flash,int,int,flash);
1306 extern void  fincr(_MIPT_ flash,int,int,flash);
1307 extern void  dconv(_MIPT_ double,flash);
1308 extern double fdsize(_MIPT_ flash);
1309 extern void  frand(_MIPT_ flash);
1310 
1311 /* Group 4 - Advanced Flash routines */
1312 
1313 extern void  fpower(_MIPT_ flash,int,flash);
1314 extern BOOL  froot(_MIPT_ flash,int,flash);
1315 extern void  fpi(_MIPT_ flash);
1316 extern void  fexp(_MIPT_ flash,flash);
1317 extern void  flog(_MIPT_ flash,flash);
1318 extern void  fpowf(_MIPT_ flash,flash,flash);
1319 extern void  ftan(_MIPT_ flash,flash);
1320 extern void  fatan(_MIPT_ flash,flash);
1321 extern void  fsin(_MIPT_ flash,flash);
1322 extern void  fasin(_MIPT_ flash,flash);
1323 extern void  fcos(_MIPT_ flash,flash);
1324 extern void  facos(_MIPT_ flash,flash);
1325 extern void  ftanh(_MIPT_ flash,flash);
1326 extern void  fatanh(_MIPT_ flash,flash);
1327 extern void  fsinh(_MIPT_ flash,flash);
1328 extern void  fasinh(_MIPT_ flash,flash);
1329 extern void  fcosh(_MIPT_ flash,flash);
1330 extern void  facosh(_MIPT_ flash,flash);
1331 #endif
1332 
1333 
1334 /* Test predefined Macros to determine compiler type, and hopefully
1335    selectively use fast in-line assembler (or other compiler specific
1336    optimisations. Note I am unsure of Microsoft version numbers. So I
1337    suspect are Microsoft.
1338 
1339    Note: It seems to be impossible to get the 16-bit Microsoft compiler
1340    to allow inline 32-bit op-codes. So I suspect that INLINE_ASM == 2 will
1341    never work with it. Pity.
1342 
1343 #define INLINE_ASM 1    -> generates 8086 inline assembly
1344 #define INLINE_ASM 2    -> generates mixed 8086 & 80386 inline assembly,
1345                            so you can get some benefit while running in a
1346                            16-bit environment on 32-bit hardware (DOS, Windows
1347                            3.1...)
1348 #define INLINE_ASM 3    -> generate true 80386 inline assembly - (Using DOS
1349                            extender, Windows '95/Windows NT)
1350                            Actually optimised for Pentium
1351 
1352 #define INLINE_ASM 4    -> 80386 code in the GNU style (for (DJGPP)
1353 
1354 Small, medium, compact and large memory models are supported for the
1355 first two of the above.
1356 
1357 */
1358 
1359 /* To allow for inline assembly */
1360 
1361 #ifdef __GNUC__
1362     #define ASM __asm__ __volatile__
1363 #endif
1364 
1365 #ifdef __TURBOC__
1366     #define ASM asm
1367 #endif
1368 
1369 #ifdef _MSC_VER
1370     #define ASM _asm
1371 #endif
1372 
1373 #ifndef MR_NOASM
1374 
1375 /* Win64 - inline the time critical function */
1376 #ifndef MR_NO_INTRINSICS
1377 	#ifdef MR_WIN64
1378 		#define muldvd(a,b,c,rp) (*(rp)=_umul128((a),(b),&(tm)),*(rp)+=(c),tm+=(*(rp)<(c)),tm)
1379 		#define muldvd2(a,b,c,rp) (tr=_umul128((a),(b),&(tm)),tr+=(*(c)),tm+=(tr<(*(c))),tr+=(*(rp)),tm+=(tr<(*(rp))),*(rp)=tr,*(c)=tm)
1380 	#endif
1381 
1382 /* Itanium - inline the time-critical functions */
1383 
1384     #ifdef MR_ITANIUM
1385         #define muldvd(a,b,c,rp)  (tm=_m64_xmahu((a),(b),(c)),*(rp)=_m64_xmalu((a),(b),(c)),tm)
1386         #define muldvd2(a,b,c,rp) (tm=_m64_xmalu((a),(b),(*(c))),*(c)=_m64_xmahu((a),(b),(*(c))),tm+=*(rp),*(c)+=(tm<*(rp)),*(rp)=tm)
1387     #endif
1388 #endif
1389 /*
1390 
1391 SSE2 code. Works as for itanium - but in fact it is slower than the regular code so not recommended
1392 Would require a call to emmintrin.h or xmmintrin.h, and an __m128i variable tm to be declared in effected
1393 functions. But it works!
1394 
1395 	#define muldvd(a,b,c,rp)  (tm=_mm_add_epi64(_mm_mul_epu32(_mm_cvtsi32_si128((a)),_mm_cvtsi32_si128((b))),_mm_cvtsi32_si128((c))),*(rp)=_mm_cvtsi128_si32(tm),_mm_cvtsi128_si32(_mm_shuffle_epi32(tm,_MM_SHUFFLE(3,2,0,1))) )
1396 	#define muldvd2(a,b,c,rp) (tm=_mm_add_epi64(_mm_add_epi64(_mm_mul_epu32(_mm_cvtsi32_si128((a)),_mm_cvtsi32_si128((b))),_mm_cvtsi32_si128(*(c))),_mm_cvtsi32_si128(*(rp))),*(rp)=_mm_cvtsi128_si32(tm),*(c)=_mm_cvtsi128_si32( _mm_shuffle_epi32(tm,_MM_SHUFFLE(3,2,0,1))  )
1397 */
1398 
1399 /* Borland C/Turbo C */
1400 
1401     #ifdef __TURBOC__
1402     #ifndef __HUGE__
1403         #if defined(__COMPACT__) || defined(__LARGE__)
1404             #define MR_LMM
1405         #endif
1406 
1407         #if MIRACL==16
1408             #define INLINE_ASM 1
1409         #endif
1410 
1411         #if __TURBOC__>=0x410
1412             #if MIRACL==32
1413 #if defined(__SMALL__) || defined(__MEDIUM__) || defined(__LARGE__) || defined(__COMPACT__)
1414                     #define INLINE_ASM 2
1415                 #else
1416                     #define INLINE_ASM 3
1417                 #endif
1418             #endif
1419         #endif
1420     #endif
1421     #endif
1422 
1423 /* Microsoft C */
1424 
1425     #ifdef _MSC_VER
1426     #ifndef M_I86HM
1427         #if defined(M_I86CM) || defined(M_I86LM)
1428             #define MR_LMM
1429         #endif
1430         #if _MSC_VER>=600
1431             #if _MSC_VER<1200
1432                 #if MIRACL==16
1433                     #define INLINE_ASM 1
1434                 #endif
1435             #endif
1436         #endif
1437         #if _MSC_VER>=1000
1438             #if MIRACL==32
1439                 #define INLINE_ASM 3
1440             #endif
1441         #endif
1442     #endif
1443     #endif
1444 
1445 /* DJGPP GNU C */
1446 
1447     #ifdef __GNUC__
1448     #ifdef i386
1449         #if MIRACL==32
1450             #define INLINE_ASM 4
1451         #endif
1452     #endif
1453     #endif
1454 
1455 #endif
1456 
1457 
1458 
1459 /*
1460    The following contribution is from Tielo Jongmans, Netherlands
1461    These inline assembler routines are suitable for Watcom 10.0 and up
1462 
1463    Added into miracl.h.  Notice the override of the original declarations
1464    of these routines, which should be removed.
1465 
1466    The following pragma is optional, it is dangerous, but it saves a
1467    calling sequence
1468 */
1469 
1470 /*
1471 
1472 #pragma off (check_stack);
1473 
1474 extern unsigned int muldiv(unsigned int, unsigned int, unsigned int, unsigned int, unsigned int *);
1475 #pragma aux muldiv=                 \
1476        "mul     edx"                \
1477        "add     eax,ebx"            \
1478        "adc     edx,0"              \
1479        "div     ecx"                \
1480        "mov     [esi],edx"          \
1481     parm [eax] [edx] [ebx] [ecx] [esi]   \
1482     value [eax]                     \
1483     modify [eax edx];
1484 
1485 extern unsigned int muldvm(unsigned int, unsigned int, unsigned int, unsigned int *);
1486 #pragma aux muldvm=                 \
1487         "div     ebx"               \
1488         "mov     [ecx],edx"         \
1489     parm [edx] [eax] [ebx] [ecx]    \
1490     value [eax]                     \
1491     modify [eax edx];
1492 
1493 extern unsigned int muldvd(unsigned int, unsigned int, unsigned int, unsigned int *);
1494 #pragma aux muldvd=                 \
1495         "mul     edx"               \
1496         "add     eax,ebx"           \
1497         "adc     edx,0"             \
1498         "mov     [ecx],eax"         \
1499         "mov     eax,edx"           \
1500     parm [eax] [edx] [ebx] [ecx]    \
1501     value [eax]                     \
1502     modify [eax edx];
1503 
1504 */
1505 
1506 
1507 #endif
1508 
1509 
1510