Пример #1
0
// only for prime N -- stupid but lazy, see if I care
void bn_inv(u8 *d, u8 *a, u8 *N, u32 n)
{
	u8 t[512], s[512];

	bn_copy(t, N, n);
	bn_zero(s, n);
	s[n-1] = 2;
	bn_sub_modulus(t, s, n);
	bn_exp(d, a, N, n, t, n);
}
Пример #2
0
int bn_is_prime_solov(const bn_t a) {
	bn_t t0, t1, t2;
	int i, result;

	bn_null(t0);
	bn_null(t1);
	bn_null(t2);

	result = 1;

	TRY {
		bn_new(t0);
		bn_new(t1);
		bn_new(t2);

		for (i = 0; i < 100; i++) {
			/* Generate t0, 2 <= t0, <= a - 2. */
			do {
				bn_rand(t0, BN_POS, bn_bits(a));
				bn_mod(t0, t0, a);
			} while (bn_cmp_dig(t0, 2) == CMP_LT);
			/* t2 = a - 1. */
			bn_copy(t2, a);
			bn_sub_dig(t2, t2, 1);
			/* t1 = (a - 1)/2. */
			bn_rsh(t1, t2, 1);
			/* t1 = t0^(a - 1)/2 mod a. */
#if BN_MOD != PMERS
			bn_mxp(t1, t0, t1, a);
#else
			bn_exp(t1, t0, t1, a);
#endif
			/* If t1 != 1 and t1 != n - 1 return 0 */
			if (bn_cmp_dig(t1, 1) != CMP_EQ && bn_cmp(t1, t2) != CMP_EQ) {
				result = 0;
				break;
			}

			/* t2 = (t0|a). */
			bn_smb_jac(t2, t0, a);
			if (bn_sign(t2) == BN_NEG) {
				bn_add(t2, t2, a);
			}
			/* If t1 != t2 (mod a) return 0. */
			bn_mod(t1, t1, a);
			bn_mod(t2, t2, a);
			if (bn_cmp(t1, t2) != CMP_EQ) {
				result = 0;
				break;
			}
		}
	}
	CATCH_ANY {
		result = 0;
		THROW(ERR_CAUGHT);
	}
	FINALLY {
		bn_free(t0);
		bn_free(t1);
		bn_free(t2);
	}
	return result;
}
Пример #3
0
void bn_gen_prime_stron(bn_t a, int bits) {
	dig_t i, j;
	int found, k;
	bn_t r, s, t;

	bn_null(r);
	bn_null(s);
	bn_null(t);

	TRY {
		bn_new(r);
		bn_new(s);
		bn_new(t);

		do {
			do {
				/* Generate two large primes r and s. */
				bn_rand(s, BN_POS, bits / 2 - BN_DIGIT / 2);
				bn_rand(t, BN_POS, bits / 2 - BN_DIGIT / 2);
			} while (!bn_is_prime(s) || !bn_is_prime(t));
			found = 1;
			bn_rand(a, BN_POS, bits / 2 - bn_bits(t) - 1);
			i = a->dp[0];
			bn_dbl(t, t);
			do {
				/* Find first prime r = 2 * i * t + 1. */
				bn_mul_dig(r, t, i);
				bn_add_dig(r, r, 1);
				i++;
				if (bn_bits(r) > bits / 2 - 1) {
					found = 0;
					break;
				}
			} while (!bn_is_prime(r));
			if (found == 0) {
				continue;
			}
			/* Compute t = 2 * (s^(r-2) mod r) * s - 1. */
			bn_sub_dig(t, r, 2);
#if BN_MOD != PMERS
			bn_mxp(t, s, t, r);
#else
			bn_exp(t, s, t, r);
#endif

			bn_mul(t, t, s);
			bn_dbl(t, t);
			bn_sub_dig(t, t, 1);

			k = bits - bn_bits(r);
			k -= bn_bits(s);
			bn_rand(a, BN_POS, k);
			j = a->dp[0];
			do {
				/* Find first prime a = t + 2 * j * r * s. */
				bn_mul(a, r, s);
				bn_mul_dig(a, a, j);
				bn_dbl(a, a);
				bn_add(a, a, t);
				j++;
				if (bn_bits(a) > bits) {
					found = 0;
					break;
				}
			} while (!bn_is_prime(a));
		} while (found == 0 && bn_bits(a) != bits);
	}
	CATCH_ANY {
		THROW(ERR_CAUGHT);
	}
	FINALLY {
		bn_free(r);
		bn_free(s);
		bn_free(t);
	}
}
Пример #4
0
int bn_is_prime_rabin(const bn_t a) {
	bn_t t, n1, y, r;
	int i, s, j, result, b, tests = 0;

	tests = 0;
	result = 1;

	bn_null(t);
	bn_null(n1);
	bn_null(y);
	bn_null(r);

	if (bn_cmp_dig(a, 1) == CMP_EQ) {
		return 0;
	}

	TRY {
		/*
		 * These values are taken from Table 4.4 inside Handbook of Applied
		 * Cryptography.
		 */
		b = bn_bits(a);
		if (b >= 1300) {
			tests = 2;
		} else if (b >= 850) {
			tests = 3;
		} else if (b >= 650) {
			tests = 4;
		} else if (b >= 550) {
			tests = 5;
		} else if (b >= 450) {
			tests = 6;
		} else if (b >= 400) {
			tests = 7;
		} else if (b >= 350) {
			tests = 8;
		} else if (b >= 300) {
			tests = 9;
		} else if (b >= 250) {
			tests = 12;
		} else if (b >= 200) {
			tests = 15;
		} else if (b >= 150) {
			tests = 18;
		} else {
			tests = 27;
		}

		bn_new(t);
		bn_new(n1);
		bn_new(y);
		bn_new(r);

		/* r = (n - 1)/2^s. */
		bn_sub_dig(n1, a, 1);
		s = 0;
		while (bn_is_even(n1)) {
			s++;
			bn_rsh(n1, n1, 1);
		}
		bn_lsh(r, n1, s);

		for (i = 0; i < tests; i++) {
			/* Fix the basis as the first few primes. */
			bn_set_dig(t, primes[i]);

			/* y = b^r mod a. */
#if BN_MOD != PMERS
			bn_mxp(y, t, r, a);
#else
			bn_exp(y, t, r, a);
#endif

			if (bn_cmp_dig(y, 1) != CMP_EQ && bn_cmp(y, n1) != CMP_EQ) {
				j = 1;
				while ((j <= (s - 1)) && bn_cmp(y, n1) != CMP_EQ) {
					bn_sqr(y, y);
					bn_mod(y, y, a);

					/* If y == 1 then composite. */
					if (bn_cmp_dig(y, 1) == CMP_EQ) {
						result = 0;
						break;
					}
					++j;
				}

				/* If y != n1 then composite. */
				if (bn_cmp(y, n1) != CMP_EQ) {
					result = 0;
					break;
				}
			}
		}
	}
	CATCH_ANY {
		result = 0;
		THROW(ERR_CAUGHT);
	}
	FINALLY {
		bn_free(r);
		bn_free(y);
		bn_free(n1);
		bn_free(t);
	}
	return result;
}