diff --git a/src/PAST/NQP.pir b/src/PAST/NQP.pir index 208a8e1376..32f1c094ea 100644 --- a/src/PAST/NQP.pir +++ b/src/PAST/NQP.pir @@ -453,6 +453,7 @@ entry to produce the node to be returned. maphash['div_n'] = 'div__Nnn' maphash['mod_i'] = 'mod__Iii' maphash['mod_I'] = 'nqp_bigint_mod__PPPP' + maphash['expmod_I'] = 'nqp_bigint_exp_mod__PPPPP' maphash['mod_n'] = 'mod__Nnn' maphash['pow_n'] = 'pow__Nnn' maphash['pow_I'] = 'nqp_bigint_pow__PPPPP' diff --git a/src/ops/nqp_bigint.ops b/src/ops/nqp_bigint.ops index 6596cc42da..c8e4b5431b 100644 --- a/src/ops/nqp_bigint.ops +++ b/src/ops/nqp_bigint.ops @@ -176,6 +176,16 @@ inline op nqp_bigint_mod(out PMC, in PMC, in PMC, in PMC) :base_core { mp_mod(a, b, get_bigint(interp, $1)); } +inline op nqp_bigint_exp_mod(out PMC, in PMC, in PMC, in PMC, in PMC) :base_core { + mp_int *a = get_bigint(interp, $2); + mp_int *b = get_bigint(interp, $3); + mp_int *c = get_bigint(interp, $4); + $1 = REPR($5)->allocate(interp, STABLE($5)); + REPR($1)->initialize(interp, STABLE($1), OBJECT_BODY($1)); + mp_exptmod(a, b, c, get_bigint(interp, $1)); +} + + inline op nqp_bigint_neg(out PMC, in PMC, in PMC) :base_core { mp_int *a = get_bigint(interp, $2); $1 = REPR($3)->allocate(interp, STABLE($3)); diff --git a/t/nqp/60-bigint.t b/t/nqp/60-bigint.t index ed6763d3a0..9e08aa2de8 100644 --- a/t/nqp/60-bigint.t +++ b/t/nqp/60-bigint.t @@ -1,7 +1,7 @@ #! nqp use nqpmo; -plan(30); +plan(31); my $knowhow := pir::get_knowhow__P(); my $bi_type := $knowhow.new_type(:name('TestBigInt'), :repr('P6bigint')); @@ -84,3 +84,10 @@ ok(nqp::iseq_n($float, nqp::tonum_I(nqp::fromnum_I($float, $bi_type))), ok(nqp::base_I(box(-1234), 10) eq '-1234', 'base_I with base 10'); ok(nqp::base_I(box(-1234), 16) eq '-4D2', 'base_I with base 16'); + +ok(str(nqp::expmod_I( + nqp::fromstr_I('2988348162058574136915891421498819466320163312926952423791023078876139', $bi_type), + nqp::fromstr_I('2351399303373464486466122544523690094744975233415544072992656881240319', $bi_type), + nqp::fromstr_I('10000000000000000000000000000000000000000', $bi_type), + $bi_type, +)) eq '1527229998585248450016808958343740453059', 'nqp::expmod_I');