zahl.h (7741B)
1 /* See LICENSE file for copyright and license details. */ 2 3 /* Warning: libzahl is not thread-safe. */ 4 /* Caution: Do not use libzahl for cryptographic applications, use a specialised library. */ 5 6 #ifndef ZAHL_H 7 #define ZAHL_H 1 8 9 10 #include <limits.h> 11 #include <setjmp.h> 12 #include <stddef.h> 13 #include <stdint.h> 14 #include <unistd.h> 15 16 17 18 /* TODO these should be documented*/ 19 #define ZAHL_VERSION_MAJOR 1L 20 #define ZAHL_VERSION_MINOR 1L 21 #define ZAHL_VERSION_PATCHLEVEL 0L 22 #define ZAHL_VERSION (ZAHL_VERSION_MAJOR * 1000000L + \ 23 ZAHL_VERSION_MINOR * 1000L + \ 24 ZAHL_VERSION_PATCHLEVEL) 25 #define ZAHL_VERSION_STRING "1.1" 26 #define ZAHL_INTERNALS_VERSION 1 27 #define ZAHL_ZRANDDEV_COUNT 7 28 #define ZAHL_ZRANDDIST_COUNT 3 29 #define ZAHL_ZERROR_COUNT 6 30 31 32 33 #include "zahl/internals.h" 34 35 36 37 typedef struct zahl z_t[1]; 38 39 40 41 enum zprimality { 42 NONPRIME = 0, /* The number is definitely composite. */ 43 PROBABLY_PRIME, /* The number is probably prime. */ 44 PRIME /* The number is definitely prime. */ 45 }; 46 47 enum zranddev { 48 FAST_RANDOM = 0, /* Random numbers are generated directly from /dev/urandom. */ 49 SECURE_RANDOM, /* Random numbers are generated directly from /dev/random. */ 50 DEFAULT_RANDOM, /* Select the default random number generator. */ 51 FASTEST_RANDOM, /* Select the fastest random number generator. */ 52 LIBC_RAND_RANDOM, /* Use rand(3). */ 53 LIBC_RANDOM_RANDOM, /* Use random(3). */ 54 LIBC_RAND48_RANDOM /* Use lrand48(3). */ 55 }; 56 57 enum zranddist { 58 QUASIUNIFORM = 0, /* Almost uniformly random, per the usual recommendation. */ 59 UNIFORM, /* Actually uniformly random. */ 60 MODUNIFORM /* Almost uniformly random, using the naïve approach of modulation. */ 61 }; 62 63 enum zerror { 64 ZERROR_ERRNO_SET = 0, /* Please refer to errno. */ 65 ZERROR_0_POW_0, /* Indeterminate form: 0:th power of 0. (Translatable to EDOM.) */ 66 ZERROR_0_DIV_0, /* Indeterminate form: 0 divided by 0. (Translatable to EDOM.) */ 67 ZERROR_DIV_0, /* Undefined result: Division by 0. (Translatable to EDOM.) */ 68 ZERROR_NEGATIVE, /* Argument must be non-negative. (Translatable to EDOM or EINVAL.) */ 69 ZERROR_INVALID_RADIX /* Radix must be at least 2. (Translatable to EINVAL.) */ 70 }; 71 72 73 74 /* The parameters in the functions below are numbers a, b, c, ... */ 75 76 77 /* Library initialisation and destruction. */ 78 79 void zsetup(jmp_buf); /* Prepare libzahl for use. */ 80 void zunsetup(void); /* Free resources used by libzahl */ 81 82 83 /* Memory functions. */ 84 85 ZAHL_INLINE void zinit(z_t); /* Prepare a for use. */ 86 ZAHL_INLINE void zswap(z_t, z_t); /* (a, b) := (b, a) */ 87 void zfree(z_t); /* Free resources in a. */ 88 ZAHL_INLINE size_t zsave(z_t, void *); /* Store a into b (if !!b), and return number of written bytes. */ 89 size_t zload(z_t, const void *); /* Restore a from b, and return number of read bytes. */ 90 91 92 /* Assignment functions. */ 93 94 ZAHL_INLINE void zset(z_t, z_t); /* a := b */ 95 ZAHL_INLINE void zsetu(z_t, uint64_t); /* a := b */ 96 ZAHL_INLINE void zseti(z_t, int64_t); /* a := b */ 97 98 99 /* Comparison functions. */ 100 101 ZAHL_INLINE int zcmp(z_t, z_t); /* signum (a - b) */ 102 ZAHL_INLINE int zcmpu(z_t, uint64_t); /* signum (a - b) */ 103 ZAHL_INLINE int zcmpi(z_t, int64_t); /* signum (a - b) */ 104 ZAHL_INLINE int zcmpmag(z_t, z_t); /* signum (|a| - |b|) */ 105 106 107 /* Arithmetic functions. */ 108 109 ZAHL_INLINE void zabs(z_t, z_t); /* a := |b| */ 110 ZAHL_INLINE void zneg(z_t, z_t); /* a := -b */ 111 void zadd(z_t, z_t, z_t); /* a := b + c */ 112 void zsub(z_t, z_t, z_t); /* a := b - c */ 113 ZAHL_INLINE void zmul(z_t, z_t, z_t); /* a := b * c */ 114 void zmodmul(z_t, z_t, z_t, z_t); /* a := (b * c) % d */ 115 ZAHL_INLINE void zdiv(z_t, z_t, z_t); /* a := b / c */ 116 void zdivmod(z_t, z_t, z_t, z_t); /* a := c / d, b = c % d */ 117 ZAHL_INLINE void zmod(z_t, z_t, z_t); /* a := b % c */ 118 ZAHL_INLINE void zsqr(z_t, z_t); /* a := b² */ 119 void zmodsqr(z_t, z_t, z_t); /* a := b² % c */ 120 void zpow(z_t, z_t, z_t); /* a := b ↑ c */ 121 void zmodpow(z_t, z_t, z_t, z_t); /* a := (b ↑ c) % d */ 122 void zpowu(z_t, z_t, unsigned long long int); 123 void zmodpowu(z_t, z_t, unsigned long long int, z_t); 124 125 /* These are used internally and may be removed in a future version. */ 126 void zadd_unsigned(z_t, z_t, z_t); /* a := |b| + |c| */ 127 void zsub_unsigned(z_t, z_t, z_t); /* a := |b| - |c| */ 128 void zadd_unsigned_assign(z_t, z_t); /* a := |a| + |b| */ 129 void zsub_nonnegative_assign(z_t, z_t); /* a := a - b, assuming a ≥ b ≥ 0 */ 130 void zsub_positive_assign(z_t, z_t); /* a := a - b, assuming a > b > 0 */ 131 132 133 /* Bitwise operations. */ 134 135 void zand(z_t, z_t, z_t); /* a := b & c */ 136 void zor(z_t, z_t, z_t); /* a := b | c */ 137 void zxor(z_t, z_t, z_t); /* a := b ^ c */ 138 void znot(z_t, z_t); /* a := ~b */ 139 void zlsh(z_t, z_t, size_t); /* a := b << c */ 140 void zrsh(z_t, z_t, size_t); /* a := b >> c */ 141 void ztrunc(z_t, z_t, size_t); /* a := b & ((1 << c) - 1) */ 142 ZAHL_INLINE void zsplit(z_t, z_t, z_t, size_t); 143 /* a := c >> d, b := c - (a << d) */ 144 ZAHL_INLINE int zbtest(z_t, size_t); /* (a >> b) & 1 */ 145 ZAHL_INLINE size_t zlsb(z_t); /* Index of first set bit, SIZE_MAX if none are set. */ 146 ZAHL_INLINE size_t zbits(z_t); /* ⌊log₂ |a|⌋ + 1, 1 if a = 0 */ 147 148 /* If d > 0: a := b | (1 << c), if d = 0: a := b & ~(1 << c), if d < 0: a := b ^ (1 << c) */ 149 ZAHL_INLINE void zbset(z_t, z_t, size_t, int); 150 151 152 /* Number theory. */ 153 154 ZAHL_INLINE int zeven(z_t); /* Is a even? */ 155 ZAHL_INLINE int zodd(z_t); /* Is a odd? */ 156 ZAHL_INLINE int zeven_nonzero(z_t); /* Is a even? Assumes a ≠ 0. */ 157 ZAHL_INLINE int zodd_nonzero(z_t); /* Is a odd? Assumes a ≠ 0. */ 158 ZAHL_INLINE int zzero(z_t); /* Is a zero? */ 159 ZAHL_INLINE int zsignum(z_t); /* a/|a|, 0 if a is zero. */ 160 void zgcd(z_t, z_t, z_t); /* a := gcd(b, c) */ 161 162 /* NONPRIME if b ∉ ℙ, PROBABLY_PRIME, if b ∈ ℙ with (1 − 4↑−c) certainty, 2 if PRIME ∈ ℙ. 163 * If NONPRIME is returned the witness of b's compositeness is stored in a. */ 164 enum zprimality zptest(z_t, z_t, int); 165 166 167 /* Random number generation. */ 168 169 /* Pick a randomly from [0, d] ∩ ℤ. */ 170 void zrand(z_t, enum zranddev, enum zranddist, z_t); 171 172 173 /* String conversion. */ 174 175 char *zstr(z_t, char *, size_t); /* Write a in decimal onto b. c is the output size or 0. */ 176 int zsets(z_t, const char *); /* a := b */ 177 178 /* Length of a in radix b. */ 179 size_t zstr_length(z_t, unsigned long long int); 180 181 182 /* Error handling functions. */ 183 184 enum zerror zerror(const char **); /* Return the current error code, and unless !a, a description in *a. */ 185 void zperror(const char *); /* Identical to perror(3p) except it supports libzahl errors. */ 186 187 188 189 /* Low-level functions. [Do not count on these to be retained between different versions of libzahl.] */ 190 191 void zbset_ll_set(z_t, size_t); /* zbset(a, a, b, 1) */ 192 void zbset_ll_clear(z_t, size_t); /* zbset(a, a, b, 0) */ 193 void zbset_ll_flip(z_t, size_t); /* zbset(a, a, b, -1) */ 194 void zmul_ll(z_t, z_t, z_t); /* zmul for non-negative operands */ 195 void zsqr_ll(z_t, z_t); /* zsqr for non-negative operand */ 196 197 198 199 #include "zahl/inlines.h" 200 201 202 #endif