libk  num.h

File mod/knum/num.h from the latest check-in


#ifndef KInum
#define KInum

#ifdef __cplusplus
	extern "C" {
#endif

#include <k/type.h>

typedef enum kncond {
	kncond_ok = kncond_id,
	kncond_saturate,
	kncond_wrap,

	/* error states */
	kncond_fail,
	kncond_fail_io,
	kncond_overflow,
	kncond_underflow,
	kncond_bad_domain,
	kncond_bad_base,
 
} kncond;

/* this "hard" random number generator
 * returns a block of random data that
 * can be used safely in cryptographic
 * pseudorandom number algorithms such
 * as e.g. knrands() */

enum kncond
knrandh(u8* mem, sz count);

/* we define the largest available native
 * type as `knword` for convenience; this
 * is the type that the pseudorandom func
 * will use for state and return; */
typedef unsigned long long knword;

/* to encapsulate the state of the pseudo
 * random number generator,  we define an
 * array as an opaque seed reference type */
typedef knword knseed [8];

/* this function implements a "soft" RNG
 * that can be safely used as a cryptographic
 * primitive, keeping its state in a value of
 * type of knseed (which needs to be seeded
 * initially by knrandh() or another reliable
 * source of entropy. */
knword knrands(knseed state);

/* addition and subtraction in C can be
 * complex due to the need to check for
 * underflow and overflow,  so we offer
 * a suite of functions which implement
 * reliable arithmetic over integers of
 * arbitrary bit lengths. functions for 
 * fixed point & floating point numbers
 * should also be added eventually.
 * note that these functions use either
 * two's complement or one's complement
 * for signed */

typedef enum knmode {
	/* knmode operations may be or'd with a base;
	 * base will be inferred by prefix otherwise */
	knmode_saturate = 0x0001 << 7, /* 0b001 */
	knmode_wrap     = 0x0002 << 7, /* 0b010 */
	knmode_fail     = 0x0003 << 7, /* 0b011 */

	knmode_signed   = 1 << 6, /* 0b100*/
	knmode_unsigned = 0 /* default */
} knmode;

/* it is legal for  src and dest to be the
 * same location in memory.  this will not
 * produce incorrect output.  although the
 * functions  formally   take  pointers to
 * ubyte, they are converted appropriately
 * with  regard  to sign  and  size within
 * the fn */

kncond kniadd(knmode, sz, ubyte* dest, ubyte* src, ubyte* delta);
kncond knisub(knmode, sz, ubyte* dest, ubyte* src, ubyte* delta);
kncond knimul(knmode, sz, ubyte* dest, ubyte* src, ubyte* delta);
kncond knidiv(knmode, sz,
	/* output */ ubyte* ratio, ubyte* remainder,
	/*  input */ ubyte* src, ubyte delta);

/* we should probably also offer a bignum
 * type eventually, tho this will need to
 * be integrated with kmem for allocation. */

kncond knstr(knmode, sz, char* dest_begin, char* dest_end, ubyte* src);
kncond knparse(knmode, sz, ubyte* dest, ksraw src);

#ifdef __cplusplus
	}
#endif

#endif