Botan  1.11.15
src/lib/math/mp/mp_comba.cpp
Go to the documentation of this file.
00001 /*
00002 * Comba Multiplication and Squaring
00003 * (C) 1999-2007,2011,2014 Jack Lloyd
00004 *
00005 * Botan is released under the Simplified BSD License (see license.txt)
00006 */
00007 
00008 #include <botan/internal/mp_core.h>
00009 #include <botan/internal/mp_asmi.h>
00010 
00011 namespace Botan {
00012 
00013 extern "C" {
00014 
00015 /*
00016 * Comba 4x4 Squaring
00017 */
00018 void bigint_comba_sqr4(word z[8], const word x[4])
00019    {
00020    word w2 = 0, w1 = 0, w0 = 0;
00021 
00022    word3_muladd(&w2, &w1, &w0, x[ 0], x[ 0]);
00023    z[ 0] = w0; w0 = 0;
00024 
00025    word3_muladd_2(&w0, &w2, &w1, x[ 0], x[ 1]);
00026    z[ 1] = w1; w1 = 0;
00027 
00028    word3_muladd_2(&w1, &w0, &w2, x[ 0], x[ 2]);
00029    word3_muladd(&w1, &w0, &w2, x[ 1], x[ 1]);
00030    z[ 2] = w2; w2 = 0;
00031 
00032    word3_muladd_2(&w2, &w1, &w0, x[ 0], x[ 3]);
00033    word3_muladd_2(&w2, &w1, &w0, x[ 1], x[ 2]);
00034    z[ 3] = w0; w0 = 0;
00035 
00036    word3_muladd_2(&w0, &w2, &w1, x[ 1], x[ 3]);
00037    word3_muladd(&w0, &w2, &w1, x[ 2], x[ 2]);
00038    z[ 4] = w1; w1 = 0;
00039 
00040    word3_muladd_2(&w1, &w0, &w2, x[ 2], x[ 3]);
00041    z[ 5] = w2; w2 = 0;
00042 
00043    word3_muladd(&w2, &w1, &w0, x[ 3], x[ 3]);
00044    z[ 6] = w0;
00045    z[ 7] = w1;
00046    }
00047 
00048 /*
00049 * Comba 4x4 Multiplication
00050 */
00051 void bigint_comba_mul4(word z[8], const word x[4], const word y[4])
00052    {
00053    word w2 = 0, w1 = 0, w0 = 0;
00054 
00055    word3_muladd(&w2, &w1, &w0, x[ 0], y[ 0]);
00056    z[ 0] = w0; w0 = 0;
00057 
00058    word3_muladd(&w0, &w2, &w1, x[ 0], y[ 1]);
00059    word3_muladd(&w0, &w2, &w1, x[ 1], y[ 0]);
00060    z[ 1] = w1; w1 = 0;
00061 
00062    word3_muladd(&w1, &w0, &w2, x[ 0], y[ 2]);
00063    word3_muladd(&w1, &w0, &w2, x[ 1], y[ 1]);
00064    word3_muladd(&w1, &w0, &w2, x[ 2], y[ 0]);
00065    z[ 2] = w2; w2 = 0;
00066 
00067    word3_muladd(&w2, &w1, &w0, x[ 0], y[ 3]);
00068    word3_muladd(&w2, &w1, &w0, x[ 1], y[ 2]);
00069    word3_muladd(&w2, &w1, &w0, x[ 2], y[ 1]);
00070    word3_muladd(&w2, &w1, &w0, x[ 3], y[ 0]);
00071    z[ 3] = w0; w0 = 0;
00072 
00073    word3_muladd(&w0, &w2, &w1, x[ 1], y[ 3]);
00074    word3_muladd(&w0, &w2, &w1, x[ 2], y[ 2]);
00075    word3_muladd(&w0, &w2, &w1, x[ 3], y[ 1]);
00076    z[ 4] = w1; w1 = 0;
00077 
00078    word3_muladd(&w1, &w0, &w2, x[ 2], y[ 3]);
00079    word3_muladd(&w1, &w0, &w2, x[ 3], y[ 2]);
00080    z[ 5] = w2; w2 = 0;
00081 
00082    word3_muladd(&w2, &w1, &w0, x[ 3], y[ 3]);
00083    z[ 6] = w0;
00084    z[ 7] = w1;
00085    }
00086 
00087 /*
00088 * Comba 6x6 Squaring
00089 */
00090 void bigint_comba_sqr6(word z[12], const word x[6])
00091    {
00092    word w2 = 0, w1 = 0, w0 = 0;
00093 
00094    word3_muladd(&w2, &w1, &w0, x[ 0], x[ 0]);
00095    z[ 0] = w0; w0 = 0;
00096 
00097    word3_muladd_2(&w0, &w2, &w1, x[ 0], x[ 1]);
00098    z[ 1] = w1; w1 = 0;
00099 
00100    word3_muladd_2(&w1, &w0, &w2, x[ 0], x[ 2]);
00101    word3_muladd(&w1, &w0, &w2, x[ 1], x[ 1]);
00102    z[ 2] = w2; w2 = 0;
00103 
00104    word3_muladd_2(&w2, &w1, &w0, x[ 0], x[ 3]);
00105    word3_muladd_2(&w2, &w1, &w0, x[ 1], x[ 2]);
00106    z[ 3] = w0; w0 = 0;
00107 
00108    word3_muladd_2(&w0, &w2, &w1, x[ 0], x[ 4]);
00109    word3_muladd_2(&w0, &w2, &w1, x[ 1], x[ 3]);
00110    word3_muladd(&w0, &w2, &w1, x[ 2], x[ 2]);
00111    z[ 4] = w1; w1 = 0;
00112 
00113    word3_muladd_2(&w1, &w0, &w2, x[ 0], x[ 5]);
00114    word3_muladd_2(&w1, &w0, &w2, x[ 1], x[ 4]);
00115    word3_muladd_2(&w1, &w0, &w2, x[ 2], x[ 3]);
00116    z[ 5] = w2; w2 = 0;
00117 
00118    word3_muladd_2(&w2, &w1, &w0, x[ 1], x[ 5]);
00119    word3_muladd_2(&w2, &w1, &w0, x[ 2], x[ 4]);
00120    word3_muladd(&w2, &w1, &w0, x[ 3], x[ 3]);
00121    z[ 6] = w0; w0 = 0;
00122 
00123    word3_muladd_2(&w0, &w2, &w1, x[ 2], x[ 5]);
00124    word3_muladd_2(&w0, &w2, &w1, x[ 3], x[ 4]);
00125    z[ 7] = w1; w1 = 0;
00126 
00127    word3_muladd_2(&w1, &w0, &w2, x[ 3], x[ 5]);
00128    word3_muladd(&w1, &w0, &w2, x[ 4], x[ 4]);
00129    z[ 8] = w2; w2 = 0;
00130 
00131    word3_muladd_2(&w2, &w1, &w0, x[ 4], x[ 5]);
00132    z[ 9] = w0; w0 = 0;
00133 
00134    word3_muladd(&w0, &w2, &w1, x[ 5], x[ 5]);
00135    z[10] = w1;
00136    z[11] = w2;
00137    }
00138 
00139 /*
00140 * Comba 6x6 Multiplication
00141 */
00142 void bigint_comba_mul6(word z[12], const word x[6], const word y[6])
00143    {
00144    word w2 = 0, w1 = 0, w0 = 0;
00145 
00146    word3_muladd(&w2, &w1, &w0, x[ 0], y[ 0]);
00147    z[ 0] = w0; w0 = 0;
00148 
00149    word3_muladd(&w0, &w2, &w1, x[ 0], y[ 1]);
00150    word3_muladd(&w0, &w2, &w1, x[ 1], y[ 0]);
00151    z[ 1] = w1; w1 = 0;
00152 
00153    word3_muladd(&w1, &w0, &w2, x[ 0], y[ 2]);
00154    word3_muladd(&w1, &w0, &w2, x[ 1], y[ 1]);
00155    word3_muladd(&w1, &w0, &w2, x[ 2], y[ 0]);
00156    z[ 2] = w2; w2 = 0;
00157 
00158    word3_muladd(&w2, &w1, &w0, x[ 0], y[ 3]);
00159    word3_muladd(&w2, &w1, &w0, x[ 1], y[ 2]);
00160    word3_muladd(&w2, &w1, &w0, x[ 2], y[ 1]);
00161    word3_muladd(&w2, &w1, &w0, x[ 3], y[ 0]);
00162    z[ 3] = w0; w0 = 0;
00163 
00164    word3_muladd(&w0, &w2, &w1, x[ 0], y[ 4]);
00165    word3_muladd(&w0, &w2, &w1, x[ 1], y[ 3]);
00166    word3_muladd(&w0, &w2, &w1, x[ 2], y[ 2]);
00167    word3_muladd(&w0, &w2, &w1, x[ 3], y[ 1]);
00168    word3_muladd(&w0, &w2, &w1, x[ 4], y[ 0]);
00169    z[ 4] = w1; w1 = 0;
00170 
00171    word3_muladd(&w1, &w0, &w2, x[ 0], y[ 5]);
00172    word3_muladd(&w1, &w0, &w2, x[ 1], y[ 4]);
00173    word3_muladd(&w1, &w0, &w2, x[ 2], y[ 3]);
00174    word3_muladd(&w1, &w0, &w2, x[ 3], y[ 2]);
00175    word3_muladd(&w1, &w0, &w2, x[ 4], y[ 1]);
00176    word3_muladd(&w1, &w0, &w2, x[ 5], y[ 0]);
00177    z[ 5] = w2; w2 = 0;
00178 
00179    word3_muladd(&w2, &w1, &w0, x[ 1], y[ 5]);
00180    word3_muladd(&w2, &w1, &w0, x[ 2], y[ 4]);
00181    word3_muladd(&w2, &w1, &w0, x[ 3], y[ 3]);
00182    word3_muladd(&w2, &w1, &w0, x[ 4], y[ 2]);
00183    word3_muladd(&w2, &w1, &w0, x[ 5], y[ 1]);
00184    z[ 6] = w0; w0 = 0;
00185 
00186    word3_muladd(&w0, &w2, &w1, x[ 2], y[ 5]);
00187    word3_muladd(&w0, &w2, &w1, x[ 3], y[ 4]);
00188    word3_muladd(&w0, &w2, &w1, x[ 4], y[ 3]);
00189    word3_muladd(&w0, &w2, &w1, x[ 5], y[ 2]);
00190    z[ 7] = w1; w1 = 0;
00191 
00192    word3_muladd(&w1, &w0, &w2, x[ 3], y[ 5]);
00193    word3_muladd(&w1, &w0, &w2, x[ 4], y[ 4]);
00194    word3_muladd(&w1, &w0, &w2, x[ 5], y[ 3]);
00195    z[ 8] = w2; w2 = 0;
00196 
00197    word3_muladd(&w2, &w1, &w0, x[ 4], y[ 5]);
00198    word3_muladd(&w2, &w1, &w0, x[ 5], y[ 4]);
00199    z[ 9] = w0; w0 = 0;
00200 
00201    word3_muladd(&w0, &w2, &w1, x[ 5], y[ 5]);
00202    z[10] = w1;
00203    z[11] = w2;
00204    }
00205 
00206 /*
00207 * Comba 8x8 Squaring
00208 */
00209 void bigint_comba_sqr8(word z[16], const word x[8])
00210    {
00211    word w2 = 0, w1 = 0, w0 = 0;
00212 
00213    word3_muladd(&w2, &w1, &w0, x[ 0], x[ 0]);
00214    z[ 0] = w0; w0 = 0;
00215 
00216    word3_muladd_2(&w0, &w2, &w1, x[ 0], x[ 1]);
00217    z[ 1] = w1; w1 = 0;
00218 
00219    word3_muladd_2(&w1, &w0, &w2, x[ 0], x[ 2]);
00220    word3_muladd(&w1, &w0, &w2, x[ 1], x[ 1]);
00221    z[ 2] = w2; w2 = 0;
00222 
00223    word3_muladd_2(&w2, &w1, &w0, x[ 0], x[ 3]);
00224    word3_muladd_2(&w2, &w1, &w0, x[ 1], x[ 2]);
00225    z[ 3] = w0; w0 = 0;
00226 
00227    word3_muladd_2(&w0, &w2, &w1, x[ 0], x[ 4]);
00228    word3_muladd_2(&w0, &w2, &w1, x[ 1], x[ 3]);
00229    word3_muladd(&w0, &w2, &w1, x[ 2], x[ 2]);
00230    z[ 4] = w1; w1 = 0;
00231 
00232    word3_muladd_2(&w1, &w0, &w2, x[ 0], x[ 5]);
00233    word3_muladd_2(&w1, &w0, &w2, x[ 1], x[ 4]);
00234    word3_muladd_2(&w1, &w0, &w2, x[ 2], x[ 3]);
00235    z[ 5] = w2; w2 = 0;
00236 
00237    word3_muladd_2(&w2, &w1, &w0, x[ 0], x[ 6]);
00238    word3_muladd_2(&w2, &w1, &w0, x[ 1], x[ 5]);
00239    word3_muladd_2(&w2, &w1, &w0, x[ 2], x[ 4]);
00240    word3_muladd(&w2, &w1, &w0, x[ 3], x[ 3]);
00241    z[ 6] = w0; w0 = 0;
00242 
00243    word3_muladd_2(&w0, &w2, &w1, x[ 0], x[ 7]);
00244    word3_muladd_2(&w0, &w2, &w1, x[ 1], x[ 6]);
00245    word3_muladd_2(&w0, &w2, &w1, x[ 2], x[ 5]);
00246    word3_muladd_2(&w0, &w2, &w1, x[ 3], x[ 4]);
00247    z[ 7] = w1; w1 = 0;
00248 
00249    word3_muladd_2(&w1, &w0, &w2, x[ 1], x[ 7]);
00250    word3_muladd_2(&w1, &w0, &w2, x[ 2], x[ 6]);
00251    word3_muladd_2(&w1, &w0, &w2, x[ 3], x[ 5]);
00252    word3_muladd(&w1, &w0, &w2, x[ 4], x[ 4]);
00253    z[ 8] = w2; w2 = 0;
00254 
00255    word3_muladd_2(&w2, &w1, &w0, x[ 2], x[ 7]);
00256    word3_muladd_2(&w2, &w1, &w0, x[ 3], x[ 6]);
00257    word3_muladd_2(&w2, &w1, &w0, x[ 4], x[ 5]);
00258    z[ 9] = w0; w0 = 0;
00259 
00260    word3_muladd_2(&w0, &w2, &w1, x[ 3], x[ 7]);
00261    word3_muladd_2(&w0, &w2, &w1, x[ 4], x[ 6]);
00262    word3_muladd(&w0, &w2, &w1, x[ 5], x[ 5]);
00263    z[10] = w1; w1 = 0;
00264 
00265    word3_muladd_2(&w1, &w0, &w2, x[ 4], x[ 7]);
00266    word3_muladd_2(&w1, &w0, &w2, x[ 5], x[ 6]);
00267    z[11] = w2; w2 = 0;
00268 
00269    word3_muladd_2(&w2, &w1, &w0, x[ 5], x[ 7]);
00270    word3_muladd(&w2, &w1, &w0, x[ 6], x[ 6]);
00271    z[12] = w0; w0 = 0;
00272 
00273    word3_muladd_2(&w0, &w2, &w1, x[ 6], x[ 7]);
00274    z[13] = w1; w1 = 0;
00275 
00276    word3_muladd(&w1, &w0, &w2, x[ 7], x[ 7]);
00277    z[14] = w2;
00278    z[15] = w0;
00279    }
00280 
00281 /*
00282 * Comba 8x8 Multiplication
00283 */
00284 void bigint_comba_mul8(word z[16], const word x[8], const word y[8])
00285    {
00286    word w2 = 0, w1 = 0, w0 = 0;
00287 
00288    word3_muladd(&w2, &w1, &w0, x[ 0], y[ 0]);
00289    z[ 0] = w0; w0 = 0;
00290 
00291    word3_muladd(&w0, &w2, &w1, x[ 0], y[ 1]);
00292    word3_muladd(&w0, &w2, &w1, x[ 1], y[ 0]);
00293    z[ 1] = w1; w1 = 0;
00294 
00295    word3_muladd(&w1, &w0, &w2, x[ 0], y[ 2]);
00296    word3_muladd(&w1, &w0, &w2, x[ 1], y[ 1]);
00297    word3_muladd(&w1, &w0, &w2, x[ 2], y[ 0]);
00298    z[ 2] = w2; w2 = 0;
00299 
00300    word3_muladd(&w2, &w1, &w0, x[ 0], y[ 3]);
00301    word3_muladd(&w2, &w1, &w0, x[ 1], y[ 2]);
00302    word3_muladd(&w2, &w1, &w0, x[ 2], y[ 1]);
00303    word3_muladd(&w2, &w1, &w0, x[ 3], y[ 0]);
00304    z[ 3] = w0; w0 = 0;
00305 
00306    word3_muladd(&w0, &w2, &w1, x[ 0], y[ 4]);
00307    word3_muladd(&w0, &w2, &w1, x[ 1], y[ 3]);
00308    word3_muladd(&w0, &w2, &w1, x[ 2], y[ 2]);
00309    word3_muladd(&w0, &w2, &w1, x[ 3], y[ 1]);
00310    word3_muladd(&w0, &w2, &w1, x[ 4], y[ 0]);
00311    z[ 4] = w1; w1 = 0;
00312 
00313    word3_muladd(&w1, &w0, &w2, x[ 0], y[ 5]);
00314    word3_muladd(&w1, &w0, &w2, x[ 1], y[ 4]);
00315    word3_muladd(&w1, &w0, &w2, x[ 2], y[ 3]);
00316    word3_muladd(&w1, &w0, &w2, x[ 3], y[ 2]);
00317    word3_muladd(&w1, &w0, &w2, x[ 4], y[ 1]);
00318    word3_muladd(&w1, &w0, &w2, x[ 5], y[ 0]);
00319    z[ 5] = w2; w2 = 0;
00320 
00321    word3_muladd(&w2, &w1, &w0, x[ 0], y[ 6]);
00322    word3_muladd(&w2, &w1, &w0, x[ 1], y[ 5]);
00323    word3_muladd(&w2, &w1, &w0, x[ 2], y[ 4]);
00324    word3_muladd(&w2, &w1, &w0, x[ 3], y[ 3]);
00325    word3_muladd(&w2, &w1, &w0, x[ 4], y[ 2]);
00326    word3_muladd(&w2, &w1, &w0, x[ 5], y[ 1]);
00327    word3_muladd(&w2, &w1, &w0, x[ 6], y[ 0]);
00328    z[ 6] = w0; w0 = 0;
00329 
00330    word3_muladd(&w0, &w2, &w1, x[ 0], y[ 7]);
00331    word3_muladd(&w0, &w2, &w1, x[ 1], y[ 6]);
00332    word3_muladd(&w0, &w2, &w1, x[ 2], y[ 5]);
00333    word3_muladd(&w0, &w2, &w1, x[ 3], y[ 4]);
00334    word3_muladd(&w0, &w2, &w1, x[ 4], y[ 3]);
00335    word3_muladd(&w0, &w2, &w1, x[ 5], y[ 2]);
00336    word3_muladd(&w0, &w2, &w1, x[ 6], y[ 1]);
00337    word3_muladd(&w0, &w2, &w1, x[ 7], y[ 0]);
00338    z[ 7] = w1; w1 = 0;
00339 
00340    word3_muladd(&w1, &w0, &w2, x[ 1], y[ 7]);
00341    word3_muladd(&w1, &w0, &w2, x[ 2], y[ 6]);
00342    word3_muladd(&w1, &w0, &w2, x[ 3], y[ 5]);
00343    word3_muladd(&w1, &w0, &w2, x[ 4], y[ 4]);
00344    word3_muladd(&w1, &w0, &w2, x[ 5], y[ 3]);
00345    word3_muladd(&w1, &w0, &w2, x[ 6], y[ 2]);
00346    word3_muladd(&w1, &w0, &w2, x[ 7], y[ 1]);
00347    z[ 8] = w2; w2 = 0;
00348 
00349    word3_muladd(&w2, &w1, &w0, x[ 2], y[ 7]);
00350    word3_muladd(&w2, &w1, &w0, x[ 3], y[ 6]);
00351    word3_muladd(&w2, &w1, &w0, x[ 4], y[ 5]);
00352    word3_muladd(&w2, &w1, &w0, x[ 5], y[ 4]);
00353    word3_muladd(&w2, &w1, &w0, x[ 6], y[ 3]);
00354    word3_muladd(&w2, &w1, &w0, x[ 7], y[ 2]);
00355    z[ 9] = w0; w0 = 0;
00356 
00357    word3_muladd(&w0, &w2, &w1, x[ 3], y[ 7]);
00358    word3_muladd(&w0, &w2, &w1, x[ 4], y[ 6]);
00359    word3_muladd(&w0, &w2, &w1, x[ 5], y[ 5]);
00360    word3_muladd(&w0, &w2, &w1, x[ 6], y[ 4]);
00361    word3_muladd(&w0, &w2, &w1, x[ 7], y[ 3]);
00362    z[10] = w1; w1 = 0;
00363 
00364    word3_muladd(&w1, &w0, &w2, x[ 4], y[ 7]);
00365    word3_muladd(&w1, &w0, &w2, x[ 5], y[ 6]);
00366    word3_muladd(&w1, &w0, &w2, x[ 6], y[ 5]);
00367    word3_muladd(&w1, &w0, &w2, x[ 7], y[ 4]);
00368    z[11] = w2; w2 = 0;
00369 
00370    word3_muladd(&w2, &w1, &w0, x[ 5], y[ 7]);
00371    word3_muladd(&w2, &w1, &w0, x[ 6], y[ 6]);
00372    word3_muladd(&w2, &w1, &w0, x[ 7], y[ 5]);
00373    z[12] = w0; w0 = 0;
00374 
00375    word3_muladd(&w0, &w2, &w1, x[ 6], y[ 7]);
00376    word3_muladd(&w0, &w2, &w1, x[ 7], y[ 6]);
00377    z[13] = w1; w1 = 0;
00378 
00379    word3_muladd(&w1, &w0, &w2, x[ 7], y[ 7]);
00380    z[14] = w2;
00381    z[15] = w0;
00382    }
00383 
00384 /*
00385 * Comba 9x9 Squaring
00386 */
00387 void bigint_comba_sqr9(word z[18], const word x[9])
00388    {
00389    word w2 = 0, w1 = 0, w0 = 0;
00390 
00391    word3_muladd(&w2, &w1, &w0, x[ 0], x[ 0]);
00392    z[ 0] = w0; w0 = 0;
00393 
00394    word3_muladd_2(&w0, &w2, &w1, x[ 0], x[ 1]);
00395    z[ 1] = w1; w1 = 0;
00396 
00397    word3_muladd_2(&w1, &w0, &w2, x[ 0], x[ 2]);
00398    word3_muladd(&w1, &w0, &w2, x[ 1], x[ 1]);
00399    z[ 2] = w2; w2 = 0;
00400 
00401    word3_muladd_2(&w2, &w1, &w0, x[ 0], x[ 3]);
00402    word3_muladd_2(&w2, &w1, &w0, x[ 1], x[ 2]);
00403    z[ 3] = w0; w0 = 0;
00404 
00405    word3_muladd_2(&w0, &w2, &w1, x[ 0], x[ 4]);
00406    word3_muladd_2(&w0, &w2, &w1, x[ 1], x[ 3]);
00407    word3_muladd(&w0, &w2, &w1, x[ 2], x[ 2]);
00408    z[ 4] = w1; w1 = 0;
00409 
00410    word3_muladd_2(&w1, &w0, &w2, x[ 0], x[ 5]);
00411    word3_muladd_2(&w1, &w0, &w2, x[ 1], x[ 4]);
00412    word3_muladd_2(&w1, &w0, &w2, x[ 2], x[ 3]);
00413    z[ 5] = w2; w2 = 0;
00414 
00415    word3_muladd_2(&w2, &w1, &w0, x[ 0], x[ 6]);
00416    word3_muladd_2(&w2, &w1, &w0, x[ 1], x[ 5]);
00417    word3_muladd_2(&w2, &w1, &w0, x[ 2], x[ 4]);
00418    word3_muladd(&w2, &w1, &w0, x[ 3], x[ 3]);
00419    z[ 6] = w0; w0 = 0;
00420 
00421    word3_muladd_2(&w0, &w2, &w1, x[ 0], x[ 7]);
00422    word3_muladd_2(&w0, &w2, &w1, x[ 1], x[ 6]);
00423    word3_muladd_2(&w0, &w2, &w1, x[ 2], x[ 5]);
00424    word3_muladd_2(&w0, &w2, &w1, x[ 3], x[ 4]);
00425    z[ 7] = w1; w1 = 0;
00426 
00427    word3_muladd_2(&w1, &w0, &w2, x[ 0], x[ 8]);
00428    word3_muladd_2(&w1, &w0, &w2, x[ 1], x[ 7]);
00429    word3_muladd_2(&w1, &w0, &w2, x[ 2], x[ 6]);
00430    word3_muladd_2(&w1, &w0, &w2, x[ 3], x[ 5]);
00431    word3_muladd(&w1, &w0, &w2, x[ 4], x[ 4]);
00432    z[ 8] = w2; w2 = 0;
00433 
00434    word3_muladd_2(&w2, &w1, &w0, x[ 1], x[ 8]);
00435    word3_muladd_2(&w2, &w1, &w0, x[ 2], x[ 7]);
00436    word3_muladd_2(&w2, &w1, &w0, x[ 3], x[ 6]);
00437    word3_muladd_2(&w2, &w1, &w0, x[ 4], x[ 5]);
00438    z[ 9] = w0; w0 = 0;
00439 
00440    word3_muladd_2(&w0, &w2, &w1, x[ 2], x[ 8]);
00441    word3_muladd_2(&w0, &w2, &w1, x[ 3], x[ 7]);
00442    word3_muladd_2(&w0, &w2, &w1, x[ 4], x[ 6]);
00443    word3_muladd(&w0, &w2, &w1, x[ 5], x[ 5]);
00444    z[10] = w1; w1 = 0;
00445 
00446    word3_muladd_2(&w1, &w0, &w2, x[ 3], x[ 8]);
00447    word3_muladd_2(&w1, &w0, &w2, x[ 4], x[ 7]);
00448    word3_muladd_2(&w1, &w0, &w2, x[ 5], x[ 6]);
00449    z[11] = w2; w2 = 0;
00450 
00451    word3_muladd_2(&w2, &w1, &w0, x[ 4], x[ 8]);
00452    word3_muladd_2(&w2, &w1, &w0, x[ 5], x[ 7]);
00453    word3_muladd(&w2, &w1, &w0, x[ 6], x[ 6]);
00454    z[12] = w0; w0 = 0;
00455 
00456    word3_muladd_2(&w0, &w2, &w1, x[ 5], x[ 8]);
00457    word3_muladd_2(&w0, &w2, &w1, x[ 6], x[ 7]);
00458    z[13] = w1; w1 = 0;
00459 
00460    word3_muladd_2(&w1, &w0, &w2, x[ 6], x[ 8]);
00461    word3_muladd(&w1, &w0, &w2, x[ 7], x[ 7]);
00462    z[14] = w2; w2 = 0;
00463 
00464    word3_muladd_2(&w2, &w1, &w0, x[ 7], x[ 8]);
00465    z[15] = w0; w0 = 0;
00466 
00467    word3_muladd(&w0, &w2, &w1, x[ 8], x[ 8]);
00468    z[16] = w1;
00469    z[17] = w2;
00470    }
00471 
00472 /*
00473 * Comba 9x9 Multiplication
00474 */
00475 void bigint_comba_mul9(word z[18], const word x[9], const word y[9])
00476    {
00477    word w2 = 0, w1 = 0, w0 = 0;
00478 
00479    word3_muladd(&w2, &w1, &w0, x[ 0], y[ 0]);
00480    z[ 0] = w0; w0 = 0;
00481 
00482    word3_muladd(&w0, &w2, &w1, x[ 0], y[ 1]);
00483    word3_muladd(&w0, &w2, &w1, x[ 1], y[ 0]);
00484    z[ 1] = w1; w1 = 0;
00485 
00486    word3_muladd(&w1, &w0, &w2, x[ 0], y[ 2]);
00487    word3_muladd(&w1, &w0, &w2, x[ 1], y[ 1]);
00488    word3_muladd(&w1, &w0, &w2, x[ 2], y[ 0]);
00489    z[ 2] = w2; w2 = 0;
00490 
00491    word3_muladd(&w2, &w1, &w0, x[ 0], y[ 3]);
00492    word3_muladd(&w2, &w1, &w0, x[ 1], y[ 2]);
00493    word3_muladd(&w2, &w1, &w0, x[ 2], y[ 1]);
00494    word3_muladd(&w2, &w1, &w0, x[ 3], y[ 0]);
00495    z[ 3] = w0; w0 = 0;
00496 
00497    word3_muladd(&w0, &w2, &w1, x[ 0], y[ 4]);
00498    word3_muladd(&w0, &w2, &w1, x[ 1], y[ 3]);
00499    word3_muladd(&w0, &w2, &w1, x[ 2], y[ 2]);
00500    word3_muladd(&w0, &w2, &w1, x[ 3], y[ 1]);
00501    word3_muladd(&w0, &w2, &w1, x[ 4], y[ 0]);
00502    z[ 4] = w1; w1 = 0;
00503 
00504    word3_muladd(&w1, &w0, &w2, x[ 0], y[ 5]);
00505    word3_muladd(&w1, &w0, &w2, x[ 1], y[ 4]);
00506    word3_muladd(&w1, &w0, &w2, x[ 2], y[ 3]);
00507    word3_muladd(&w1, &w0, &w2, x[ 3], y[ 2]);
00508    word3_muladd(&w1, &w0, &w2, x[ 4], y[ 1]);
00509    word3_muladd(&w1, &w0, &w2, x[ 5], y[ 0]);
00510    z[ 5] = w2; w2 = 0;
00511 
00512    word3_muladd(&w2, &w1, &w0, x[ 0], y[ 6]);
00513    word3_muladd(&w2, &w1, &w0, x[ 1], y[ 5]);
00514    word3_muladd(&w2, &w1, &w0, x[ 2], y[ 4]);
00515    word3_muladd(&w2, &w1, &w0, x[ 3], y[ 3]);
00516    word3_muladd(&w2, &w1, &w0, x[ 4], y[ 2]);
00517    word3_muladd(&w2, &w1, &w0, x[ 5], y[ 1]);
00518    word3_muladd(&w2, &w1, &w0, x[ 6], y[ 0]);
00519    z[ 6] = w0; w0 = 0;
00520 
00521    word3_muladd(&w0, &w2, &w1, x[ 0], y[ 7]);
00522    word3_muladd(&w0, &w2, &w1, x[ 1], y[ 6]);
00523    word3_muladd(&w0, &w2, &w1, x[ 2], y[ 5]);
00524    word3_muladd(&w0, &w2, &w1, x[ 3], y[ 4]);
00525    word3_muladd(&w0, &w2, &w1, x[ 4], y[ 3]);
00526    word3_muladd(&w0, &w2, &w1, x[ 5], y[ 2]);
00527    word3_muladd(&w0, &w2, &w1, x[ 6], y[ 1]);
00528    word3_muladd(&w0, &w2, &w1, x[ 7], y[ 0]);
00529    z[ 7] = w1; w1 = 0;
00530 
00531    word3_muladd(&w1, &w0, &w2, x[ 0], y[ 8]);
00532    word3_muladd(&w1, &w0, &w2, x[ 1], y[ 7]);
00533    word3_muladd(&w1, &w0, &w2, x[ 2], y[ 6]);
00534    word3_muladd(&w1, &w0, &w2, x[ 3], y[ 5]);
00535    word3_muladd(&w1, &w0, &w2, x[ 4], y[ 4]);
00536    word3_muladd(&w1, &w0, &w2, x[ 5], y[ 3]);
00537    word3_muladd(&w1, &w0, &w2, x[ 6], y[ 2]);
00538    word3_muladd(&w1, &w0, &w2, x[ 7], y[ 1]);
00539    word3_muladd(&w1, &w0, &w2, x[ 8], y[ 0]);
00540    z[ 8] = w2; w2 = 0;
00541 
00542    word3_muladd(&w2, &w1, &w0, x[ 1], y[ 8]);
00543    word3_muladd(&w2, &w1, &w0, x[ 2], y[ 7]);
00544    word3_muladd(&w2, &w1, &w0, x[ 3], y[ 6]);
00545    word3_muladd(&w2, &w1, &w0, x[ 4], y[ 5]);
00546    word3_muladd(&w2, &w1, &w0, x[ 5], y[ 4]);
00547    word3_muladd(&w2, &w1, &w0, x[ 6], y[ 3]);
00548    word3_muladd(&w2, &w1, &w0, x[ 7], y[ 2]);
00549    word3_muladd(&w2, &w1, &w0, x[ 8], y[ 1]);
00550    z[ 9] = w0; w0 = 0;
00551 
00552    word3_muladd(&w0, &w2, &w1, x[ 2], y[ 8]);
00553    word3_muladd(&w0, &w2, &w1, x[ 3], y[ 7]);
00554    word3_muladd(&w0, &w2, &w1, x[ 4], y[ 6]);
00555    word3_muladd(&w0, &w2, &w1, x[ 5], y[ 5]);
00556    word3_muladd(&w0, &w2, &w1, x[ 6], y[ 4]);
00557    word3_muladd(&w0, &w2, &w1, x[ 7], y[ 3]);
00558    word3_muladd(&w0, &w2, &w1, x[ 8], y[ 2]);
00559    z[10] = w1; w1 = 0;
00560 
00561    word3_muladd(&w1, &w0, &w2, x[ 3], y[ 8]);
00562    word3_muladd(&w1, &w0, &w2, x[ 4], y[ 7]);
00563    word3_muladd(&w1, &w0, &w2, x[ 5], y[ 6]);
00564    word3_muladd(&w1, &w0, &w2, x[ 6], y[ 5]);
00565    word3_muladd(&w1, &w0, &w2, x[ 7], y[ 4]);
00566    word3_muladd(&w1, &w0, &w2, x[ 8], y[ 3]);
00567    z[11] = w2; w2 = 0;
00568 
00569    word3_muladd(&w2, &w1, &w0, x[ 4], y[ 8]);
00570    word3_muladd(&w2, &w1, &w0, x[ 5], y[ 7]);
00571    word3_muladd(&w2, &w1, &w0, x[ 6], y[ 6]);
00572    word3_muladd(&w2, &w1, &w0, x[ 7], y[ 5]);
00573    word3_muladd(&w2, &w1, &w0, x[ 8], y[ 4]);
00574    z[12] = w0; w0 = 0;
00575 
00576    word3_muladd(&w0, &w2, &w1, x[ 5], y[ 8]);
00577    word3_muladd(&w0, &w2, &w1, x[ 6], y[ 7]);
00578    word3_muladd(&w0, &w2, &w1, x[ 7], y[ 6]);
00579    word3_muladd(&w0, &w2, &w1, x[ 8], y[ 5]);
00580    z[13] = w1; w1 = 0;
00581 
00582    word3_muladd(&w1, &w0, &w2, x[ 6], y[ 8]);
00583    word3_muladd(&w1, &w0, &w2, x[ 7], y[ 7]);
00584    word3_muladd(&w1, &w0, &w2, x[ 8], y[ 6]);
00585    z[14] = w2; w2 = 0;
00586 
00587    word3_muladd(&w2, &w1, &w0, x[ 7], y[ 8]);
00588    word3_muladd(&w2, &w1, &w0, x[ 8], y[ 7]);
00589    z[15] = w0; w0 = 0;
00590 
00591    word3_muladd(&w0, &w2, &w1, x[ 8], y[ 8]);
00592    z[16] = w1;
00593    z[17] = w2;
00594    }
00595 
00596 /*
00597 * Comba 16x16 Squaring
00598 */
00599 void bigint_comba_sqr16(word z[32], const word x[16])
00600    {
00601    word w2 = 0, w1 = 0, w0 = 0;
00602 
00603    word3_muladd(&w2, &w1, &w0, x[ 0], x[ 0]);
00604    z[ 0] = w0; w0 = 0;
00605 
00606    word3_muladd_2(&w0, &w2, &w1, x[ 0], x[ 1]);
00607    z[ 1] = w1; w1 = 0;
00608 
00609    word3_muladd_2(&w1, &w0, &w2, x[ 0], x[ 2]);
00610    word3_muladd(&w1, &w0, &w2, x[ 1], x[ 1]);
00611    z[ 2] = w2; w2 = 0;
00612 
00613    word3_muladd_2(&w2, &w1, &w0, x[ 0], x[ 3]);
00614    word3_muladd_2(&w2, &w1, &w0, x[ 1], x[ 2]);
00615    z[ 3] = w0; w0 = 0;
00616 
00617    word3_muladd_2(&w0, &w2, &w1, x[ 0], x[ 4]);
00618    word3_muladd_2(&w0, &w2, &w1, x[ 1], x[ 3]);
00619    word3_muladd(&w0, &w2, &w1, x[ 2], x[ 2]);
00620    z[ 4] = w1; w1 = 0;
00621 
00622    word3_muladd_2(&w1, &w0, &w2, x[ 0], x[ 5]);
00623    word3_muladd_2(&w1, &w0, &w2, x[ 1], x[ 4]);
00624    word3_muladd_2(&w1, &w0, &w2, x[ 2], x[ 3]);
00625    z[ 5] = w2; w2 = 0;
00626 
00627    word3_muladd_2(&w2, &w1, &w0, x[ 0], x[ 6]);
00628    word3_muladd_2(&w2, &w1, &w0, x[ 1], x[ 5]);
00629    word3_muladd_2(&w2, &w1, &w0, x[ 2], x[ 4]);
00630    word3_muladd(&w2, &w1, &w0, x[ 3], x[ 3]);
00631    z[ 6] = w0; w0 = 0;
00632 
00633    word3_muladd_2(&w0, &w2, &w1, x[ 0], x[ 7]);
00634    word3_muladd_2(&w0, &w2, &w1, x[ 1], x[ 6]);
00635    word3_muladd_2(&w0, &w2, &w1, x[ 2], x[ 5]);
00636    word3_muladd_2(&w0, &w2, &w1, x[ 3], x[ 4]);
00637    z[ 7] = w1; w1 = 0;
00638 
00639    word3_muladd_2(&w1, &w0, &w2, x[ 0], x[ 8]);
00640    word3_muladd_2(&w1, &w0, &w2, x[ 1], x[ 7]);
00641    word3_muladd_2(&w1, &w0, &w2, x[ 2], x[ 6]);
00642    word3_muladd_2(&w1, &w0, &w2, x[ 3], x[ 5]);
00643    word3_muladd(&w1, &w0, &w2, x[ 4], x[ 4]);
00644    z[ 8] = w2; w2 = 0;
00645 
00646    word3_muladd_2(&w2, &w1, &w0, x[ 0], x[ 9]);
00647    word3_muladd_2(&w2, &w1, &w0, x[ 1], x[ 8]);
00648    word3_muladd_2(&w2, &w1, &w0, x[ 2], x[ 7]);
00649    word3_muladd_2(&w2, &w1, &w0, x[ 3], x[ 6]);
00650    word3_muladd_2(&w2, &w1, &w0, x[ 4], x[ 5]);
00651    z[ 9] = w0; w0 = 0;
00652 
00653    word3_muladd_2(&w0, &w2, &w1, x[ 0], x[10]);
00654    word3_muladd_2(&w0, &w2, &w1, x[ 1], x[ 9]);
00655    word3_muladd_2(&w0, &w2, &w1, x[ 2], x[ 8]);
00656    word3_muladd_2(&w0, &w2, &w1, x[ 3], x[ 7]);
00657    word3_muladd_2(&w0, &w2, &w1, x[ 4], x[ 6]);
00658    word3_muladd(&w0, &w2, &w1, x[ 5], x[ 5]);
00659    z[10] = w1; w1 = 0;
00660 
00661    word3_muladd_2(&w1, &w0, &w2, x[ 0], x[11]);
00662    word3_muladd_2(&w1, &w0, &w2, x[ 1], x[10]);
00663    word3_muladd_2(&w1, &w0, &w2, x[ 2], x[ 9]);
00664    word3_muladd_2(&w1, &w0, &w2, x[ 3], x[ 8]);
00665    word3_muladd_2(&w1, &w0, &w2, x[ 4], x[ 7]);
00666    word3_muladd_2(&w1, &w0, &w2, x[ 5], x[ 6]);
00667    z[11] = w2; w2 = 0;
00668 
00669    word3_muladd_2(&w2, &w1, &w0, x[ 0], x[12]);
00670    word3_muladd_2(&w2, &w1, &w0, x[ 1], x[11]);
00671    word3_muladd_2(&w2, &w1, &w0, x[ 2], x[10]);
00672    word3_muladd_2(&w2, &w1, &w0, x[ 3], x[ 9]);
00673    word3_muladd_2(&w2, &w1, &w0, x[ 4], x[ 8]);
00674    word3_muladd_2(&w2, &w1, &w0, x[ 5], x[ 7]);
00675    word3_muladd(&w2, &w1, &w0, x[ 6], x[ 6]);
00676    z[12] = w0; w0 = 0;
00677 
00678    word3_muladd_2(&w0, &w2, &w1, x[ 0], x[13]);
00679    word3_muladd_2(&w0, &w2, &w1, x[ 1], x[12]);
00680    word3_muladd_2(&w0, &w2, &w1, x[ 2], x[11]);
00681    word3_muladd_2(&w0, &w2, &w1, x[ 3], x[10]);
00682    word3_muladd_2(&w0, &w2, &w1, x[ 4], x[ 9]);
00683    word3_muladd_2(&w0, &w2, &w1, x[ 5], x[ 8]);
00684    word3_muladd_2(&w0, &w2, &w1, x[ 6], x[ 7]);
00685    z[13] = w1; w1 = 0;
00686 
00687    word3_muladd_2(&w1, &w0, &w2, x[ 0], x[14]);
00688    word3_muladd_2(&w1, &w0, &w2, x[ 1], x[13]);
00689    word3_muladd_2(&w1, &w0, &w2, x[ 2], x[12]);
00690    word3_muladd_2(&w1, &w0, &w2, x[ 3], x[11]);
00691    word3_muladd_2(&w1, &w0, &w2, x[ 4], x[10]);
00692    word3_muladd_2(&w1, &w0, &w2, x[ 5], x[ 9]);
00693    word3_muladd_2(&w1, &w0, &w2, x[ 6], x[ 8]);
00694    word3_muladd(&w1, &w0, &w2, x[ 7], x[ 7]);
00695    z[14] = w2; w2 = 0;
00696 
00697    word3_muladd_2(&w2, &w1, &w0, x[ 0], x[15]);
00698    word3_muladd_2(&w2, &w1, &w0, x[ 1], x[14]);
00699    word3_muladd_2(&w2, &w1, &w0, x[ 2], x[13]);
00700    word3_muladd_2(&w2, &w1, &w0, x[ 3], x[12]);
00701    word3_muladd_2(&w2, &w1, &w0, x[ 4], x[11]);
00702    word3_muladd_2(&w2, &w1, &w0, x[ 5], x[10]);
00703    word3_muladd_2(&w2, &w1, &w0, x[ 6], x[ 9]);
00704    word3_muladd_2(&w2, &w1, &w0, x[ 7], x[ 8]);
00705    z[15] = w0; w0 = 0;
00706 
00707    word3_muladd_2(&w0, &w2, &w1, x[ 1], x[15]);
00708    word3_muladd_2(&w0, &w2, &w1, x[ 2], x[14]);
00709    word3_muladd_2(&w0, &w2, &w1, x[ 3], x[13]);
00710    word3_muladd_2(&w0, &w2, &w1, x[ 4], x[12]);
00711    word3_muladd_2(&w0, &w2, &w1, x[ 5], x[11]);
00712    word3_muladd_2(&w0, &w2, &w1, x[ 6], x[10]);
00713    word3_muladd_2(&w0, &w2, &w1, x[ 7], x[ 9]);
00714    word3_muladd(&w0, &w2, &w1, x[ 8], x[ 8]);
00715    z[16] = w1; w1 = 0;
00716 
00717    word3_muladd_2(&w1, &w0, &w2, x[ 2], x[15]);
00718    word3_muladd_2(&w1, &w0, &w2, x[ 3], x[14]);
00719    word3_muladd_2(&w1, &w0, &w2, x[ 4], x[13]);
00720    word3_muladd_2(&w1, &w0, &w2, x[ 5], x[12]);
00721    word3_muladd_2(&w1, &w0, &w2, x[ 6], x[11]);
00722    word3_muladd_2(&w1, &w0, &w2, x[ 7], x[10]);
00723    word3_muladd_2(&w1, &w0, &w2, x[ 8], x[ 9]);
00724    z[17] = w2; w2 = 0;
00725 
00726    word3_muladd_2(&w2, &w1, &w0, x[ 3], x[15]);
00727    word3_muladd_2(&w2, &w1, &w0, x[ 4], x[14]);
00728    word3_muladd_2(&w2, &w1, &w0, x[ 5], x[13]);
00729    word3_muladd_2(&w2, &w1, &w0, x[ 6], x[12]);
00730    word3_muladd_2(&w2, &w1, &w0, x[ 7], x[11]);
00731    word3_muladd_2(&w2, &w1, &w0, x[ 8], x[10]);
00732    word3_muladd(&w2, &w1, &w0, x[ 9], x[ 9]);
00733    z[18] = w0; w0 = 0;
00734 
00735    word3_muladd_2(&w0, &w2, &w1, x[ 4], x[15]);
00736    word3_muladd_2(&w0, &w2, &w1, x[ 5], x[14]);
00737    word3_muladd_2(&w0, &w2, &w1, x[ 6], x[13]);
00738    word3_muladd_2(&w0, &w2, &w1, x[ 7], x[12]);
00739    word3_muladd_2(&w0, &w2, &w1, x[ 8], x[11]);
00740    word3_muladd_2(&w0, &w2, &w1, x[ 9], x[10]);
00741    z[19] = w1; w1 = 0;
00742 
00743    word3_muladd_2(&w1, &w0, &w2, x[ 5], x[15]);
00744    word3_muladd_2(&w1, &w0, &w2, x[ 6], x[14]);
00745    word3_muladd_2(&w1, &w0, &w2, x[ 7], x[13]);
00746    word3_muladd_2(&w1, &w0, &w2, x[ 8], x[12]);
00747    word3_muladd_2(&w1, &w0, &w2, x[ 9], x[11]);
00748    word3_muladd(&w1, &w0, &w2, x[10], x[10]);
00749    z[20] = w2; w2 = 0;
00750 
00751    word3_muladd_2(&w2, &w1, &w0, x[ 6], x[15]);
00752    word3_muladd_2(&w2, &w1, &w0, x[ 7], x[14]);
00753    word3_muladd_2(&w2, &w1, &w0, x[ 8], x[13]);
00754    word3_muladd_2(&w2, &w1, &w0, x[ 9], x[12]);
00755    word3_muladd_2(&w2, &w1, &w0, x[10], x[11]);
00756    z[21] = w0; w0 = 0;
00757 
00758    word3_muladd_2(&w0, &w2, &w1, x[ 7], x[15]);
00759    word3_muladd_2(&w0, &w2, &w1, x[ 8], x[14]);
00760    word3_muladd_2(&w0, &w2, &w1, x[ 9], x[13]);
00761    word3_muladd_2(&w0, &w2, &w1, x[10], x[12]);
00762    word3_muladd(&w0, &w2, &w1, x[11], x[11]);
00763    z[22] = w1; w1 = 0;
00764 
00765    word3_muladd_2(&w1, &w0, &w2, x[ 8], x[15]);
00766    word3_muladd_2(&w1, &w0, &w2, x[ 9], x[14]);
00767    word3_muladd_2(&w1, &w0, &w2, x[10], x[13]);
00768    word3_muladd_2(&w1, &w0, &w2, x[11], x[12]);
00769    z[23] = w2; w2 = 0;
00770 
00771    word3_muladd_2(&w2, &w1, &w0, x[ 9], x[15]);
00772    word3_muladd_2(&w2, &w1, &w0, x[10], x[14]);
00773    word3_muladd_2(&w2, &w1, &w0, x[11], x[13]);
00774    word3_muladd(&w2, &w1, &w0, x[12], x[12]);
00775    z[24] = w0; w0 = 0;
00776 
00777    word3_muladd_2(&w0, &w2, &w1, x[10], x[15]);
00778    word3_muladd_2(&w0, &w2, &w1, x[11], x[14]);
00779    word3_muladd_2(&w0, &w2, &w1, x[12], x[13]);
00780    z[25] = w1; w1 = 0;
00781 
00782    word3_muladd_2(&w1, &w0, &w2, x[11], x[15]);
00783    word3_muladd_2(&w1, &w0, &w2, x[12], x[14]);
00784    word3_muladd(&w1, &w0, &w2, x[13], x[13]);
00785    z[26] = w2; w2 = 0;
00786 
00787    word3_muladd_2(&w2, &w1, &w0, x[12], x[15]);
00788    word3_muladd_2(&w2, &w1, &w0, x[13], x[14]);
00789    z[27] = w0; w0 = 0;
00790 
00791    word3_muladd_2(&w0, &w2, &w1, x[13], x[15]);
00792    word3_muladd(&w0, &w2, &w1, x[14], x[14]);
00793    z[28] = w1; w1 = 0;
00794 
00795    word3_muladd_2(&w1, &w0, &w2, x[14], x[15]);
00796    z[29] = w2; w2 = 0;
00797 
00798    word3_muladd(&w2, &w1, &w0, x[15], x[15]);
00799    z[30] = w0;
00800    z[31] = w1;
00801    }
00802 
00803 /*
00804 * Comba 16x16 Multiplication
00805 */
00806 void bigint_comba_mul16(word z[32], const word x[16], const word y[16])
00807    {
00808    word w2 = 0, w1 = 0, w0 = 0;
00809 
00810    word3_muladd(&w2, &w1, &w0, x[ 0], y[ 0]);
00811    z[ 0] = w0; w0 = 0;
00812 
00813    word3_muladd(&w0, &w2, &w1, x[ 0], y[ 1]);
00814    word3_muladd(&w0, &w2, &w1, x[ 1], y[ 0]);
00815    z[ 1] = w1; w1 = 0;
00816 
00817    word3_muladd(&w1, &w0, &w2, x[ 0], y[ 2]);
00818    word3_muladd(&w1, &w0, &w2, x[ 1], y[ 1]);
00819    word3_muladd(&w1, &w0, &w2, x[ 2], y[ 0]);
00820    z[ 2] = w2; w2 = 0;
00821 
00822    word3_muladd(&w2, &w1, &w0, x[ 0], y[ 3]);
00823    word3_muladd(&w2, &w1, &w0, x[ 1], y[ 2]);
00824    word3_muladd(&w2, &w1, &w0, x[ 2], y[ 1]);
00825    word3_muladd(&w2, &w1, &w0, x[ 3], y[ 0]);
00826    z[ 3] = w0; w0 = 0;
00827 
00828    word3_muladd(&w0, &w2, &w1, x[ 0], y[ 4]);
00829    word3_muladd(&w0, &w2, &w1, x[ 1], y[ 3]);
00830    word3_muladd(&w0, &w2, &w1, x[ 2], y[ 2]);
00831    word3_muladd(&w0, &w2, &w1, x[ 3], y[ 1]);
00832    word3_muladd(&w0, &w2, &w1, x[ 4], y[ 0]);
00833    z[ 4] = w1; w1 = 0;
00834 
00835    word3_muladd(&w1, &w0, &w2, x[ 0], y[ 5]);
00836    word3_muladd(&w1, &w0, &w2, x[ 1], y[ 4]);
00837    word3_muladd(&w1, &w0, &w2, x[ 2], y[ 3]);
00838    word3_muladd(&w1, &w0, &w2, x[ 3], y[ 2]);
00839    word3_muladd(&w1, &w0, &w2, x[ 4], y[ 1]);
00840    word3_muladd(&w1, &w0, &w2, x[ 5], y[ 0]);
00841    z[ 5] = w2; w2 = 0;
00842 
00843    word3_muladd(&w2, &w1, &w0, x[ 0], y[ 6]);
00844    word3_muladd(&w2, &w1, &w0, x[ 1], y[ 5]);
00845    word3_muladd(&w2, &w1, &w0, x[ 2], y[ 4]);
00846    word3_muladd(&w2, &w1, &w0, x[ 3], y[ 3]);
00847    word3_muladd(&w2, &w1, &w0, x[ 4], y[ 2]);
00848    word3_muladd(&w2, &w1, &w0, x[ 5], y[ 1]);
00849    word3_muladd(&w2, &w1, &w0, x[ 6], y[ 0]);
00850    z[ 6] = w0; w0 = 0;
00851 
00852    word3_muladd(&w0, &w2, &w1, x[ 0], y[ 7]);
00853    word3_muladd(&w0, &w2, &w1, x[ 1], y[ 6]);
00854    word3_muladd(&w0, &w2, &w1, x[ 2], y[ 5]);
00855    word3_muladd(&w0, &w2, &w1, x[ 3], y[ 4]);
00856    word3_muladd(&w0, &w2, &w1, x[ 4], y[ 3]);
00857    word3_muladd(&w0, &w2, &w1, x[ 5], y[ 2]);
00858    word3_muladd(&w0, &w2, &w1, x[ 6], y[ 1]);
00859    word3_muladd(&w0, &w2, &w1, x[ 7], y[ 0]);
00860    z[ 7] = w1; w1 = 0;
00861 
00862    word3_muladd(&w1, &w0, &w2, x[ 0], y[ 8]);
00863    word3_muladd(&w1, &w0, &w2, x[ 1], y[ 7]);
00864    word3_muladd(&w1, &w0, &w2, x[ 2], y[ 6]);
00865    word3_muladd(&w1, &w0, &w2, x[ 3], y[ 5]);
00866    word3_muladd(&w1, &w0, &w2, x[ 4], y[ 4]);
00867    word3_muladd(&w1, &w0, &w2, x[ 5], y[ 3]);
00868    word3_muladd(&w1, &w0, &w2, x[ 6], y[ 2]);
00869    word3_muladd(&w1, &w0, &w2, x[ 7], y[ 1]);
00870    word3_muladd(&w1, &w0, &w2, x[ 8], y[ 0]);
00871    z[ 8] = w2; w2 = 0;
00872 
00873    word3_muladd(&w2, &w1, &w0, x[ 0], y[ 9]);
00874    word3_muladd(&w2, &w1, &w0, x[ 1], y[ 8]);
00875    word3_muladd(&w2, &w1, &w0, x[ 2], y[ 7]);
00876    word3_muladd(&w2, &w1, &w0, x[ 3], y[ 6]);
00877    word3_muladd(&w2, &w1, &w0, x[ 4], y[ 5]);
00878    word3_muladd(&w2, &w1, &w0, x[ 5], y[ 4]);
00879    word3_muladd(&w2, &w1, &w0, x[ 6], y[ 3]);
00880    word3_muladd(&w2, &w1, &w0, x[ 7], y[ 2]);
00881    word3_muladd(&w2, &w1, &w0, x[ 8], y[ 1]);
00882    word3_muladd(&w2, &w1, &w0, x[ 9], y[ 0]);
00883    z[ 9] = w0; w0 = 0;
00884 
00885    word3_muladd(&w0, &w2, &w1, x[ 0], y[10]);
00886    word3_muladd(&w0, &w2, &w1, x[ 1], y[ 9]);
00887    word3_muladd(&w0, &w2, &w1, x[ 2], y[ 8]);
00888    word3_muladd(&w0, &w2, &w1, x[ 3], y[ 7]);
00889    word3_muladd(&w0, &w2, &w1, x[ 4], y[ 6]);
00890    word3_muladd(&w0, &w2, &w1, x[ 5], y[ 5]);
00891    word3_muladd(&w0, &w2, &w1, x[ 6], y[ 4]);
00892    word3_muladd(&w0, &w2, &w1, x[ 7], y[ 3]);
00893    word3_muladd(&w0, &w2, &w1, x[ 8], y[ 2]);
00894    word3_muladd(&w0, &w2, &w1, x[ 9], y[ 1]);
00895    word3_muladd(&w0, &w2, &w1, x[10], y[ 0]);
00896    z[10] = w1; w1 = 0;
00897 
00898    word3_muladd(&w1, &w0, &w2, x[ 0], y[11]);
00899    word3_muladd(&w1, &w0, &w2, x[ 1], y[10]);
00900    word3_muladd(&w1, &w0, &w2, x[ 2], y[ 9]);
00901    word3_muladd(&w1, &w0, &w2, x[ 3], y[ 8]);
00902    word3_muladd(&w1, &w0, &w2, x[ 4], y[ 7]);
00903    word3_muladd(&w1, &w0, &w2, x[ 5], y[ 6]);
00904    word3_muladd(&w1, &w0, &w2, x[ 6], y[ 5]);
00905    word3_muladd(&w1, &w0, &w2, x[ 7], y[ 4]);
00906    word3_muladd(&w1, &w0, &w2, x[ 8], y[ 3]);
00907    word3_muladd(&w1, &w0, &w2, x[ 9], y[ 2]);
00908    word3_muladd(&w1, &w0, &w2, x[10], y[ 1]);
00909    word3_muladd(&w1, &w0, &w2, x[11], y[ 0]);
00910    z[11] = w2; w2 = 0;
00911 
00912    word3_muladd(&w2, &w1, &w0, x[ 0], y[12]);
00913    word3_muladd(&w2, &w1, &w0, x[ 1], y[11]);
00914    word3_muladd(&w2, &w1, &w0, x[ 2], y[10]);
00915    word3_muladd(&w2, &w1, &w0, x[ 3], y[ 9]);
00916    word3_muladd(&w2, &w1, &w0, x[ 4], y[ 8]);
00917    word3_muladd(&w2, &w1, &w0, x[ 5], y[ 7]);
00918    word3_muladd(&w2, &w1, &w0, x[ 6], y[ 6]);
00919    word3_muladd(&w2, &w1, &w0, x[ 7], y[ 5]);
00920    word3_muladd(&w2, &w1, &w0, x[ 8], y[ 4]);
00921    word3_muladd(&w2, &w1, &w0, x[ 9], y[ 3]);
00922    word3_muladd(&w2, &w1, &w0, x[10], y[ 2]);
00923    word3_muladd(&w2, &w1, &w0, x[11], y[ 1]);
00924    word3_muladd(&w2, &w1, &w0, x[12], y[ 0]);
00925    z[12] = w0; w0 = 0;
00926 
00927    word3_muladd(&w0, &w2, &w1, x[ 0], y[13]);
00928    word3_muladd(&w0, &w2, &w1, x[ 1], y[12]);
00929    word3_muladd(&w0, &w2, &w1, x[ 2], y[11]);
00930    word3_muladd(&w0, &w2, &w1, x[ 3], y[10]);
00931    word3_muladd(&w0, &w2, &w1, x[ 4], y[ 9]);
00932    word3_muladd(&w0, &w2, &w1, x[ 5], y[ 8]);
00933    word3_muladd(&w0, &w2, &w1, x[ 6], y[ 7]);
00934    word3_muladd(&w0, &w2, &w1, x[ 7], y[ 6]);
00935    word3_muladd(&w0, &w2, &w1, x[ 8], y[ 5]);
00936    word3_muladd(&w0, &w2, &w1, x[ 9], y[ 4]);
00937    word3_muladd(&w0, &w2, &w1, x[10], y[ 3]);
00938    word3_muladd(&w0, &w2, &w1, x[11], y[ 2]);
00939    word3_muladd(&w0, &w2, &w1, x[12], y[ 1]);
00940    word3_muladd(&w0, &w2, &w1, x[13], y[ 0]);
00941    z[13] = w1; w1 = 0;
00942 
00943    word3_muladd(&w1, &w0, &w2, x[ 0], y[14]);
00944    word3_muladd(&w1, &w0, &w2, x[ 1], y[13]);
00945    word3_muladd(&w1, &w0, &w2, x[ 2], y[12]);
00946    word3_muladd(&w1, &w0, &w2, x[ 3], y[11]);
00947    word3_muladd(&w1, &w0, &w2, x[ 4], y[10]);
00948    word3_muladd(&w1, &w0, &w2, x[ 5], y[ 9]);
00949    word3_muladd(&w1, &w0, &w2, x[ 6], y[ 8]);
00950    word3_muladd(&w1, &w0, &w2, x[ 7], y[ 7]);
00951    word3_muladd(&w1, &w0, &w2, x[ 8], y[ 6]);
00952    word3_muladd(&w1, &w0, &w2, x[ 9], y[ 5]);
00953    word3_muladd(&w1, &w0, &w2, x[10], y[ 4]);
00954    word3_muladd(&w1, &w0, &w2, x[11], y[ 3]);
00955    word3_muladd(&w1, &w0, &w2, x[12], y[ 2]);
00956    word3_muladd(&w1, &w0, &w2, x[13], y[ 1]);
00957    word3_muladd(&w1, &w0, &w2, x[14], y[ 0]);
00958    z[14] = w2; w2 = 0;
00959 
00960    word3_muladd(&w2, &w1, &w0, x[ 0], y[15]);
00961    word3_muladd(&w2, &w1, &w0, x[ 1], y[14]);
00962    word3_muladd(&w2, &w1, &w0, x[ 2], y[13]);
00963    word3_muladd(&w2, &w1, &w0, x[ 3], y[12]);
00964    word3_muladd(&w2, &w1, &w0, x[ 4], y[11]);
00965    word3_muladd(&w2, &w1, &w0, x[ 5], y[10]);
00966    word3_muladd(&w2, &w1, &w0, x[ 6], y[ 9]);
00967    word3_muladd(&w2, &w1, &w0, x[ 7], y[ 8]);
00968    word3_muladd(&w2, &w1, &w0, x[ 8], y[ 7]);
00969    word3_muladd(&w2, &w1, &w0, x[ 9], y[ 6]);
00970    word3_muladd(&w2, &w1, &w0, x[10], y[ 5]);
00971    word3_muladd(&w2, &w1, &w0, x[11], y[ 4]);
00972    word3_muladd(&w2, &w1, &w0, x[12], y[ 3]);
00973    word3_muladd(&w2, &w1, &w0, x[13], y[ 2]);
00974    word3_muladd(&w2, &w1, &w0, x[14], y[ 1]);
00975    word3_muladd(&w2, &w1, &w0, x[15], y[ 0]);
00976    z[15] = w0; w0 = 0;
00977 
00978    word3_muladd(&w0, &w2, &w1, x[ 1], y[15]);
00979    word3_muladd(&w0, &w2, &w1, x[ 2], y[14]);
00980    word3_muladd(&w0, &w2, &w1, x[ 3], y[13]);
00981    word3_muladd(&w0, &w2, &w1, x[ 4], y[12]);
00982    word3_muladd(&w0, &w2, &w1, x[ 5], y[11]);
00983    word3_muladd(&w0, &w2, &w1, x[ 6], y[10]);
00984    word3_muladd(&w0, &w2, &w1, x[ 7], y[ 9]);
00985    word3_muladd(&w0, &w2, &w1, x[ 8], y[ 8]);
00986    word3_muladd(&w0, &w2, &w1, x[ 9], y[ 7]);
00987    word3_muladd(&w0, &w2, &w1, x[10], y[ 6]);
00988    word3_muladd(&w0, &w2, &w1, x[11], y[ 5]);
00989    word3_muladd(&w0, &w2, &w1, x[12], y[ 4]);
00990    word3_muladd(&w0, &w2, &w1, x[13], y[ 3]);
00991    word3_muladd(&w0, &w2, &w1, x[14], y[ 2]);
00992    word3_muladd(&w0, &w2, &w1, x[15], y[ 1]);
00993    z[16] = w1; w1 = 0;
00994 
00995    word3_muladd(&w1, &w0, &w2, x[ 2], y[15]);
00996    word3_muladd(&w1, &w0, &w2, x[ 3], y[14]);
00997    word3_muladd(&w1, &w0, &w2, x[ 4], y[13]);
00998    word3_muladd(&w1, &w0, &w2, x[ 5], y[12]);
00999    word3_muladd(&w1, &w0, &w2, x[ 6], y[11]);
01000    word3_muladd(&w1, &w0, &w2, x[ 7], y[10]);
01001    word3_muladd(&w1, &w0, &w2, x[ 8], y[ 9]);
01002    word3_muladd(&w1, &w0, &w2, x[ 9], y[ 8]);
01003    word3_muladd(&w1, &w0, &w2, x[10], y[ 7]);
01004    word3_muladd(&w1, &w0, &w2, x[11], y[ 6]);
01005    word3_muladd(&w1, &w0, &w2, x[12], y[ 5]);
01006    word3_muladd(&w1, &w0, &w2, x[13], y[ 4]);
01007    word3_muladd(&w1, &w0, &w2, x[14], y[ 3]);
01008    word3_muladd(&w1, &w0, &w2, x[15], y[ 2]);
01009    z[17] = w2; w2 = 0;
01010 
01011    word3_muladd(&w2, &w1, &w0, x[ 3], y[15]);
01012    word3_muladd(&w2, &w1, &w0, x[ 4], y[14]);
01013    word3_muladd(&w2, &w1, &w0, x[ 5], y[13]);
01014    word3_muladd(&w2, &w1, &w0, x[ 6], y[12]);
01015    word3_muladd(&w2, &w1, &w0, x[ 7], y[11]);
01016    word3_muladd(&w2, &w1, &w0, x[ 8], y[10]);
01017    word3_muladd(&w2, &w1, &w0, x[ 9], y[ 9]);
01018    word3_muladd(&w2, &w1, &w0, x[10], y[ 8]);
01019    word3_muladd(&w2, &w1, &w0, x[11], y[ 7]);
01020    word3_muladd(&w2, &w1, &w0, x[12], y[ 6]);
01021    word3_muladd(&w2, &w1, &w0, x[13], y[ 5]);
01022    word3_muladd(&w2, &w1, &w0, x[14], y[ 4]);
01023    word3_muladd(&w2, &w1, &w0, x[15], y[ 3]);
01024    z[18] = w0; w0 = 0;
01025 
01026    word3_muladd(&w0, &w2, &w1, x[ 4], y[15]);
01027    word3_muladd(&w0, &w2, &w1, x[ 5], y[14]);
01028    word3_muladd(&w0, &w2, &w1, x[ 6], y[13]);
01029    word3_muladd(&w0, &w2, &w1, x[ 7], y[12]);
01030    word3_muladd(&w0, &w2, &w1, x[ 8], y[11]);
01031    word3_muladd(&w0, &w2, &w1, x[ 9], y[10]);
01032    word3_muladd(&w0, &w2, &w1, x[10], y[ 9]);
01033    word3_muladd(&w0, &w2, &w1, x[11], y[ 8]);
01034    word3_muladd(&w0, &w2, &w1, x[12], y[ 7]);
01035    word3_muladd(&w0, &w2, &w1, x[13], y[ 6]);
01036    word3_muladd(&w0, &w2, &w1, x[14], y[ 5]);
01037    word3_muladd(&w0, &w2, &w1, x[15], y[ 4]);
01038    z[19] = w1; w1 = 0;
01039 
01040    word3_muladd(&w1, &w0, &w2, x[ 5], y[15]);
01041    word3_muladd(&w1, &w0, &w2, x[ 6], y[14]);
01042    word3_muladd(&w1, &w0, &w2, x[ 7], y[13]);
01043    word3_muladd(&w1, &w0, &w2, x[ 8], y[12]);
01044    word3_muladd(&w1, &w0, &w2, x[ 9], y[11]);
01045    word3_muladd(&w1, &w0, &w2, x[10], y[10]);
01046    word3_muladd(&w1, &w0, &w2, x[11], y[ 9]);
01047    word3_muladd(&w1, &w0, &w2, x[12], y[ 8]);
01048    word3_muladd(&w1, &w0, &w2, x[13], y[ 7]);
01049    word3_muladd(&w1, &w0, &w2, x[14], y[ 6]);
01050    word3_muladd(&w1, &w0, &w2, x[15], y[ 5]);
01051    z[20] = w2; w2 = 0;
01052 
01053    word3_muladd(&w2, &w1, &w0, x[ 6], y[15]);
01054    word3_muladd(&w2, &w1, &w0, x[ 7], y[14]);
01055    word3_muladd(&w2, &w1, &w0, x[ 8], y[13]);
01056    word3_muladd(&w2, &w1, &w0, x[ 9], y[12]);
01057    word3_muladd(&w2, &w1, &w0, x[10], y[11]);
01058    word3_muladd(&w2, &w1, &w0, x[11], y[10]);
01059    word3_muladd(&w2, &w1, &w0, x[12], y[ 9]);
01060    word3_muladd(&w2, &w1, &w0, x[13], y[ 8]);
01061    word3_muladd(&w2, &w1, &w0, x[14], y[ 7]);
01062    word3_muladd(&w2, &w1, &w0, x[15], y[ 6]);
01063    z[21] = w0; w0 = 0;
01064 
01065    word3_muladd(&w0, &w2, &w1, x[ 7], y[15]);
01066    word3_muladd(&w0, &w2, &w1, x[ 8], y[14]);
01067    word3_muladd(&w0, &w2, &w1, x[ 9], y[13]);
01068    word3_muladd(&w0, &w2, &w1, x[10], y[12]);
01069    word3_muladd(&w0, &w2, &w1, x[11], y[11]);
01070    word3_muladd(&w0, &w2, &w1, x[12], y[10]);
01071    word3_muladd(&w0, &w2, &w1, x[13], y[ 9]);
01072    word3_muladd(&w0, &w2, &w1, x[14], y[ 8]);
01073    word3_muladd(&w0, &w2, &w1, x[15], y[ 7]);
01074    z[22] = w1; w1 = 0;
01075 
01076    word3_muladd(&w1, &w0, &w2, x[ 8], y[15]);
01077    word3_muladd(&w1, &w0, &w2, x[ 9], y[14]);
01078    word3_muladd(&w1, &w0, &w2, x[10], y[13]);
01079    word3_muladd(&w1, &w0, &w2, x[11], y[12]);
01080    word3_muladd(&w1, &w0, &w2, x[12], y[11]);
01081    word3_muladd(&w1, &w0, &w2, x[13], y[10]);
01082    word3_muladd(&w1, &w0, &w2, x[14], y[ 9]);
01083    word3_muladd(&w1, &w0, &w2, x[15], y[ 8]);
01084    z[23] = w2; w2 = 0;
01085 
01086    word3_muladd(&w2, &w1, &w0, x[ 9], y[15]);
01087    word3_muladd(&w2, &w1, &w0, x[10], y[14]);
01088    word3_muladd(&w2, &w1, &w0, x[11], y[13]);
01089    word3_muladd(&w2, &w1, &w0, x[12], y[12]);
01090    word3_muladd(&w2, &w1, &w0, x[13], y[11]);
01091    word3_muladd(&w2, &w1, &w0, x[14], y[10]);
01092    word3_muladd(&w2, &w1, &w0, x[15], y[ 9]);
01093    z[24] = w0; w0 = 0;
01094 
01095    word3_muladd(&w0, &w2, &w1, x[10], y[15]);
01096    word3_muladd(&w0, &w2, &w1, x[11], y[14]);
01097    word3_muladd(&w0, &w2, &w1, x[12], y[13]);
01098    word3_muladd(&w0, &w2, &w1, x[13], y[12]);
01099    word3_muladd(&w0, &w2, &w1, x[14], y[11]);
01100    word3_muladd(&w0, &w2, &w1, x[15], y[10]);
01101    z[25] = w1; w1 = 0;
01102 
01103    word3_muladd(&w1, &w0, &w2, x[11], y[15]);
01104    word3_muladd(&w1, &w0, &w2, x[12], y[14]);
01105    word3_muladd(&w1, &w0, &w2, x[13], y[13]);
01106    word3_muladd(&w1, &w0, &w2, x[14], y[12]);
01107    word3_muladd(&w1, &w0, &w2, x[15], y[11]);
01108    z[26] = w2; w2 = 0;
01109 
01110    word3_muladd(&w2, &w1, &w0, x[12], y[15]);
01111    word3_muladd(&w2, &w1, &w0, x[13], y[14]);
01112    word3_muladd(&w2, &w1, &w0, x[14], y[13]);
01113    word3_muladd(&w2, &w1, &w0, x[15], y[12]);
01114    z[27] = w0; w0 = 0;
01115 
01116    word3_muladd(&w0, &w2, &w1, x[13], y[15]);
01117    word3_muladd(&w0, &w2, &w1, x[14], y[14]);
01118    word3_muladd(&w0, &w2, &w1, x[15], y[13]);
01119    z[28] = w1; w1 = 0;
01120 
01121    word3_muladd(&w1, &w0, &w2, x[14], y[15]);
01122    word3_muladd(&w1, &w0, &w2, x[15], y[14]);
01123    z[29] = w2; w2 = 0;
01124 
01125    word3_muladd(&w2, &w1, &w0, x[15], y[15]);
01126    z[30] = w0;
01127    z[31] = w1;
01128    }
01129 
01130 }
01131 
01132 }