Botan  1.11.15
src/lib/math/mp/mp_asm.cpp
Go to the documentation of this file.
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 }