This commit is contained in:
purplerain 2023-06-25 21:25:02 +00:00
parent 82bafdd0b3
commit ae25582c29
Signed by: purplerain
GPG key ID: F42C07F07E2E35B7
37 changed files with 421 additions and 1406 deletions

View file

@ -1,4 +1,4 @@
/* $OpenBSD: bn_arch.c,v 1.6 2023/02/22 05:46:37 jsing Exp $ */
/* $OpenBSD: bn_arch.c,v 1.7 2023/06/24 16:01:44 jsing Exp $ */
/*
* Copyright (c) 2023 Joel Sing <jsing@openbsd.org>
*
@ -96,9 +96,9 @@ bn_mul_comba8(BN_ULONG *rd, BN_ULONG *ad, BN_ULONG *bd)
#ifdef HAVE_BN_SQR
int
bn_sqr(BIGNUM *r, const BIGNUM *a, int rn, BN_CTX *ctx)
bn_sqr(BIGNUM *r, const BIGNUM *a, int r_len, BN_CTX *ctx)
{
bignum_sqr(rn, (uint64_t *)r->d, a->top, (uint64_t *)a->d);
bignum_sqr(r_len, (uint64_t *)r->d, a->top, (uint64_t *)a->d);
return 1;
}

View file

@ -1,4 +1,4 @@
/* $OpenBSD: bn_arch.h,v 1.1 2023/01/20 10:04:33 jsing Exp $ */
/* $OpenBSD: bn_arch.h,v 1.2 2023/06/24 15:51:47 jsing Exp $ */
/*
* Copyright (c) 2023 Joel Sing <jsing@openbsd.org>
*
@ -15,10 +15,59 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <openssl/bn.h>
#ifndef HEADER_BN_ARCH_H
#define HEADER_BN_ARCH_H
#ifndef OPENSSL_NO_ASM
#if defined(__GNUC__)
#define HAVE_BN_SUBW
static inline void
bn_subw(BN_ULONG a, BN_ULONG b, BN_ULONG *out_borrow, BN_ULONG *out_r0)
{
BN_ULONG borrow, r0;
__asm__ (
"mov %[borrow], #0 \n"
"subs %[r0], %[a], %[b] \n"
"sbc %[borrow], %[borrow], #0 \n"
"neg %[borrow], %[borrow] \n"
: [borrow]"=&r"(borrow), [r0]"=r"(r0)
: [a]"r"(a), [b]"r"(b)
: "cc");
*out_borrow = borrow;
*out_r0 = r0;
}
#define HAVE_BN_SUBW_SUBW
static inline void
bn_subw_subw(BN_ULONG a, BN_ULONG b, BN_ULONG c, BN_ULONG *out_borrow,
BN_ULONG *out_r0)
{
BN_ULONG borrow, r0;
__asm__ (
"mov %[borrow], #0 \n"
"subs %[r0], %[a], %[b] \n"
"sbc %[borrow], %[borrow], #0 \n"
"subs %[r0], %[r0], %[c] \n"
"sbc %[borrow], %[borrow], #0 \n"
"neg %[borrow], %[borrow] \n"
: [borrow]"=&r"(borrow), [r0]"=&r"(r0)
: [a]"r"(a), [b]"r"(b), [c]"r"(c)
: "cc");
*out_borrow = borrow;
*out_r0 = r0;
}
#endif /* __GNUC__ */
#endif
#endif

View file

@ -1,4 +1,4 @@
/* $OpenBSD: bn_internal.h,v 1.14 2023/06/21 07:48:41 jsing Exp $ */
/* $OpenBSD: bn_internal.h,v 1.15 2023/06/25 11:42:26 jsing Exp $ */
/*
* Copyright (c) 2023 Joel Sing <jsing@openbsd.org>
*
@ -80,12 +80,18 @@ bn_clzw(BN_ULONG w)
*/
/*
* bn_addw() computes (r1:r0) = a + b, where both inputs are single words,
* producing a double word result. The value of r1 is the carry from the
* addition.
* Default implementations for BN_ULLONG architectures.
*
* On these platforms the C compiler is generally better at optimising without
* the use of inline assembly primitives. However, it can be difficult for the
* compiler to see through primitives in order to combine operations, due to
* type changes/narrowing. For this reason compound primitives are usually
* explicitly provided.
*/
#ifdef BN_ULLONG
#ifndef HAVE_BN_ADDW
#ifdef BN_LLONG
#define HAVE_BN_ADDW
static inline void
bn_addw(BN_ULONG a, BN_ULONG b, BN_ULONG *out_r1, BN_ULONG *out_r0)
{
@ -96,8 +102,75 @@ bn_addw(BN_ULONG a, BN_ULONG b, BN_ULONG *out_r1, BN_ULONG *out_r0)
*out_r1 = r >> BN_BITS2;
*out_r0 = r & BN_MASK2;
}
#else
#endif
#ifndef HAVE_BN_ADDW_ADDW
#define HAVE_BN_ADDW_ADDW
static inline void
bn_addw_addw(BN_ULONG a, BN_ULONG b, BN_ULONG c, BN_ULONG *out_r1,
BN_ULONG *out_r0)
{
BN_ULLONG r;
r = (BN_ULLONG)a + (BN_ULLONG)b + (BN_ULLONG)c;
*out_r1 = r >> BN_BITS2;
*out_r0 = r & BN_MASK2;
}
#endif
#ifndef HAVE_BN_MULW
#define HAVE_BN_MULW
static inline void
bn_mulw(BN_ULONG a, BN_ULONG b, BN_ULONG *out_r1, BN_ULONG *out_r0)
{
BN_ULLONG r;
r = (BN_ULLONG)a * (BN_ULLONG)b;
*out_r1 = r >> BN_BITS2;
*out_r0 = r & BN_MASK2;
}
#endif
#ifndef HAVE_BN_MULW_ADDW
#define HAVE_BN_MULW_ADDW
static inline void
bn_mulw_addw(BN_ULONG a, BN_ULONG b, BN_ULONG c, BN_ULONG *out_r1,
BN_ULONG *out_r0)
{
BN_ULLONG r;
r = (BN_ULLONG)a * (BN_ULLONG)b + (BN_ULLONG)c;
*out_r1 = r >> BN_BITS2;
*out_r0 = r & BN_MASK2;
}
#endif
#ifndef HAVE_BN_MULW_ADDW_ADDW
#define HAVE_BN_MULW_ADDW_ADDW
static inline void
bn_mulw_addw_addw(BN_ULONG a, BN_ULONG b, BN_ULONG c, BN_ULONG d,
BN_ULONG *out_r1, BN_ULONG *out_r0)
{
BN_ULLONG r;
r = (BN_ULLONG)a * (BN_ULLONG)b + (BN_ULLONG)c + (BN_ULLONG)d;
*out_r1 = r >> BN_BITS2;
*out_r0 = r & BN_MASK2;
}
#endif
#endif /* !BN_ULLONG */
/*
* bn_addw() computes (r1:r0) = a + b, where both inputs are single words,
* producing a double word result. The value of r1 is the carry from the
* addition.
*/
#ifndef HAVE_BN_ADDW
static inline void
bn_addw(BN_ULONG a, BN_ULONG b, BN_ULONG *out_r1, BN_ULONG *out_r0)
{
@ -112,7 +185,6 @@ bn_addw(BN_ULONG a, BN_ULONG b, BN_ULONG *out_r1, BN_ULONG *out_r0)
*out_r0 = r0;
}
#endif
#endif
/*
* bn_addw_addw() computes (r1:r0) = a + b + c, where all inputs are single
@ -230,19 +302,6 @@ bn_qwsubqw(BN_ULONG a3, BN_ULONG a2, BN_ULONG a1, BN_ULONG a0, BN_ULONG b3,
* producing a double word result.
*/
#ifndef HAVE_BN_MULW
#ifdef BN_LLONG
static inline void
bn_mulw(BN_ULONG a, BN_ULONG b, BN_ULONG *out_r1, BN_ULONG *out_r0)
{
BN_ULLONG r;
r = (BN_ULLONG)a * (BN_ULLONG)b;
*out_r1 = r >> BN_BITS2;
*out_r0 = r & BN_MASK2;
}
#else /* !BN_LLONG */
/*
* Multiply two words (a * b) producing a double word result (h:l).
*
@ -339,7 +398,6 @@ bn_mulw(BN_ULONG a, BN_ULONG b, BN_ULONG *out_r1, BN_ULONG *out_r0)
*out_r0 = (acc1 << BN_BITS4) | acc0;
}
#endif
#endif /* !BN_LLONG */
#endif
#ifndef HAVE_BN_MULW_LO

View file

@ -1,4 +1,4 @@
/* $OpenBSD: bn_local.h,v 1.23 2023/06/21 07:41:55 jsing Exp $ */
/* $OpenBSD: bn_local.h,v 1.24 2023/06/24 16:01:43 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@ -252,7 +252,6 @@ void bn_mul_normal(BN_ULONG *r, BN_ULONG *a, int na, BN_ULONG *b, int nb);
void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b);
void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b);
void bn_sqr_normal(BN_ULONG *r, const BN_ULONG *a, int n, BN_ULONG *tmp);
void bn_sqr_comba4(BN_ULONG *r, const BN_ULONG *a);
void bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a);

View file

@ -1,4 +1,4 @@
/* $OpenBSD: bn_sqr.c,v 1.30 2023/04/19 10:51:22 jsing Exp $ */
/* $OpenBSD: bn_sqr.c,v 1.34 2023/06/24 17:06:54 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@ -191,52 +191,60 @@ bn_sqr_words(BN_ULONG *r, const BN_ULONG *a, int n)
}
#endif
/* tmp must have 2*n words */
void
bn_sqr_normal(BN_ULONG *r, const BN_ULONG *a, int n, BN_ULONG *tmp)
#ifndef HAVE_BN_SQR
static void
bn_sqr_normal(BN_ULONG *r, int r_len, const BN_ULONG *a, int a_len,
BN_ULONG *tmp)
{
int i, j, max;
const BN_ULONG *ap;
BN_ULONG *rp;
BN_ULONG w;
int n;
if (a_len <= 0)
return;
max = n * 2;
ap = a;
w = ap[0];
ap++;
rp = r;
rp[0] = rp[max - 1] = 0;
rp[0] = rp[r_len - 1] = 0;
rp++;
j = n;
if (--j > 0) {
/* Compute initial product - r[n:1] = a[n:1] * a[0] */
n = a_len - 1;
if (n > 0) {
rp[n] = bn_mul_words(rp, ap, n, w);
}
rp += 2;
n--;
/* Compute and sum remaining products. */
while (n > 0) {
w = ap[0];
ap++;
rp[j] = bn_mul_words(rp, ap, j, ap[-1]);
rp[n] = bn_mul_add_words(rp, ap, n, w);
rp += 2;
n--;
}
for (i = n - 2; i > 0; i--) {
j--;
ap++;
rp[j] = bn_mul_add_words(rp, ap, j, ap[-1]);
rp += 2;
}
/* Double the sum of products. */
bn_add_words(r, r, r, r_len);
bn_add_words(r, r, r, max);
/* There will not be a carry */
bn_sqr_words(tmp, a, n);
bn_add_words(r, r, tmp, max);
/* Add squares. */
bn_sqr_words(tmp, a, a_len);
bn_add_words(r, r, tmp, r_len);
}
/*
* bn_sqr() computes a * a, storing the result in r. The caller must ensure that
* r is not the same BIGNUM as a and that r has been expanded to rn = a->top * 2
* words.
*/
#ifndef HAVE_BN_SQR
int
bn_sqr(BIGNUM *r, const BIGNUM *a, int rn, BN_CTX *ctx)
bn_sqr(BIGNUM *r, const BIGNUM *a, int r_len, BN_CTX *ctx)
{
BIGNUM *tmp;
int ret = 0;
@ -245,10 +253,10 @@ bn_sqr(BIGNUM *r, const BIGNUM *a, int rn, BN_CTX *ctx)
if ((tmp = BN_CTX_get(ctx)) == NULL)
goto err;
if (!bn_wexpand(tmp, rn))
if (!bn_wexpand(tmp, r_len))
goto err;
bn_sqr_normal(r->d, a->d, a->top, tmp->d);
bn_sqr_normal(r->d, r_len, a->d, a->top, tmp->d);
ret = 1;
@ -263,12 +271,12 @@ int
BN_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
{
BIGNUM *rr;
int rn;
int r_len;
int ret = 1;
BN_CTX_start(ctx);
if (BN_is_zero(a)) {
if (a->top < 1) {
BN_zero(r);
goto done;
}
@ -278,10 +286,9 @@ BN_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
if (rr == NULL)
goto err;
rn = a->top * 2;
if (rn < a->top)
if ((r_len = a->top * 2) < a->top)
goto err;
if (!bn_wexpand(rr, rn))
if (!bn_wexpand(rr, r_len))
goto err;
if (a->top == 4) {
@ -289,11 +296,11 @@ BN_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
} else if (a->top == 8) {
bn_sqr_comba8(rr->d, a->d);
} else {
if (!bn_sqr(rr, a, rn, ctx))
if (!bn_sqr(rr, a, r_len, ctx))
goto err;
}
rr->top = rn;
rr->top = r_len;
bn_correct_top(rr);
rr->neg = 0;