Beispiel #1
0
int BN_rand_range_ex(BIGNUM *r, BN_ULONG min_inclusive,
                     const BIGNUM *max_exclusive, RAND *rng) {
  unsigned n;
  unsigned count = 100;

  if (BN_cmp_word(max_exclusive, min_inclusive) <= 0) {
    OPENSSL_PUT_ERROR(BN, BN_R_INVALID_RANGE);
    return 0;
  }

  n = BN_num_bits(max_exclusive); /* n > 0 */

  /* BN_is_bit_set(range, n - 1) always holds */
  if (n == 1) {
    BN_zero(r);
    return 1;
  }

  do {
    if (!--count) {
      OPENSSL_PUT_ERROR(BN, BN_R_TOO_MANY_ITERATIONS);
      return 0;
    }

    if (!BN_is_bit_set(max_exclusive, n - 2) &&
        !BN_is_bit_set(max_exclusive, n - 3)) {
      /* range = 100..._2, so 3*range (= 11..._2) is exactly one bit longer
       * than range. This is a common scenario when generating a random value
       * modulo an RSA public modulus, e.g. for RSA base blinding. */
      if (!BN_rand(r, n + 1, -1 /* don't set most significant bits */,
                   0 /* don't set least significant bits */, rng)) {
        return 0;
      }

      /* If r < 3*range, use r := r MOD range (which is either r, r - range, or
       * r - 2*range). Otherwise, iterate again. Since 3*range = 11..._2, each
       * iteration succeeds with probability >= .75. */
      if (BN_cmp(r, max_exclusive) >= 0) {
        if (!BN_sub(r, r, max_exclusive)) {
          return 0;
        }
        if (BN_cmp(r, max_exclusive) >= 0) {
          if (!BN_sub(r, r, max_exclusive)) {
            return 0;
          }
        }
      }
    } else {
      /* range = 11..._2  or  range = 101..._2 */
      if (!BN_rand(r, n, -1, 0, rng)) {
        return 0;
      }
    }
  } while (BN_cmp_word(r, min_inclusive) < 0 ||
           BN_cmp(r, max_exclusive) >= 0);

  return 1;
}
Beispiel #2
0
static int bn_rand_range_with_additional_data(
    BIGNUM *r, BN_ULONG min_inclusive, const BIGNUM *max_exclusive,
    const uint8_t additional_data[32]) {
  if (BN_cmp_word(max_exclusive, min_inclusive) <= 0) {
    OPENSSL_PUT_ERROR(BN, BN_R_INVALID_RANGE);
    return 0;
  }

  /* This function is used to implement steps 4 through 7 of FIPS 186-4
   * appendices B.4.2 and B.5.2. When called in those contexts, |max_exclusive|
   * is n and |min_inclusive| is one. */
  unsigned count = 100;
  unsigned n = BN_num_bits(max_exclusive); /* n > 0 */
  do {
    if (!--count) {
      OPENSSL_PUT_ERROR(BN, BN_R_TOO_MANY_ITERATIONS);
      return 0;
    }

    if (/* steps 4 and 5 */
        !bn_rand_with_additional_data(r, n, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY,
                                      additional_data) ||
        /* step 7 */
        !BN_add_word(r, min_inclusive)) {
      return 0;
    }

    /* Step 6. This loops if |r| >= |max_exclusive|. This is identical to
     * checking |r| > |max_exclusive| - 1 or |r| - 1 > |max_exclusive| - 2, the
     * formulation stated in FIPS 186-4. */
  } while (BN_cmp(r, max_exclusive) >= 0);

  return 1;
}
Beispiel #3
0
int BN_enhanced_miller_rabin_primality_test(
    enum bn_primality_result_t *out_result, const BIGNUM *w, int iterations,
    BN_CTX *ctx, BN_GENCB *cb) {
  /* Enhanced Miller-Rabin is only valid on odd integers greater than 3. */
  if (!BN_is_odd(w) || BN_cmp_word(w, 3) <= 0) {
    OPENSSL_PUT_ERROR(BN, BN_R_INVALID_INPUT);
    return 0;
  }

  if (iterations == BN_prime_checks) {
    iterations = BN_prime_checks_for_size(BN_num_bits(w));
  }

  int ret = 0;
  BN_MONT_CTX *mont = NULL;

  BN_CTX_start(ctx);

  BIGNUM *w1 = BN_CTX_get(ctx);
  if (w1 == NULL ||
      !BN_copy(w1, w) ||
      !BN_sub_word(w1, 1)) {
    goto err;
  }

  /* Write w1 as m*2^a (Steps 1 and 2). */
  int a = 0;
  while (!BN_is_bit_set(w1, a)) {
    a++;
  }
  BIGNUM *m = BN_CTX_get(ctx);
  if (m == NULL ||
      !BN_rshift(m, w1, a)) {
    goto err;
  }

  BIGNUM *b = BN_CTX_get(ctx);
  BIGNUM *g = BN_CTX_get(ctx);
  BIGNUM *z = BN_CTX_get(ctx);
  BIGNUM *x = BN_CTX_get(ctx);
  BIGNUM *x1 = BN_CTX_get(ctx);
  if (b == NULL ||
      g == NULL ||
      z == NULL ||
      x == NULL ||
      x1 == NULL) {
    goto err;
  }

  /* Montgomery setup for computations mod A */
  mont = BN_MONT_CTX_new();
  if (mont == NULL ||
      !BN_MONT_CTX_set(mont, w, ctx)) {
    goto err;
  }

  /* The following loop performs in inner iteration of the Enhanced Miller-Rabin
   * Primality test (Step 4). */
  for (int i = 1; i <= iterations; i++) {
    /* Step 4.1-4.2 */
    if (!BN_rand_range_ex(b, 2, w1)) {
      goto err;
    }

    /* Step 4.3-4.4 */
    if (!BN_gcd(g, b, w, ctx)) {
      goto err;
    }
    if (BN_cmp_word(g, 1) > 0) {
      *out_result = bn_composite;
      ret = 1;
      goto err;
    }

    /* Step 4.5 */
    if (!BN_mod_exp_mont(z, b, m, w, ctx, mont)) {
      goto err;
    }

    /* Step 4.6 */
    if (BN_is_one(z) || BN_cmp(z, w1) == 0) {
      goto loop;
    }

    /* Step 4.7 */
    for (int j = 1; j < a; j++) {
      if (!BN_copy(x, z) || !BN_mod_mul(z, x, x, w, ctx)) {
        goto err;
      }
      if (BN_cmp(z, w1) == 0) {
        goto loop;
      }
      if (BN_is_one(z)) {
        goto composite;
      }
    }

    /* Step 4.8-4.9 */
    if (!BN_copy(x, z) || !BN_mod_mul(z, x, x, w, ctx)) {
      goto err;
    }

    /* Step 4.10-4.11 */
    if (!BN_is_one(z) && !BN_copy(x, z)) {
      goto err;
    }

 composite:
    /* Step 4.12-4.14 */
    if (!BN_copy(x1, x) ||
        !BN_sub_word(x1, 1) ||
        !BN_gcd(g, x1, w, ctx)) {
      goto err;
    }
    if (BN_cmp_word(g, 1) > 0) {
      *out_result = bn_composite;
    } else {
      *out_result = bn_non_prime_power_composite;
    }

    ret = 1;
    goto err;

 loop:
    /* Step 4.15 */
    if (!BN_GENCB_call(cb, 1, i)) {
      goto err;
    }
  }

  *out_result = bn_probably_prime;
  ret = 1;

err:
  BN_MONT_CTX_free(mont);
  BN_CTX_end(ctx);

  return ret;
}