1/*
2Copyright (C) 1999-2007 The Botan Project. All rights reserved.
3
4Redistribution and use in source and binary forms, for any use, with or without
5modification, is permitted provided that the following conditions are met:
6
71. Redistributions of source code must retain the above copyright notice, this
8list of conditions, and the following disclaimer.
9
102. Redistributions in binary form must reproduce the above copyright notice,
11this list of conditions, and the following disclaimer in the documentation
12and/or other materials provided with the distribution.
13
14THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) "AS IS" AND ANY EXPRESS OR IMPLIED
15WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
17
18IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE FOR ANY DIRECT,
19INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
20BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
22LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
23OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
24ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25*/
26// LICENSEHEADER_END
27namespace QCA { // WRAPNS_LINE
28/*************************************************
29 * Lowest Level MPI Algorithms Source File *
30 * (C) 1999-2007 The Botan Project *
31 *************************************************/
32
33} // WRAPNS_LINE
34#include <botan/mp_asm.h>
35namespace QCA { // WRAPNS_LINE
36} // WRAPNS_LINE
37#include <botan/mp_asmi.h>
38namespace QCA { // WRAPNS_LINE
39} // WRAPNS_LINE
40#include <botan/mp_core.h>
41namespace QCA { // WRAPNS_LINE
42} // WRAPNS_LINE
43#include <botan/mem_ops.h>
44namespace QCA { // WRAPNS_LINE
45
46namespace Botan {
47
48extern "C" {
49
50/*************************************************
51 * Two Operand Addition, No Carry *
52 *************************************************/
53word bigint_add2_nc(word x[], u32bit x_size, const word y[], u32bit y_size)
54{
55 word carry = 0;
56
57 const u32bit blocks = y_size - (y_size % 8);
58
59 for (u32bit j = 0; j != blocks; j += 8)
60 carry = word8_add2(x: x + j, y: y + j, carry);
61
62 for (u32bit j = blocks; j != y_size; ++j)
63 x[j] = word_add(x: x[j], y: y[j], carry: &carry);
64
65 if (!carry)
66 return 0;
67
68 for (u32bit j = y_size; j != x_size; ++j)
69 if (++x[j])
70 return 0;
71
72 return 1;
73}
74
75/*************************************************
76 * Three Operand Addition, No Carry *
77 *************************************************/
78word bigint_add3_nc(word z[], const word x[], u32bit x_size, const word y[], u32bit y_size)
79{
80 if (x_size < y_size) {
81 return bigint_add3_nc(z, x: y, x_size: y_size, y: x, y_size: x_size);
82 }
83
84 word carry = 0;
85
86 const u32bit blocks = y_size - (y_size % 8);
87
88 for (u32bit j = 0; j != blocks; j += 8)
89 carry = word8_add3(z: z + j, x: x + j, y: y + j, carry);
90
91 for (u32bit j = blocks; j != y_size; ++j)
92 z[j] = word_add(x: x[j], y: y[j], carry: &carry);
93
94 for (u32bit j = y_size; j != x_size; ++j) {
95 word x_j = x[j] + carry;
96 if (carry && x_j)
97 carry = 0;
98 z[j] = x_j;
99 }
100
101 return carry;
102}
103
104/*************************************************
105 * Two Operand Addition *
106 *************************************************/
107void bigint_add2(word x[], u32bit x_size, const word y[], u32bit y_size)
108{
109 if (bigint_add2_nc(x, x_size, y, y_size))
110 ++x[x_size];
111}
112
113/*************************************************
114 * Three Operand Addition *
115 *************************************************/
116void bigint_add3(word z[], const word x[], u32bit x_size, const word y[], u32bit y_size)
117{
118 if (bigint_add3_nc(z, x, x_size, y, y_size))
119 ++z[(x_size > y_size ? x_size : y_size)];
120}
121
122/*************************************************
123 * Two Operand Subtraction *
124 *************************************************/
125void bigint_sub2(word x[], u32bit x_size, const word y[], u32bit y_size)
126{
127 word carry = 0;
128
129 const u32bit blocks = y_size - (y_size % 8);
130
131 for (u32bit j = 0; j != blocks; j += 8)
132 carry = word8_sub2(x: x + j, y: y + j, carry);
133
134 for (u32bit j = blocks; j != y_size; ++j)
135 x[j] = word_sub(x: x[j], y: y[j], carry: &carry);
136
137 if (!carry)
138 return;
139
140 for (u32bit j = y_size; j != x_size; ++j) {
141 --x[j];
142 if (x[j] != MP_WORD_MAX)
143 return;
144 }
145}
146
147/*************************************************
148 * Three Operand Subtraction *
149 *************************************************/
150void bigint_sub3(word z[], const word x[], u32bit x_size, const word y[], u32bit y_size)
151{
152 word carry = 0;
153
154 const u32bit blocks = y_size - (y_size % 8);
155
156 for (u32bit j = 0; j != blocks; j += 8)
157 carry = word8_sub3(z: z + j, x: x + j, y: y + j, carry);
158
159 for (u32bit j = blocks; j != y_size; ++j)
160 z[j] = word_sub(x: x[j], y: y[j], carry: &carry);
161
162 for (u32bit j = y_size; j != x_size; ++j) {
163 word x_j = x[j] - carry;
164 if (carry && x_j != MP_WORD_MAX)
165 carry = 0;
166 z[j] = x_j;
167 }
168}
169
170/*************************************************
171 * Two Operand Linear Multiply *
172 *************************************************/
173void bigint_linmul2(word x[], u32bit x_size, word y)
174{
175 const u32bit blocks = x_size - (x_size % 8);
176
177 word carry = 0;
178
179 for (u32bit j = 0; j != blocks; j += 8)
180 carry = word8_linmul2(x: x + j, y, carry);
181
182 for (u32bit j = blocks; j != x_size; ++j)
183 x[j] = word_madd2(a: x[j], b: y, c: carry, carry: &carry);
184
185 x[x_size] = carry;
186}
187
188/*************************************************
189 * Three Operand Linear Multiply *
190 *************************************************/
191void bigint_linmul3(word z[], const word x[], u32bit x_size, word y)
192{
193 const u32bit blocks = x_size - (x_size % 8);
194
195 word carry = 0;
196
197 for (u32bit j = 0; j != blocks; j += 8)
198 carry = word8_linmul3(z: z + j, x: x + j, y, carry);
199
200 for (u32bit j = blocks; j != x_size; ++j)
201 z[j] = word_madd2(a: x[j], b: y, c: carry, carry: &carry);
202
203 z[x_size] = carry;
204}
205
206/*************************************************
207 * Montgomery Reduction Algorithm *
208 *************************************************/
209#ifndef BOTAN_MINIMAL_BIGINT
210void bigint_monty_redc(word z[], u32bit z_size, const word x[], u32bit x_size, word u)
211{
212 for (u32bit j = 0; j != x_size; ++j) {
213 word *z_j = z + j;
214
215 const word y = z_j[0] * u;
216
217 word carry = bigint_mul_add_words(z_j, x, x_size, y);
218
219 word z_sum = z_j[x_size] + carry;
220 carry = (z_sum < z_j[x_size]);
221 z_j[x_size] = z_sum;
222
223 for (u32bit k = x_size + 1; carry && k != z_size - j; ++k) {
224 ++z_j[k];
225 carry = !z_j[k];
226 }
227 }
228
229 if (bigint_cmp(z + x_size, x_size + 1, x, x_size) >= 0)
230 bigint_sub2(z + x_size, x_size + 1, x, x_size);
231}
232#endif
233}
234
235}
236} // WRAPNS_LINE
237

source code of qca/src/botantools/botan/mp_asm.cpp