1 /*
2 * Lowest Level MPI Algorithms
3 * (C) 1999-2010 Jack Lloyd
4 *     2006 Luca Piccarreta
5 *
6 * Distributed under the terms of the Botan license
7 */
8 
9 #ifndef BOTAN_MP_ASM_INTERNAL_H__
10 #define BOTAN_MP_ASM_INTERNAL_H__
11 
12 #include <botan/internal/mp_asm.h>
13 
14 namespace Botan {
15 
16 extern "C" {
17 
18 /*
19 * Word Addition
20 */
word_add(word x,word y,word * carry)21 inline word word_add(word x, word y, word* carry)
22    {
23    word z = x + y;
24    word c1 = (z < x);
25    z += *carry;
26    *carry = c1 | (z < *carry);
27    return z;
28    }
29 
30 /*
31 * Eight Word Block Addition, Two Argument
32 */
word8_add2(word x[8],const word y[8],word carry)33 inline word word8_add2(word x[8], const word y[8], word carry)
34    {
35    x[0] = word_add(x[0], y[0], &carry);
36    x[1] = word_add(x[1], y[1], &carry);
37    x[2] = word_add(x[2], y[2], &carry);
38    x[3] = word_add(x[3], y[3], &carry);
39    x[4] = word_add(x[4], y[4], &carry);
40    x[5] = word_add(x[5], y[5], &carry);
41    x[6] = word_add(x[6], y[6], &carry);
42    x[7] = word_add(x[7], y[7], &carry);
43    return carry;
44    }
45 
46 /*
47 * Eight Word Block Addition, Three Argument
48 */
word8_add3(word z[8],const word x[8],const word y[8],word carry)49 inline word word8_add3(word z[8], const word x[8],
50                        const word y[8], word carry)
51    {
52    z[0] = word_add(x[0], y[0], &carry);
53    z[1] = word_add(x[1], y[1], &carry);
54    z[2] = word_add(x[2], y[2], &carry);
55    z[3] = word_add(x[3], y[3], &carry);
56    z[4] = word_add(x[4], y[4], &carry);
57    z[5] = word_add(x[5], y[5], &carry);
58    z[6] = word_add(x[6], y[6], &carry);
59    z[7] = word_add(x[7], y[7], &carry);
60    return carry;
61    }
62 
63 /*
64 * Word Subtraction
65 */
word_sub(word x,word y,word * carry)66 inline word word_sub(word x, word y, word* carry)
67    {
68    word t0 = x - y;
69    word c1 = (t0 > x);
70    word z = t0 - *carry;
71    *carry = c1 | (z > t0);
72    return z;
73    }
74 
75 /*
76 * Eight Word Block Subtraction, Two Argument
77 */
word8_sub2(word x[8],const word y[8],word carry)78 inline word word8_sub2(word x[8], const word y[8], word carry)
79    {
80    x[0] = word_sub(x[0], y[0], &carry);
81    x[1] = word_sub(x[1], y[1], &carry);
82    x[2] = word_sub(x[2], y[2], &carry);
83    x[3] = word_sub(x[3], y[3], &carry);
84    x[4] = word_sub(x[4], y[4], &carry);
85    x[5] = word_sub(x[5], y[5], &carry);
86    x[6] = word_sub(x[6], y[6], &carry);
87    x[7] = word_sub(x[7], y[7], &carry);
88    return carry;
89    }
90 
91 /*
92 * Eight Word Block Subtraction, Two Argument
93 */
word8_sub2_rev(word x[8],const word y[8],word carry)94 inline word word8_sub2_rev(word x[8], const word y[8], word carry)
95    {
96    x[0] = word_sub(y[0], x[0], &carry);
97    x[1] = word_sub(y[1], x[1], &carry);
98    x[2] = word_sub(y[2], x[2], &carry);
99    x[3] = word_sub(y[3], x[3], &carry);
100    x[4] = word_sub(y[4], x[4], &carry);
101    x[5] = word_sub(y[5], x[5], &carry);
102    x[6] = word_sub(y[6], x[6], &carry);
103    x[7] = word_sub(y[7], x[7], &carry);
104    return carry;
105    }
106 
107 /*
108 * Eight Word Block Subtraction, Three Argument
109 */
word8_sub3(word z[8],const word x[8],const word y[8],word carry)110 inline word word8_sub3(word z[8], const word x[8],
111                        const word y[8], word carry)
112    {
113    z[0] = word_sub(x[0], y[0], &carry);
114    z[1] = word_sub(x[1], y[1], &carry);
115    z[2] = word_sub(x[2], y[2], &carry);
116    z[3] = word_sub(x[3], y[3], &carry);
117    z[4] = word_sub(x[4], y[4], &carry);
118    z[5] = word_sub(x[5], y[5], &carry);
119    z[6] = word_sub(x[6], y[6], &carry);
120    z[7] = word_sub(x[7], y[7], &carry);
121    return carry;
122    }
123 
124 /*
125 * Eight Word Block Linear Multiplication
126 */
word8_linmul2(word x[8],word y,word carry)127 inline word word8_linmul2(word x[8], word y, word carry)
128    {
129    x[0] = word_madd2(x[0], y, &carry);
130    x[1] = word_madd2(x[1], y, &carry);
131    x[2] = word_madd2(x[2], y, &carry);
132    x[3] = word_madd2(x[3], y, &carry);
133    x[4] = word_madd2(x[4], y, &carry);
134    x[5] = word_madd2(x[5], y, &carry);
135    x[6] = word_madd2(x[6], y, &carry);
136    x[7] = word_madd2(x[7], y, &carry);
137    return carry;
138    }
139 
140 /*
141 * Eight Word Block Linear Multiplication
142 */
word8_linmul3(word z[8],const word x[8],word y,word carry)143 inline word word8_linmul3(word z[8], const word x[8], word y, word carry)
144    {
145    z[0] = word_madd2(x[0], y, &carry);
146    z[1] = word_madd2(x[1], y, &carry);
147    z[2] = word_madd2(x[2], y, &carry);
148    z[3] = word_madd2(x[3], y, &carry);
149    z[4] = word_madd2(x[4], y, &carry);
150    z[5] = word_madd2(x[5], y, &carry);
151    z[6] = word_madd2(x[6], y, &carry);
152    z[7] = word_madd2(x[7], y, &carry);
153    return carry;
154    }
155 
156 /*
157 * Eight Word Block Multiply/Add
158 */
word8_madd3(word z[8],const word x[8],word y,word carry)159 inline word word8_madd3(word z[8], const word x[8], word y, word carry)
160    {
161    z[0] = word_madd3(x[0], y, z[0], &carry);
162    z[1] = word_madd3(x[1], y, z[1], &carry);
163    z[2] = word_madd3(x[2], y, z[2], &carry);
164    z[3] = word_madd3(x[3], y, z[3], &carry);
165    z[4] = word_madd3(x[4], y, z[4], &carry);
166    z[5] = word_madd3(x[5], y, z[5], &carry);
167    z[6] = word_madd3(x[6], y, z[6], &carry);
168    z[7] = word_madd3(x[7], y, z[7], &carry);
169    return carry;
170    }
171 
172 /*
173 * Multiply-Add Accumulator
174 */
word3_muladd(word * w2,word * w1,word * w0,word a,word b)175 inline void word3_muladd(word* w2, word* w1, word* w0, word a, word b)
176    {
177    word carry = *w0;
178    *w0 = word_madd2(a, b, &carry);
179    *w1 += carry;
180    *w2 += (*w1 < carry) ? 1 : 0;
181    }
182 
183 /*
184 * Multiply-Add Accumulator
185 */
word3_muladd_2(word * w2,word * w1,word * w0,word a,word b)186 inline void word3_muladd_2(word* w2, word* w1, word* w0, word a, word b)
187    {
188    word carry = 0;
189    a = word_madd2(a, b, &carry);
190    b = carry;
191 
192    word top = (b >> (BOTAN_MP_WORD_BITS-1));
193    b <<= 1;
194    b |= (a >> (BOTAN_MP_WORD_BITS-1));
195    a <<= 1;
196 
197    carry = 0;
198    *w0 = word_add(*w0, a, &carry);
199    *w1 = word_add(*w1, b, &carry);
200    *w2 = word_add(*w2, top, &carry);
201    }
202 
203 }
204 
205 }
206 
207 #endif
208