/*
 * MPLib.h - Multiple-Precision Integer Arithmetic Shared Library
 *
 * This code is in the public domain. I would appreciate bug reports and
 * enhancements.
 *
 * Duncan S Wong  <swong@ieee.org>
 *
 * Feb 11, 2001 - v0.2
 * Dec 14, 2000 - Initial Version (v0.1)
 */

// Version 0.2 (Feb 11, 2001) - CRT speical case for two moduli (MPLibMP_crt2)
//                            - Primality test algorithm (MPLibMP_probab_prime)
// Version 0.1 (Dec 14, 2000) - Initial Implementation

#ifndef __MPLIB_H__
#define __MPLIB_H__

#ifndef __palmos__
#define __palmos__
#endif

#include <PalmOS.h>     // for OS 3.5, previously Pilot.h
#include "mp.h"

// Use this for SysLibFind calls.
// This is what we 'name' our dispatch table, too.
#define MPLIB_NAME	   "MPLib"
#define MPLIB_CREATOR  'DWMP'      // Register this with Palm

// These are possible error types that the library might return:
typedef enum tagMPErrEnum
{
	MPErrNone      = 0,			
	MPErrParam     = -1,
	MPErrNoGlobals = -2

	// Your custom return codes go here...
} MPErr;

// These are trap identifiers.
// The PalmOS constant 'sysLibTrapCustom' is the first trap number
// we can use after open, close, sleep, and wake.
typedef enum tagMPTrapNumEnum
{
	// - Trap modification checklist -
	// 
	// If you add, remove or otherwise modify something here,
  // be sure you've also done all of the following steps!
  //
	// 0) All trap identifiers must always run sequentially; no gaps!
	// 1) Modify the MPTrapNumEnum in MPLib.h
	// 2) Modify the DC.W to DispatchTable() in MPLibDispatch.c (no gaps!)
	// 3) Modify the JMP in DispatchTable() in MPLibDispatch.c (no gaps!)
	// 4) Update NUMBER_OF_FUNCTIONS in MPLibDispatch.c (0-based)
	// 5) Add or remove an "extern MyFunc(...) SYS_TRAP(MPTrapMyFunc)" prototype somewhere

	MPLibTrapMP_new            = sysLibTrapCustom,    // libDispatchEntry(4)
	MPLibTrapMP_clear,
	MPLibTrapMP_free,
	MPLibTrapMP_clear_free,
	MPLibTrapMP_CTX_new,
	MPLibTrapMP_CTX_free,
  MPLibTrapMP_MONT_CTX_new,
  MPLibTrapMP_MONT_CTX_free,
  MPLibTrapMP_MONT_CTX_set,

	MPLibTrapMP_mask_bits,
	MPLibTrapMP_copy,

	MPLibTrapMP_add,
	MPLibTrapMP_qadd,
	MPLibTrapMP_sub,
	MPLibTrapMP_qsub,
	MPLibTrapMP_mul,
	MPLibTrapMP_mul_digit,
	MPLibTrapMP_mul_add_digit,
	MPLibTrapMP_sqr,
	MPLibTrapMP_div,

	MPLibTrapMP_lshift,
	MPLibTrapMP_lshift1,
	MPLibTrapMP_rshift,
	MPLibTrapMP_rshift1,

	MPLibTrapMP_cmp,
	MPLibTrapMP_ucmp,
	MPLibTrapMP_is_bit_set,

	MPLibTrapMP_mod_mul,
	MPLibTrapMP_mont_mul,
	MPLibTrapMP_mod_inverse,
	MPLibTrapMP_mod_exp,
	MPLibTrapMP_mont_exp,
	MPLibTrapMP_gcd,
	MPLibTrapMP_binary_gcd,
	MPLibTrapMP_crt2,
	MPLibTrapMP_probab_prime,

	MPLibTrapMP_bin2bn,
	MPLibTrapMP_bn2bin,
	MPLibTrapMP_ascii2bn,
	MPLibTrapMP_bn2ascii,
	MPLibTrapMP_num_bits,
  MPLibTrapMP_num_bits_digit
} MPTrapNumEnum;


/*************************
 * MPLib Interface
 *************************/
// These are the four required entry points:
extern MPErr MPLibOpen(UInt16 uRefNum)  SYS_TRAP(sysLibTrapOpen);
extern MPErr MPLibClose(UInt16 uRefNum, UInt32* dwRefCountP)  SYS_TRAP(sysLibTrapClose);
extern Err   MPLibSleep(UInt16 uRefNum) SYS_TRAP(sysLibTrapSleep);
extern Err   MPLibWake(UInt16 uRefNum)  SYS_TRAP(sysLibTrapWake);

// Here are the actual functions we want the library to extend to callers.
extern INT *MPLibMP_new(UInt16 uRefNum)  SYS_TRAP(MPLibTrapMP_new );
extern void	MPLibMP_clear(UInt16 uRefNum, INT *integer)  SYS_TRAP(MPLibTrapMP_clear);
extern void	MPLibMP_free(UInt16 uRefNum, INT *integer)  SYS_TRAP(MPLibTrapMP_free);
extern void	MPLibMP_clear_free(UInt16 uRefNum, INT *integer)  SYS_TRAP(MPLibTrapMP_clear_free);
extern MP_CTX *MPLibMP_CTX_new(UInt16 uRefNum)  SYS_TRAP(MPLibTrapMP_CTX_new);
extern void	MPLibMP_CTX_free(UInt16 uRefNum, MP_CTX *c)  SYS_TRAP(MPLibTrapMP_CTX_free);
extern MP_MONT_CTX *MPLibMP_MONT_CTX_new(UInt16 uRefNum)  SYS_TRAP(MPLibTrapMP_MONT_CTX_new);
extern void MPLibMP_MONT_CTX_free(UInt16 uRefNum, MP_MONT_CTX *mont)  SYS_TRAP(MPLibTrapMP_MONT_CTX_free);
extern Int16 MPLibMP_MONT_CTX_set(UInt16 uRefNum, MP_MONT_CTX *mont, INT *modulus, MP_CTX *ctx)  SYS_TRAP(MPLibTrapMP_MONT_CTX_set);

extern Int16 MPLibMP_mask_bits(UInt16 uRefNum, INT *a, Int16 n)  SYS_TRAP(MPLibTrapMP_mask_bits);
extern INT *MPLibMP_copy(UInt16 uRefNum, INT *dest, INT *src)  SYS_TRAP(MPLibTrapMP_copy);

extern Int16 MPLibMP_add(UInt16 uRefNum, INT *r, INT *a, INT *b)  SYS_TRAP(MPLibTrapMP_add);
extern void	MPLibMP_qadd(UInt16 uRefNum, INT *r, INT *a, INT *b)  SYS_TRAP(MPLibTrapMP_qadd);
extern Int16 MPLibMP_sub(UInt16 uRefNum, INT *r, INT *a, INT *b)  SYS_TRAP(MPLibTrapMP_sub);
extern void	MPLibMP_qsub(UInt16 uRefNum, INT *r, INT *a, INT *b)  SYS_TRAP(MPLibTrapMP_qsub);
extern Int16 MPLibMP_mul(UInt16 uRefNum, INT *r, INT *a, INT *b)  SYS_TRAP(MPLibTrapMP_mul);
extern DIGIT MPLibMP_mul_digit(UInt16 uRefNum, DIGIT *rp, DIGIT *ap, Int16 num, DIGIT w)  SYS_TRAP(MPLibTrapMP_mul_digit);
extern DIGIT MPLibMP_mul_add_digit(UInt16 uRefNum, DIGIT *rp, DIGIT *ap, Int16 num, DIGIT w)  SYS_TRAP(MPLibTrapMP_mul_add_digit);
extern Int16 MPLibMP_sqr(UInt16 uRefNum, INT *r, INT *a)  SYS_TRAP(MPLibTrapMP_sqr);
extern Int16 MPLibMP_div(UInt16 uRefNum, INT *q, INT *r, INT *dividend, INT *divisor, MP_CTX *ctx)  SYS_TRAP(MPLibTrapMP_div);

extern Int16 MPLibMP_lshift(UInt16 uRefNum, INT *to, INT *from, Int16 n)  SYS_TRAP(MPLibTrapMP_lshift);
extern Int16 MPLibMP_lshift1(UInt16 uRefNum, INT *r, INT *a)  SYS_TRAP(MPLibTrapMP_lshift1);
extern Int16 MPLibMP_rshift(UInt16 uRefNum, INT *to, INT *from, Int16 n)  SYS_TRAP(MPLibTrapMP_rshift);
extern Int16 MPLibMP_rshift1(UInt16 uRefNum, INT *r, INT *a)  SYS_TRAP(MPLibTrapMP_rshift1);

extern Int16 MPLibMP_cmp(UInt16 uRefNum, INT *a, INT *b)  SYS_TRAP(MPLibTrapMP_cmp);
extern Int16 MPLibMP_ucmp(UInt16 uRefNum, INT *a, INT *b)  SYS_TRAP(MPLibTrapMP_ucmp);
extern Int16 MPLibMP_is_bit_set(UInt16 uRefNum, INT *a, Int16 n)  SYS_TRAP(MPLibTrapMP_is_bit_set);

extern Int16 MPLibMP_mod_mul(UInt16 uRefNum, INT *r, INT *a, INT *b, INT *m, MP_CTX *ctx)  SYS_TRAP(MPLibTrapMP_mod_mul);
extern Int16 MPLibMP_mont_mul(UInt16 uRefNum, INT *r, INT *a, INT *b, MP_MONT_CTX *mont, MP_CTX *ctx)  SYS_TRAP(MPLibTrapMP_mont_mul);
extern INT *MPLibMP_mod_inverse(UInt16 uRefNum, INT *a, INT *n, MP_CTX *ctx)  SYS_TRAP(MPLibTrapMP_mod_inverse);
extern Int16 MPLibMP_mod_exp(UInt16 uRefNum, INT *r, INT *a, INT *b, INT *m, MP_CTX *ctx)  SYS_TRAP(MPLibTrapMP_mod_exp);
extern Int16 MPLibMP_mont_exp(UInt16 uRefNum, INT *r, INT *a, INT *e, MP_MONT_CTX *mont, MP_CTX *ctx)  SYS_TRAP(MPLibTrapMP_mont_exp);
extern Int16 MPLibMP_gcd(UInt16 uRefNum, INT *d, INT *a, INT *b, MP_CTX *ctx)  SYS_TRAP(MPLibTrapMP_gcd);
extern Int16 MPLibMP_binary_gcd(UInt16 uRefNum, INT *d, INT *a, INT *b, MP_CTX *ctx)  SYS_TRAP(MPLibTrapMP_binary_gcd);
extern Int16 MPLibMP_crt2(UInt16 uRefNum, INT *x, INT *v1, INT *v2, INT *p, INT *q, MP_CTX *ctx)  SYS_TRAP(MPLibTrapMP_crt2);
extern Int16 MPLibMP_probab_prime(UInt16 uRefNum, INT *n, UInt16 reps, MP_CTX *ctx)  SYS_TRAP(MPLibTrapMP_probab_prime);

extern INT *MPLibMP_bin2bn(UInt16 uRefNum, UInt8 *s, UInt16 len)  SYS_TRAP(MPLibTrapMP_bin2bn);
extern UInt16 MPLibMP_bn2bin(UInt16 uRefNum, INT *a, UInt8 *to)  SYS_TRAP(MPLibTrapMP_bn2bin);
extern INT *MPLibMP_ascii2bn(UInt16 uRefNum, Char *str)  SYS_TRAP(MPLibTrapMP_ascii2bn);
extern Char *MPLibMP_bn2ascii(UInt16 uRefNum, INT *a)  SYS_TRAP(MPLibTrapMP_bn2ascii);
extern UInt32 MPLibMP_num_bits(UInt16 uRefNum, INT *a)  SYS_TRAP(MPLibTrapMP_num_bits);
extern UInt16 MPLibMP_num_bits_digit(UInt16 uRefNum, DIGIT l)  SYS_TRAP(MPLibTrapMP_num_bits_digit);

#endif

