aboutsummaryrefslogtreecommitdiff
path: root/core/math
diff options
context:
space:
mode:
authorJeroen van Rijn <Kelimion@users.noreply.github.com>2021-09-01 12:33:33 +0200
committerJeroen van Rijn <Kelimion@users.noreply.github.com>2021-09-01 19:13:47 +0200
commit7d7ed6b95f50ec36e6ed5ad6bded466ca75de26e (patch)
tree826853f24ab3853ddbbb96253bd6d416ec45dc81 /core/math
parenta056e1943435ed37330bc6d5c0eac241d323170b (diff)
big: Add `internal_int_exponent_mod`.
Diffstat (limited to 'core/math')
-rw-r--r--core/math/big/example.odin2
-rw-r--r--core/math/big/prime.odin107
2 files changed, 53 insertions, 56 deletions
diff --git a/core/math/big/example.odin b/core/math/big/example.odin
index de0aed468..64ac30424 100644
--- a/core/math/big/example.odin
+++ b/core/math/big/example.odin
@@ -218,7 +218,7 @@ demo :: proc() {
set(b, 6);
set(c, 131);
- if err := _private_int_exponent_mod(res, a, b, c, 1); err != nil {
+ if err := internal_int_exponent_mod(res, a, b, c); err != nil {
fmt.printf("Error: %v\n", err);
}
diff --git a/core/math/big/prime.odin b/core/math/big/prime.odin
index edd6d9f3d..85a7b931f 100644
--- a/core/math/big/prime.odin
+++ b/core/math/big/prime.odin
@@ -43,73 +43,70 @@ internal_int_prime_is_divisible :: proc(a: ^Int, allocator := context.allocator)
internal_int_exponent_mod :: proc(res, G, X, P: ^Int, allocator := context.allocator) -> (err: Error) {
context.allocator = allocator;
-/*
- int dr;
-
- /* modulus P must be positive */
- if (mp_isneg(P)) {
- return MP_VAL;
- }
-
- /* if exponent X is negative we have to recurse */
- if (mp_isneg(X)) {
- mp_int tmpG, tmpX;
- mp_err err;
-
- if (!MP_HAS(MP_INVMOD)) {
- return MP_VAL;
- }
-
- if ((err = mp_init_multi(&tmpG, &tmpX, NULL)) != MP_OKAY) {
- return err;
- }
-
- /* first compute 1/G mod P */
- if ((err = mp_invmod(G, P, &tmpG)) != MP_OKAY) {
- goto LBL_ERR;
- }
+ dr: int;
- /* now get |X| */
- if ((err = mp_abs(X, &tmpX)) != MP_OKAY) {
- goto LBL_ERR;
- }
+ /*
+ Modulus P must be positive.
+ */
+ if internal_is_negative(P) { return .Invalid_Argument; }
- /* and now compute (1/G)**|X| instead of G**X [X < 0] */
- err = mp_exptmod(&tmpG, &tmpX, P, Y);
-LBL_ERR:
- mp_clear_multi(&tmpG, &tmpX, NULL);
- return err;
+ /*
+ If exponent X is negative we have to recurse.
+ */
+ if internal_is_negative(X) {
+ tmpG, tmpX := &Int{}, &Int{};
+ defer internal_destroy(tmpG, tmpX);
+
+ internal_init_multi(tmpG, tmpX) or_return;
+
+ /*
+ First compute 1/G mod P.
+ */
+ internal_invmod(tmpG, G, P) or_return;
+
+ /*
+ now get |X|.
+ */
+ internal_abs(tmpX, X) or_return;
+
+ /*
+ And now compute (1/G)**|X| instead of G**X [X < 0].
+ */
+ return internal_int_exponent_mod(res, tmpG, tmpX, P);
}
- /* modified diminished radix reduction */
- if (MP_HAS(MP_REDUCE_IS_2K_L) && MP_HAS(MP_REDUCE_2K_L) && MP_HAS(S_MP_EXPTMOD) &&
- mp_reduce_is_2k_l(P)) {
- return s_mp_exptmod(G, X, P, Y, 1);
+ /*
+ Modified diminished radix reduction.
+ */
+ can_reduce_2k_l := _private_int_reduce_is_2k_l(P) or_return;
+ if can_reduce_2k_l {
+ return _private_int_exponent_mod(res, G, X, P, 1);
}
- /* is it a DR modulus? default to no */
- dr = (MP_HAS(MP_DR_IS_MODULUS) && mp_dr_is_modulus(P)) ? 1 : 0;
-
- /* if not, is it a unrestricted DR modulus? */
- if (MP_HAS(MP_REDUCE_IS_2K) && (dr == 0)) {
- dr = (mp_reduce_is_2k(P)) ? 2 : 0;
- }
+ /*
+ Is it a DR modulus? default to no.
+ */
+ dr = 1 if _private_dr_is_modulus(P) else 0;
- /* if the modulus is odd or dr != 0 use the montgomery method */
- if (MP_HAS(S_MP_EXPTMOD_FAST) && (mp_isodd(P) || (dr != 0))) {
- return s_mp_exptmod_fast(G, X, P, Y, dr);
+ /*
+ If not, is it a unrestricted DR modulus?
+ */
+ if dr == 0 {
+ reduce_is_2k := _private_int_reduce_is_2k(P) or_return;
+ dr = 2 if reduce_is_2k else 0;
}
- /* otherwise use the generic Barrett reduction technique */
- if (MP_HAS(S_MP_EXPTMOD)) {
- return s_mp_exptmod(G, X, P, Y, 0);
+ /*
+ If the modulus is odd or dr != 0 use the montgomery method.
+ */
+ if internal_int_is_odd(P) || dr != 0 {
+ return _private_int_exponent_mod(res, G, X, P, dr);
}
- /* no exptmod for evens */
- return MP_VAL;
-
+ /*
+ Otherwise use the generic Barrett reduction technique.
*/
- return nil;
+ return _private_int_exponent_mod(res, G, X, P, 0);
}
/*