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 #include <botan/internal/mp_core.h> 00010 #include <botan/internal/mp_asmi.h> 00011 #include <botan/internal/mp_core.h> 00012 #include <botan/exceptn.h> 00013 #include <botan/mem_ops.h> 00014 00015 namespace Botan { 00016 00017 extern "C" { 00018 00019 /* 00020 * Two Operand Addition, No Carry 00021 */ 00022 word bigint_add2_nc(word x[], size_t x_size, const word y[], size_t y_size) 00023 { 00024 word carry = 0; 00025 00026 BOTAN_ASSERT(x_size >= y_size, "Expected sizes"); 00027 00028 const size_t blocks = y_size - (y_size % 8); 00029 00030 for(size_t i = 0; i != blocks; i += 8) 00031 carry = word8_add2(x + i, y + i, carry); 00032 00033 for(size_t i = blocks; i != y_size; ++i) 00034 x[i] = word_add(x[i], y[i], &carry); 00035 00036 for(size_t i = y_size; i != x_size; ++i) 00037 x[i] = word_add(x[i], 0, &carry); 00038 00039 return carry; 00040 } 00041 00042 /* 00043 * Three Operand Addition, No Carry 00044 */ 00045 word bigint_add3_nc(word z[], const word x[], size_t x_size, 00046 const word y[], size_t y_size) 00047 { 00048 if(x_size < y_size) 00049 { return bigint_add3_nc(z, y, y_size, x, x_size); } 00050 00051 word carry = 0; 00052 00053 const size_t blocks = y_size - (y_size % 8); 00054 00055 for(size_t i = 0; i != blocks; i += 8) 00056 carry = word8_add3(z + i, x + i, y + i, carry); 00057 00058 for(size_t i = blocks; i != y_size; ++i) 00059 z[i] = word_add(x[i], y[i], &carry); 00060 00061 for(size_t i = y_size; i != x_size; ++i) 00062 z[i] = word_add(x[i], 0, &carry); 00063 00064 return carry; 00065 } 00066 00067 /* 00068 * Two Operand Addition 00069 */ 00070 void bigint_add2(word x[], size_t x_size, const word y[], size_t y_size) 00071 { 00072 if(bigint_add2_nc(x, x_size, y, y_size)) 00073 x[x_size] += 1; 00074 } 00075 00076 /* 00077 * Three Operand Addition 00078 */ 00079 void bigint_add3(word z[], const word x[], size_t x_size, 00080 const word y[], size_t y_size) 00081 { 00082 z[(x_size > y_size ? x_size : y_size)] += 00083 bigint_add3_nc(z, x, x_size, y, y_size); 00084 } 00085 00086 /* 00087 * Two Operand Subtraction 00088 */ 00089 word bigint_sub2(word x[], size_t x_size, const word y[], size_t y_size) 00090 { 00091 word borrow = 0; 00092 00093 BOTAN_ASSERT(x_size >= y_size, "Expected sizes"); 00094 00095 const size_t blocks = y_size - (y_size % 8); 00096 00097 for(size_t i = 0; i != blocks; i += 8) 00098 borrow = word8_sub2(x + i, y + i, borrow); 00099 00100 for(size_t i = blocks; i != y_size; ++i) 00101 x[i] = word_sub(x[i], y[i], &borrow); 00102 00103 for(size_t i = y_size; i != x_size; ++i) 00104 x[i] = word_sub(x[i], 0, &borrow); 00105 00106 return borrow; 00107 } 00108 00109 /* 00110 * Two Operand Subtraction x = y - x 00111 */ 00112 void bigint_sub2_rev(word x[], const word y[], size_t y_size) 00113 { 00114 word borrow = 0; 00115 00116 const size_t blocks = y_size - (y_size % 8); 00117 00118 for(size_t i = 0; i != blocks; i += 8) 00119 borrow = word8_sub2_rev(x + i, y + i, borrow); 00120 00121 for(size_t i = blocks; i != y_size; ++i) 00122 x[i] = word_sub(y[i], x[i], &borrow); 00123 00124 BOTAN_ASSERT(!borrow, "y must be greater than x"); 00125 } 00126 00127 /* 00128 * Three Operand Subtraction 00129 */ 00130 word bigint_sub3(word z[], const word x[], size_t x_size, 00131 const word y[], size_t y_size) 00132 { 00133 word borrow = 0; 00134 00135 BOTAN_ASSERT(x_size >= y_size, "Expected sizes"); 00136 00137 const size_t blocks = y_size - (y_size % 8); 00138 00139 for(size_t i = 0; i != blocks; i += 8) 00140 borrow = word8_sub3(z + i, x + i, y + i, borrow); 00141 00142 for(size_t i = blocks; i != y_size; ++i) 00143 z[i] = word_sub(x[i], y[i], &borrow); 00144 00145 for(size_t i = y_size; i != x_size; ++i) 00146 z[i] = word_sub(x[i], 0, &borrow); 00147 00148 return borrow; 00149 } 00150 00151 /* 00152 * Two Operand Linear Multiply 00153 */ 00154 void bigint_linmul2(word x[], size_t x_size, word y) 00155 { 00156 const size_t blocks = x_size - (x_size % 8); 00157 00158 word carry = 0; 00159 00160 for(size_t i = 0; i != blocks; i += 8) 00161 carry = word8_linmul2(x + i, y, carry); 00162 00163 for(size_t i = blocks; i != x_size; ++i) 00164 x[i] = word_madd2(x[i], y, &carry); 00165 00166 x[x_size] = carry; 00167 } 00168 00169 /* 00170 * Three Operand Linear Multiply 00171 */ 00172 void bigint_linmul3(word z[], const word x[], size_t x_size, word y) 00173 { 00174 const size_t blocks = x_size - (x_size % 8); 00175 00176 word carry = 0; 00177 00178 for(size_t i = 0; i != blocks; i += 8) 00179 carry = word8_linmul3(z + i, x + i, y, carry); 00180 00181 for(size_t i = blocks; i != x_size; ++i) 00182 z[i] = word_madd2(x[i], y, &carry); 00183 00184 z[x_size] = carry; 00185 } 00186 00187 } 00188 00189 }