fixed

Pure Haskell large fixed-width integers and Montgomery arithmetic (docs.ppad.tech/fixed).
git clone git://git.ppad.tech/fixed.git
Log | Files | Refs | README | LICENSE

commit dda4a9c68ad1f80affda6a367439a2228a79b31f
parent e396a7f0d97471e8a9c19ac83f3d3366c3300a4e
Author: Jared Tobin <jared@jtobin.io>
Date:   Sun,  7 Jun 2026 18:30:08 -0230

lib: addition-chain modular inversion

Replaces the naive square-and-multiply Fermat inversion with an addition
chain that coalesces runs of 1 bits. The square-and-multiply schedule
stays fixed and data-independent, so inv# remains constant-time by
construction.

Operation counts (sqr + mul) and -f+llvm timings:

  curve:  256 + 249 -> 261 + 19   7.13us -> 3.57us  (2.0x)
  scalar: 256 + 196 -> 258 + 47   6.40us -> 4.08us  (1.6x)

etc/generate_inv.sh is updated to emit the new chains.

Diffstat:
Metc/generate_inv.sh | 165+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------
Mlib/Numeric/Montgomery/Secp256k1/Curve.hs | 534+++++++++++++++++++++++--------------------------------------------------------
Mlib/Numeric/Montgomery/Secp256k1/Scalar.hs | 500++++++++++++++++++++++++++++---------------------------------------------------
3 files changed, 463 insertions(+), 736 deletions(-)

diff --git a/etc/generate_inv.sh b/etc/generate_inv.sh @@ -3,23 +3,30 @@ # generates a constant-time haskell function for performing modular # inversion with montgomery arithmetic on a secp256k1-derived field. # -# fermat inversion is used. one proceeds through the (fixed, known) -# bit-string of the exponent in MSB order, montgomery-squaring an -# accumulator each time, and montgomery-multiplying on every '1' bit. -# this script generates a function consisting of this loop, unrolled. +# fermat inversion is used: a^-1 = a ^ (m - 2) mod m, where m is the +# secp256k1 field prime (curve) or the scalar group order (scalar). # -# since the square-and-multiply schedule is fixed, then given -# constant-time 'sqr#' and 'mul#", 'inv#' is also constant-time by -# construction. - -# for fermat inversion, we raise an argument to e.g. the secp256k1 field -# prime - 2. i.e.: +# rather than a naive square-and-multiply over the exponent bits (one +# montgomery-multiply per set bit), we use an addition chain that +# coalesces runs of 1 bits. for a maximal run of L consecutive 1 bits +# we precompute the block +# +# x_L = a ^ (2^L - 1) +# +# and fold the whole run in with a single multiply, since +# +# result^(2^L) * x_L +# +# appends L ones to the accumulated exponent. the x_L blocks are built +# with a doubling ladder using the identities # -# a^-1 = a ^ p - 2 mod p +# x_(i+j) = (x_i)^(2^j) * x_j (so x_2k = (x_k)^(2^k) * x_k) # -# or to the secp256k1 scalar group order - 2: +# which costs O(log L) multiplies per block instead of O(L). # -# a^-1 = a ^ q - 2 mod q +# the square-and-multiply schedule is still fixed and data-independent, +# so given constant-time 'sqr#' and 'mul#', 'inv#' is constant-time by +# construction. # secp256k1 field prime - 2 exponent_curve="1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111011111111111111111111110000101101" @@ -28,40 +35,134 @@ exponent_curve="1111111111111111111111111111111111111111111111111111111111111111 exponent_scalar="1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111010111010101011101101110011100110101011110100100010100000001110111011111111010010010111101000110011010000001101100100000100111111" # adjust me as desired; use 'curve' or 'scalar' -target="scalar" +target="curve" declare exponent - if [[ $target == "curve" ]]; then exponent=$exponent_curve elif [[ $target == "scalar" ]]; then exponent=$exponent_scalar +else + echo "unknown target: $target" >&2 + exit 1 fi +# next free t-label, and a map from block length L to the variable +# holding x_L = a ^ (2^L - 1). x_1 is the argument 'a' itself. +idx=1 +declare -A blk +blk[1]="a" + +# REPLY conventions: emit_* helpers return the resulting variable in +# the global REPLY. + +emit_sqr_n() { # $1 = source var, $2 = count + local src=$1 n=$2 i + for (( i = 0; i < n; i++ )); do + echo " !t$idx = sqr# $src" + src=t$idx + idx=$((idx + 1)) + done + REPLY=$src +} + +emit_mul() { # $1, $2 = vars + echo " !t$idx = mul# $1 $2" + REPLY=t$idx + idx=$((idx + 1)) +} + +# ensure x_1, x_2, x_4, ..., x_hp (powers of two up to hp) are built +build_powers() { # $1 = highest power of two needed + local hp=$1 p=1 np acc + while (( p < hp )); do + np=$((p * 2)) + if [[ -z ${blk[$np]:-} ]]; then + emit_sqr_n "${blk[$p]}" "$p"; acc=$REPLY # x_p ^ (2^p) + emit_mul "$acc" "${blk[$p]}"; acc=$REPLY # * x_p = x_2p + blk[$np]=$acc + fi + p=$np + done +} + +# ensure x_L is built, composing it from power-of-two blocks +build_block() { # $1 = run length L + local L=$1 hp pw rem acc + [[ -n ${blk[$L]:-} ]] && return + hp=1 + while (( hp * 2 <= L )); do hp=$((hp * 2)); done + build_powers "$hp" + rem=$L; acc=""; pw=$hp + while (( pw >= 1 )); do + if (( rem >= pw )); then + if [[ -z $acc ]]; then + acc=${blk[$pw]} + else + emit_sqr_n "$acc" "$pw"; acc=$REPLY + emit_mul "$acc" "${blk[$pw]}"; acc=$REPLY + fi + rem=$((rem - pw)) + fi + pw=$((pw / 2)) + done + blk[$L]=$acc +} + +# parse the exponent into alternating runs ('R', ones) and gaps ('G') +seg_type=(); seg_len=() +i=0; n=${#exponent} +while (( i < n )); do + c=${exponent:i:1} + j=$i + while (( j < n )) && [[ ${exponent:j:1} == "$c" ]]; do j=$((j + 1)); done + if [[ $c == 1 ]]; then seg_type+=("R"); else seg_type+=("G"); fi + seg_len+=("$((j - i))") + i=$j +done + echo "-- generated by etc/generate_inv.sh" echo "inv#" -echo " :: (# Limb, Limb, Limb, Limb #)" -echo " -> (# Limb, Limb, Limb, Limb #)" +echo " :: Limb4" +echo " -> Limb4" echo "inv# a =" -if [[ $target == "curve" ]]; then - echo " let !t0 = (# Limb 0x1000003D1##, Limb 0##, Limb 0##, Limb 0## #)" -elif [[ $target == "scalar" ]]; then - echo " let !t0 = (# Limb 0x402DA1732FC9BEBF##, Limb 0x4551231950B75FC4##" - echo " , Limb 0x0000000000000001##, Limb 0x0000000000000000## #)" -fi +echo " let" -label=1 +# build blocks for the longest run first so the doubling ladder is +# shared, then any shorter runs reuse the cached intermediates. +maxrun=0 +for k in "${!seg_type[@]}"; do + if [[ ${seg_type[k]} == R ]] && (( seg_len[k] > maxrun )); then + maxrun=${seg_len[k]} + fi +done +build_block "$maxrun" +for k in "${!seg_type[@]}"; do + if [[ ${seg_type[k]} == R ]]; then build_block "${seg_len[k]}"; fi +done -for ((i = 0; i < ${#exponent}; i++)); do - echo " !t""$label"" = sqr# t""$((label-1))" - if [[ "${exponent:i:1}" == "1" ]]; then - label=$((label+1)) - echo " !t""$label"" = mul# a t""$((label-1))" +# fold the exponent: result starts at the leading run, then each +# subsequent run is appended via result^(2^(gap+run)) * x_run. +result=""; pending=0; first=1 +for k in "${!seg_type[@]}"; do + if [[ ${seg_type[k]} == G ]]; then + pending=$((pending + seg_len[k])) + else + L=${seg_len[k]} + if (( first )); then + result=${blk[$L]}; first=0 + else + emit_sqr_n "$result" "$((pending + L))"; result=$REPLY + emit_mul "$result" "${blk[$L]}"; result=$REPLY + fi + pending=0 fi - label=$((label+1)) done +# trailing zero bits, if any +if (( pending > 0 )); then + emit_sqr_n "$result" "$pending"; result=$REPLY +fi -echo " !r = t""$((label-1))" +echo " !r = $result" echo " in r" echo '{-# INLINE inv# #-}' - diff --git a/lib/Numeric/Montgomery/Secp256k1/Curve.hs b/lib/Numeric/Montgomery/Secp256k1/Curve.hs @@ -474,514 +474,288 @@ inv# :: Limb4 -> Limb4 inv# a = - let -- montgomery 'one' - !t0 = L4 0x1000003D1## 0## 0## 0## - !t1 = sqr# t0 - !t2 = mul# a t1 + let + !t1 = sqr# a + !t2 = mul# t1 a !t3 = sqr# t2 - !t4 = mul# a t3 - !t5 = sqr# t4 - !t6 = mul# a t5 + !t4 = sqr# t3 + !t5 = mul# t4 t2 + !t6 = sqr# t5 !t7 = sqr# t6 - !t8 = mul# a t7 + !t8 = sqr# t7 !t9 = sqr# t8 - !t10 = mul# a t9 + !t10 = mul# t9 t5 !t11 = sqr# t10 - !t12 = mul# a t11 + !t12 = sqr# t11 !t13 = sqr# t12 - !t14 = mul# a t13 + !t14 = sqr# t13 !t15 = sqr# t14 - !t16 = mul# a t15 + !t16 = sqr# t15 !t17 = sqr# t16 - !t18 = mul# a t17 - !t19 = sqr# t18 - !t20 = mul# a t19 + !t18 = sqr# t17 + !t19 = mul# t18 t10 + !t20 = sqr# t19 !t21 = sqr# t20 - !t22 = mul# a t21 + !t22 = sqr# t21 !t23 = sqr# t22 - !t24 = mul# a t23 + !t24 = sqr# t23 !t25 = sqr# t24 - !t26 = mul# a t25 + !t26 = sqr# t25 !t27 = sqr# t26 - !t28 = mul# a t27 + !t28 = sqr# t27 !t29 = sqr# t28 - !t30 = mul# a t29 + !t30 = sqr# t29 !t31 = sqr# t30 - !t32 = mul# a t31 + !t32 = sqr# t31 !t33 = sqr# t32 - !t34 = mul# a t33 + !t34 = sqr# t33 !t35 = sqr# t34 - !t36 = mul# a t35 + !t36 = mul# t35 t19 !t37 = sqr# t36 - !t38 = mul# a t37 + !t38 = sqr# t37 !t39 = sqr# t38 - !t40 = mul# a t39 + !t40 = sqr# t39 !t41 = sqr# t40 - !t42 = mul# a t41 + !t42 = sqr# t41 !t43 = sqr# t42 - !t44 = mul# a t43 + !t44 = sqr# t43 !t45 = sqr# t44 - !t46 = mul# a t45 + !t46 = sqr# t45 !t47 = sqr# t46 - !t48 = mul# a t47 + !t48 = sqr# t47 !t49 = sqr# t48 - !t50 = mul# a t49 + !t50 = sqr# t49 !t51 = sqr# t50 - !t52 = mul# a t51 + !t52 = sqr# t51 !t53 = sqr# t52 - !t54 = mul# a t53 + !t54 = sqr# t53 !t55 = sqr# t54 - !t56 = mul# a t55 + !t56 = sqr# t55 !t57 = sqr# t56 - !t58 = mul# a t57 + !t58 = sqr# t57 !t59 = sqr# t58 - !t60 = mul# a t59 + !t60 = sqr# t59 !t61 = sqr# t60 - !t62 = mul# a t61 + !t62 = sqr# t61 !t63 = sqr# t62 - !t64 = mul# a t63 + !t64 = sqr# t63 !t65 = sqr# t64 - !t66 = mul# a t65 + !t66 = sqr# t65 !t67 = sqr# t66 - !t68 = mul# a t67 - !t69 = sqr# t68 - !t70 = mul# a t69 + !t68 = sqr# t67 + !t69 = mul# t68 t36 + !t70 = sqr# t69 !t71 = sqr# t70 - !t72 = mul# a t71 + !t72 = sqr# t71 !t73 = sqr# t72 - !t74 = mul# a t73 + !t74 = sqr# t73 !t75 = sqr# t74 - !t76 = mul# a t75 + !t76 = sqr# t75 !t77 = sqr# t76 - !t78 = mul# a t77 + !t78 = sqr# t77 !t79 = sqr# t78 - !t80 = mul# a t79 + !t80 = sqr# t79 !t81 = sqr# t80 - !t82 = mul# a t81 + !t82 = sqr# t81 !t83 = sqr# t82 - !t84 = mul# a t83 + !t84 = sqr# t83 !t85 = sqr# t84 - !t86 = mul# a t85 + !t86 = sqr# t85 !t87 = sqr# t86 - !t88 = mul# a t87 + !t88 = sqr# t87 !t89 = sqr# t88 - !t90 = mul# a t89 + !t90 = sqr# t89 !t91 = sqr# t90 - !t92 = mul# a t91 + !t92 = sqr# t91 !t93 = sqr# t92 - !t94 = mul# a t93 + !t94 = sqr# t93 !t95 = sqr# t94 - !t96 = mul# a t95 + !t96 = sqr# t95 !t97 = sqr# t96 - !t98 = mul# a t97 + !t98 = sqr# t97 !t99 = sqr# t98 - !t100 = mul# a t99 + !t100 = sqr# t99 !t101 = sqr# t100 - !t102 = mul# a t101 + !t102 = sqr# t101 !t103 = sqr# t102 - !t104 = mul# a t103 + !t104 = sqr# t103 !t105 = sqr# t104 - !t106 = mul# a t105 + !t106 = sqr# t105 !t107 = sqr# t106 - !t108 = mul# a t107 + !t108 = sqr# t107 !t109 = sqr# t108 - !t110 = mul# a t109 + !t110 = sqr# t109 !t111 = sqr# t110 - !t112 = mul# a t111 + !t112 = sqr# t111 !t113 = sqr# t112 - !t114 = mul# a t113 + !t114 = sqr# t113 !t115 = sqr# t114 - !t116 = mul# a t115 + !t116 = sqr# t115 !t117 = sqr# t116 - !t118 = mul# a t117 + !t118 = sqr# t117 !t119 = sqr# t118 - !t120 = mul# a t119 + !t120 = sqr# t119 !t121 = sqr# t120 - !t122 = mul# a t121 + !t122 = sqr# t121 !t123 = sqr# t122 - !t124 = mul# a t123 + !t124 = sqr# t123 !t125 = sqr# t124 - !t126 = mul# a t125 + !t126 = sqr# t125 !t127 = sqr# t126 - !t128 = mul# a t127 + !t128 = sqr# t127 !t129 = sqr# t128 - !t130 = mul# a t129 + !t130 = sqr# t129 !t131 = sqr# t130 - !t132 = mul# a t131 + !t132 = sqr# t131 !t133 = sqr# t132 - !t134 = mul# a t133 + !t134 = mul# t133 t69 !t135 = sqr# t134 - !t136 = mul# a t135 + !t136 = sqr# t135 !t137 = sqr# t136 - !t138 = mul# a t137 + !t138 = sqr# t137 !t139 = sqr# t138 - !t140 = mul# a t139 + !t140 = sqr# t139 !t141 = sqr# t140 - !t142 = mul# a t141 + !t142 = sqr# t141 !t143 = sqr# t142 - !t144 = mul# a t143 + !t144 = sqr# t143 !t145 = sqr# t144 - !t146 = mul# a t145 + !t146 = sqr# t145 !t147 = sqr# t146 - !t148 = mul# a t147 + !t148 = sqr# t147 !t149 = sqr# t148 - !t150 = mul# a t149 + !t150 = sqr# t149 !t151 = sqr# t150 - !t152 = mul# a t151 + !t152 = sqr# t151 !t153 = sqr# t152 - !t154 = mul# a t153 + !t154 = sqr# t153 !t155 = sqr# t154 - !t156 = mul# a t155 + !t156 = sqr# t155 !t157 = sqr# t156 - !t158 = mul# a t157 + !t158 = sqr# t157 !t159 = sqr# t158 - !t160 = mul# a t159 + !t160 = sqr# t159 !t161 = sqr# t160 - !t162 = mul# a t161 + !t162 = sqr# t161 !t163 = sqr# t162 - !t164 = mul# a t163 + !t164 = sqr# t163 !t165 = sqr# t164 - !t166 = mul# a t165 + !t166 = sqr# t165 !t167 = sqr# t166 - !t168 = mul# a t167 + !t168 = sqr# t167 !t169 = sqr# t168 - !t170 = mul# a t169 + !t170 = sqr# t169 !t171 = sqr# t170 - !t172 = mul# a t171 + !t172 = sqr# t171 !t173 = sqr# t172 - !t174 = mul# a t173 + !t174 = sqr# t173 !t175 = sqr# t174 - !t176 = mul# a t175 + !t176 = sqr# t175 !t177 = sqr# t176 - !t178 = mul# a t177 + !t178 = sqr# t177 !t179 = sqr# t178 - !t180 = mul# a t179 + !t180 = sqr# t179 !t181 = sqr# t180 - !t182 = mul# a t181 + !t182 = sqr# t181 !t183 = sqr# t182 - !t184 = mul# a t183 + !t184 = sqr# t183 !t185 = sqr# t184 - !t186 = mul# a t185 + !t186 = sqr# t185 !t187 = sqr# t186 - !t188 = mul# a t187 + !t188 = sqr# t187 !t189 = sqr# t188 - !t190 = mul# a t189 + !t190 = sqr# t189 !t191 = sqr# t190 - !t192 = mul# a t191 + !t192 = sqr# t191 !t193 = sqr# t192 - !t194 = mul# a t193 + !t194 = sqr# t193 !t195 = sqr# t194 - !t196 = mul# a t195 + !t196 = sqr# t195 !t197 = sqr# t196 - !t198 = mul# a t197 - !t199 = sqr# t198 - !t200 = mul# a t199 + !t198 = sqr# t197 + !t199 = mul# t198 t69 + !t200 = sqr# t199 !t201 = sqr# t200 - !t202 = mul# a t201 + !t202 = sqr# t201 !t203 = sqr# t202 - !t204 = mul# a t203 + !t204 = sqr# t203 !t205 = sqr# t204 - !t206 = mul# a t205 + !t206 = sqr# t205 !t207 = sqr# t206 - !t208 = mul# a t207 + !t208 = sqr# t207 !t209 = sqr# t208 - !t210 = mul# a t209 + !t210 = sqr# t209 !t211 = sqr# t210 - !t212 = mul# a t211 + !t212 = sqr# t211 !t213 = sqr# t212 - !t214 = mul# a t213 + !t214 = sqr# t213 !t215 = sqr# t214 - !t216 = mul# a t215 + !t216 = mul# t215 t19 !t217 = sqr# t216 - !t218 = mul# a t217 + !t218 = sqr# t217 !t219 = sqr# t218 - !t220 = mul# a t219 + !t220 = sqr# t219 !t221 = sqr# t220 - !t222 = mul# a t221 + !t222 = sqr# t221 !t223 = sqr# t222 - !t224 = mul# a t223 - !t225 = sqr# t224 - !t226 = mul# a t225 + !t224 = sqr# t223 + !t225 = mul# t224 t10 + !t226 = sqr# t225 !t227 = sqr# t226 - !t228 = mul# a t227 + !t228 = sqr# t227 !t229 = sqr# t228 - !t230 = mul# a t229 + !t230 = mul# t229 t5 !t231 = sqr# t230 - !t232 = mul# a t231 - !t233 = sqr# t232 - !t234 = mul# a t233 - !t235 = sqr# t234 - !t236 = mul# a t235 + !t232 = sqr# t231 + !t233 = mul# t232 t2 + !t234 = sqr# t233 + !t235 = mul# t234 a + !t236 = sqr# t19 !t237 = sqr# t236 - !t238 = mul# a t237 + !t238 = sqr# t237 !t239 = sqr# t238 - !t240 = mul# a t239 + !t240 = mul# t239 t5 !t241 = sqr# t240 - !t242 = mul# a t241 - !t243 = sqr# t242 - !t244 = mul# a t243 + !t242 = sqr# t241 + !t243 = mul# t242 t2 + !t244 = sqr# t235 !t245 = sqr# t244 - !t246 = mul# a t245 + !t246 = sqr# t245 !t247 = sqr# t246 - !t248 = mul# a t247 + !t248 = sqr# t247 !t249 = sqr# t248 - !t250 = mul# a t249 + !t250 = sqr# t249 !t251 = sqr# t250 - !t252 = mul# a t251 + !t252 = sqr# t251 !t253 = sqr# t252 - !t254 = mul# a t253 + !t254 = sqr# t253 !t255 = sqr# t254 - !t256 = mul# a t255 + !t256 = sqr# t255 !t257 = sqr# t256 - !t258 = mul# a t257 + !t258 = sqr# t257 !t259 = sqr# t258 - !t260 = mul# a t259 + !t260 = sqr# t259 !t261 = sqr# t260 - !t262 = mul# a t261 + !t262 = sqr# t261 !t263 = sqr# t262 - !t264 = mul# a t263 + !t264 = sqr# t263 !t265 = sqr# t264 - !t266 = mul# a t265 - !t267 = sqr# t266 - !t268 = mul# a t267 + !t266 = sqr# t265 + !t267 = mul# t266 t243 + !t268 = sqr# t267 !t269 = sqr# t268 - !t270 = mul# a t269 + !t270 = sqr# t269 !t271 = sqr# t270 - !t272 = mul# a t271 - !t273 = sqr# t272 - !t274 = mul# a t273 + !t272 = sqr# t271 + !t273 = mul# t272 a + !t274 = sqr# t273 !t275 = sqr# t274 - !t276 = mul# a t275 - !t277 = sqr# t276 - !t278 = mul# a t277 + !t276 = sqr# t275 + !t277 = mul# t276 t2 + !t278 = sqr# t277 !t279 = sqr# t278 - !t280 = mul# a t279 - !t281 = sqr# t280 - !t282 = mul# a t281 - !t283 = sqr# t282 - !t284 = mul# a t283 - !t285 = sqr# t284 - !t286 = mul# a t285 - !t287 = sqr# t286 - !t288 = mul# a t287 - !t289 = sqr# t288 - !t290 = mul# a t289 - !t291 = sqr# t290 - !t292 = mul# a t291 - !t293 = sqr# t292 - !t294 = mul# a t293 - !t295 = sqr# t294 - !t296 = mul# a t295 - !t297 = sqr# t296 - !t298 = mul# a t297 - !t299 = sqr# t298 - !t300 = mul# a t299 - !t301 = sqr# t300 - !t302 = mul# a t301 - !t303 = sqr# t302 - !t304 = mul# a t303 - !t305 = sqr# t304 - !t306 = mul# a t305 - !t307 = sqr# t306 - !t308 = mul# a t307 - !t309 = sqr# t308 - !t310 = mul# a t309 - !t311 = sqr# t310 - !t312 = mul# a t311 - !t313 = sqr# t312 - !t314 = mul# a t313 - !t315 = sqr# t314 - !t316 = mul# a t315 - !t317 = sqr# t316 - !t318 = mul# a t317 - !t319 = sqr# t318 - !t320 = mul# a t319 - !t321 = sqr# t320 - !t322 = mul# a t321 - !t323 = sqr# t322 - !t324 = mul# a t323 - !t325 = sqr# t324 - !t326 = mul# a t325 - !t327 = sqr# t326 - !t328 = mul# a t327 - !t329 = sqr# t328 - !t330 = mul# a t329 - !t331 = sqr# t330 - !t332 = mul# a t331 - !t333 = sqr# t332 - !t334 = mul# a t333 - !t335 = sqr# t334 - !t336 = mul# a t335 - !t337 = sqr# t336 - !t338 = mul# a t337 - !t339 = sqr# t338 - !t340 = mul# a t339 - !t341 = sqr# t340 - !t342 = mul# a t341 - !t343 = sqr# t342 - !t344 = mul# a t343 - !t345 = sqr# t344 - !t346 = mul# a t345 - !t347 = sqr# t346 - !t348 = mul# a t347 - !t349 = sqr# t348 - !t350 = mul# a t349 - !t351 = sqr# t350 - !t352 = mul# a t351 - !t353 = sqr# t352 - !t354 = mul# a t353 - !t355 = sqr# t354 - !t356 = mul# a t355 - !t357 = sqr# t356 - !t358 = mul# a t357 - !t359 = sqr# t358 - !t360 = mul# a t359 - !t361 = sqr# t360 - !t362 = mul# a t361 - !t363 = sqr# t362 - !t364 = mul# a t363 - !t365 = sqr# t364 - !t366 = mul# a t365 - !t367 = sqr# t366 - !t368 = mul# a t367 - !t369 = sqr# t368 - !t370 = mul# a t369 - !t371 = sqr# t370 - !t372 = mul# a t371 - !t373 = sqr# t372 - !t374 = mul# a t373 - !t375 = sqr# t374 - !t376 = mul# a t375 - !t377 = sqr# t376 - !t378 = mul# a t377 - !t379 = sqr# t378 - !t380 = mul# a t379 - !t381 = sqr# t380 - !t382 = mul# a t381 - !t383 = sqr# t382 - !t384 = mul# a t383 - !t385 = sqr# t384 - !t386 = mul# a t385 - !t387 = sqr# t386 - !t388 = mul# a t387 - !t389 = sqr# t388 - !t390 = mul# a t389 - !t391 = sqr# t390 - !t392 = mul# a t391 - !t393 = sqr# t392 - !t394 = mul# a t393 - !t395 = sqr# t394 - !t396 = mul# a t395 - !t397 = sqr# t396 - !t398 = mul# a t397 - !t399 = sqr# t398 - !t400 = mul# a t399 - !t401 = sqr# t400 - !t402 = mul# a t401 - !t403 = sqr# t402 - !t404 = mul# a t403 - !t405 = sqr# t404 - !t406 = mul# a t405 - !t407 = sqr# t406 - !t408 = mul# a t407 - !t409 = sqr# t408 - !t410 = mul# a t409 - !t411 = sqr# t410 - !t412 = mul# a t411 - !t413 = sqr# t412 - !t414 = mul# a t413 - !t415 = sqr# t414 - !t416 = mul# a t415 - !t417 = sqr# t416 - !t418 = mul# a t417 - !t419 = sqr# t418 - !t420 = mul# a t419 - !t421 = sqr# t420 - !t422 = mul# a t421 - !t423 = sqr# t422 - !t424 = mul# a t423 - !t425 = sqr# t424 - !t426 = mul# a t425 - !t427 = sqr# t426 - !t428 = mul# a t427 - !t429 = sqr# t428 - !t430 = mul# a t429 - !t431 = sqr# t430 - !t432 = mul# a t431 - !t433 = sqr# t432 - !t434 = mul# a t433 - !t435 = sqr# t434 - !t436 = mul# a t435 - !t437 = sqr# t436 - !t438 = mul# a t437 - !t439 = sqr# t438 - !t440 = mul# a t439 - !t441 = sqr# t440 - !t442 = mul# a t441 - !t443 = sqr# t442 - !t444 = mul# a t443 - !t445 = sqr# t444 - !t446 = mul# a t445 - !t447 = sqr# t446 - !t448 = sqr# t447 - !t449 = mul# a t448 - !t450 = sqr# t449 - !t451 = mul# a t450 - !t452 = sqr# t451 - !t453 = mul# a t452 - !t454 = sqr# t453 - !t455 = mul# a t454 - !t456 = sqr# t455 - !t457 = mul# a t456 - !t458 = sqr# t457 - !t459 = mul# a t458 - !t460 = sqr# t459 - !t461 = mul# a t460 - !t462 = sqr# t461 - !t463 = mul# a t462 - !t464 = sqr# t463 - !t465 = mul# a t464 - !t466 = sqr# t465 - !t467 = mul# a t466 - !t468 = sqr# t467 - !t469 = mul# a t468 - !t470 = sqr# t469 - !t471 = mul# a t470 - !t472 = sqr# t471 - !t473 = mul# a t472 - !t474 = sqr# t473 - !t475 = mul# a t474 - !t476 = sqr# t475 - !t477 = mul# a t476 - !t478 = sqr# t477 - !t479 = mul# a t478 - !t480 = sqr# t479 - !t481 = mul# a t480 - !t482 = sqr# t481 - !t483 = mul# a t482 - !t484 = sqr# t483 - !t485 = mul# a t484 - !t486 = sqr# t485 - !t487 = mul# a t486 - !t488 = sqr# t487 - !t489 = mul# a t488 - !t490 = sqr# t489 - !t491 = mul# a t490 - !t492 = sqr# t491 - !t493 = sqr# t492 - !t494 = sqr# t493 - !t495 = sqr# t494 - !t496 = sqr# t495 - !t497 = mul# a t496 - !t498 = sqr# t497 - !t499 = sqr# t498 - !t500 = mul# a t499 - !t501 = sqr# t500 - !t502 = mul# a t501 - !t503 = sqr# t502 - !t504 = sqr# t503 - !t505 = mul# a t504 - !r = t505 + !t280 = mul# t279 a + !r = t280 in r {-# INLINE inv# #-} diff --git a/lib/Numeric/Montgomery/Secp256k1/Scalar.hs b/lib/Numeric/Montgomery/Secp256k1/Scalar.hs @@ -480,461 +480,313 @@ inv# :: Limb4 -> Limb4 inv# a = - let !t0 = L4 0x402DA1732FC9BEBF## 0x4551231950B75FC4## - 0x0000000000000001## 0x0000000000000000## - !t1 = sqr# t0 - !t2 = mul# a t1 + let + !t1 = sqr# a + !t2 = mul# t1 a !t3 = sqr# t2 - !t4 = mul# a t3 - !t5 = sqr# t4 - !t6 = mul# a t5 + !t4 = sqr# t3 + !t5 = mul# t4 t2 + !t6 = sqr# t5 !t7 = sqr# t6 - !t8 = mul# a t7 + !t8 = sqr# t7 !t9 = sqr# t8 - !t10 = mul# a t9 + !t10 = mul# t9 t5 !t11 = sqr# t10 - !t12 = mul# a t11 + !t12 = sqr# t11 !t13 = sqr# t12 - !t14 = mul# a t13 + !t14 = sqr# t13 !t15 = sqr# t14 - !t16 = mul# a t15 + !t16 = sqr# t15 !t17 = sqr# t16 - !t18 = mul# a t17 - !t19 = sqr# t18 - !t20 = mul# a t19 + !t18 = sqr# t17 + !t19 = mul# t18 t10 + !t20 = sqr# t19 !t21 = sqr# t20 - !t22 = mul# a t21 + !t22 = sqr# t21 !t23 = sqr# t22 - !t24 = mul# a t23 + !t24 = sqr# t23 !t25 = sqr# t24 - !t26 = mul# a t25 + !t26 = sqr# t25 !t27 = sqr# t26 - !t28 = mul# a t27 + !t28 = sqr# t27 !t29 = sqr# t28 - !t30 = mul# a t29 + !t30 = sqr# t29 !t31 = sqr# t30 - !t32 = mul# a t31 + !t32 = sqr# t31 !t33 = sqr# t32 - !t34 = mul# a t33 + !t34 = sqr# t33 !t35 = sqr# t34 - !t36 = mul# a t35 + !t36 = mul# t35 t19 !t37 = sqr# t36 - !t38 = mul# a t37 + !t38 = sqr# t37 !t39 = sqr# t38 - !t40 = mul# a t39 + !t40 = sqr# t39 !t41 = sqr# t40 - !t42 = mul# a t41 + !t42 = sqr# t41 !t43 = sqr# t42 - !t44 = mul# a t43 + !t44 = sqr# t43 !t45 = sqr# t44 - !t46 = mul# a t45 + !t46 = sqr# t45 !t47 = sqr# t46 - !t48 = mul# a t47 + !t48 = sqr# t47 !t49 = sqr# t48 - !t50 = mul# a t49 + !t50 = sqr# t49 !t51 = sqr# t50 - !t52 = mul# a t51 + !t52 = sqr# t51 !t53 = sqr# t52 - !t54 = mul# a t53 + !t54 = sqr# t53 !t55 = sqr# t54 - !t56 = mul# a t55 + !t56 = sqr# t55 !t57 = sqr# t56 - !t58 = mul# a t57 + !t58 = sqr# t57 !t59 = sqr# t58 - !t60 = mul# a t59 + !t60 = sqr# t59 !t61 = sqr# t60 - !t62 = mul# a t61 + !t62 = sqr# t61 !t63 = sqr# t62 - !t64 = mul# a t63 + !t64 = sqr# t63 !t65 = sqr# t64 - !t66 = mul# a t65 + !t66 = sqr# t65 !t67 = sqr# t66 - !t68 = mul# a t67 - !t69 = sqr# t68 - !t70 = mul# a t69 + !t68 = sqr# t67 + !t69 = mul# t68 t36 + !t70 = sqr# t69 !t71 = sqr# t70 - !t72 = mul# a t71 + !t72 = sqr# t71 !t73 = sqr# t72 - !t74 = mul# a t73 + !t74 = sqr# t73 !t75 = sqr# t74 - !t76 = mul# a t75 + !t76 = sqr# t75 !t77 = sqr# t76 - !t78 = mul# a t77 + !t78 = sqr# t77 !t79 = sqr# t78 - !t80 = mul# a t79 + !t80 = sqr# t79 !t81 = sqr# t80 - !t82 = mul# a t81 + !t82 = sqr# t81 !t83 = sqr# t82 - !t84 = mul# a t83 + !t84 = sqr# t83 !t85 = sqr# t84 - !t86 = mul# a t85 + !t86 = sqr# t85 !t87 = sqr# t86 - !t88 = mul# a t87 + !t88 = sqr# t87 !t89 = sqr# t88 - !t90 = mul# a t89 + !t90 = sqr# t89 !t91 = sqr# t90 - !t92 = mul# a t91 + !t92 = sqr# t91 !t93 = sqr# t92 - !t94 = mul# a t93 + !t94 = sqr# t93 !t95 = sqr# t94 - !t96 = mul# a t95 + !t96 = sqr# t95 !t97 = sqr# t96 - !t98 = mul# a t97 + !t98 = sqr# t97 !t99 = sqr# t98 - !t100 = mul# a t99 + !t100 = sqr# t99 !t101 = sqr# t100 - !t102 = mul# a t101 + !t102 = mul# t101 t36 !t103 = sqr# t102 - !t104 = mul# a t103 + !t104 = sqr# t103 !t105 = sqr# t104 - !t106 = mul# a t105 + !t106 = sqr# t105 !t107 = sqr# t106 - !t108 = mul# a t107 + !t108 = sqr# t107 !t109 = sqr# t108 - !t110 = mul# a t109 + !t110 = sqr# t109 !t111 = sqr# t110 - !t112 = mul# a t111 + !t112 = sqr# t111 !t113 = sqr# t112 - !t114 = mul# a t113 + !t114 = sqr# t113 !t115 = sqr# t114 - !t116 = mul# a t115 + !t116 = sqr# t115 !t117 = sqr# t116 - !t118 = mul# a t117 - !t119 = sqr# t118 - !t120 = mul# a t119 + !t118 = sqr# t117 + !t119 = mul# t118 t19 + !t120 = sqr# t119 !t121 = sqr# t120 - !t122 = mul# a t121 + !t122 = sqr# t121 !t123 = sqr# t122 - !t124 = mul# a t123 + !t124 = sqr# t123 !t125 = sqr# t124 - !t126 = mul# a t125 + !t126 = sqr# t125 !t127 = sqr# t126 - !t128 = mul# a t127 + !t128 = mul# t127 t10 !t129 = sqr# t128 - !t130 = mul# a t129 + !t130 = sqr# t129 !t131 = sqr# t130 - !t132 = mul# a t131 - !t133 = sqr# t132 - !t134 = mul# a t133 + !t132 = sqr# t131 + !t133 = mul# t132 t5 + !t134 = sqr# t133 !t135 = sqr# t134 - !t136 = mul# a t135 + !t136 = mul# t135 t2 !t137 = sqr# t136 - !t138 = mul# a t137 - !t139 = sqr# t138 - !t140 = mul# a t139 - !t141 = sqr# t140 - !t142 = mul# a t141 - !t143 = sqr# t142 - !t144 = mul# a t143 + !t138 = mul# t137 a + !t139 = sqr# t2 + !t140 = mul# t139 a + !t141 = sqr# t5 + !t142 = sqr# t141 + !t143 = mul# t142 t2 + !t144 = sqr# t138 !t145 = sqr# t144 - !t146 = mul# a t145 + !t146 = mul# t145 a !t147 = sqr# t146 - !t148 = mul# a t147 + !t148 = sqr# t147 !t149 = sqr# t148 - !t150 = mul# a t149 - !t151 = sqr# t150 - !t152 = mul# a t151 + !t150 = sqr# t149 + !t151 = mul# t150 t140 + !t152 = sqr# t151 !t153 = sqr# t152 - !t154 = mul# a t153 + !t154 = mul# t153 a !t155 = sqr# t154 - !t156 = mul# a t155 - !t157 = sqr# t156 - !t158 = mul# a t157 + !t156 = sqr# t155 + !t157 = mul# t156 a + !t158 = sqr# t157 !t159 = sqr# t158 - !t160 = mul# a t159 + !t160 = mul# t159 a !t161 = sqr# t160 - !t162 = mul# a t161 + !t162 = sqr# t161 !t163 = sqr# t162 - !t164 = mul# a t163 - !t165 = sqr# t164 - !t166 = mul# a t165 + !t164 = sqr# t163 + !t165 = mul# t164 t140 + !t166 = sqr# t165 !t167 = sqr# t166 - !t168 = mul# a t167 - !t169 = sqr# t168 - !t170 = mul# a t169 + !t168 = sqr# t167 + !t169 = mul# t168 t2 + !t170 = sqr# t169 !t171 = sqr# t170 - !t172 = mul# a t171 + !t172 = sqr# t171 !t173 = sqr# t172 - !t174 = mul# a t173 + !t174 = mul# t173 t140 !t175 = sqr# t174 - !t176 = mul# a t175 + !t176 = sqr# t175 !t177 = sqr# t176 - !t178 = mul# a t177 + !t178 = sqr# t177 !t179 = sqr# t178 - !t180 = mul# a t179 + !t180 = mul# t179 t140 !t181 = sqr# t180 - !t182 = mul# a t181 + !t182 = sqr# t181 !t183 = sqr# t182 - !t184 = mul# a t183 - !t185 = sqr# t184 - !t186 = mul# a t185 + !t184 = sqr# t183 + !t185 = mul# t184 t2 + !t186 = sqr# t185 !t187 = sqr# t186 - !t188 = mul# a t187 + !t188 = mul# t187 a !t189 = sqr# t188 - !t190 = mul# a t189 - !t191 = sqr# t190 - !t192 = mul# a t191 + !t190 = sqr# t189 + !t191 = mul# t190 a + !t192 = sqr# t191 !t193 = sqr# t192 - !t194 = mul# a t193 + !t194 = sqr# t193 !t195 = sqr# t194 - !t196 = mul# a t195 - !t197 = sqr# t196 - !t198 = mul# a t197 + !t196 = sqr# t195 + !t197 = mul# t196 t5 + !t198 = sqr# t197 !t199 = sqr# t198 - !t200 = mul# a t199 + !t200 = mul# t199 a !t201 = sqr# t200 - !t202 = mul# a t201 + !t202 = sqr# t201 !t203 = sqr# t202 - !t204 = mul# a t203 + !t204 = mul# t203 a !t205 = sqr# t204 - !t206 = mul# a t205 + !t206 = sqr# t205 !t207 = sqr# t206 - !t208 = mul# a t207 - !t209 = sqr# t208 - !t210 = mul# a t209 + !t208 = sqr# t207 + !t209 = mul# t208 a + !t210 = sqr# t209 !t211 = sqr# t210 - !t212 = mul# a t211 + !t212 = mul# t211 a !t213 = sqr# t212 - !t214 = mul# a t213 + !t214 = sqr# t213 !t215 = sqr# t214 - !t216 = mul# a t215 + !t216 = sqr# t215 !t217 = sqr# t216 - !t218 = mul# a t217 + !t218 = sqr# t217 !t219 = sqr# t218 - !t220 = mul# a t219 + !t220 = sqr# t219 !t221 = sqr# t220 - !t222 = mul# a t221 - !t223 = sqr# t222 - !t224 = mul# a t223 + !t222 = sqr# t221 + !t223 = mul# t222 t140 + !t224 = sqr# t223 !t225 = sqr# t224 - !t226 = mul# a t225 + !t226 = sqr# t225 !t227 = sqr# t226 - !t228 = mul# a t227 + !t228 = mul# t227 t140 !t229 = sqr# t228 - !t230 = mul# a t229 + !t230 = sqr# t229 !t231 = sqr# t230 - !t232 = mul# a t231 + !t232 = sqr# t231 !t233 = sqr# t232 - !t234 = mul# a t233 + !t234 = sqr# t233 !t235 = sqr# t234 - !t236 = mul# a t235 + !t236 = sqr# t235 !t237 = sqr# t236 - !t238 = mul# a t237 + !t238 = mul# t237 t10 !t239 = sqr# t238 - !t240 = mul# a t239 - !t241 = sqr# t240 - !t242 = mul# a t241 + !t240 = sqr# t239 + !t241 = mul# t240 a + !t242 = sqr# t241 !t243 = sqr# t242 - !t244 = mul# a t243 - !t245 = sqr# t244 - !t246 = mul# a t245 + !t244 = sqr# t243 + !t245 = mul# t244 a + !t246 = sqr# t245 !t247 = sqr# t246 - !t248 = mul# a t247 - !t249 = sqr# t248 - !t250 = mul# a t249 + !t248 = sqr# t247 + !t249 = mul# t248 a + !t250 = sqr# t249 !t251 = sqr# t250 - !t252 = mul# a t251 + !t252 = sqr# t251 !t253 = sqr# t252 - !t254 = mul# a t253 - !t255 = sqr# t254 + !t254 = sqr# t253 + !t255 = mul# t254 t5 !t256 = sqr# t255 - !t257 = mul# a t256 - !t258 = sqr# t257 + !t257 = sqr# t256 + !t258 = mul# t257 a !t259 = sqr# t258 - !t260 = mul# a t259 + !t260 = sqr# t259 !t261 = sqr# t260 - !t262 = mul# a t261 + !t262 = sqr# t261 !t263 = sqr# t262 - !t264 = mul# a t263 + !t264 = mul# t263 t2 !t265 = sqr# t264 !t266 = sqr# t265 - !t267 = mul# a t266 + !t267 = sqr# t266 !t268 = sqr# t267 - !t269 = sqr# t268 - !t270 = mul# a t269 + !t269 = mul# t268 t2 + !t270 = sqr# t269 !t271 = sqr# t270 - !t272 = sqr# t271 - !t273 = mul# a t272 + !t272 = mul# t271 a + !t273 = sqr# t272 !t274 = sqr# t273 !t275 = sqr# t274 - !t276 = mul# a t275 + !t276 = sqr# t275 !t277 = sqr# t276 - !t278 = mul# a t277 + !t278 = sqr# t277 !t279 = sqr# t278 - !t280 = mul# a t279 - !t281 = sqr# t280 + !t280 = sqr# t279 + !t281 = mul# t280 t2 !t282 = sqr# t281 - !t283 = mul# a t282 + !t283 = sqr# t282 !t284 = sqr# t283 - !t285 = mul# a t284 + !t285 = mul# t284 t2 !t286 = sqr# t285 !t287 = sqr# t286 - !t288 = mul# a t287 - !t289 = sqr# t288 - !t290 = mul# a t289 + !t288 = sqr# t287 + !t289 = mul# t288 a + !t290 = sqr# t289 !t291 = sqr# t290 - !t292 = mul# a t291 + !t292 = sqr# t291 !t293 = sqr# t292 !t294 = sqr# t293 !t295 = sqr# t294 - !t296 = mul# a t295 + !t296 = mul# t295 a !t297 = sqr# t296 - !t298 = mul# a t297 + !t298 = sqr# t297 !t299 = sqr# t298 - !t300 = mul# a t299 + !t300 = sqr# t299 !t301 = sqr# t300 !t302 = sqr# t301 !t303 = sqr# t302 - !t304 = mul# a t303 - !t305 = sqr# t304 - !t306 = mul# a t305 - !t307 = sqr# t306 - !t308 = sqr# t307 - !t309 = mul# a t308 - !t310 = sqr# t309 - !t311 = sqr# t310 - !t312 = mul# a t311 - !t313 = sqr# t312 - !t314 = sqr# t313 - !t315 = mul# a t314 - !t316 = sqr# t315 - !t317 = mul# a t316 - !t318 = sqr# t317 - !t319 = mul# a t318 - !t320 = sqr# t319 - !t321 = mul# a t320 - !t322 = sqr# t321 - !t323 = sqr# t322 - !t324 = mul# a t323 - !t325 = sqr# t324 - !t326 = sqr# t325 - !t327 = sqr# t326 - !t328 = mul# a t327 - !t329 = sqr# t328 - !t330 = sqr# t329 - !t331 = sqr# t330 - !t332 = sqr# t331 - !t333 = mul# a t332 - !t334 = sqr# t333 - !t335 = sqr# t334 - !t336 = mul# a t335 - !t337 = sqr# t336 - !t338 = sqr# t337 - !t339 = sqr# t338 - !t340 = sqr# t339 - !t341 = sqr# t340 - !t342 = sqr# t341 - !t343 = sqr# t342 - !t344 = sqr# t343 - !t345 = mul# a t344 - !t346 = sqr# t345 - !t347 = mul# a t346 - !t348 = sqr# t347 - !t349 = mul# a t348 - !t350 = sqr# t349 - !t351 = sqr# t350 - !t352 = mul# a t351 - !t353 = sqr# t352 - !t354 = mul# a t353 - !t355 = sqr# t354 - !t356 = mul# a t355 - !t357 = sqr# t356 - !t358 = sqr# t357 - !t359 = mul# a t358 - !t360 = sqr# t359 - !t361 = mul# a t360 - !t362 = sqr# t361 - !t363 = mul# a t362 - !t364 = sqr# t363 - !t365 = mul# a t364 - !t366 = sqr# t365 - !t367 = mul# a t366 - !t368 = sqr# t367 - !t369 = mul# a t368 - !t370 = sqr# t369 - !t371 = mul# a t370 - !t372 = sqr# t371 - !t373 = mul# a t372 - !t374 = sqr# t373 - !t375 = sqr# t374 - !t376 = mul# a t375 - !t377 = sqr# t376 - !t378 = sqr# t377 - !t379 = sqr# t378 - !t380 = mul# a t379 - !t381 = sqr# t380 - !t382 = sqr# t381 - !t383 = sqr# t382 - !t384 = mul# a t383 - !t385 = sqr# t384 - !t386 = sqr# t385 - !t387 = mul# a t386 - !t388 = sqr# t387 - !t389 = mul# a t388 - !t390 = sqr# t389 - !t391 = mul# a t390 - !t392 = sqr# t391 - !t393 = mul# a t392 - !t394 = sqr# t393 - !t395 = sqr# t394 - !t396 = mul# a t395 - !t397 = sqr# t396 - !t398 = sqr# t397 - !t399 = sqr# t398 - !t400 = sqr# t399 - !t401 = mul# a t400 - !t402 = sqr# t401 - !t403 = mul# a t402 - !t404 = sqr# t403 - !t405 = sqr# t404 - !t406 = sqr# t405 - !t407 = mul# a t406 - !t408 = sqr# t407 - !t409 = mul# a t408 - !t410 = sqr# t409 - !t411 = sqr# t410 - !t412 = mul# a t411 - !t413 = sqr# t412 - !t414 = sqr# t413 - !t415 = sqr# t414 - !t416 = sqr# t415 - !t417 = sqr# t416 - !t418 = sqr# t417 - !t419 = sqr# t418 - !t420 = mul# a t419 - !t421 = sqr# t420 - !t422 = mul# a t421 - !t423 = sqr# t422 - !t424 = sqr# t423 - !t425 = mul# a t424 - !t426 = sqr# t425 - !t427 = mul# a t426 - !t428 = sqr# t427 - !t429 = sqr# t428 - !t430 = sqr# t429 - !t431 = mul# a t430 - !t432 = sqr# t431 - !t433 = sqr# t432 - !t434 = sqr# t433 - !t435 = sqr# t434 - !t436 = sqr# t435 - !t437 = sqr# t436 - !t438 = mul# a t437 - !t439 = sqr# t438 - !t440 = sqr# t439 - !t441 = sqr# t440 - !t442 = mul# a t441 - !t443 = sqr# t442 - !t444 = mul# a t443 - !t445 = sqr# t444 - !t446 = mul# a t445 - !t447 = sqr# t446 - !t448 = mul# a t447 - !t449 = sqr# t448 - !t450 = mul# a t449 - !t451 = sqr# t450 - !t452 = mul# a t451 - !r = t452 + !t304 = sqr# t303 + !t305 = mul# t304 t143 + !r = t305 in r {-# INLINE inv# #-}