summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/libcrypto/bn/bn_sqr.c130
1 files changed, 80 insertions, 50 deletions
diff --git a/src/lib/libcrypto/bn/bn_sqr.c b/src/lib/libcrypto/bn/bn_sqr.c
index c017887beb..ff254764e3 100644
--- a/src/lib/libcrypto/bn/bn_sqr.c
+++ b/src/lib/libcrypto/bn/bn_sqr.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: bn_sqr.c,v 1.20 2023/01/20 17:34:52 jsing Exp $ */ 1/* $OpenBSD: bn_sqr.c,v 1.21 2023/01/21 14:10:46 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 *
@@ -62,6 +62,8 @@
62#include "bn_arch.h" 62#include "bn_arch.h"
63#include "bn_local.h" 63#include "bn_local.h"
64 64
65int bn_sqr(BIGNUM *r, const BIGNUM *a, int max, BN_CTX *ctx);
66
65#ifndef HAVE_BN_SQR_COMBA4 67#ifndef HAVE_BN_SQR_COMBA4
66void 68void
67bn_sqr_comba4(BN_ULONG *r, const BN_ULONG *a) 69bn_sqr_comba4(BN_ULONG *r, const BN_ULONG *a)
@@ -298,76 +300,104 @@ bn_sqr_recursive(BN_ULONG *r, const BN_ULONG *a, int n2, BN_ULONG *t)
298} 300}
299#endif 301#endif
300 302
301/* I've just gone over this and it is now %20 faster on x86 - eay - 27 Jun 96 */ 303/*
304 * bn_sqr() computes a * a, storing the result in r. The caller must ensure that
305 * r is not the same BIGNUM as a and that r has been expanded to rn = a->top * 2
306 * words.
307 */
308#ifndef HAVE_BN_SQR
302int 309int
303BN_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx) 310bn_sqr(BIGNUM *r, const BIGNUM *a, int rn, BN_CTX *ctx)
304{ 311{
305 int max, al; 312 BIGNUM *tmp;
306 int ret = 0; 313 int ret = 0;
307 BIGNUM *tmp, *rr;
308 314
315 BN_CTX_start(ctx);
316
317 if ((tmp = BN_CTX_get(ctx)) == NULL)
318 goto err;
309 319
310 al = a->top; 320#if defined(BN_RECURSION)
311 if (al <= 0) { 321 if (a->top < BN_SQR_RECURSIVE_SIZE_NORMAL) {
312 r->top = 0; 322 BN_ULONG t[BN_SQR_RECURSIVE_SIZE_NORMAL*2];
313 r->neg = 0; 323 bn_sqr_normal(r->d, a->d, a->top, t);
314 return 1; 324 } else {
325 int j, k;
326
327 j = BN_num_bits_word((BN_ULONG)a->top);
328 j = 1 << (j - 1);
329 k = j + j;
330 if (a->top == j) {
331 if (!bn_wexpand(tmp, k * 2))
332 goto err;
333 bn_sqr_recursive(r->d, a->d, a->top, tmp->d);
334 } else {
335 if (!bn_wexpand(tmp, rn))
336 goto err;
337 bn_sqr_normal(r->d, a->d, a->top, tmp->d);
338 }
315 } 339 }
340#else
341 if (!bn_wexpand(tmp, rn))
342 goto err;
343 bn_sqr_normal(r->d, a->d, a->top, tmp->d);
344#endif
345
346 ret = 1;
347
348 err:
349 BN_CTX_end(ctx);
350
351 return ret;
352}
353#endif
354
355int
356BN_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
357{
358 BIGNUM *rr;
359 int rn;
360 int ret = 1;
316 361
317 BN_CTX_start(ctx); 362 BN_CTX_start(ctx);
318 rr = (a != r) ? r : BN_CTX_get(ctx); 363
319 tmp = BN_CTX_get(ctx); 364 if (BN_is_zero(a)) {
320 if (rr == NULL || tmp == NULL) 365 BN_zero(r);
366 goto done;
367 }
368
369 if ((rr = r) == a)
370 rr = BN_CTX_get(ctx);
371 if (rr == NULL)
321 goto err; 372 goto err;
322 373
323 max = 2 * al; /* Non-zero (from above) */ 374 rn = a->top * 2;
324 if (!bn_wexpand(rr, max)) 375 if (rn < a->top)
376 goto err;
377 if (!bn_wexpand(rr, rn))
325 goto err; 378 goto err;
326 379
327 if (al == 4) { 380 if (a->top == 4) {
328 bn_sqr_comba4(rr->d, a->d); 381 bn_sqr_comba4(rr->d, a->d);
329 } else if (al == 8) { 382 } else if (a->top == 8) {
330 bn_sqr_comba8(rr->d, a->d); 383 bn_sqr_comba8(rr->d, a->d);
331 } else { 384 } else {
332#if defined(BN_RECURSION) 385 if (!bn_sqr(rr, a, rn, ctx))
333 if (al < BN_SQR_RECURSIVE_SIZE_NORMAL) {
334 BN_ULONG t[BN_SQR_RECURSIVE_SIZE_NORMAL*2];
335 bn_sqr_normal(rr->d, a->d, al, t);
336 } else {
337 int j, k;
338
339 j = BN_num_bits_word((BN_ULONG)al);
340 j = 1 << (j - 1);
341 k = j + j;
342 if (al == j) {
343 if (!bn_wexpand(tmp, k * 2))
344 goto err;
345 bn_sqr_recursive(rr->d, a->d, al, tmp->d);
346 } else {
347 if (!bn_wexpand(tmp, max))
348 goto err;
349 bn_sqr_normal(rr->d, a->d, al, tmp->d);
350 }
351 }
352#else
353 if (!bn_wexpand(tmp, max))
354 goto err; 386 goto err;
355 bn_sqr_normal(rr->d, a->d, al, tmp->d);
356#endif
357 } 387 }
358 388
389 rr->top = rn;
359 rr->neg = 0; 390 rr->neg = 0;
360 /* If the most-significant half of the top word of 'a' is zero, then 391
361 * the square of 'a' will max-1 words. */ 392 bn_correct_top(rr);
362 if (a->d[al - 1] == (a->d[al - 1] & BN_MASK2l)) 393
363 rr->top = max - 1;
364 else
365 rr->top = max;
366 if (rr != r) 394 if (rr != r)
367 BN_copy(r, rr); 395 BN_copy(r, rr);
368 ret = 1;
369 396
370err: 397 done:
398 ret = 1;
399 err:
371 BN_CTX_end(ctx); 400 BN_CTX_end(ctx);
372 return (ret); 401
402 return ret;
373} 403}