| 159 | |
| 160 | |
| 161 | void mul(Ring_Element& ans,const Ring_Element& a,const Ring_Element& b) |
| 162 | { |
| 163 | CODE_LOCATION_NO_SCOPE |
| 164 | |
| 165 | assert(a.FFTD); |
| 166 | if (a.rep!=b.rep) { throw rep_mismatch(); } |
| 167 | if (a.FFTD!=b.FFTD) { throw pr_mismatch(); } |
| 168 | if (a.element.empty() or b.element.empty()) |
| 169 | { |
| 170 | ans = Ring_Element(*a.FFTD, a.rep); |
| 171 | return; |
| 172 | } |
| 173 | |
| 174 | if (a.rep==evaluation) |
| 175 | { // In evaluation representation, so we can just multiply componentwise |
| 176 | if (&ans == &a) |
| 177 | { |
| 178 | ans *= b; |
| 179 | return; |
| 180 | } |
| 181 | else if (&ans == &b) |
| 182 | { |
| 183 | ans *= a; |
| 184 | return; |
| 185 | } |
| 186 | ans.prepare(a); |
| 187 | for (int i=0; i<(*ans.FFTD).phi_m(); i++) |
| 188 | ans.element.push_back(a.element[i].mul(b.element[i], a.FFTD->get_prD())); |
| 189 | } |
| 190 | else if ((*a.FFTD).get_twop()!=0) |
| 191 | { // This is the case where m is not a power of two |
| 192 | |
| 193 | // Here we have to do a poly mult followed by a reduction |
| 194 | // We could be clever (e.g. use Karatsuba etc), but instead |
| 195 | // we do the school book method followed by term re-writing |
| 196 | |
| 197 | // School book mult |
| 198 | vector<modp> aa(2*(*a.FFTD).phi_m()); |
| 199 | for (int i=0; i<2*(*a.FFTD).phi_m(); i++) |
| 200 | { assignZero(aa[i],(*a.FFTD).get_prD()); } |
| 201 | modp temp; |
| 202 | for (int i=0; i<(*a.FFTD).phi_m(); i++) |
| 203 | { for (int j=0; j<(*a.FFTD).phi_m(); j++) |
| 204 | { Mul(temp,a.element[i],b.element[j],(*a.FFTD).get_prD()); |
| 205 | int k=i+j; |
| 206 | Add(aa[k],aa[k],temp,(*a.FFTD).get_prD()); |
| 207 | } |
| 208 | } |
| 209 | // Now apply reduction, assumes Ring.poly is monic |
| 210 | reduce(aa, 2*(*a.FFTD).phi_m(), (*a.FFTD).phi_m(), *a.FFTD); |
| 211 | // Now stick into answer |
| 212 | ans.partial_assign(a); |
| 213 | for (int i=0; i<(*ans.FFTD).phi_m(); i++) |
| 214 | { ans.element[i]=aa[i]; } |
| 215 | } |
| 216 | else if ((*a.FFTD).get_twop()==0) |
| 217 | { // m a power of two case |
| 218 | Ring_Element aa(*ans.FFTD,ans.rep); |
nothing calls this directly
no test coverage detected