| 205 | } |
| 206 | |
| 207 | void Rq_Element::Scale(const bigint& p) |
| 208 | { |
| 209 | if (lev==0) { return; } |
| 210 | |
| 211 | if (a[0].is_zero() and a[1].is_zero()) |
| 212 | { |
| 213 | lev = 0; |
| 214 | return; |
| 215 | } |
| 216 | |
| 217 | CODE_LOCATION_NO_SCOPE |
| 218 | |
| 219 | if (n_mults() == 0) { |
| 220 | //for some reason we scale but we have just one level |
| 221 | throw level_mismatch(); |
| 222 | } |
| 223 | bigint p0=a[0].get_prime(),p1=a[1].get_prime(),p1i,lambda,n=p1*p; |
| 224 | invMod(p1i,p1%p,p); |
| 225 | |
| 226 | // First multiply input by [p1]_p |
| 227 | bigint te=p1%p; |
| 228 | if (te>p/2) { te-=p; } |
| 229 | modp tep; |
| 230 | to_modp(tep,te,a[0].get_prD()); |
| 231 | mul(a[0],a[0],tep); |
| 232 | to_modp(tep,te,a[1].get_prD()); |
| 233 | mul(a[1],a[1],tep); |
| 234 | |
| 235 | // Now compute delta |
| 236 | Ring_Element b0(a[0].get_FFTD(),evaluation); |
| 237 | Ring_Element b1(a[1].get_FFTD(),evaluation); |
| 238 | // scope to ensure deconstruction of write iterators |
| 239 | { |
| 240 | auto poly_a1 = a[1]; |
| 241 | poly_a1.change_rep(polynomial); |
| 242 | auto it = poly_a1.get_iterator(); |
| 243 | auto it0 = b0.get_write_iterator(); |
| 244 | auto it1 = b1.get_write_iterator(); |
| 245 | bigint half_n = n / 2; |
| 246 | bigint delta; |
| 247 | for (int i=0; i < a[1].get_FFTD().phi_m(); i++) |
| 248 | { |
| 249 | it.get(delta); |
| 250 | lambda = delta; |
| 251 | lambda *= p1i; |
| 252 | lambda %= p; |
| 253 | lambda *= p1; |
| 254 | lambda -= delta; |
| 255 | lambda %= n; |
| 256 | if (lambda > half_n) |
| 257 | lambda -= n; |
| 258 | it0.get(lambda); |
| 259 | it1.get(lambda); |
| 260 | } |
| 261 | } |
| 262 | |
| 263 | // Now add delta back onto a0 |
| 264 | Rq_Element bb(b0,b1); |
nothing calls this directly
no test coverage detected