/src/libressl/crypto/bn/bn_shift.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* $OpenBSD: bn_shift.c,v 1.14 2022/06/22 09:03:06 tb Exp $ */ |
2 | | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 | | * All rights reserved. |
4 | | * |
5 | | * This package is an SSL implementation written |
6 | | * by Eric Young (eay@cryptsoft.com). |
7 | | * The implementation was written so as to conform with Netscapes SSL. |
8 | | * |
9 | | * This library is free for commercial and non-commercial use as long as |
10 | | * the following conditions are aheared to. The following conditions |
11 | | * apply to all code found in this distribution, be it the RC4, RSA, |
12 | | * lhash, DES, etc., code; not just the SSL code. The SSL documentation |
13 | | * included with this distribution is covered by the same copyright terms |
14 | | * except that the holder is Tim Hudson (tjh@cryptsoft.com). |
15 | | * |
16 | | * Copyright remains Eric Young's, and as such any Copyright notices in |
17 | | * the code are not to be removed. |
18 | | * If this package is used in a product, Eric Young should be given attribution |
19 | | * as the author of the parts of the library used. |
20 | | * This can be in the form of a textual message at program startup or |
21 | | * in documentation (online or textual) provided with the package. |
22 | | * |
23 | | * Redistribution and use in source and binary forms, with or without |
24 | | * modification, are permitted provided that the following conditions |
25 | | * are met: |
26 | | * 1. Redistributions of source code must retain the copyright |
27 | | * notice, this list of conditions and the following disclaimer. |
28 | | * 2. Redistributions in binary form must reproduce the above copyright |
29 | | * notice, this list of conditions and the following disclaimer in the |
30 | | * documentation and/or other materials provided with the distribution. |
31 | | * 3. All advertising materials mentioning features or use of this software |
32 | | * must display the following acknowledgement: |
33 | | * "This product includes cryptographic software written by |
34 | | * Eric Young (eay@cryptsoft.com)" |
35 | | * The word 'cryptographic' can be left out if the rouines from the library |
36 | | * being used are not cryptographic related :-). |
37 | | * 4. If you include any Windows specific code (or a derivative thereof) from |
38 | | * the apps directory (application code) you must include an acknowledgement: |
39 | | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" |
40 | | * |
41 | | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND |
42 | | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
43 | | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
44 | | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE |
45 | | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
46 | | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
47 | | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
48 | | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
49 | | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
50 | | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
51 | | * SUCH DAMAGE. |
52 | | * |
53 | | * The licence and distribution terms for any publically available version or |
54 | | * derivative of this code cannot be changed. i.e. this code cannot simply be |
55 | | * copied and put under another distribution licence |
56 | | * [including the GNU Public Licence.] |
57 | | */ |
58 | | |
59 | | #include <stdio.h> |
60 | | #include <string.h> |
61 | | |
62 | | #include <openssl/err.h> |
63 | | |
64 | | #include "bn_lcl.h" |
65 | | |
66 | | int |
67 | | BN_lshift1(BIGNUM *r, const BIGNUM *a) |
68 | 7.16M | { |
69 | 7.16M | BN_ULONG *ap, *rp, t, c; |
70 | 7.16M | int i; |
71 | | |
72 | 7.16M | bn_check_top(r); |
73 | 7.16M | bn_check_top(a); |
74 | | |
75 | 7.16M | if (r != a) { |
76 | 4.82M | r->neg = a->neg; |
77 | 4.82M | if (bn_wexpand(r, a->top + 1) == NULL) |
78 | 0 | return (0); |
79 | 4.82M | r->top = a->top; |
80 | 4.82M | } else { |
81 | 2.33M | if (bn_wexpand(r, a->top + 1) == NULL) |
82 | 0 | return (0); |
83 | 2.33M | } |
84 | 7.16M | ap = a->d; |
85 | 7.16M | rp = r->d; |
86 | 7.16M | c = 0; |
87 | 64.2M | for (i = 0; i < a->top; i++) { |
88 | 57.0M | t= *(ap++); |
89 | 57.0M | *(rp++) = ((t << 1) | c) & BN_MASK2; |
90 | 57.0M | c = (t & BN_TBIT) ? 1 : 0; |
91 | 57.0M | } |
92 | 7.16M | if (c) { |
93 | 2.07M | *rp = 1; |
94 | 2.07M | r->top++; |
95 | 2.07M | } |
96 | 7.16M | bn_check_top(r); |
97 | 7.16M | return (1); |
98 | 7.16M | } |
99 | | |
100 | | int |
101 | | BN_rshift1(BIGNUM *r, const BIGNUM *a) |
102 | 1.24M | { |
103 | 1.24M | BN_ULONG *ap, *rp, t, c; |
104 | 1.24M | int i, j; |
105 | | |
106 | 1.24M | bn_check_top(r); |
107 | 1.24M | bn_check_top(a); |
108 | | |
109 | 1.24M | if (BN_is_zero(a)) { |
110 | 104 | BN_zero(r); |
111 | 104 | return (1); |
112 | 104 | } |
113 | 1.24M | i = a->top; |
114 | 1.24M | ap = a->d; |
115 | 1.24M | j = i - (ap[i - 1]==1); |
116 | 1.24M | if (a != r) { |
117 | 1.12M | if (bn_wexpand(r, j) == NULL) |
118 | 0 | return (0); |
119 | 1.12M | r->neg = a->neg; |
120 | 1.12M | } |
121 | 1.24M | rp = r->d; |
122 | 1.24M | t = ap[--i]; |
123 | 1.24M | c = (t & 1) ? BN_TBIT : 0; |
124 | 1.24M | if (t >>= 1) |
125 | 1.03M | rp[i] = t; |
126 | 11.0M | while (i > 0) { |
127 | 9.79M | t = ap[--i]; |
128 | 9.79M | rp[i] = ((t >> 1) & BN_MASK2) | c; |
129 | 9.79M | c = (t & 1) ? BN_TBIT : 0; |
130 | 9.79M | } |
131 | 1.24M | r->top = j; |
132 | 1.24M | bn_check_top(r); |
133 | 1.24M | return (1); |
134 | 1.24M | } |
135 | | |
136 | | int |
137 | | BN_lshift(BIGNUM *r, const BIGNUM *a, int n) |
138 | 5.04M | { |
139 | 5.04M | int i, nw, lb, rb; |
140 | 5.04M | BN_ULONG *t, *f; |
141 | 5.04M | BN_ULONG l; |
142 | | |
143 | 5.04M | if (n < 0) { |
144 | 0 | BNerror(BN_R_INVALID_LENGTH); |
145 | 0 | return 0; |
146 | 0 | } |
147 | | |
148 | 5.04M | bn_check_top(r); |
149 | 5.04M | bn_check_top(a); |
150 | | |
151 | 5.04M | r->neg = a->neg; |
152 | 5.04M | nw = n / BN_BITS2; |
153 | 5.04M | if (bn_wexpand(r, a->top + nw + 1) == NULL) |
154 | 0 | return (0); |
155 | 5.04M | lb = n % BN_BITS2; |
156 | 5.04M | rb = BN_BITS2 - lb; |
157 | 5.04M | f = a->d; |
158 | 5.04M | t = r->d; |
159 | 5.04M | t[a->top + nw] = 0; |
160 | 5.04M | if (lb == 0) |
161 | 1.40M | for (i = a->top - 1; i >= 0; i--) |
162 | 1.24M | t[nw + i] = f[i]; |
163 | 4.88M | else |
164 | 36.7M | for (i = a->top - 1; i >= 0; i--) { |
165 | 31.8M | l = f[i]; |
166 | 31.8M | t[nw + i + 1] |= (l >> rb) & BN_MASK2; |
167 | 31.8M | t[nw + i] = (l << lb) & BN_MASK2; |
168 | 31.8M | } |
169 | 5.04M | memset(t, 0, nw * sizeof(t[0])); |
170 | | /* for (i=0; i<nw; i++) |
171 | | t[i]=0;*/ |
172 | 5.04M | r->top = a->top + nw + 1; |
173 | 5.04M | bn_correct_top(r); |
174 | 5.04M | bn_check_top(r); |
175 | 5.04M | return (1); |
176 | 5.04M | } |
177 | | |
178 | | int |
179 | | BN_rshift(BIGNUM *r, const BIGNUM *a, int n) |
180 | 1.19M | { |
181 | 1.19M | int i, j, nw, lb, rb; |
182 | 1.19M | BN_ULONG *t, *f; |
183 | 1.19M | BN_ULONG l, tmp; |
184 | | |
185 | 1.19M | if (n < 0) { |
186 | 0 | BNerror(BN_R_INVALID_LENGTH); |
187 | 0 | return 0; |
188 | 0 | } |
189 | | |
190 | 1.19M | bn_check_top(r); |
191 | 1.19M | bn_check_top(a); |
192 | | |
193 | 1.19M | nw = n / BN_BITS2; |
194 | 1.19M | rb = n % BN_BITS2; |
195 | 1.19M | lb = BN_BITS2 - rb; |
196 | 1.19M | if (nw >= a->top || a->top == 0) { |
197 | 9.11k | BN_zero(r); |
198 | 9.11k | return (1); |
199 | 9.11k | } |
200 | 1.18M | i = (BN_num_bits(a) - n + (BN_BITS2 - 1)) / BN_BITS2; |
201 | 1.18M | if (r != a) { |
202 | 1.16M | r->neg = a->neg; |
203 | 1.16M | if (bn_wexpand(r, i) == NULL) |
204 | 0 | return (0); |
205 | 1.16M | } else { |
206 | 16.9k | if (n == 0) |
207 | 3.75k | return 1; /* or the copying loop will go berserk */ |
208 | 16.9k | } |
209 | | |
210 | 1.18M | f = &(a->d[nw]); |
211 | 1.18M | t = r->d; |
212 | 1.18M | j = a->top - nw; |
213 | 1.18M | r->top = i; |
214 | | |
215 | 1.18M | if (rb == 0) { |
216 | 331k | for (i = j; i != 0; i--) |
217 | 286k | *(t++) = *(f++); |
218 | 1.13M | } else { |
219 | 1.13M | l = *(f++); |
220 | 5.26M | for (i = j - 1; i != 0; i--) { |
221 | 4.13M | tmp = (l >> rb) & BN_MASK2; |
222 | 4.13M | l = *(f++); |
223 | 4.13M | *(t++) = (tmp|(l << lb)) & BN_MASK2; |
224 | 4.13M | } |
225 | 1.13M | if ((l = (l >> rb) & BN_MASK2)) |
226 | 1.06M | *(t) = l; |
227 | 1.13M | } |
228 | 1.18M | bn_check_top(r); |
229 | 1.18M | return (1); |
230 | 1.18M | } |