int fp_invmod_mont_ct(fp_int *a, fp_int *b, fp_int *c, fp_digit mp)
{
  int i, j;
#ifndef WOLFSSL_SMALL_STACK
  fp_int t[1], e[1];
  fp_int pre[CT_INV_MOD_PRE_CNT];
#else
  fp_int* t;
  fp_int* e;
  fp_int* pre;
#endif

#ifdef WOLFSSL_SMALL_STACK
  t = (fp_int*)XMALLOC(sizeof(fp_int) * (2 + CT_INV_MOD_PRE_CNT), NULL,
                                                           DYNAMIC_TYPE_BIGINT);
  if (t == NULL)
    return FP_MEM;
  e = t + 1;
  pre = t + 2;
#endif

  fp_init(t);
  fp_init(e);

  fp_init(&pre[0]);
  fp_copy(a, &pre[0]);
  for (i = 1; i < CT_INV_MOD_PRE_CNT; i++) {
    fp_init(&pre[i]);
    fp_sqr(&pre[i-1], &pre[i]);
    fp_montgomery_reduce(&pre[i], b, mp);
    fp_mul(&pre[i], a, &pre[i]);
    fp_montgomery_reduce(&pre[i], b, mp);
  }

  fp_sub_d(b, 2, e);
  /* Highest bit is always set. */
  for (i = fp_count_bits(e)-2, j = 1; i >= 0; i--, j++) {
      if (!fp_is_bit_set(e, i) || j == CT_INV_MOD_PRE_CNT)
          break;
  }
  fp_copy(&pre[j-1], t);
  for (j = 0; i >= 0; i--) {
    int set = fp_is_bit_set(e, i);

    if ((j == CT_INV_MOD_PRE_CNT) || (!set && j > 0)) {
      fp_mul(t, &pre[j-1], t);
      fp_montgomery_reduce(t, b, mp);
      j = 0;
    }
    fp_sqr(t, t);
    fp_montgomery_reduce(t, b, mp);
    j += set;
  }
  if (j > 0) {
    fp_mul(t, &pre[j-1], c);
    fp_montgomery_reduce(c, b, mp);
  }
  else 
    fp_copy(t, c);

#ifdef WOLFSSL_SMALL_STACK
  XFREE(t, NULL, DYNAMIC_TYPE_BIGINT);
#endif
  return FP_OKAY;
}
int fp_invmod_mont_ct(fp_int *a, fp_int *b, fp_int *c, fp_digit mp)
{
  int i, j;
#ifndef WOLFSSL_SMALL_STACK
  fp_int t[1], e[1];
  fp_int pre[CT_INV_MOD_PRE_CNT];
#else
  fp_int* t;
  fp_int* e;
  fp_int* pre;
#endif

#ifdef WOLFSSL_SMALL_STACK
  t = (fp_int*)XMALLOC(sizeof(fp_int) * (2 + CT_INV_MOD_PRE_CNT), NULL,
                                                           DYNAMIC_TYPE_BIGINT);
  if (t == NULL)
    return FP_MEM;
  e = t + 1;
  pre = t + 2;
#endif

  fp_init(t);
  fp_init(e);

  fp_init(&pre[0]);
  fp_copy(a, &pre[0]);
  for (i = 1; i < CT_INV_MOD_PRE_CNT; i++) {
    fp_init(&pre[i]);
    fp_sqr(&pre[i-1], &pre[i]);
    fp_montgomery_reduce(&pre[i], b, mp);
    fp_mul(&pre[i], a, &pre[i]);
    fp_montgomery_reduce(&pre[i], b, mp);
  }

  fp_sub_d(b, 2, e);
   
  for (i = fp_count_bits(e)-2, j = 1; i >= 0; i--, j++) {
      if (!fp_is_bit_set(e, i) || j == CT_INV_MOD_PRE_CNT)
          break;
  }
  fp_copy(&pre[j-1], t);
  for (j = 0; i >= 0; i--) {
    int set = fp_is_bit_set(e, i);

    if ((j == CT_INV_MOD_PRE_CNT) || (!set && j > 0)) {
      fp_mul(t, &pre[j-1], t);
      fp_montgomery_reduce(t, b, mp);
      j = 0;
    }
    fp_sqr(t, t);
    fp_montgomery_reduce(t, b, mp);
    j += set;
  }
  if (j > 0) {
    fp_mul(t, &pre[j-1], c);
    fp_montgomery_reduce(c, b, mp);
  }
  else 
    fp_copy(t, c);

#ifdef WOLFSSL_SMALL_STACK
  XFREE(t, NULL, DYNAMIC_TYPE_BIGINT);
#endif
  return FP_OKAY;
}