1 /** math functions **/
2 module tomcrypt.math;
3 
4 import core.stdc.config;
5 import tomcrypt.prng;
6 import tomcrypt.pk;
7 
8 extern(C) nothrow:
9 
10 enum LTC_MP_LT   = -1;
11 enum LTC_MP_EQ   = 0;
12 enum LTC_MP_GT   = 1;
13 
14 enum LTC_MP_NO   = 0;
15 enum LTC_MP_YES  = 1;
16 
17 version(LTC_MECC) {}
18 else
19 {
20    alias void ecc_point;
21 }
22 
23 version(LTC_MRSA) {}
24 else
25 {
26    alias void rsa_key;
27 }
28 
29 /** math descriptor */
30 struct ltc_math_descriptor
31 {
32    /** Name of the math provider */
33    char *name;
34 
35    /** Bits per digit, amount of bits must fit in an c_ulong */
36    int  bits_per_digit;
37 
38 /* ---- init/deinit functions ---- */
39 
40    /** initialize a bignum
41      @param   a     The number to initialize
42      @return  CRYPT_OK on success
43    */
44    int function(void **a) nothrow init;
45    
46    /** init copy 
47      @param  dst    The number to initialize and write to
48      @param  src    The number to copy from
49      @return CRYPT_OK on success
50    */
51    int function(void **dst, void *src) nothrow init_copy;
52 
53    /** deinit 
54       @param   a    The number to free
55       @return CRYPT_OK on success
56    */
57    void function(void *a) nothrow deinit;
58 
59 /* ---- data movement ---- */
60 
61    /** negate
62       @param   src   The number to negate
63       @param   dst   The destination
64       @return CRYPT_OK on success
65    */
66    int function(void *src, void *dst) nothrow neg;
67    
68    /** copy 
69       @param   src   The number to copy from
70       @param   dst   The number to write to 
71       @return CRYPT_OK on success
72    */
73    int function(void *src, void *dst) nothrow copy;
74 
75 /* ---- trivial low level functions ---- */
76 
77    /** set small constant 
78       @param a    Number to write to
79       @param n    Source upto bits_per_digit (actually meant for very small constants) 
80       @return CRYPT_OK on succcess
81    */
82    int function(void *a, c_ulong n) nothrow set_int;
83 
84    /** get small constant 
85       @param a    Number to read, only fetches upto bits_per_digit from the number
86       @return  The lower bits_per_digit of the integer (unsigned)
87    */
88    c_ulong function(void *a) nothrow get_int;
89 
90    /** get digit n 
91      @param a  The number to read from
92      @param n  The number of the digit to fetch
93      @return  The bits_per_digit  sized n'th digit of a
94    */
95    c_ulong function(void *a, int n) nothrow get_digit;
96 
97    /** Get the number of digits that represent the number
98      @param a   The number to count
99      @return The number of digits used to represent the number
100    */
101    int function(void *a) nothrow get_digit_count;
102 
103    /** compare two integers
104      @param a   The left side integer
105      @param b   The right side integer
106      @return LTC_MP_LT if a < b, LTC_MP_GT if a > b and LTC_MP_EQ otherwise.  (signed comparison)
107    */
108    int function(void *a, void *b) nothrow compare;
109 
110    /** compare against int 
111      @param a   The left side integer
112      @param b   The right side integer (upto bits_per_digit)
113      @return LTC_MP_LT if a < b, LTC_MP_GT if a > b and LTC_MP_EQ otherwise.  (signed comparison)
114    */
115    int function(void *a, c_ulong n) nothrow compare_d;
116 
117    /** Count the number of bits used to represent the integer
118      @param a   The integer to count
119      @return The number of bits required to represent the integer
120    */
121    int function(void * a) nothrow count_bits;
122 
123    /** Count the number of LSB bits which are zero 
124      @param a   The integer to count
125      @return The number of contiguous zero LSB bits
126    */
127    int function(void *a) nothrow count_lsb_bits;
128 
129    /** Compute a power of two
130      @param a  The integer to store the power in
131      @param n  The power of two you want to store (a = 2^n)
132      @return CRYPT_OK on success
133    */
134    int function(void *a , int n) nothrow twoexpt;
135 
136 /* ---- radix conversions ---- */
137    
138    /** read ascii string 
139      @param a     The integer to store into
140      @param str   The string to read
141      @param radix The radix the integer has been represented in (2-64)
142      @return CRYPT_OK on success
143    */
144    int function(void *a, const char *str, int radix) nothrow read_radix;
145 
146    /** write number to string
147      @param a     The integer to store
148      @param str   The destination for the string
149      @param radix The radix the integer is to be represented in (2-64)
150      @return CRYPT_OK on success
151    */
152    int function(void *a, char *str, int radix) nothrow write_radix;
153 
154    /** get size as unsigned char string 
155      @param a     The integer to get the size (when stored in array of octets)
156      @return The length of the integer
157    */
158    c_ulong function(void *a) nothrow unsigned_size;
159 
160    /** store an integer as an array of octets 
161      @param src   The integer to store
162      @param dst   The buffer to store the integer in
163      @return CRYPT_OK on success
164    */
165    int function(void *src, ubyte* dst) nothrow unsigned_write;
166 
167    /** read an array of octets and store as integer
168      @param dst   The integer to load
169      @param src   The array of octets 
170      @param len   The number of octets 
171      @return CRYPT_OK on success
172    */
173    int function(void *dst, ubyte* src, c_ulong len) nothrow unsigned_read;
174 
175 /* ---- basic math ---- */
176 
177    /** add two integers 
178      @param a   The first source integer
179      @param b   The second source integer
180      @param c   The destination of "a + b"
181      @return CRYPT_OK on success
182    */
183    int function(void *a, void *b, void *c) nothrow add;
184 
185 
186    /** add two integers 
187      @param a   The first source integer
188      @param b   The second source integer (single digit of upto bits_per_digit in length)
189      @param c   The destination of "a + b"
190      @return CRYPT_OK on success
191    */
192    int function(void *a, c_ulong b, void *c) nothrow addi;
193 
194    /** subtract two integers 
195      @param a   The first source integer
196      @param b   The second source integer
197      @param c   The destination of "a - b"
198      @return CRYPT_OK on success
199    */
200    int function(void *a, void *b, void *c) nothrow sub;
201 
202    /** subtract two integers 
203      @param a   The first source integer
204      @param b   The second source integer (single digit of upto bits_per_digit in length)
205      @param c   The destination of "a - b"
206      @return CRYPT_OK on success
207    */
208    int function(void *a, c_ulong b, void *c) nothrow subi;
209 
210    /** multiply two integers 
211      @param a   The first source integer
212      @param b   The second source integer (single digit of upto bits_per_digit in length)
213      @param c   The destination of "a * b"
214      @return CRYPT_OK on success
215    */
216    int function(void *a, void *b, void *c) nothrow mul;
217 
218    /** multiply two integers 
219      @param a   The first source integer
220      @param b   The second source integer (single digit of upto bits_per_digit in length)
221      @param c   The destination of "a * b"
222      @return CRYPT_OK on success
223    */
224    int function(void *a, c_ulong b, void *c) nothrow muli;
225 
226    /** Square an integer
227      @param a    The integer to square
228      @param b    The destination
229      @return CRYPT_OK on success
230    */
231    int function(void *a, void *b) nothrow sqr;
232 
233    /** Divide an integer
234      @param a    The dividend
235      @param b    The divisor
236      @param c    The quotient (can be NULL to signify don't care)
237      @param d    The remainder (can be NULL to signify don't care)
238      @return CRYPT_OK on success
239    */
240    int function(void *a, void *b, void *c, void *d) nothrow mpdiv;
241 
242    /** divide by two 
243       @param  a   The integer to divide (shift right)
244       @param  b   The destination 
245       @return CRYPT_OK on success
246    */
247    int function(void *a, void *b) nothrow div_2;
248 
249    /** Get remainder (small value)
250       @param  a    The integer to reduce
251       @param  b    The modulus (upto bits_per_digit in length)
252       @param  c    The destination for the residue
253       @return CRYPT_OK on success
254    */
255    int function(void *a, c_ulong b, c_ulong *c) nothrow modi;
256 
257    /** gcd 
258       @param  a     The first integer
259       @param  b     The second integer
260       @param  c     The destination for (a, b)
261       @return CRYPT_OK on success
262    */
263    int function(void *a, void *b, void *c) nothrow gcd;
264 
265    /** lcm 
266       @param  a     The first integer
267       @param  b     The second integer
268       @param  c     The destination for [a, b]
269       @return CRYPT_OK on success
270    */
271    int function(void *a, void *b, void *c) nothrow lcm;
272 
273    /** Modular multiplication
274       @param  a     The first source
275       @param  b     The second source 
276       @param  c     The modulus
277       @param  d     The destination (a*b mod c)
278       @return CRYPT_OK on success
279    */
280    int function(void *a, void *b, void *c, void *d) nothrow mulmod;
281 
282    /** Modular squaring
283       @param  a     The first source
284       @param  b     The modulus
285       @param  c     The destination (a*a mod b)
286       @return CRYPT_OK on success
287    */
288    int function(void *a, void *b, void *c) nothrow sqrmod;
289 
290    /** Modular inversion
291       @param  a     The value to invert
292       @param  b     The modulus 
293       @param  c     The destination (1/a mod b)
294       @return CRYPT_OK on success
295    */
296    int function(void *, void *, void *) nothrow invmod;
297 
298 /* ---- reduction ---- */
299 
300    /** setup montgomery
301        @param a  The modulus 
302        @param b  The destination for the reduction digit 
303        @return CRYPT_OK on success
304    */
305    int function(void *a, void **b) nothrow montgomery_setup;
306 
307    /** get normalization value 
308        @param a   The destination for the normalization value
309        @param b   The modulus
310        @return  CRYPT_OK on success
311    */
312    int function(void *a, void *b) nothrow montgomery_normalization;
313 
314    /** reduce a number
315        @param a   The number [and dest] to reduce
316        @param b   The modulus
317        @param c   The value "b" from montgomery_setup()
318        @return CRYPT_OK on success
319    */
320    int function(void *a, void *b, void *c) nothrow montgomery_reduce;
321 
322    /** clean up  (frees memory)
323        @param a   The value "b" from montgomery_setup()
324        @return CRYPT_OK on success
325    */      
326    void function(void *a) nothrow montgomery_deinit;
327 
328 /* ---- exponentiation ---- */
329 
330    /** Modular exponentiation
331        @param a    The base integer
332        @param b    The power (can be negative) integer
333        @param c    The modulus integer
334        @param d    The destination
335        @return CRYPT_OK on success
336    */
337    int function(void *a, void *b, void *c, void *d) nothrow exptmod;
338 
339    /** Primality testing
340        @param a     The integer to test
341        @param b     The destination of the result (FP_YES if prime)
342        @return CRYPT_OK on success
343    */
344    int function(void *a, int *b) nothrow isprime;
345 
346 /* ----  (optional) ecc point math ---- */
347 
348    /** ECC GF(p) point multiplication (from the NIST curves)
349        @param k   The integer to multiply the point by
350        @param G   The point to multiply
351        @param R   The destination for kG  
352        @param modulus  The modulus for the field
353        @param map Boolean indicated whether to map back to affine or not (can be ignored if you work in affine only)
354        @return CRYPT_OK on success
355    */
356    int function(void *k, ecc_point *G, ecc_point *R, void *modulus, int map) nothrow ecc_ptmul;
357 
358    /** ECC GF(p) point addition 
359        @param P    The first point
360        @param Q    The second point
361        @param R    The destination of P + Q
362        @param modulus  The modulus
363        @param mp   The "b" value from montgomery_setup()
364        @return CRYPT_OK on success
365    */
366    int function(ecc_point *P, ecc_point *Q, ecc_point *R, void *modulus, void *mp) nothrow ecc_ptadd;
367 
368    /** ECC GF(p) point double 
369        @param P    The first point
370        @param R    The destination of 2P
371        @param modulus  The modulus
372        @param mp   The "b" value from montgomery_setup()
373        @return CRYPT_OK on success
374    */
375    int function(ecc_point *P, ecc_point *R, void *modulus, void *mp) nothrow ecc_ptdbl;
376 
377    /** ECC mapping from projective to affine, currently uses (x,y,z) => (x/z^2, y/z^3, 1)
378        @param P     The point to map
379        @param modulus The modulus
380        @param mp    The "b" value from montgomery_setup()
381        @return CRYPT_OK on success
382        @remark  The mapping can be different but keep in mind a ecc_point only has three 
383                 integers (x,y,z) so if you use a different mapping you have to make it fit.
384    */
385    int function(ecc_point *P, void *modulus, void *mp) nothrow ecc_map;
386 
387    /** Computes kA*A + kB*B = C using Shamir's Trick
388        @param A        First point to multiply
389        @param kA       What to multiple A by
390        @param B        Second point to multiply
391        @param kB       What to multiple B by
392        @param C        [out] Destination point (can overlap with A or B
393        @param modulus  Modulus for curve 
394        @return CRYPT_OK on success
395    */ 
396    int function(ecc_point *A, void *kA,
397            ecc_point *B, void *kB,
398            ecc_point *C,
399            void *modulus) nothrow ecc_mul2add;
400 
401 /* ---- (optional) rsa optimized math (for internal CRT) ---- */
402 
403    /** RSA Key Generation 
404        @param prng     An active PRNG state
405        @param wprng    The index of the PRNG desired
406        @param size     The size of the modulus (key size) desired (octets)
407        @param e        The "e" value (public key).  e==65537 is a good choice
408        @param key      [out] Destination of a newly created private key pair
409        @return CRYPT_OK if successful, upon error all allocated ram is freed
410     */
411     int function(prng_state *prng, int wprng, int size, long e, rsa_key *key) nothrow rsa_keygen;
412    
413 
414    /** RSA exponentiation
415       @param in       The octet array representing the base
416       @param inlen    The length of the input
417       @param out      The destination (to be stored in an octet array format)
418       @param outlen   The length of the output buffer and the resulting size (zero padded to the size of the modulus)
419       @param which    PK_PUBLIC for public RSA and PK_PRIVATE for private RSA
420       @param key      The RSA key to use 
421       @return CRYPT_OK on success
422    */
423    int function(const ubyte* _in,   c_ulong inlen,
424                        ubyte* _out,  c_ulong *outlen, int which,
425                        rsa_key *key) nothrow rsa_me;
426 }
427 
428 extern __gshared ltc_math_descriptor ltc_mp;
429 
430 int ltc_init_multi(void **a, ...);
431 void ltc_deinit_multi(void *a, ...);
432 
433 version(LTM_DESC)
434 {
435     extern const __gshared ltc_math_descriptor ltm_desc;
436 }
437 
438 version(TFM_DESC)
439 {
440     extern const __gshared ltc_math_descriptor tfm_desc;
441 }
442 
443 version(GMP_DESC)
444 {
445     extern const __gshared ltc_math_descriptor gmp_desc;
446 }
447 
448 version(DESC_DEF_ONLY) {}
449 else version(LTC_SOURCE)
450 {
451 
452     alias MP_DIGIT_BIT                 = ltc_mp.bits_per_digit;
453     
454     /* some handy macros */
455     int mp_init(void **a)                   { return ltc_mp.init(a); }
456     alias mp_init_multi                     = ltc_init_multi;
457     void mp_clear(void *a)                  { ltc_mp.deinit(a); }
458     alias mp_clear_multi                    = ltc_deinit_multi;
459     int mp_init_copy(void **dst, void *src) { return ltc_mp.init_copy(dst, src); }
460     
461     int mp_neg(void *src, void *dst)   { return ltc_mp.neg(src, dst); }
462     int mp_copy(void *src, void *dst)  { return ltc_mp.copy(src, dst); }
463     
464     int mp_set(void *a, c_ulong n)     { return ltc_mp.set_int(a, n); } 
465     alias mp_set_int                   = mp_set;
466     
467     c_ulong mp_get_int(void *a)          { return ltc_mp.get_int(a); } 
468     c_ulong mp_get_digit(void *a, int n) { return ltc_mp.get_digit(a, n); }
469     int mp_get_digit_count(void *a)      { return ltc_mp.get_digit_count(a); }
470     int mp_cmp(void *a, void *b)         { return ltc_mp.compare(a, b); }
471     int mp_cmp_d(void *a, c_ulong n)       { return ltc_mp.compare_d(a, n); }
472     int mp_count_bits(void * a)          { return ltc_mp.count_bits(a); }
473     int mp_cnt_lsb(void *a)              { return ltc_mp.count_lsb_bits(a); }
474     int mp_2expt(void *a , int n)        { return ltc_mp.twoexpt(a, n); }
475 
476     int mp_read_radix(void *a, const char *str, int radix)       { return ltc_mp.read_radix(a, str, radix); }
477     int mp_toradix(void *a, char *str, int radix)                { return ltc_mp.write_radix(a, str, radix); }
478     c_ulong mp_unsigned_bin_size(void *a)                        { return ltc_mp.unsigned_size(a); }
479     int mp_to_unsigned_bin(void *src, ubyte* dst)                { return ltc_mp.unsigned_write(src, dst); }
480     int mp_read_unsigned_bin(void *dst, ubyte* src, c_ulong len) { return ltc_mp.unsigned_read(dst, src, len); }
481    
482     int mp_add(void *a, void *b, void *c)               { return ltc_mp.add(a, b, c); }
483     int mp_add_d(void *a, c_ulong b, void *c)           { return ltc_mp.addi(a, b, c); }
484     int mp_sub(void *a, void *b, void *c)               { return ltc_mp.sub(a, b, c); }
485     int mp_sub_d(void *a, c_ulong b, void *c)           { return ltc_mp.subi(a, b, c); }
486     int mp_mul(void *a, void *b, void *c)               { return ltc_mp.mul(a, b, c); }
487     int mp_mul_d(void *a, c_ulong b, void *c)           { return ltc_mp.muli(a, b, c); }
488     int mp_sqr(void *a, void *b)                        { return ltc_mp.sqr(a, b); }
489     int mp_div(void *a, void *b, void *c, void *d)      { return ltc_mp.mpdiv(a, b, c, d); }
490     int mp_div_2(void *a, void *b)                      { return ltc_mp.div_2(a, b); }
491     int mp_mod(void *a, void *b, void *c)               { return ltc_mp.mpdiv(a, b, null, c);} 
492     int mp_mod_d(void *a, c_ulong b, c_ulong *c)        { return ltc_mp.modi(a, b, c); }
493     int mp_gcd(void *a, void *b, void *c)               { return ltc_mp.gcd(a, b, c); }
494     int mp_lcm(void *a, void *b, void *c)               { return ltc_mp.lcm(a, b, c); }
495     
496     int mp_mulmod(void *a, void *b, void *c, void *d)   { return ltc_mp.mulmod(a, b, c, d); }
497     int mp_sqrmod(void *a, void *b, void *c)            { return ltc_mp.sqrmod(a, b, c); }
498     int mp_invmod(void *a, void *b, void *c)            { return ltc_mp.invmod(a, b, c); }
499     
500     int mp_montgomery_setup(void *a, void **b)          { return ltc_mp.montgomery_setup(a, b);}
501     int mp_montgomery_normalization(void *a, void *b)   { return ltc_mp.montgomery_normalization(a, b);}
502     int mp_montgomery_reduce(void *a, void *b, void *c) { return ltc_mp.montgomery_reduce(a, b, c);}   
503     void mp_montgomery_free(void *a)                    { return ltc_mp.montgomery_deinit(a);}
504     
505     int mp_exptmod(void *a, void *b, void *c, void *d)  { return ltc_mp.exptmod(a, b, c, d);}
506     int mp_prime_is_prime(void *a, int *b)              { return ltc_mp.isprime(a, b);}
507     
508     bool mp_iszero(void* a)           {return (mp_cmp_d(a, 0) == LTC_MP_EQ ? LTC_MP_YES : LTC_MP_NO);}
509     bool mp_isodd(void *a)            {return (mp_get_digit_count(a) > 0 ? (mp_get_digit(a, 0) & 1 ? LTC_MP_YES : LTC_MP_NO) : LTC_MP_NO);}
510     void mp_exch(T)(T a, T b)         {void *ABC__tmp = a; a = b; b = ABC__tmp;}
511     
512     int mp_tohex(void *a, char *str) {return mp_toradix(a, str, 16);}
513 }
514 
515 /* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_math.h,v $ */
516 /* $Revision: 1.44 $ */
517 /* $Date: 2007/05/12 14:32:35 $ */