static error bignum_monty_reduce(bignum *A, const bignum *T, const bignum *m, const monty_ctx *monty) { size_t n = bignum_len_words(m); BIGNUM_TMP(tmp); /* 1. A <- T */ ER(bignum_dup(A, T)); /* 2. For i from 0 to (n - 1) do the following: */ for (size_t i = 0; i < n; i++) { /* 2.1 u_i <- a_i m' mod b */ uint32_t u = word(A, i) * monty->mprime; /* 2.2 A <- A + u_i m b^i */ ER(bignum_mulw(&tmp, m, u)); ER(bignum_shl(&tmp, i * BIGNUM_BITS)); ER(bignum_addl(A, &tmp)); } /* 3. A <- A / b^n */ bignum_dump(" A-pre-div", A); ER(bignum_shr(A, monty->R_shift)); /* 4. If A >= m then A <- A - m. */ if (bignum_gte(A, m)) ER(bignum_subl(A, m)); return OK; }
error monty_normalise_n(bignum *xR, const bignum *x, const bignum *m, size_t R_shift) { BIGNUM_TMP(tmp); ER(bignum_dup(&tmp, x)); ER(bignum_shl(&tmp, R_shift)); ER(bignum_mod(xR, &tmp, m)); return OK; }
static obj long_lshl(INT_64 a, INT_32 b) { int am; if((am = search_one_sub(a, 0)) < 0) return ZERO; if(am + b <= 63) return int_64_compact(int_64_shl(a, b)); return bignum_shl(int64_to_bignum_u(a), b); }
static obj int_lshl(INT_32 a, INT_32 b) { int am; if(!a) return int2fx(0); if(b > 63 || (am = (b + search_one32(a))) > 63) return bignum_shl(int_32_to_bignum_u(a), b); if(am > 30) return int_64_compact(int_64_shl(int_32_to_int_64(a), b)); return int2fx(a<<b); }