mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 23:58:50 +00:00
big: Add Miller-Rabin.
This commit is contained in:
@@ -204,6 +204,88 @@ internal_int_kronecker :: proc(a, p: ^Int, allocator := context.allocator) -> (k
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Miller-Rabin test of "a" to the base of "b" as described in HAC pp. 139 Algorithm 4.24.
|
||||||
|
|
||||||
|
Sets result to 0 if definitely composite or 1 if probably prime.
|
||||||
|
Randomly the chance of error is no more than 1/4 and often very much lower.
|
||||||
|
|
||||||
|
Assumes `a` and `b` not to be `nil` and to have been initialized.
|
||||||
|
*/
|
||||||
|
internal_int_prime_miller_rabin :: proc(a, b: ^Int, allocator := context.allocator) -> (probably_prime: bool, err: Error) {
|
||||||
|
context.allocator = allocator;
|
||||||
|
|
||||||
|
n1, y, r := &Int{}, &Int{}, &Int{};
|
||||||
|
defer internal_destroy(n1, y, r);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Ensure `b` > 1.
|
||||||
|
*/
|
||||||
|
if internal_gt(b, 1) { return false, nil; }
|
||||||
|
|
||||||
|
/*
|
||||||
|
Get n1 = a - 1.
|
||||||
|
*/
|
||||||
|
internal_copy(n1, a) or_return;
|
||||||
|
internal_sub(n1, n1, 1) or_return;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Set 2**s * r = n1
|
||||||
|
*/
|
||||||
|
internal_copy(r, n1) or_return;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Count the number of least significant bits which are zero.
|
||||||
|
*/
|
||||||
|
s := internal_count_lsb(r) or_return;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Now divide n - 1 by 2**s.
|
||||||
|
*/
|
||||||
|
internal_shr(r, r, s) or_return;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Compute y = b**r mod a.
|
||||||
|
*/
|
||||||
|
internal_int_exponent_mod(y, b, r, a) or_return;
|
||||||
|
|
||||||
|
/*
|
||||||
|
If y != 1 and y != n1 do.
|
||||||
|
*/
|
||||||
|
if !internal_eq(y, 1) && !internal_eq(y, n1) {
|
||||||
|
j := 1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
While `j` <= `s` - 1 and `y` != `n1`.
|
||||||
|
*/
|
||||||
|
for j <= (s - 1) && !internal_eq(y, n1) {
|
||||||
|
internal_sqrmod(y, y, a) or_return;
|
||||||
|
|
||||||
|
/*
|
||||||
|
If `y` == 1 then composite.
|
||||||
|
*/
|
||||||
|
if internal_eq(y, 1) {
|
||||||
|
return false, nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
j += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
If `y` != `n1` then composite.
|
||||||
|
*/
|
||||||
|
if !internal_eq(y, n1) {
|
||||||
|
return false, nil;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Probably prime now.
|
||||||
|
*/
|
||||||
|
return true, nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Returns the number of Rabin-Miller trials needed for a given bit size.
|
Returns the number of Rabin-Miller trials needed for a given bit size.
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user