/*
* Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/
#include <assert.h>
#include <openssl/crypto.h>
#include "internal/cryptlib.h"
#include "bn_local.h"
#if defined(BN_LLONG) || defined(BN_UMULT_HIGH)
BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num,
BN_ULONG w)
{
BN_ULONG c1 = 0;
assert(num >= 0);
if (num <= 0)
return c1;
# ifndef OPENSSL_SMALL_FOOTPRINT
while (num & ~3) {
mul_add(rp[0], ap[0], w, c1);
mul_add(rp[1], ap[1], w, c1);
mul_add(rp[2], ap[2], w, c1);
mul_add(rp[3], ap[3], w, c1);
ap += 4;
rp += 4;
num -= 4;
}
# endif
while (num) {
mul_add(rp[0], ap[0], w, c1);
ap++;
rp++;
num--;
}
return c1;
}
BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w)
{
BN_ULONG c1 = 0;
assert(num >= 0);
if (num <= 0)
return c1;
# ifndef OPENSSL_SMALL_FOOTPRINT
while (num & ~3) {
mul(rp[0], ap[0], w, c1);
mul(rp[1], ap[1], w, c1);
mul(rp[2], ap[2], w, c1);
mul(rp[3], ap[3], w, c1);
ap += 4;
rp += 4;
num -= 4;
}
# endif
while (num) {
mul(rp[0], ap[0], w, c1);
ap++;
rp++;
num--;
}
return c1;
}
void bn_sqr_words(BN_ULONG *r, const BN_ULONG *a, int n)
{
assert(n >= 0);
if (n <= 0)
return;
# ifndef OPENSSL_SMALL_FOOTPRINT
while (n & ~3) {
sqr(r[0], r[1], a[0]);
sqr(r[2], r[3], a[1]);
sqr(r[4], r[5], a[2]);
sqr(r[6], r[7], a[3]);
a += 4;
r += 8;
n -= 4;
}
# endif
while (n) {
sqr(r[0], r[1], a[0]);
a++;
r += 2;
n--;
}
}
#else /* !(defined(BN_LLONG) ||
* defined(BN_UMULT_HIGH)) */
BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num,
BN_ULONG w)
{
BN_ULONG c = 0;
BN_ULONG bl, bh;
assert(num >= 0);
if (num <= 0)
return (BN_ULONG)0;
bl = LBITS(w);
bh = HBITS(w);
# ifndef OPENSSL_SMALL_FOOTPRINT
while (num & ~3) {
mul_add(rp[0], ap[0], bl