Пример #1
0
// mod_montgomery sets |r| to |I| mod |p|. |I| must already be fully reduced
// modulo |p| times |q|. It returns one on success and zero on error.
static int mod_montgomery(BIGNUM *r, const BIGNUM *I, const BIGNUM *p,
                          const BN_MONT_CTX *mont_p, const BIGNUM *q,
                          BN_CTX *ctx) {
  // Reducing in constant-time with Montgomery reduction requires I <= p * R. We
  // have I < p * q, so this follows if q < R. In particular, this always holds
  // if p and q are the same size, which is true for any RSA keys we or anyone
  // sane generates. For other keys, we fall back to |BN_mod|.
  if (!bn_less_than_montgomery_R(q, mont_p)) {
    return BN_mod(r, I, p, ctx);
  }

  if (// Reduce mod p with Montgomery reduction. This computes I * R^-1 mod p.
      !BN_from_montgomery(r, I, mont_p, ctx) ||
      // Multiply by R^2 and do another Montgomery reduction to compute
      // I * R^-1 * R^2 * R^-1 = I mod p.
      !BN_to_montgomery(r, r, mont_p, ctx)) {
    return 0;
  }

  // By precomputing R^3 mod p (normally |BN_MONT_CTX| only uses R^2 mod p) and
  // adjusting the API for |BN_mod_exp_mont_consttime|, we could instead compute
  // I * R mod p here and save a reduction per prime. But this would require
  // changing the RSAZ code and may not be worth it. Note that the RSAZ code
  // uses a different radix, so it uses R' = 2^1044. There we'd actually want
  // R^2 * R', and would futher benefit from a precomputed R'^2. It currently
  // converts |mont_p->RR| to R'^2.
  return 1;
}
Пример #2
0
int ec_GFp_mont_group_set_curve(EC_GROUP *group, const BIGNUM *p,
                                const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
{
    BN_CTX *new_ctx = NULL;
    BN_MONT_CTX *mont = NULL;
    BIGNUM *one = NULL;
    int ret = 0;

    if (group->field_data1 != NULL) {
        BN_MONT_CTX_free(group->field_data1);
        group->field_data1 = NULL;
    }
    if (group->field_data2 != NULL) {
        BN_free(group->field_data2);
        group->field_data2 = NULL;
    }

    if (ctx == NULL) {
        ctx = new_ctx = BN_CTX_new();
        if (ctx == NULL)
            return 0;
    }

    mont = BN_MONT_CTX_new();
    if (mont == NULL)
        goto err;
    if (!BN_MONT_CTX_set(mont, p, ctx)) {
        ECerr(EC_F_EC_GFP_MONT_GROUP_SET_CURVE, ERR_R_BN_LIB);
        goto err;
    }
    one = BN_new();
    if (one == NULL)
        goto err;
    if (!BN_to_montgomery(one, BN_value_one(), mont, ctx))
        goto err;

    group->field_data1 = mont;
    mont = NULL;
    group->field_data2 = one;
    one = NULL;

    ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);

    if (!ret) {
        BN_MONT_CTX_free(group->field_data1);
        group->field_data1 = NULL;
        BN_free(group->field_data2);
        group->field_data2 = NULL;
    }

 err:
    if (new_ctx != NULL)
        BN_CTX_free(new_ctx);
    if (mont != NULL)
        BN_MONT_CTX_free(mont);
    if (one != NULL)
        BN_free(one);
    return ret;
}
Пример #3
0
int ec_GFp_mont_field_encode(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
                             BN_CTX *ctx) {
  if (group->field_data1 == NULL) {
    OPENSSL_PUT_ERROR(EC, ec_GFp_mont_field_encode, EC_R_NOT_INITIALIZED);
    return 0;
  }

  return BN_to_montgomery(r, a, (BN_MONT_CTX *)group->field_data1, ctx);
}
Пример #4
0
int ec_GFp_mont_field_encode(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
	{
	if (group->field_data1 == NULL)
		{
		ECerr(EC_F_EC_GFP_MONT_FIELD_ENCODE, EC_R_NOT_INITIALIZED);
		return 0;
		}

	return BN_to_montgomery(r, a, (BN_MONT_CTX *)group->field_data1, ctx);
	}
Пример #5
0
int ec_GFp_mont_group_set_curve(EC_GROUP *group, const BIGNUM *p,
                                const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) {
  BN_CTX *new_ctx = NULL;
  BN_MONT_CTX *mont = NULL;
  BIGNUM *one = NULL;
  int ret = 0;

  BN_MONT_CTX_free(group->mont);
  group->mont = NULL;
  BN_free(group->one);
  group->one = NULL;

  if (ctx == NULL) {
    ctx = new_ctx = BN_CTX_new();
    if (ctx == NULL) {
      return 0;
    }
  }

  mont = BN_MONT_CTX_new();
  if (mont == NULL) {
    goto err;
  }
  if (!BN_MONT_CTX_set(mont, p, ctx)) {
    OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
    goto err;
  }
  one = BN_new();
  if (one == NULL || !BN_to_montgomery(one, BN_value_one(), mont, ctx)) {
    goto err;
  }

  group->mont = mont;
  mont = NULL;
  group->one = one;
  one = NULL;

  ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);

  if (!ret) {
    BN_MONT_CTX_free(group->mont);
    group->mont = NULL;
    BN_free(group->one);
    group->one = NULL;
  }

err:
  BN_CTX_free(new_ctx);
  BN_MONT_CTX_free(mont);
  BN_free(one);
  return ret;
}
Пример #6
0
static int bn_blinding_create_param(BN_BLINDING *b, const RSA *rsa, BN_CTX *ctx) {
  int retry_counter = 32;

  do {
    if (!BN_rand_range(b->A, rsa->n)) {
      OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
      return 0;
    }

    /* `BN_from_montgomery` + `BN_mod_inverse_no_branch` is equivalent to, but
     * more efficient than, `BN_mod_inverse_no_branch` + `BN_to_montgomery`. */

    if (!BN_from_montgomery(b->Ai, b->A, rsa->mont_n, ctx)) {
      return 0;
    }

    assert(BN_get_flags(b->A, BN_FLG_CONSTTIME));
    int no_inverse;
    if (BN_mod_inverse_no_branch(b->Ai, &no_inverse, b->Ai, rsa->n, ctx) ==
        NULL) {
      /* this should almost never happen for good RSA keys */
      if (no_inverse) {
        if (retry_counter-- == 0) {
          OPENSSL_PUT_ERROR(RSA, RSA_R_TOO_MANY_ITERATIONS);
          return 0;
        }
        ERR_clear_error();
      } else {
        OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
        return 0;
      }
    } else {
      break;
    }
  } while (1);

  if (!BN_mod_exp_mont(b->A, b->A, rsa->e, rsa->n, ctx, rsa->mont_n)) {
    OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
    return 0;
  }

  if (!BN_to_montgomery(b->A, b->A, rsa->mont_n, ctx)) {
    OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
    return 0;
  }
  return 1;
}
Пример #7
0
int BN_reduce_montgomery(BIGNUM *r, const BIGNUM *a,
                         const BN_MONT_CTX *mod_mont, BN_CTX *ctx) {
  BIGNUM tmp;
  BN_init(&tmp);
  if (!BN_copy(&tmp, a)) {
    OPENSSL_PUT_ERROR(BN, ERR_R_INTERNAL_ERROR);
    return 0;
  }

  int ret = 0;

  if (!BN_from_montgomery_word(r, &tmp, mod_mont) ||
      !BN_to_montgomery(r, r, mod_mont, ctx)) {
    goto err;
  }

  ret = 1;

err:
  BN_free(&tmp);
  return ret;
}
Пример #8
0
// freeze_private_key finishes initializing |rsa|'s private key components.
// After this function has returned, |rsa| may not be changed. This is needed
// because |RSA| is a public struct and, additionally, OpenSSL 1.1.0 opaquified
// it wrong (see https://github.com/openssl/openssl/issues/5158).
static int freeze_private_key(RSA *rsa, BN_CTX *ctx) {
  CRYPTO_MUTEX_lock_read(&rsa->lock);
  int frozen = rsa->private_key_frozen;
  CRYPTO_MUTEX_unlock_read(&rsa->lock);
  if (frozen) {
    return 1;
  }

  int ret = 0;
  CRYPTO_MUTEX_lock_write(&rsa->lock);
  if (rsa->private_key_frozen) {
    ret = 1;
    goto err;
  }

  // Pre-compute various intermediate values, as well as copies of private
  // exponents with correct widths. Note that other threads may concurrently
  // read from |rsa->n|, |rsa->e|, etc., so any fixes must be in separate
  // copies. We use |mont_n->N|, |mont_p->N|, and |mont_q->N| as copies of |n|,
  // |p|, and |q| with the correct minimal widths.

  if (rsa->mont_n == NULL) {
    rsa->mont_n = BN_MONT_CTX_new_for_modulus(rsa->n, ctx);
    if (rsa->mont_n == NULL) {
      goto err;
    }
  }
  const BIGNUM *n_fixed = &rsa->mont_n->N;

  // The only public upper-bound of |rsa->d| is the bit length of |rsa->n|. The
  // ASN.1 serialization of RSA private keys unfortunately leaks the byte length
  // of |rsa->d|, but normalize it so we only leak it once, rather than per
  // operation.
  if (rsa->d != NULL &&
      !ensure_fixed_copy(&rsa->d_fixed, rsa->d, n_fixed->width)) {
    goto err;
  }

  if (rsa->p != NULL && rsa->q != NULL) {
    if (rsa->mont_p == NULL) {
      rsa->mont_p = BN_MONT_CTX_new_for_modulus(rsa->p, ctx);
      if (rsa->mont_p == NULL) {
        goto err;
      }
    }
    const BIGNUM *p_fixed = &rsa->mont_p->N;

    if (rsa->mont_q == NULL) {
      rsa->mont_q = BN_MONT_CTX_new_for_modulus(rsa->q, ctx);
      if (rsa->mont_q == NULL) {
        goto err;
      }
    }
    const BIGNUM *q_fixed = &rsa->mont_q->N;

    if (rsa->dmp1 != NULL && rsa->dmq1 != NULL) {
      // Key generation relies on this function to compute |iqmp|.
      if (rsa->iqmp == NULL) {
        BIGNUM *iqmp = BN_new();
        if (iqmp == NULL ||
            !bn_mod_inverse_secret_prime(iqmp, rsa->q, rsa->p, ctx,
                                         rsa->mont_p)) {
          BN_free(iqmp);
          goto err;
        }
        rsa->iqmp = iqmp;
      }

      // CRT components are only publicly bounded by their corresponding
      // moduli's bit lengths. |rsa->iqmp| is unused outside of this one-time
      // setup, so we do not compute a fixed-width version of it.
      if (!ensure_fixed_copy(&rsa->dmp1_fixed, rsa->dmp1, p_fixed->width) ||
          !ensure_fixed_copy(&rsa->dmq1_fixed, rsa->dmq1, q_fixed->width)) {
        goto err;
      }

      // Compute |inv_small_mod_large_mont|. Note that it is always modulo the
      // larger prime, independent of what is stored in |rsa->iqmp|.
      if (rsa->inv_small_mod_large_mont == NULL) {
        BIGNUM *inv_small_mod_large_mont = BN_new();
        int ok;
        if (BN_cmp(rsa->p, rsa->q) < 0) {
          ok = inv_small_mod_large_mont != NULL &&
               bn_mod_inverse_secret_prime(inv_small_mod_large_mont, rsa->p,
                                           rsa->q, ctx, rsa->mont_q) &&
               BN_to_montgomery(inv_small_mod_large_mont,
                                inv_small_mod_large_mont, rsa->mont_q, ctx);
        } else {
          ok = inv_small_mod_large_mont != NULL &&
               BN_to_montgomery(inv_small_mod_large_mont, rsa->iqmp,
                                rsa->mont_p, ctx);
        }
        if (!ok) {
          BN_free(inv_small_mod_large_mont);
          goto err;
        }
        rsa->inv_small_mod_large_mont = inv_small_mod_large_mont;
      }
    }
  }

  rsa->private_key_frozen = 1;
  ret = 1;

err:
  CRYPTO_MUTEX_unlock_write(&rsa->lock);
  return ret;
}
Пример #9
0
int test_mont(BIO *bp, BN_CTX *ctx)
	{
	BIGNUM a,b,c,d,A,B;
	BIGNUM n;
	int i;
	BN_MONT_CTX *mont;

	BN_init(&a);
	BN_init(&b);
	BN_init(&c);
	BN_init(&d);
	BN_init(&A);
	BN_init(&B);
	BN_init(&n);

	mont=BN_MONT_CTX_new();

	BN_bntest_rand(&a,100,0,0); /**/
	BN_bntest_rand(&b,100,0,0); /**/
	for (i=0; i<num2; i++)
		{
		int bits = (200*(i+1))/num2;

		if (bits == 0)
			continue;
		BN_bntest_rand(&n,bits,0,1);
		BN_MONT_CTX_set(mont,&n,ctx);

		BN_nnmod(&a,&a,&n,ctx);
		BN_nnmod(&b,&b,&n,ctx);

		BN_to_montgomery(&A,&a,mont,ctx);
		BN_to_montgomery(&B,&b,mont,ctx);

		BN_mod_mul_montgomery(&c,&A,&B,mont,ctx);/**/
		BN_from_montgomery(&A,&c,mont,ctx);/**/
		if (bp != NULL)
			{
			if (!results)
				{
#ifdef undef
fprintf(stderr,"%d * %d %% %d\n",
BN_num_bits(&a),
BN_num_bits(&b),
BN_num_bits(mont->N));
#endif
				BN_print(bp,&a);
				BIO_puts(bp," * ");
				BN_print(bp,&b);
				BIO_puts(bp," % ");
				BN_print(bp,&(mont->N));
				BIO_puts(bp," - ");
				}
			BN_print(bp,&A);
			BIO_puts(bp,"\n");
			}
		BN_mod_mul(&d,&a,&b,&n,ctx);
		BN_sub(&d,&d,&A);
		if(!BN_is_zero(&d))
		    {
		    fprintf(stderr,"Montgomery multiplication test failed!\n");
		    return 0;
		    }
		}
	BN_MONT_CTX_free(mont);
	BN_free(&a);
	BN_free(&b);
	BN_free(&c);
	BN_free(&d);
	BN_free(&A);
	BN_free(&B);
	BN_free(&n);
	return(1);
	}
Пример #10
0
// freeze_private_key finishes initializing |rsa|'s private key components.
// After this function has returned, |rsa| may not be changed. This is needed
// because |RSA| is a public struct and, additionally, OpenSSL 1.1.0 opaquified
// it wrong (see https://github.com/openssl/openssl/issues/5158).
static int freeze_private_key(RSA *rsa, BN_CTX *ctx) {
  CRYPTO_MUTEX_lock_read(&rsa->lock);
  int flags = rsa->flags;
  CRYPTO_MUTEX_unlock_read(&rsa->lock);
  if (flags & RSA_FLAG_PRIVATE_KEY_FROZEN) {
    return 1;
  }

  int ret = 0;
  CRYPTO_MUTEX_lock_write(&rsa->lock);
  if (rsa->flags & RSA_FLAG_PRIVATE_KEY_FROZEN) {
    ret = 1;
    goto err;
  }

  // |rsa->n| is public. Normalize the width.
  bn_set_minimal_width(rsa->n);
  if (rsa->mont_n == NULL) {
    rsa->mont_n = BN_MONT_CTX_new_for_modulus(rsa->n, ctx);
    if (rsa->mont_n == NULL) {
      goto err;
    }
  }

  // The only public upper-bound of |rsa->d| is the bit length of |rsa->n|. The
  // ASN.1 serialization of RSA private keys unfortunately leaks the byte length
  // of |rsa->d|, but normalize it so we only leak it once, rather than per
  // operation.
  if (rsa->d != NULL &&
      !bn_resize_words(rsa->d, rsa->n->width)) {
    goto err;
  }

  if (rsa->p != NULL && rsa->q != NULL) {
    // |p| and |q| have public bit lengths.
    bn_set_minimal_width(rsa->p);
    bn_set_minimal_width(rsa->q);

    if (rsa->mont_p == NULL) {
      rsa->mont_p = BN_MONT_CTX_new_for_modulus(rsa->p, ctx);
      if (rsa->mont_p == NULL) {
        goto err;
      }
    }

    if (rsa->mont_q == NULL) {
      rsa->mont_q = BN_MONT_CTX_new_for_modulus(rsa->q, ctx);
      if (rsa->mont_q == NULL) {
        goto err;
      }
    }

    if (rsa->dmp1 != NULL && rsa->dmq1 != NULL) {
      // Key generation relies on this function to compute |iqmp|.
      if (rsa->iqmp == NULL) {
        BIGNUM *iqmp = BN_new();
        if (iqmp == NULL ||
            !bn_mod_inverse_secret_prime(iqmp, rsa->q, rsa->p, ctx,
                                         rsa->mont_p)) {
          BN_free(iqmp);
          goto err;
        }
        rsa->iqmp = iqmp;
      }

      // CRT components are only publicly bounded by their corresponding
      // moduli's bit lengths.
      if (!bn_resize_words(rsa->dmp1, rsa->p->width) ||
          !bn_resize_words(rsa->dmq1, rsa->q->width) ||
          !bn_resize_words(rsa->iqmp, rsa->p->width)) {
        goto err;
      }

      // Compute |inv_small_mod_large_mont|. Note that it is always modulo the
      // larger prime, independent of what is stored in |rsa->iqmp|.
      if (rsa->inv_small_mod_large_mont == NULL) {
        BIGNUM *inv_small_mod_large_mont = BN_new();
        int ok;
        if (BN_cmp(rsa->p, rsa->q) < 0) {
          ok = inv_small_mod_large_mont != NULL &&
               bn_mod_inverse_secret_prime(inv_small_mod_large_mont, rsa->p,
                                           rsa->q, ctx, rsa->mont_q) &&
               BN_to_montgomery(inv_small_mod_large_mont,
                                inv_small_mod_large_mont, rsa->mont_q, ctx);
        } else {
          ok = inv_small_mod_large_mont != NULL &&
               BN_to_montgomery(inv_small_mod_large_mont, rsa->iqmp,
                                rsa->mont_p, ctx);
        }
        if (!ok) {
          BN_free(inv_small_mod_large_mont);
          goto err;
        }
        rsa->inv_small_mod_large_mont = inv_small_mod_large_mont;
      }
    }
  }

  rsa->flags |= RSA_FLAG_PRIVATE_KEY_FROZEN;
  ret = 1;

err:
  CRYPTO_MUTEX_unlock_write(&rsa->lock);
  return ret;
}
Пример #11
0
int ec_GFp_mont_field_encode(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
                             BN_CTX *ctx) {
  return BN_to_montgomery(r, a, &group->mont, ctx);
}
Пример #12
0
int BN_mod_exp2_mont(BIGNUM *rr, BIGNUM *a1, BIGNUM *p1, BIGNUM *a2,
	     BIGNUM *p2, BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)
	{
	int i,j,k,bits,bits1,bits2,ret=0,wstart,wend,window,xvalue,yvalue;
	int start=1,ts=0,x,y;
	BIGNUM *d,*aa1,*aa2,*r;
	BIGNUM val[EXP2_TABLE_SIZE][EXP2_TABLE_SIZE];
	BN_MONT_CTX *mont=NULL;

	bn_check_top(a1);
	bn_check_top(p1);
	bn_check_top(a2);
	bn_check_top(p2);
	bn_check_top(m);

	if (!(m->d[0] & 1))
		{
		BNerr(BN_F_BN_MOD_EXP_MONT,BN_R_CALLED_WITH_EVEN_MODULUS);
		return(0);
		}
	bits1=BN_num_bits(p1);
	bits2=BN_num_bits(p2);
	if ((bits1 == 0) && (bits2 == 0))
		{
		BN_one(rr);
		return(1);
		}

	BN_CTX_start(ctx);
	d = BN_CTX_get(ctx);
	r = BN_CTX_get(ctx);
	if (d == NULL || r == NULL) goto err;

	bits=(bits1 > bits2)?bits1:bits2;

	/* If this is not done, things will break in the montgomery
	 * part */

	if (in_mont != NULL)
		mont=in_mont;
	else
		{
		if ((mont=BN_MONT_CTX_new()) == NULL) goto err;
		if (!BN_MONT_CTX_set(mont,m,ctx)) goto err;
		}

	BN_init(&(val[0][0]));
	BN_init(&(val[1][1]));
	BN_init(&(val[0][1]));
	BN_init(&(val[1][0]));
	ts=1;
	if (BN_ucmp(a1,m) >= 0)
		{
		BN_mod(&(val[1][0]),a1,m,ctx);
		aa1= &(val[1][0]);
		}
	else
		aa1=a1;
	if (BN_ucmp(a2,m) >= 0)
		{
		BN_mod(&(val[0][1]),a2,m,ctx);
		aa2= &(val[0][1]);
		}
	else
		aa2=a2;
	if (!BN_to_montgomery(&(val[1][0]),aa1,mont,ctx)) goto err;
	if (!BN_to_montgomery(&(val[0][1]),aa2,mont,ctx)) goto err;
	if (!BN_mod_mul_montgomery(&(val[1][1]),
		&(val[1][0]),&(val[0][1]),mont,ctx))
		goto err;

#if 0
	if (bits <= 20) /* This is probably 3 or 0x10001, so just do singles */
		window=1;
	else if (bits > 250)
		window=5;	/* max size of window */
	else if (bits >= 120)
		window=4;
	else
		window=3;
#else
	window=EXP2_TABLE_BITS;
#endif

	k=1<<window;
	for (x=0; x<k; x++)
		{
		if (x >= 2)
			{
			BN_init(&(val[x][0]));
			BN_init(&(val[x][1]));
			if (!BN_mod_mul_montgomery(&(val[x][0]),
				&(val[1][0]),&(val[x-1][0]),mont,ctx)) goto err;
			if (!BN_mod_mul_montgomery(&(val[x][1]),
				&(val[1][0]),&(val[x-1][1]),mont,ctx)) goto err;
			}
		for (y=2; y<k; y++)
			{
			BN_init(&(val[x][y]));
			if (!BN_mod_mul_montgomery(&(val[x][y]),
				&(val[x][y-1]),&(val[0][1]),mont,ctx))
				goto err;
			}
		}
	ts=k;

	start=1;	/* This is used to avoid multiplication etc
			 * when there is only the value '1' in the
			 * buffer. */
	xvalue=0;	/* The 'x value' of the window */
	yvalue=0;	/* The 'y value' of the window */
	wstart=bits-1;	/* The top bit of the window */
	wend=0;		/* The bottom bit of the window */

        if (!BN_to_montgomery(r,BN_value_one(),mont,ctx)) goto err;
	for (;;)
		{
		xvalue=BN_is_bit_set(p1,wstart);
		yvalue=BN_is_bit_set(p2,wstart);
		if (!(xvalue || yvalue))
			{
			if (!start)
				{
				if (!BN_mod_mul_montgomery(r,r,r,mont,ctx))
					goto err;
				}
			wstart--;
			if (wstart < 0) break;
			continue;
			}
		/* We now have wstart on a 'set' bit, we now need to work out
		 * how bit a window to do.  To do this we need to scan
		 * forward until the last set bit before the end of the
		 * window */
		j=wstart;
		/* xvalue=BN_is_bit_set(p1,wstart); already set */
		/* yvalue=BN_is_bit_set(p1,wstart); already set */
		wend=0;
		for (i=1; i<window; i++)
			{
			if (wstart-i < 0) break;
			xvalue+=xvalue;
			xvalue|=BN_is_bit_set(p1,wstart-i);
			yvalue+=yvalue;
			yvalue|=BN_is_bit_set(p2,wstart-i);
			}

		/* i is the size of the current window */
		/* add the 'bytes above' */
		if (!start)
			for (j=0; j<i; j++)
				{
				if (!BN_mod_mul_montgomery(r,r,r,mont,ctx))
					goto err;
				}
		
		/* wvalue will be an odd number < 2^window */
		if (xvalue || yvalue)
			{
			if (!BN_mod_mul_montgomery(r,r,&(val[xvalue][yvalue]),
				mont,ctx)) goto err;
			}

		/* move the 'window' down further */
		wstart-=i;
		start=0;
		if (wstart < 0) break;
		}
	BN_from_montgomery(rr,r,mont,ctx);
	ret=1;
err:
	if ((in_mont == NULL) && (mont != NULL)) BN_MONT_CTX_free(mont);
	BN_CTX_end(ctx);
	for (i=0; i<ts; i++)
		{
		for (j=0; j<ts; j++)
			{
			BN_clear_free(&(val[i][j]));
			}
		}
	return(ret);
	}