Warning, file /libraries/qca/src/botantools/botan/mp_asm.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* 0002 Copyright (C) 1999-2007 The Botan Project. All rights reserved. 0003 0004 Redistribution and use in source and binary forms, for any use, with or without 0005 modification, is permitted provided that the following conditions are met: 0006 0007 1. Redistributions of source code must retain the above copyright notice, this 0008 list of conditions, and the following disclaimer. 0009 0010 2. Redistributions in binary form must reproduce the above copyright notice, 0011 this list of conditions, and the following disclaimer in the documentation 0012 and/or other materials provided with the distribution. 0013 0014 THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) "AS IS" AND ANY EXPRESS OR IMPLIED 0015 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 0016 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED. 0017 0018 IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE FOR ANY DIRECT, 0019 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 0020 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 0021 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 0022 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 0023 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 0024 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 0025 */ 0026 // LICENSEHEADER_END 0027 namespace QCA { // WRAPNS_LINE 0028 /************************************************* 0029 * Lowest Level MPI Algorithms Source File * 0030 * (C) 1999-2007 The Botan Project * 0031 *************************************************/ 0032 0033 } // WRAPNS_LINE 0034 #include <botan/mp_asm.h> 0035 namespace QCA { // WRAPNS_LINE 0036 } // WRAPNS_LINE 0037 #include <botan/mp_asmi.h> 0038 namespace QCA { // WRAPNS_LINE 0039 } // WRAPNS_LINE 0040 #include <botan/mp_core.h> 0041 namespace QCA { // WRAPNS_LINE 0042 } // WRAPNS_LINE 0043 #include <botan/mem_ops.h> 0044 namespace QCA { // WRAPNS_LINE 0045 0046 namespace Botan { 0047 0048 extern "C" { 0049 0050 /************************************************* 0051 * Two Operand Addition, No Carry * 0052 *************************************************/ 0053 word bigint_add2_nc(word x[], u32bit x_size, const word y[], u32bit y_size) 0054 { 0055 word carry = 0; 0056 0057 const u32bit blocks = y_size - (y_size % 8); 0058 0059 for (u32bit j = 0; j != blocks; j += 8) 0060 carry = word8_add2(x + j, y + j, carry); 0061 0062 for (u32bit j = blocks; j != y_size; ++j) 0063 x[j] = word_add(x[j], y[j], &carry); 0064 0065 if (!carry) 0066 return 0; 0067 0068 for (u32bit j = y_size; j != x_size; ++j) 0069 if (++x[j]) 0070 return 0; 0071 0072 return 1; 0073 } 0074 0075 /************************************************* 0076 * Three Operand Addition, No Carry * 0077 *************************************************/ 0078 word bigint_add3_nc(word z[], const word x[], u32bit x_size, const word y[], u32bit y_size) 0079 { 0080 if (x_size < y_size) { 0081 return bigint_add3_nc(z, y, y_size, x, x_size); 0082 } 0083 0084 word carry = 0; 0085 0086 const u32bit blocks = y_size - (y_size % 8); 0087 0088 for (u32bit j = 0; j != blocks; j += 8) 0089 carry = word8_add3(z + j, x + j, y + j, carry); 0090 0091 for (u32bit j = blocks; j != y_size; ++j) 0092 z[j] = word_add(x[j], y[j], &carry); 0093 0094 for (u32bit j = y_size; j != x_size; ++j) { 0095 word x_j = x[j] + carry; 0096 if (carry && x_j) 0097 carry = 0; 0098 z[j] = x_j; 0099 } 0100 0101 return carry; 0102 } 0103 0104 /************************************************* 0105 * Two Operand Addition * 0106 *************************************************/ 0107 void bigint_add2(word x[], u32bit x_size, const word y[], u32bit y_size) 0108 { 0109 if (bigint_add2_nc(x, x_size, y, y_size)) 0110 ++x[x_size]; 0111 } 0112 0113 /************************************************* 0114 * Three Operand Addition * 0115 *************************************************/ 0116 void bigint_add3(word z[], const word x[], u32bit x_size, const word y[], u32bit y_size) 0117 { 0118 if (bigint_add3_nc(z, x, x_size, y, y_size)) 0119 ++z[(x_size > y_size ? x_size : y_size)]; 0120 } 0121 0122 /************************************************* 0123 * Two Operand Subtraction * 0124 *************************************************/ 0125 void bigint_sub2(word x[], u32bit x_size, const word y[], u32bit y_size) 0126 { 0127 word carry = 0; 0128 0129 const u32bit blocks = y_size - (y_size % 8); 0130 0131 for (u32bit j = 0; j != blocks; j += 8) 0132 carry = word8_sub2(x + j, y + j, carry); 0133 0134 for (u32bit j = blocks; j != y_size; ++j) 0135 x[j] = word_sub(x[j], y[j], &carry); 0136 0137 if (!carry) 0138 return; 0139 0140 for (u32bit j = y_size; j != x_size; ++j) { 0141 --x[j]; 0142 if (x[j] != MP_WORD_MAX) 0143 return; 0144 } 0145 } 0146 0147 /************************************************* 0148 * Three Operand Subtraction * 0149 *************************************************/ 0150 void bigint_sub3(word z[], const word x[], u32bit x_size, const word y[], u32bit y_size) 0151 { 0152 word carry = 0; 0153 0154 const u32bit blocks = y_size - (y_size % 8); 0155 0156 for (u32bit j = 0; j != blocks; j += 8) 0157 carry = word8_sub3(z + j, x + j, y + j, carry); 0158 0159 for (u32bit j = blocks; j != y_size; ++j) 0160 z[j] = word_sub(x[j], y[j], &carry); 0161 0162 for (u32bit j = y_size; j != x_size; ++j) { 0163 word x_j = x[j] - carry; 0164 if (carry && x_j != MP_WORD_MAX) 0165 carry = 0; 0166 z[j] = x_j; 0167 } 0168 } 0169 0170 /************************************************* 0171 * Two Operand Linear Multiply * 0172 *************************************************/ 0173 void bigint_linmul2(word x[], u32bit x_size, word y) 0174 { 0175 const u32bit blocks = x_size - (x_size % 8); 0176 0177 word carry = 0; 0178 0179 for (u32bit j = 0; j != blocks; j += 8) 0180 carry = word8_linmul2(x + j, y, carry); 0181 0182 for (u32bit j = blocks; j != x_size; ++j) 0183 x[j] = word_madd2(x[j], y, carry, &carry); 0184 0185 x[x_size] = carry; 0186 } 0187 0188 /************************************************* 0189 * Three Operand Linear Multiply * 0190 *************************************************/ 0191 void bigint_linmul3(word z[], const word x[], u32bit x_size, word y) 0192 { 0193 const u32bit blocks = x_size - (x_size % 8); 0194 0195 word carry = 0; 0196 0197 for (u32bit j = 0; j != blocks; j += 8) 0198 carry = word8_linmul3(z + j, x + j, y, carry); 0199 0200 for (u32bit j = blocks; j != x_size; ++j) 0201 z[j] = word_madd2(x[j], y, carry, &carry); 0202 0203 z[x_size] = carry; 0204 } 0205 0206 /************************************************* 0207 * Montgomery Reduction Algorithm * 0208 *************************************************/ 0209 #ifndef BOTAN_MINIMAL_BIGINT 0210 void bigint_monty_redc(word z[], u32bit z_size, const word x[], u32bit x_size, word u) 0211 { 0212 for (u32bit j = 0; j != x_size; ++j) { 0213 word *z_j = z + j; 0214 0215 const word y = z_j[0] * u; 0216 0217 word carry = bigint_mul_add_words(z_j, x, x_size, y); 0218 0219 word z_sum = z_j[x_size] + carry; 0220 carry = (z_sum < z_j[x_size]); 0221 z_j[x_size] = z_sum; 0222 0223 for (u32bit k = x_size + 1; carry && k != z_size - j; ++k) { 0224 ++z_j[k]; 0225 carry = !z_j[k]; 0226 } 0227 } 0228 0229 if (bigint_cmp(z + x_size, x_size + 1, x, x_size) >= 0) 0230 bigint_sub2(z + x_size, x_size + 1, x, x_size); 0231 } 0232 #endif 0233 } 0234 0235 } 0236 } // WRAPNS_LINE