diff options
| author | Indrajith K L | 2022-12-03 17:00:20 +0530 | 
|---|---|---|
| committer | Indrajith K L | 2022-12-03 17:00:20 +0530 | 
| commit | f5c4671bfbad96bf346bd7e9a21fc4317b4959df (patch) | |
| tree | 2764fc62da58f2ba8da7ed341643fc359873142f /v_windows/v/thirdparty/bignum | |
| download | cli-tools-windows-master.tar.gz cli-tools-windows-master.tar.bz2 cli-tools-windows-master.zip  | |
Diffstat (limited to 'v_windows/v/thirdparty/bignum')
| -rw-r--r-- | v_windows/v/thirdparty/bignum/README.md | 2 | ||||
| -rw-r--r-- | v_windows/v/thirdparty/bignum/bn.c | 664 | ||||
| -rw-r--r-- | v_windows/v/thirdparty/bignum/bn.h | 123 | 
3 files changed, 789 insertions, 0 deletions
diff --git a/v_windows/v/thirdparty/bignum/README.md b/v_windows/v/thirdparty/bignum/README.md new file mode 100644 index 0000000..04eb555 --- /dev/null +++ b/v_windows/v/thirdparty/bignum/README.md @@ -0,0 +1,2 @@ +This folder contains bn.h and bn.c files +from https://github.com/kokke/tiny-bignum-c diff --git a/v_windows/v/thirdparty/bignum/bn.c b/v_windows/v/thirdparty/bignum/bn.c new file mode 100644 index 0000000..7ec0895 --- /dev/null +++ b/v_windows/v/thirdparty/bignum/bn.c @@ -0,0 +1,664 @@ +/* + +Big number library - arithmetic on multiple-precision unsigned integers. + +This library is an implementation of arithmetic on arbitrarily large integers. + +The difference between this and other implementations, is that the data structure +has optimal memory utilization (i.e. a 1024 bit integer takes up 128 bytes RAM), +and all memory is allocated statically: no dynamic allocation for better or worse. + +Primary goals are correctness, clarity of code and clean, portable implementation. +Secondary goal is a memory footprint small enough to make it suitable for use in +embedded applications. + + +The current state is correct functionality and adequate performance. +There may well be room for performance-optimizations and improvements. + +*/ + +#include <stdio.h> +#include <stdbool.h> +#include <assert.h> +#include "bn.h" + + + +/* Functions for shifting number in-place. */ +static void _lshift_one_bit(struct bn* a); +static void _rshift_one_bit(struct bn* a); +static void _lshift_word(struct bn* a, int nwords); +static void _rshift_word(struct bn* a, int nwords); + + + +/* Public / Exported functions. */ +void bignum_init(struct bn* n) +{ +  require(n, "n is null"); + +  int i; +  for (i = 0; i < BN_ARRAY_SIZE; ++i) +  { +    n->array[i] = 0; +  } +} + + +void bignum_from_int(struct bn* n, DTYPE_TMP i) +{ +  require(n, "n is null"); + +  bignum_init(n); + +  /* Endianness issue if machine is not little-endian? */ +#ifdef WORD_SIZE + #if (WORD_SIZE == 1) +  n->array[0] = (i & 0x000000ff); +  n->array[1] = (i & 0x0000ff00) >> 8; +  n->array[2] = (i & 0x00ff0000) >> 16; +  n->array[3] = (i & 0xff000000) >> 24; + #elif (WORD_SIZE == 2) +  n->array[0] = (i & 0x0000ffff); +  n->array[1] = (i & 0xffff0000) >> 16; + #elif (WORD_SIZE == 4) +  n->array[0] = i; +  DTYPE_TMP num_32 = 32; +  DTYPE_TMP tmp = i >> num_32; /* bit-shift with U64 operands to force 64-bit results */ +  n->array[1] = tmp; + #endif +#endif +} + + +int bignum_to_int(struct bn* n) +{ +  require(n, "n is null"); + +  int ret = 0; + +  /* Endianness issue if machine is not little-endian? */ +#if (WORD_SIZE == 1) +  ret += n->array[0]; +  ret += n->array[1] << 8; +  ret += n->array[2] << 16; +  ret += n->array[3] << 24;   +#elif (WORD_SIZE == 2) +  ret += n->array[0]; +  ret += n->array[1] << 16; +#elif (WORD_SIZE == 4) +  ret += n->array[0]; +#endif + +  return ret; +} + + +void bignum_from_string(struct bn* n, char* str, int nbytes) +{ +  require(n, "n is null"); +  require(str, "str is null"); +  require(nbytes > 0, "nbytes must be positive"); +  require((nbytes & 1) == 0, "string format must be in hex -> equal number of bytes"); + +  bignum_init(n); + +  DTYPE tmp;                        /* DTYPE is defined in bn.h - uint{8,16,32,64}_t */ +  int i = nbytes - (2 * WORD_SIZE); /* index into string */ +  int j = 0;                        /* index into array */ + +  /* reading last hex-byte "MSB" from string first -> big endian */ +  /* MSB ~= most significant byte / block ? :) */ +  while (i >= 0) +  { +    tmp = 0; +    sscanf(&str[i], SSCANF_FORMAT_STR, &tmp); +    n->array[j] = tmp; +    i -= (2 * WORD_SIZE); /* step WORD_SIZE hex-byte(s) back in the string. */ +    j += 1;               /* step one element forward in the array. */ +  } +} + + +void bignum_to_string(struct bn* n, char* str, int nbytes) +{ +  require(n, "n is null"); +  require(str, "str is null"); +  require(nbytes > 0, "nbytes must be positive"); +  require((nbytes & 1) == 0, "string format must be in hex -> equal number of bytes"); + +  int j = BN_ARRAY_SIZE - 1; /* index into array - reading "MSB" first -> big-endian */ +  int i = 0;                 /* index into string representation. */ + +  /* reading last array-element "MSB" first -> big endian */ +  while ((j >= 0) && (nbytes > (i + 1))) +  { +    sprintf(&str[i], SPRINTF_FORMAT_STR, n->array[j]); +    i += (2 * WORD_SIZE); /* step WORD_SIZE hex-byte(s) forward in the string. */ +    j -= 1;               /* step one element back in the array. */ +  } + +  /* Count leading zeros: */ +  j = 0; +  while (str[j] == '0') +  { +    j += 1; +  } +  +  /* Move string j places ahead, effectively skipping leading zeros */  +  for (i = 0; i < (nbytes - j); ++i) +  { +    str[i] = str[i + j]; +  } + +  /* Zero-terminate string */ +  str[i] = 0; +} + + +void bignum_dec(struct bn* n) +{ +  require(n, "n is null"); + +  DTYPE tmp; /* copy of n */ +  DTYPE res; + +  int i; +  for (i = 0; i < BN_ARRAY_SIZE; ++i) +  { +    tmp = n->array[i]; +    res = tmp - 1; +    n->array[i] = res; + +    if (!(res > tmp)) +    { +      break; +    } +  } +} + + +void bignum_inc(struct bn* n) +{ +  require(n, "n is null"); + +  DTYPE res; +  DTYPE_TMP tmp; /* copy of n */ + +  int i; +  for (i = 0; i < BN_ARRAY_SIZE; ++i) +  { +    tmp = n->array[i]; +    res = tmp + 1; +    n->array[i] = res; + +    if (res > tmp) +    { +      break; +    } +  } +} + + +void bignum_add(struct bn* a, struct bn* b, struct bn* c) +{ +  require(a, "a is null"); +  require(b, "b is null"); +  require(c, "c is null"); + +  DTYPE_TMP tmp; +  int carry = 0; +  int i; +  for (i = 0; i < BN_ARRAY_SIZE; ++i) +  { +    tmp = (DTYPE_TMP)a->array[i] + b->array[i] + carry; +    carry = (tmp > MAX_VAL); +    c->array[i] = (tmp & MAX_VAL); +  } +} + + +void bignum_sub(struct bn* a, struct bn* b, struct bn* c) +{ +  require(a, "a is null"); +  require(b, "b is null"); +  require(c, "c is null"); + +  DTYPE_TMP res; +  DTYPE_TMP tmp1; +  DTYPE_TMP tmp2; +  int borrow = 0; +  int i; +  for (i = 0; i < BN_ARRAY_SIZE; ++i) +  { +    tmp1 = (DTYPE_TMP)a->array[i] + (MAX_VAL + 1); /* + number_base */ +    tmp2 = (DTYPE_TMP)b->array[i] + borrow;; +    res = (tmp1 - tmp2); +    c->array[i] = (DTYPE)(res & MAX_VAL); /* "modulo number_base" == "% (number_base - 1)" if number_base is 2^N */ +    borrow = (res <= MAX_VAL); +  } +} + + +void bignum_mul(struct bn* a, struct bn* b, struct bn* c) +{ +  require(a, "a is null"); +  require(b, "b is null"); +  require(c, "c is null"); + +  struct bn row; +  struct bn tmp; +  int i, j; + +  bignum_init(c); + +  for (i = 0; i < BN_ARRAY_SIZE; ++i) +  { +    bignum_init(&row); + +    for (j = 0; j < BN_ARRAY_SIZE; ++j) +    { +      if (i + j < BN_ARRAY_SIZE) +      { +        bignum_init(&tmp); +        DTYPE_TMP intermediate = ((DTYPE_TMP)a->array[i] * (DTYPE_TMP)b->array[j]); +        bignum_from_int(&tmp, intermediate); +        _lshift_word(&tmp, i + j); +        bignum_add(&tmp, &row, &row); +      } +    } +    bignum_add(c, &row, c); +  } +} + + +void bignum_div(struct bn* a, struct bn* b, struct bn* c) +{ +  require(a, "a is null"); +  require(b, "b is null"); +  require(c, "c is null"); + +  struct bn current; +  struct bn denom; +  struct bn tmp; + +  bignum_from_int(¤t, 1);               // int current = 1; +  bignum_assign(&denom, b);                   // denom = b +  bignum_assign(&tmp, a);                     // tmp   = a + +  const DTYPE_TMP half_max = 1 + (DTYPE_TMP)(MAX_VAL / 2); +  bool overflow = false; +  while (bignum_cmp(&denom, a) != LARGER)     // while (denom <= a) { +  { +    if (denom.array[BN_ARRAY_SIZE - 1] >= half_max) +    { +      overflow = true; +      break; +    } +    _lshift_one_bit(¤t);                //   current <<= 1; +    _lshift_one_bit(&denom);                  //   denom <<= 1; +  } +  if (!overflow) +  { +    _rshift_one_bit(&denom);                  // denom >>= 1; +    _rshift_one_bit(¤t);                // current >>= 1; +  } +  bignum_init(c);                             // int answer = 0; + +  while (!bignum_is_zero(¤t))           // while (current != 0) +  { +    if (bignum_cmp(&tmp, &denom) != SMALLER)  //   if (dividend >= denom) +    { +      bignum_sub(&tmp, &denom, &tmp);         //     dividend -= denom; +      bignum_or(c, ¤t, c);              //     answer |= current; +    } +    _rshift_one_bit(¤t);                //   current >>= 1; +    _rshift_one_bit(&denom);                  //   denom >>= 1; +  }                                           // return answer; +} + + +void bignum_lshift(struct bn* a, struct bn* b, int nbits) +{ +  require(a, "a is null"); +  require(b, "b is null"); +  require(nbits >= 0, "no negative shifts"); + +  bignum_assign(b, a); +  /* Handle shift in multiples of word-size */ +  const int nbits_pr_word = (WORD_SIZE * 8); +  int nwords = nbits / nbits_pr_word; +  if (nwords != 0) +  { +    _lshift_word(b, nwords); +    nbits -= (nwords * nbits_pr_word); +  } + +  if (nbits != 0) +  { +    int i; +    for (i = (BN_ARRAY_SIZE - 1); i > 0; --i) +    { +      b->array[i] = (b->array[i] << nbits) | (b->array[i - 1] >> ((8 * WORD_SIZE) - nbits)); +    } +    b->array[i] <<= nbits; +  } +} + + +void bignum_rshift(struct bn* a, struct bn* b, int nbits) +{ +  require(a, "a is null"); +  require(b, "b is null"); +  require(nbits >= 0, "no negative shifts"); +   +  bignum_assign(b, a); +  /* Handle shift in multiples of word-size */ +  const int nbits_pr_word = (WORD_SIZE * 8); +  int nwords = nbits / nbits_pr_word; +  if (nwords != 0) +  { +    _rshift_word(b, nwords); +    nbits -= (nwords * nbits_pr_word); +  } + +  if (nbits != 0) +  { +    int i; +    for (i = 0; i < (BN_ARRAY_SIZE - 1); ++i) +    { +      b->array[i] = (b->array[i] >> nbits) | (b->array[i + 1] << ((8 * WORD_SIZE) - nbits)); +    } +    b->array[i] >>= nbits; +  } +   +} + + +void bignum_mod(struct bn* a, struct bn* b, struct bn* c) +{ +  /* +    Take divmod and throw away div part +  */ +  require(a, "a is null"); +  require(b, "b is null"); +  require(c, "c is null"); + +  struct bn tmp; + +  bignum_divmod(a,b,&tmp,c); +} + +void bignum_divmod(struct bn* a, struct bn* b, struct bn* c, struct bn* d) +{ +  /* +    Puts a%b in d +    and a/b in c + +    mod(a,b) = a - ((a / b) * b) + +    example: +      mod(8, 3) = 8 - ((8 / 3) * 3) = 2 +  */ +  require(a, "a is null"); +  require(b, "b is null"); +  require(c, "c is null"); + +  struct bn tmp; + +  /* c = (a / b) */ +  bignum_div(a, b, c); + +  /* tmp = (c * b) */ +  bignum_mul(c, b, &tmp); + +  /* c = a - tmp */ +  bignum_sub(a, &tmp, d); +} + + +void bignum_and(struct bn* a, struct bn* b, struct bn* c) +{ +  require(a, "a is null"); +  require(b, "b is null"); +  require(c, "c is null"); + +  int i; +  for (i = 0; i < BN_ARRAY_SIZE; ++i) +  { +    c->array[i] = (a->array[i] & b->array[i]); +  } +} + + +void bignum_or(struct bn* a, struct bn* b, struct bn* c) +{ +  require(a, "a is null"); +  require(b, "b is null"); +  require(c, "c is null"); + +  int i; +  for (i = 0; i < BN_ARRAY_SIZE; ++i) +  { +    c->array[i] = (a->array[i] | b->array[i]); +  } +} + + +void bignum_xor(struct bn* a, struct bn* b, struct bn* c) +{ +  require(a, "a is null"); +  require(b, "b is null"); +  require(c, "c is null"); + +  int i; +  for (i = 0; i < BN_ARRAY_SIZE; ++i) +  { +    c->array[i] = (a->array[i] ^ b->array[i]); +  } +} + + +int bignum_cmp(struct bn* a, struct bn* b) +{ +  require(a, "a is null"); +  require(b, "b is null"); + +  int i = BN_ARRAY_SIZE; +  do +  { +    i -= 1; /* Decrement first, to start with last array element */ +    if (a->array[i] > b->array[i]) +    { +      return LARGER; +    } +    else if (a->array[i] < b->array[i]) +    { +      return SMALLER; +    } +  } +  while (i != 0); + +  return EQUAL; +} + + +int bignum_is_zero(struct bn* n) +{ +  require(n, "n is null"); + +  int i; +  for (i = 0; i < BN_ARRAY_SIZE; ++i) +  { +    if (n->array[i]) +    { +      return 0; +    } +  } + +  return 1; +} + + +void bignum_pow(struct bn* a, struct bn* b, struct bn* c) +{ +  require(a, "a is null"); +  require(b, "b is null"); +  require(c, "c is null"); + +  struct bn tmp; + +  bignum_init(c); + +  if (bignum_cmp(b, c) == EQUAL) +  { +    /* Return 1 when exponent is 0 -- n^0 = 1 */ +    bignum_inc(c); +  } +  else +  { +    struct bn bcopy; +    bignum_assign(&bcopy, b); + +    /* Copy a -> tmp */ +    bignum_assign(&tmp, a); + +    bignum_dec(&bcopy); +  +    /* Begin summing products: */ +    while (!bignum_is_zero(&bcopy)) +    { + +      /* c = tmp * tmp */ +      bignum_mul(&tmp, a, c); +      /* Decrement b by one */ +      bignum_dec(&bcopy); + +      bignum_assign(&tmp, c); +    } + +    /* c = tmp */ +    bignum_assign(c, &tmp); +  } +} + +void bignum_isqrt(struct bn *a, struct bn* b) +{ +  require(a, "a is null"); +  require(b, "b is null"); + +  struct bn low, high, mid, tmp; + +  bignum_init(&low); +  bignum_assign(&high, a); +  bignum_rshift(&high, &mid, 1); +  bignum_inc(&mid); + +  while (bignum_cmp(&high, &low) > 0)  +  { +    bignum_mul(&mid, &mid, &tmp); +    if (bignum_cmp(&tmp, a) > 0)  +    { +      bignum_assign(&high, &mid); +      bignum_dec(&high); +    } +    else  +    { +      bignum_assign(&low, &mid); +    } +    bignum_sub(&high,&low,&mid); +    _rshift_one_bit(&mid); +    bignum_add(&low,&mid,&mid); +    bignum_inc(&mid); +  } +  bignum_assign(b,&low); +} + + +void bignum_assign(struct bn* dst, struct bn* src) +{ +  require(dst, "dst is null"); +  require(src, "src is null"); + +  int i; +  for (i = 0; i < BN_ARRAY_SIZE; ++i) +  { +    dst->array[i] = src->array[i]; +  } +} + + +/* Private / Static functions. */ +static void _rshift_word(struct bn* a, int nwords) +{ +  /* Naive method: */ +  require(a, "a is null"); +  require(nwords >= 0, "no negative shifts"); + +  int i; +  if (nwords >= BN_ARRAY_SIZE) +  { +    for (i = 0; i < BN_ARRAY_SIZE; ++i) +    { +      a->array[i] = 0; +    } +    return; +  } + +  for (i = 0; i < BN_ARRAY_SIZE - nwords; ++i) +  { +    a->array[i] = a->array[i + nwords]; +  } +  for (; i < BN_ARRAY_SIZE; ++i) +  { +    a->array[i] = 0; +  } +} + + +static void _lshift_word(struct bn* a, int nwords) +{ +  require(a, "a is null"); +  require(nwords >= 0, "no negative shifts"); + +  int i; +  /* Shift whole words */ +  for (i = (BN_ARRAY_SIZE - 1); i >= nwords; --i) +  { +    a->array[i] = a->array[i - nwords]; +  } +  /* Zero pad shifted words. */ +  for (; i >= 0; --i) +  { +    a->array[i] = 0; +  }   +} + + +static void _lshift_one_bit(struct bn* a) +{ +  require(a, "a is null"); + +  int i; +  for (i = (BN_ARRAY_SIZE - 1); i > 0; --i) +  { +    a->array[i] = (a->array[i] << 1) | (a->array[i - 1] >> ((8 * WORD_SIZE) - 1)); +  } +  a->array[0] <<= 1; +} + + +static void _rshift_one_bit(struct bn* a) +{ +  require(a, "a is null"); + +  int i; +  for (i = 0; i < (BN_ARRAY_SIZE - 1); ++i) +  { +    a->array[i] = (a->array[i] >> 1) | (a->array[i + 1] << ((8 * WORD_SIZE) - 1)); +  } +  a->array[BN_ARRAY_SIZE - 1] >>= 1; +} + + diff --git a/v_windows/v/thirdparty/bignum/bn.h b/v_windows/v/thirdparty/bignum/bn.h new file mode 100644 index 0000000..f82676f --- /dev/null +++ b/v_windows/v/thirdparty/bignum/bn.h @@ -0,0 +1,123 @@ +#ifndef __BIGNUM_H__ +#define __BIGNUM_H__ +/* + +Big number library - arithmetic on multiple-precision unsigned integers. + +This library is an implementation of arithmetic on arbitrarily large integers. + +The difference between this and other implementations, is that the data structure +has optimal memory utilization (i.e. a 1024 bit integer takes up 128 bytes RAM), +and all memory is allocated statically: no dynamic allocation for better or worse. + +Primary goals are correctness, clarity of code and clean, portable implementation. +Secondary goal is a memory footprint small enough to make it suitable for use in +embedded applications. + + +The current state is correct functionality and adequate performance. +There may well be room for performance-optimizations and improvements. + +*/ + +#include <stdint.h> +#include <assert.h> + + +/* This macro defines the word size in bytes of the array that constitues the big-number data structure. */ +#ifndef WORD_SIZE +  #define WORD_SIZE 4 +#endif + +/* Size of big-numbers in bytes */ +#define BN_ARRAY_SIZE    (128 / WORD_SIZE) + + +/* Here comes the compile-time specialization for how large the underlying array size should be. */ +/* The choices are 1, 2 and 4 bytes in size with uint32, uint64 for WORD_SIZE==4, as temporary. */ +#ifndef WORD_SIZE +  #error Must define WORD_SIZE to be 1, 2, 4 +#elif (WORD_SIZE == 1) +  /* Data type of array in structure */ +  #define DTYPE                    uint8_t +  /* bitmask for getting MSB */ +  #define DTYPE_MSB                ((DTYPE_TMP)(0x80)) +  /* Data-type larger than DTYPE, for holding intermediate results of calculations */ +  #define DTYPE_TMP                uint32_t +  /* sprintf format string */ +  #define SPRINTF_FORMAT_STR       "%.02x" +  #define SSCANF_FORMAT_STR        "%2hhx" +  /* Max value of integer type */ +  #define MAX_VAL                  ((DTYPE_TMP)0xFF) +#elif (WORD_SIZE == 2) +  #define DTYPE                    uint16_t +  #define DTYPE_TMP                uint32_t +  #define DTYPE_MSB                ((DTYPE_TMP)(0x8000)) +  #define SPRINTF_FORMAT_STR       "%.04x" +  #define SSCANF_FORMAT_STR        "%4hx" +  #define MAX_VAL                  ((DTYPE_TMP)0xFFFF) +#elif (WORD_SIZE == 4) +  #define DTYPE                    uint32_t +  #define DTYPE_TMP                uint64_t +  #define DTYPE_MSB                ((DTYPE_TMP)(0x80000000)) +  #define SPRINTF_FORMAT_STR       "%.08x" +  #define SSCANF_FORMAT_STR        "%8x" +  #define MAX_VAL                  ((DTYPE_TMP)0xFFFFFFFF) +#endif +#ifndef DTYPE +  #error DTYPE must be defined to uint8_t, uint16_t uint32_t or whatever +#endif + + +/* Custom assert macro - easy to disable */ +#define require(p, msg) assert(p && #msg) + + +/* Data-holding structure: array of DTYPEs */ +struct bn +{ +  DTYPE array[BN_ARRAY_SIZE]; +}; + + + +/* Tokens returned by bignum_cmp() for value comparison */ +enum { SMALLER = -1, EQUAL = 0, LARGER = 1 }; + + + +/* Initialization functions: */ +void bignum_init(struct bn* n); +void bignum_from_int(struct bn* n, DTYPE_TMP i); +int  bignum_to_int(struct bn* n); +void bignum_from_string(struct bn* n, char* str, int nbytes); +void bignum_to_string(struct bn* n, char* str, int maxsize); + +/* Basic arithmetic operations: */ +void bignum_add(struct bn* a, struct bn* b, struct bn* c); /* c = a + b */ +void bignum_sub(struct bn* a, struct bn* b, struct bn* c); /* c = a - b */ +void bignum_mul(struct bn* a, struct bn* b, struct bn* c); /* c = a * b */ +void bignum_div(struct bn* a, struct bn* b, struct bn* c); /* c = a / b */ +void bignum_mod(struct bn* a, struct bn* b, struct bn* c); /* c = a % b */ +void bignum_divmod(struct bn* a, struct bn* b, struct bn* c, struct bn* d); /* c = a/b, d = a%b */ + +/* Bitwise operations: */ +void bignum_and(struct bn* a, struct bn* b, struct bn* c); /* c = a & b */ +void bignum_or(struct bn* a, struct bn* b, struct bn* c);  /* c = a | b */ +void bignum_xor(struct bn* a, struct bn* b, struct bn* c); /* c = a ^ b */ +void bignum_lshift(struct bn* a, struct bn* b, int nbits); /* b = a << nbits */ +void bignum_rshift(struct bn* a, struct bn* b, int nbits); /* b = a >> nbits */ + +/* Special operators and comparison */ +int  bignum_cmp(struct bn* a, struct bn* b);               /* Compare: returns LARGER, EQUAL or SMALLER */ +int  bignum_is_zero(struct bn* n);                         /* For comparison with zero */ +void bignum_inc(struct bn* n);                             /* Increment: add one to n */ +void bignum_dec(struct bn* n);                             /* Decrement: subtract one from n */ +void bignum_pow(struct bn* a, struct bn* b, struct bn* c); /* Calculate a^b -- e.g. 2^10 => 1024 */ +void bignum_isqrt(struct bn* a, struct bn* b);             /* Integer square root -- e.g. isqrt(5) => 2*/ +void bignum_assign(struct bn* dst, struct bn* src);        /* Copy src into dst -- dst := src */ + + +#endif /* #ifndef __BIGNUM_H__ */ + +  | 
