diff options
author | jsing <> | 2023-01-10 04:13:22 +0000 |
---|---|---|
committer | jsing <> | 2023-01-10 04:13:22 +0000 |
commit | af9a479c0f4683a58c16c40197d66aca318e29e6 (patch) | |
tree | d00302a5800e6cc6aa751907cf8bb37f9c9b3b03 /src | |
parent | 096ef5ab2a7243f1cd6cb8aaaa679dce8b766cdf (diff) | |
download | openbsd-af9a479c0f4683a58c16c40197d66aca318e29e6.tar.gz openbsd-af9a479c0f4683a58c16c40197d66aca318e29e6.tar.bz2 openbsd-af9a479c0f4683a58c16c40197d66aca318e29e6.zip |
Rewrite BN_lshift()
This improves readability and eliminates special handling for various
cases, making the code cleaner and closer to constant time. Basic
benchmarking shows a performance gain on modern 64 bit architectures.
ok tb@
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/libcrypto/bn/bn_shift.c | 83 |
1 files changed, 57 insertions, 26 deletions
diff --git a/src/lib/libcrypto/bn/bn_shift.c b/src/lib/libcrypto/bn/bn_shift.c index 09f1c738ad..4b9a133b13 100644 --- a/src/lib/libcrypto/bn/bn_shift.c +++ b/src/lib/libcrypto/bn/bn_shift.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: bn_shift.c,v 1.18 2023/01/05 04:51:13 jsing Exp $ */ | 1 | /* $OpenBSD: bn_shift.c,v 1.19 2023/01/10 04:13:22 jsing Exp $ */ |
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
@@ -130,40 +130,71 @@ BN_rshift1(BIGNUM *r, const BIGNUM *a) | |||
130 | int | 130 | int |
131 | BN_lshift(BIGNUM *r, const BIGNUM *a, int n) | 131 | BN_lshift(BIGNUM *r, const BIGNUM *a, int n) |
132 | { | 132 | { |
133 | int i, nw, lb, rb; | 133 | size_t count, shift_bits, shift_words; |
134 | BN_ULONG *t, *f; | 134 | size_t lshift, rshift; |
135 | BN_ULONG l; | 135 | ssize_t rstride; |
136 | BN_ULONG *dst, *src; | ||
136 | 137 | ||
137 | if (n < 0) { | 138 | if (n < 0) { |
138 | BNerror(BN_R_INVALID_LENGTH); | 139 | BNerror(BN_R_INVALID_LENGTH); |
139 | return 0; | 140 | return 0; |
140 | } | 141 | } |
142 | shift_bits = n; | ||
143 | |||
144 | /* | ||
145 | * Left bit shift, potentially across word boundaries. | ||
146 | * | ||
147 | * When shift is not an exact multiple of BN_BITS2, the bottom bits of | ||
148 | * the previous word need to be right shifted and combined with the left | ||
149 | * shifted bits using bitwise OR. If shift is an exact multiple of | ||
150 | * BN_BITS2, the source for the left and right shifts are the same | ||
151 | * and the shifts become zero bits (which is effectively a memmove). | ||
152 | */ | ||
153 | shift_words = shift_bits / BN_BITS2; | ||
154 | lshift = shift_bits % BN_BITS2; | ||
155 | rshift = (BN_BITS2 - lshift) % BN_BITS2; | ||
156 | rstride = 0 - (lshift + rshift) / BN_BITS2; | ||
157 | |||
158 | if (a->top < 1) { | ||
159 | BN_zero(r); | ||
160 | return 1; | ||
161 | } | ||
141 | 162 | ||
163 | count = a->top + shift_words + 1; | ||
142 | 164 | ||
165 | if (count < shift_words) | ||
166 | return 0; | ||
167 | |||
168 | if (!bn_wexpand(r, count)) | ||
169 | return 0; | ||
170 | |||
171 | src = a->d + a->top - 1; | ||
172 | dst = r->d + a->top + shift_words; | ||
173 | |||
174 | /* Handle right shift for top most word. */ | ||
175 | *dst = (*src >> rshift) & rstride; | ||
176 | dst--; | ||
177 | |||
178 | /* Handle left shift and right shift for remaining words. */ | ||
179 | while (src > a->d) { | ||
180 | *dst = *src << lshift | src[rstride] >> rshift; | ||
181 | src--; | ||
182 | dst--; | ||
183 | } | ||
184 | *dst = *src << lshift; | ||
185 | |||
186 | /* Zero any additional words resulting from the left shift. */ | ||
187 | while (dst > r->d) { | ||
188 | dst--; | ||
189 | *dst = 0; | ||
190 | } | ||
191 | |||
192 | r->top = count; | ||
143 | r->neg = a->neg; | 193 | r->neg = a->neg; |
144 | nw = n / BN_BITS2; | 194 | |
145 | if (!bn_wexpand(r, a->top + nw + 1)) | ||
146 | return (0); | ||
147 | lb = n % BN_BITS2; | ||
148 | rb = BN_BITS2 - lb; | ||
149 | f = a->d; | ||
150 | t = r->d; | ||
151 | t[a->top + nw] = 0; | ||
152 | if (lb == 0) | ||
153 | for (i = a->top - 1; i >= 0; i--) | ||
154 | t[nw + i] = f[i]; | ||
155 | else | ||
156 | for (i = a->top - 1; i >= 0; i--) { | ||
157 | l = f[i]; | ||
158 | t[nw + i + 1] |= (l >> rb) & BN_MASK2; | ||
159 | t[nw + i] = (l << lb) & BN_MASK2; | ||
160 | } | ||
161 | memset(t, 0, nw * sizeof(t[0])); | ||
162 | /* for (i=0; i<nw; i++) | ||
163 | t[i]=0;*/ | ||
164 | r->top = a->top + nw + 1; | ||
165 | bn_correct_top(r); | 195 | bn_correct_top(r); |
166 | return (1); | 196 | |
197 | return 1; | ||
167 | } | 198 | } |
168 | 199 | ||
169 | int | 200 | int |