1 | /* |
2 | Copyright (C) 1999-2007 The Botan Project. All rights reserved. |
3 | |
4 | Redistribution and use in source and binary forms, for any use, with or without |
5 | modification, is permitted provided that the following conditions are met: |
6 | |
7 | 1. Redistributions of source code must retain the above copyright notice, this |
8 | list of conditions, and the following disclaimer. |
9 | |
10 | 2. Redistributions in binary form must reproduce the above copyright notice, |
11 | this list of conditions, and the following disclaimer in the documentation |
12 | and/or other materials provided with the distribution. |
13 | |
14 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) "AS IS" AND ANY EXPRESS OR IMPLIED |
15 | WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
16 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED. |
17 | |
18 | IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE FOR ANY DIRECT, |
19 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
20 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
21 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
22 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE |
23 | OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |
24 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
25 | */ |
26 | // LICENSEHEADER_END |
27 | namespace 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> |
35 | namespace QCA { // WRAPNS_LINE |
36 | } // WRAPNS_LINE |
37 | #include <botan/mp_asmi.h> |
38 | namespace QCA { // WRAPNS_LINE |
39 | } // WRAPNS_LINE |
40 | #include <botan/mp_core.h> |
41 | namespace QCA { // WRAPNS_LINE |
42 | } // WRAPNS_LINE |
43 | #include <botan/mem_ops.h> |
44 | namespace QCA { // WRAPNS_LINE |
45 | |
46 | namespace Botan { |
47 | |
48 | extern "C" { |
49 | |
50 | /************************************************* |
51 | * Two Operand Addition, No Carry * |
52 | *************************************************/ |
53 | word 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 | *************************************************/ |
78 | word 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 | *************************************************/ |
107 | void 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 | *************************************************/ |
116 | void 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 | *************************************************/ |
125 | void 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 | *************************************************/ |
150 | void 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 | *************************************************/ |
173 | void 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 | *************************************************/ |
191 | void 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 |
210 | void 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 | |