1 /*
2  * lbn.h - Low-level bignum header.
3  * Defines various word sizes and useful macros.
4  *
5  * Copyright (c) 1995  Colin Plumb.  All rights reserved.
6  */
7 #ifndef LBN_H
8 #define LBN_H
9 
10 #ifndef HAVE_CONFIG_H
11 #define HAVE_CONFIG_H 0
12 #endif
13 #if HAVE_CONFIG_H
14 #include "bnconfig.h"
15 #endif
16 
17 /*
18  * Some compilers complain about #if FOO if FOO isn't defined,
19  * so do the ANSI-mandated thing explicitly...
20  */
21 #ifndef NO_LIMITS_H
22 #define NO_LIMITS_H 0
23 #endif
24 
25 /* Make sure we have 8-bit bytes */
26 #if !NO_LIMITS_H
27 #include <limits.h>
28 #if UCHAR_MAX != 0xff || CHAR_BIT != 8
29 #error The bignum library requires 8-bit unsigned characters.
30 #endif
31 #endif /* !NO_LIMITS_H */
32 
33 #ifdef BNINCLUDE	/* If this is defined as, say, foo.h */
34 #define STR(x) #x	/* STR(BNINCLUDE) -> "BNINCLUDE" */
35 #define XSTR(x) STR(x)	/* XSTR(BNINCLUDE) -> STR(foo.h) -> "foo.h" */
36 #include XSTR(BNINCLUDE)	/* #include "foo.h" */
37 #undef XSTR
38 #undef STR
39 #endif
40 
41 /* Do we want bnYield()? */
42 #ifndef BNYIELD
43 #define BNYIELD 0
44 #endif
45 
46 /* Figure out the endianness */
47 /* Error if more than one is defined */
48 #if defined(BN_BIG_ENDIAN) && defined(BN_LITTLE_ENDIAN)
49 #error Only one of BN_BIG_ENDIAN or BN_LITTLE_ENDIAN may be defined
50 #endif
51 
52 /*
53  * If no preference is stated, little-endian C code is slightly more
54  * efficient, so prefer that.  (The endianness here does NOT have to
55  * match the machine's native byte sex; the library's C code will work
56  * either way.  The flexibility is allowed for assembly routines
57  * that do care.
58  */
59 #if !defined(BN_BIG_ENDIAN) && !defined(BN_LITTLE_ENDIAN)
60 #define BN_LITTLE_ENDIAN 1
61 #endif /* !BN_BIG_ENDIAN && !BN_LITTLE_ENDIAN */
62 
63 /* Macros to choose between big and little endian */
64 #if defined(BN_BIG_ENDIAN)
65 #define BIG(b) b
66 #define LITTLE(l) /*nothing*/
67 #define BIGLITTLE(b,l) b
68 #elif BN_LITTLE_ENDIAN
69 #define BIG(b) /*nothing*/
70 #define LITTLE(l) l
71 #define BIGLITTLE(b,l) l
72 #else
73 #error One of BN_BIG_ENDIAN or BN_LITTLE_ENDIAN must be defined as 1
74 #endif
75 
76 
77 /*
78  * Find a 16-bit unsigned type.
79  * Unsigned short is preferred over unsigned int to make the type chosen
80  * by this file more stable on platforms (such as many 68000 compilers)
81  * which support both 16- and 32-bit ints.
82  */
83 #ifndef BNWORD16
84 #ifndef USHRT_MAX	/* No <limits.h> available - guess */
85 typedef unsigned short bnword16;
86 #define BNWORD16 bnword16
87 #elif USHRT_MAX == 0xffff
88 typedef unsigned short bnword16;
89 #define BNWORD16 bnword16
90 #elif UINT_MAX == 0xffff
91 typedef unsigned bnword16;
92 #define BNWORD16 bnword16
93 #endif
94 #endif /* BNWORD16 */
95 
96 /*
97  * Find a 32-bit unsigned type.
98  * Unsigned long is preferred over unsigned int to make the type chosen
99  * by this file more stable on platforms (such as many 68000 compilers)
100  * which support both 16- and 32-bit ints.
101  */
102 #ifndef BNWORD32
103 #ifndef ULONG_MAX	/* No <limits.h> available - guess */
104 typedef unsigned long bnword32;
105 #define BNWORD32 bnword32
106 #elif ULONG_MAX == 0xfffffffful
107 typedef unsigned long bnword32;
108 #define BNWORD32 bnword32
109 #elif UINT_MAX == 0xffffffff
110 typedef unsigned bnword32;
111 #define BNWORD32 bnword32
112 #elif USHRT_MAX == 0xffffffff
113 typedef unsigned short bnword32;
114 #define BNWORD32 bnword32
115 #endif
116 #endif /* BNWORD16 */
117 
118 /*
119  * Find a 64-bit unsigned type.
120  * The conditions here are more complicated to avoid using numbers that
121  * will choke lesser preprocessors (like 0xffffffffffffffff) unless
122  * we're reasonably certain that they'll be acceptable.
123  */
124 #if !defined(BNWORD64) && ULONG_MAX > 0xfffffffful
125 #if ULONG_MAX == 0xffffffffffffffff
126 typedef unsigned long bnword64;
127 #define BNWORD64 bnword64
128 #endif
129 #endif
130 
131 /*
132  * I would test the value of unsigned long long, but some *preprocessors*
133  * don't constants that long even if the compiler can accept them, so it
134  * doesn't work reliably.  So cross our fingers and hope that it's a 64-bit
135  * type.
136  *
137  * GCC uses ULONG_LONG_MAX.  Solaris uses ULLONG_MAX.  IRIX uses ULONGLONG_MAX.
138  * Are there any other names for this?
139  */
140 #if !defined(BNWORD64) && \
141     (defined(ULONG_LONG_MAX) || defined (ULLONG_MAX) || defined(ULONGLONG_MAX))
142 typedef unsigned long long bnword64;
143 #define BNWORD64 bnword64
144 #else
145 typedef unsigned long long bnword64;
146 #define BNWORD64 bnword64
147 #endif
148 
149 /* We don't even try to find a 128-bit type at the moment */
150 
151 #endif /* !LBN_H */
152