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