Botan
1.11.15
|
00001 /* 00002 * Lowest Level MPI Algorithms 00003 * (C) 1999-2010 Jack Lloyd 00004 * 2006 Luca Piccarreta 00005 * 00006 * Botan is released under the Simplified BSD License (see license.txt) 00007 */ 00008 00009 #ifndef BOTAN_MP_ASM_INTERNAL_H__ 00010 #define BOTAN_MP_ASM_INTERNAL_H__ 00011 00012 #include <botan/internal/mp_madd.h> 00013 00014 namespace Botan { 00015 00016 extern "C" { 00017 00018 /* 00019 * Word Addition 00020 */ 00021 inline word word_add(word x, word y, word* carry) 00022 { 00023 word z = x + y; 00024 word c1 = (z < x); 00025 z += *carry; 00026 *carry = c1 | (z < *carry); 00027 return z; 00028 } 00029 00030 /* 00031 * Eight Word Block Addition, Two Argument 00032 */ 00033 inline word word8_add2(word x[8], const word y[8], word carry) 00034 { 00035 x[0] = word_add(x[0], y[0], &carry); 00036 x[1] = word_add(x[1], y[1], &carry); 00037 x[2] = word_add(x[2], y[2], &carry); 00038 x[3] = word_add(x[3], y[3], &carry); 00039 x[4] = word_add(x[4], y[4], &carry); 00040 x[5] = word_add(x[5], y[5], &carry); 00041 x[6] = word_add(x[6], y[6], &carry); 00042 x[7] = word_add(x[7], y[7], &carry); 00043 return carry; 00044 } 00045 00046 /* 00047 * Eight Word Block Addition, Three Argument 00048 */ 00049 inline word word8_add3(word z[8], const word x[8], 00050 const word y[8], word carry) 00051 { 00052 z[0] = word_add(x[0], y[0], &carry); 00053 z[1] = word_add(x[1], y[1], &carry); 00054 z[2] = word_add(x[2], y[2], &carry); 00055 z[3] = word_add(x[3], y[3], &carry); 00056 z[4] = word_add(x[4], y[4], &carry); 00057 z[5] = word_add(x[5], y[5], &carry); 00058 z[6] = word_add(x[6], y[6], &carry); 00059 z[7] = word_add(x[7], y[7], &carry); 00060 return carry; 00061 } 00062 00063 /* 00064 * Word Subtraction 00065 */ 00066 inline word word_sub(word x, word y, word* carry) 00067 { 00068 word t0 = x - y; 00069 word c1 = (t0 > x); 00070 word z = t0 - *carry; 00071 *carry = c1 | (z > t0); 00072 return z; 00073 } 00074 00075 /* 00076 * Eight Word Block Subtraction, Two Argument 00077 */ 00078 inline word word8_sub2(word x[8], const word y[8], word carry) 00079 { 00080 x[0] = word_sub(x[0], y[0], &carry); 00081 x[1] = word_sub(x[1], y[1], &carry); 00082 x[2] = word_sub(x[2], y[2], &carry); 00083 x[3] = word_sub(x[3], y[3], &carry); 00084 x[4] = word_sub(x[4], y[4], &carry); 00085 x[5] = word_sub(x[5], y[5], &carry); 00086 x[6] = word_sub(x[6], y[6], &carry); 00087 x[7] = word_sub(x[7], y[7], &carry); 00088 return carry; 00089 } 00090 00091 /* 00092 * Eight Word Block Subtraction, Two Argument 00093 */ 00094 inline word word8_sub2_rev(word x[8], const word y[8], word carry) 00095 { 00096 x[0] = word_sub(y[0], x[0], &carry); 00097 x[1] = word_sub(y[1], x[1], &carry); 00098 x[2] = word_sub(y[2], x[2], &carry); 00099 x[3] = word_sub(y[3], x[3], &carry); 00100 x[4] = word_sub(y[4], x[4], &carry); 00101 x[5] = word_sub(y[5], x[5], &carry); 00102 x[6] = word_sub(y[6], x[6], &carry); 00103 x[7] = word_sub(y[7], x[7], &carry); 00104 return carry; 00105 } 00106 00107 /* 00108 * Eight Word Block Subtraction, Three Argument 00109 */ 00110 inline word word8_sub3(word z[8], const word x[8], 00111 const word y[8], word carry) 00112 { 00113 z[0] = word_sub(x[0], y[0], &carry); 00114 z[1] = word_sub(x[1], y[1], &carry); 00115 z[2] = word_sub(x[2], y[2], &carry); 00116 z[3] = word_sub(x[3], y[3], &carry); 00117 z[4] = word_sub(x[4], y[4], &carry); 00118 z[5] = word_sub(x[5], y[5], &carry); 00119 z[6] = word_sub(x[6], y[6], &carry); 00120 z[7] = word_sub(x[7], y[7], &carry); 00121 return carry; 00122 } 00123 00124 /* 00125 * Eight Word Block Linear Multiplication 00126 */ 00127 inline word word8_linmul2(word x[8], word y, word carry) 00128 { 00129 x[0] = word_madd2(x[0], y, &carry); 00130 x[1] = word_madd2(x[1], y, &carry); 00131 x[2] = word_madd2(x[2], y, &carry); 00132 x[3] = word_madd2(x[3], y, &carry); 00133 x[4] = word_madd2(x[4], y, &carry); 00134 x[5] = word_madd2(x[5], y, &carry); 00135 x[6] = word_madd2(x[6], y, &carry); 00136 x[7] = word_madd2(x[7], y, &carry); 00137 return carry; 00138 } 00139 00140 /* 00141 * Eight Word Block Linear Multiplication 00142 */ 00143 inline word word8_linmul3(word z[8], const word x[8], word y, word carry) 00144 { 00145 z[0] = word_madd2(x[0], y, &carry); 00146 z[1] = word_madd2(x[1], y, &carry); 00147 z[2] = word_madd2(x[2], y, &carry); 00148 z[3] = word_madd2(x[3], y, &carry); 00149 z[4] = word_madd2(x[4], y, &carry); 00150 z[5] = word_madd2(x[5], y, &carry); 00151 z[6] = word_madd2(x[6], y, &carry); 00152 z[7] = word_madd2(x[7], y, &carry); 00153 return carry; 00154 } 00155 00156 /* 00157 * Eight Word Block Multiply/Add 00158 */ 00159 inline word word8_madd3(word z[8], const word x[8], word y, word carry) 00160 { 00161 z[0] = word_madd3(x[0], y, z[0], &carry); 00162 z[1] = word_madd3(x[1], y, z[1], &carry); 00163 z[2] = word_madd3(x[2], y, z[2], &carry); 00164 z[3] = word_madd3(x[3], y, z[3], &carry); 00165 z[4] = word_madd3(x[4], y, z[4], &carry); 00166 z[5] = word_madd3(x[5], y, z[5], &carry); 00167 z[6] = word_madd3(x[6], y, z[6], &carry); 00168 z[7] = word_madd3(x[7], y, z[7], &carry); 00169 return carry; 00170 } 00171 00172 /* 00173 * Multiply-Add Accumulator 00174 */ 00175 inline void word3_muladd(word* w2, word* w1, word* w0, word a, word b) 00176 { 00177 word carry = *w0; 00178 *w0 = word_madd2(a, b, &carry); 00179 *w1 += carry; 00180 *w2 += (*w1 < carry) ? 1 : 0; 00181 } 00182 00183 /* 00184 * Multiply-Add Accumulator 00185 */ 00186 inline void word3_muladd_2(word* w2, word* w1, word* w0, word a, word b) 00187 { 00188 word carry = 0; 00189 a = word_madd2(a, b, &carry); 00190 b = carry; 00191 00192 word top = (b >> (BOTAN_MP_WORD_BITS-1)); 00193 b <<= 1; 00194 b |= (a >> (BOTAN_MP_WORD_BITS-1)); 00195 a <<= 1; 00196 00197 carry = 0; 00198 *w0 = word_add(*w0, a, &carry); 00199 *w1 = word_add(*w1, b, &carry); 00200 *w2 = word_add(*w2, top, &carry); 00201 } 00202 00203 } 00204 00205 } 00206 00207 #endif