1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. 3e1051a39Sopenharmony_ci * 4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License"). You may not use 5e1051a39Sopenharmony_ci * this file except in compliance with the License. You can obtain a copy 6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at 7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html 8e1051a39Sopenharmony_ci */ 9e1051a39Sopenharmony_ci 10e1051a39Sopenharmony_ci#include <assert.h> 11e1051a39Sopenharmony_ci#include <openssl/crypto.h> 12e1051a39Sopenharmony_ci#include "internal/cryptlib.h" 13e1051a39Sopenharmony_ci#include "bn_local.h" 14e1051a39Sopenharmony_ci 15e1051a39Sopenharmony_ci#if defined(BN_LLONG) || defined(BN_UMULT_HIGH) 16e1051a39Sopenharmony_ci 17e1051a39Sopenharmony_ciBN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num, 18e1051a39Sopenharmony_ci BN_ULONG w) 19e1051a39Sopenharmony_ci{ 20e1051a39Sopenharmony_ci BN_ULONG c1 = 0; 21e1051a39Sopenharmony_ci 22e1051a39Sopenharmony_ci assert(num >= 0); 23e1051a39Sopenharmony_ci if (num <= 0) 24e1051a39Sopenharmony_ci return c1; 25e1051a39Sopenharmony_ci 26e1051a39Sopenharmony_ci# ifndef OPENSSL_SMALL_FOOTPRINT 27e1051a39Sopenharmony_ci while (num & ~3) { 28e1051a39Sopenharmony_ci mul_add(rp[0], ap[0], w, c1); 29e1051a39Sopenharmony_ci mul_add(rp[1], ap[1], w, c1); 30e1051a39Sopenharmony_ci mul_add(rp[2], ap[2], w, c1); 31e1051a39Sopenharmony_ci mul_add(rp[3], ap[3], w, c1); 32e1051a39Sopenharmony_ci ap += 4; 33e1051a39Sopenharmony_ci rp += 4; 34e1051a39Sopenharmony_ci num -= 4; 35e1051a39Sopenharmony_ci } 36e1051a39Sopenharmony_ci# endif 37e1051a39Sopenharmony_ci while (num) { 38e1051a39Sopenharmony_ci mul_add(rp[0], ap[0], w, c1); 39e1051a39Sopenharmony_ci ap++; 40e1051a39Sopenharmony_ci rp++; 41e1051a39Sopenharmony_ci num--; 42e1051a39Sopenharmony_ci } 43e1051a39Sopenharmony_ci 44e1051a39Sopenharmony_ci return c1; 45e1051a39Sopenharmony_ci} 46e1051a39Sopenharmony_ci 47e1051a39Sopenharmony_ciBN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w) 48e1051a39Sopenharmony_ci{ 49e1051a39Sopenharmony_ci BN_ULONG c1 = 0; 50e1051a39Sopenharmony_ci 51e1051a39Sopenharmony_ci assert(num >= 0); 52e1051a39Sopenharmony_ci if (num <= 0) 53e1051a39Sopenharmony_ci return c1; 54e1051a39Sopenharmony_ci 55e1051a39Sopenharmony_ci# ifndef OPENSSL_SMALL_FOOTPRINT 56e1051a39Sopenharmony_ci while (num & ~3) { 57e1051a39Sopenharmony_ci mul(rp[0], ap[0], w, c1); 58e1051a39Sopenharmony_ci mul(rp[1], ap[1], w, c1); 59e1051a39Sopenharmony_ci mul(rp[2], ap[2], w, c1); 60e1051a39Sopenharmony_ci mul(rp[3], ap[3], w, c1); 61e1051a39Sopenharmony_ci ap += 4; 62e1051a39Sopenharmony_ci rp += 4; 63e1051a39Sopenharmony_ci num -= 4; 64e1051a39Sopenharmony_ci } 65e1051a39Sopenharmony_ci# endif 66e1051a39Sopenharmony_ci while (num) { 67e1051a39Sopenharmony_ci mul(rp[0], ap[0], w, c1); 68e1051a39Sopenharmony_ci ap++; 69e1051a39Sopenharmony_ci rp++; 70e1051a39Sopenharmony_ci num--; 71e1051a39Sopenharmony_ci } 72e1051a39Sopenharmony_ci return c1; 73e1051a39Sopenharmony_ci} 74e1051a39Sopenharmony_ci 75e1051a39Sopenharmony_civoid bn_sqr_words(BN_ULONG *r, const BN_ULONG *a, int n) 76e1051a39Sopenharmony_ci{ 77e1051a39Sopenharmony_ci assert(n >= 0); 78e1051a39Sopenharmony_ci if (n <= 0) 79e1051a39Sopenharmony_ci return; 80e1051a39Sopenharmony_ci 81e1051a39Sopenharmony_ci# ifndef OPENSSL_SMALL_FOOTPRINT 82e1051a39Sopenharmony_ci while (n & ~3) { 83e1051a39Sopenharmony_ci sqr(r[0], r[1], a[0]); 84e1051a39Sopenharmony_ci sqr(r[2], r[3], a[1]); 85e1051a39Sopenharmony_ci sqr(r[4], r[5], a[2]); 86e1051a39Sopenharmony_ci sqr(r[6], r[7], a[3]); 87e1051a39Sopenharmony_ci a += 4; 88e1051a39Sopenharmony_ci r += 8; 89e1051a39Sopenharmony_ci n -= 4; 90e1051a39Sopenharmony_ci } 91e1051a39Sopenharmony_ci# endif 92e1051a39Sopenharmony_ci while (n) { 93e1051a39Sopenharmony_ci sqr(r[0], r[1], a[0]); 94e1051a39Sopenharmony_ci a++; 95e1051a39Sopenharmony_ci r += 2; 96e1051a39Sopenharmony_ci n--; 97e1051a39Sopenharmony_ci } 98e1051a39Sopenharmony_ci} 99e1051a39Sopenharmony_ci 100e1051a39Sopenharmony_ci#else /* !(defined(BN_LLONG) || 101e1051a39Sopenharmony_ci * defined(BN_UMULT_HIGH)) */ 102e1051a39Sopenharmony_ci 103e1051a39Sopenharmony_ciBN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num, 104e1051a39Sopenharmony_ci BN_ULONG w) 105e1051a39Sopenharmony_ci{ 106e1051a39Sopenharmony_ci BN_ULONG c = 0; 107e1051a39Sopenharmony_ci BN_ULONG bl, bh; 108e1051a39Sopenharmony_ci 109e1051a39Sopenharmony_ci assert(num >= 0); 110e1051a39Sopenharmony_ci if (num <= 0) 111e1051a39Sopenharmony_ci return (BN_ULONG)0; 112e1051a39Sopenharmony_ci 113e1051a39Sopenharmony_ci bl = LBITS(w); 114e1051a39Sopenharmony_ci bh = HBITS(w); 115e1051a39Sopenharmony_ci 116e1051a39Sopenharmony_ci# ifndef OPENSSL_SMALL_FOOTPRINT 117e1051a39Sopenharmony_ci while (num & ~3) { 118e1051a39Sopenharmony_ci mul_add(rp[0], ap[0], bl, bh, c); 119e1051a39Sopenharmony_ci mul_add(rp[1], ap[1], bl, bh, c); 120e1051a39Sopenharmony_ci mul_add(rp[2], ap[2], bl, bh, c); 121e1051a39Sopenharmony_ci mul_add(rp[3], ap[3], bl, bh, c); 122e1051a39Sopenharmony_ci ap += 4; 123e1051a39Sopenharmony_ci rp += 4; 124e1051a39Sopenharmony_ci num -= 4; 125e1051a39Sopenharmony_ci } 126e1051a39Sopenharmony_ci# endif 127e1051a39Sopenharmony_ci while (num) { 128e1051a39Sopenharmony_ci mul_add(rp[0], ap[0], bl, bh, c); 129e1051a39Sopenharmony_ci ap++; 130e1051a39Sopenharmony_ci rp++; 131e1051a39Sopenharmony_ci num--; 132e1051a39Sopenharmony_ci } 133e1051a39Sopenharmony_ci return c; 134e1051a39Sopenharmony_ci} 135e1051a39Sopenharmony_ci 136e1051a39Sopenharmony_ciBN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w) 137e1051a39Sopenharmony_ci{ 138e1051a39Sopenharmony_ci BN_ULONG carry = 0; 139e1051a39Sopenharmony_ci BN_ULONG bl, bh; 140e1051a39Sopenharmony_ci 141e1051a39Sopenharmony_ci assert(num >= 0); 142e1051a39Sopenharmony_ci if (num <= 0) 143e1051a39Sopenharmony_ci return (BN_ULONG)0; 144e1051a39Sopenharmony_ci 145e1051a39Sopenharmony_ci bl = LBITS(w); 146e1051a39Sopenharmony_ci bh = HBITS(w); 147e1051a39Sopenharmony_ci 148e1051a39Sopenharmony_ci# ifndef OPENSSL_SMALL_FOOTPRINT 149e1051a39Sopenharmony_ci while (num & ~3) { 150e1051a39Sopenharmony_ci mul(rp[0], ap[0], bl, bh, carry); 151e1051a39Sopenharmony_ci mul(rp[1], ap[1], bl, bh, carry); 152e1051a39Sopenharmony_ci mul(rp[2], ap[2], bl, bh, carry); 153e1051a39Sopenharmony_ci mul(rp[3], ap[3], bl, bh, carry); 154e1051a39Sopenharmony_ci ap += 4; 155e1051a39Sopenharmony_ci rp += 4; 156e1051a39Sopenharmony_ci num -= 4; 157e1051a39Sopenharmony_ci } 158e1051a39Sopenharmony_ci# endif 159e1051a39Sopenharmony_ci while (num) { 160e1051a39Sopenharmony_ci mul(rp[0], ap[0], bl, bh, carry); 161e1051a39Sopenharmony_ci ap++; 162e1051a39Sopenharmony_ci rp++; 163e1051a39Sopenharmony_ci num--; 164e1051a39Sopenharmony_ci } 165e1051a39Sopenharmony_ci return carry; 166e1051a39Sopenharmony_ci} 167e1051a39Sopenharmony_ci 168e1051a39Sopenharmony_civoid bn_sqr_words(BN_ULONG *r, const BN_ULONG *a, int n) 169e1051a39Sopenharmony_ci{ 170e1051a39Sopenharmony_ci assert(n >= 0); 171e1051a39Sopenharmony_ci if (n <= 0) 172e1051a39Sopenharmony_ci return; 173e1051a39Sopenharmony_ci 174e1051a39Sopenharmony_ci# ifndef OPENSSL_SMALL_FOOTPRINT 175e1051a39Sopenharmony_ci while (n & ~3) { 176e1051a39Sopenharmony_ci sqr64(r[0], r[1], a[0]); 177e1051a39Sopenharmony_ci sqr64(r[2], r[3], a[1]); 178e1051a39Sopenharmony_ci sqr64(r[4], r[5], a[2]); 179e1051a39Sopenharmony_ci sqr64(r[6], r[7], a[3]); 180e1051a39Sopenharmony_ci a += 4; 181e1051a39Sopenharmony_ci r += 8; 182e1051a39Sopenharmony_ci n -= 4; 183e1051a39Sopenharmony_ci } 184e1051a39Sopenharmony_ci# endif 185e1051a39Sopenharmony_ci while (n) { 186e1051a39Sopenharmony_ci sqr64(r[0], r[1], a[0]); 187e1051a39Sopenharmony_ci a++; 188e1051a39Sopenharmony_ci r += 2; 189e1051a39Sopenharmony_ci n--; 190e1051a39Sopenharmony_ci } 191e1051a39Sopenharmony_ci} 192e1051a39Sopenharmony_ci 193e1051a39Sopenharmony_ci#endif /* !(defined(BN_LLONG) || 194e1051a39Sopenharmony_ci * defined(BN_UMULT_HIGH)) */ 195e1051a39Sopenharmony_ci 196e1051a39Sopenharmony_ci#if defined(BN_LLONG) && defined(BN_DIV2W) 197e1051a39Sopenharmony_ci 198e1051a39Sopenharmony_ciBN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d) 199e1051a39Sopenharmony_ci{ 200e1051a39Sopenharmony_ci return ((BN_ULONG)(((((BN_ULLONG) h) << BN_BITS2) | l) / (BN_ULLONG) d)); 201e1051a39Sopenharmony_ci} 202e1051a39Sopenharmony_ci 203e1051a39Sopenharmony_ci#else 204e1051a39Sopenharmony_ci 205e1051a39Sopenharmony_ci/* Divide h,l by d and return the result. */ 206e1051a39Sopenharmony_ci/* I need to test this some more :-( */ 207e1051a39Sopenharmony_ciBN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d) 208e1051a39Sopenharmony_ci{ 209e1051a39Sopenharmony_ci BN_ULONG dh, dl, q, ret = 0, th, tl, t; 210e1051a39Sopenharmony_ci int i, count = 2; 211e1051a39Sopenharmony_ci 212e1051a39Sopenharmony_ci if (d == 0) 213e1051a39Sopenharmony_ci return BN_MASK2; 214e1051a39Sopenharmony_ci 215e1051a39Sopenharmony_ci i = BN_num_bits_word(d); 216e1051a39Sopenharmony_ci assert((i == BN_BITS2) || (h <= (BN_ULONG)1 << i)); 217e1051a39Sopenharmony_ci 218e1051a39Sopenharmony_ci i = BN_BITS2 - i; 219e1051a39Sopenharmony_ci if (h >= d) 220e1051a39Sopenharmony_ci h -= d; 221e1051a39Sopenharmony_ci 222e1051a39Sopenharmony_ci if (i) { 223e1051a39Sopenharmony_ci d <<= i; 224e1051a39Sopenharmony_ci h = (h << i) | (l >> (BN_BITS2 - i)); 225e1051a39Sopenharmony_ci l <<= i; 226e1051a39Sopenharmony_ci } 227e1051a39Sopenharmony_ci dh = (d & BN_MASK2h) >> BN_BITS4; 228e1051a39Sopenharmony_ci dl = (d & BN_MASK2l); 229e1051a39Sopenharmony_ci for (;;) { 230e1051a39Sopenharmony_ci if ((h >> BN_BITS4) == dh) 231e1051a39Sopenharmony_ci q = BN_MASK2l; 232e1051a39Sopenharmony_ci else 233e1051a39Sopenharmony_ci q = h / dh; 234e1051a39Sopenharmony_ci 235e1051a39Sopenharmony_ci th = q * dh; 236e1051a39Sopenharmony_ci tl = dl * q; 237e1051a39Sopenharmony_ci for (;;) { 238e1051a39Sopenharmony_ci t = h - th; 239e1051a39Sopenharmony_ci if ((t & BN_MASK2h) || 240e1051a39Sopenharmony_ci ((tl) <= ((t << BN_BITS4) | ((l & BN_MASK2h) >> BN_BITS4)))) 241e1051a39Sopenharmony_ci break; 242e1051a39Sopenharmony_ci q--; 243e1051a39Sopenharmony_ci th -= dh; 244e1051a39Sopenharmony_ci tl -= dl; 245e1051a39Sopenharmony_ci } 246e1051a39Sopenharmony_ci t = (tl >> BN_BITS4); 247e1051a39Sopenharmony_ci tl = (tl << BN_BITS4) & BN_MASK2h; 248e1051a39Sopenharmony_ci th += t; 249e1051a39Sopenharmony_ci 250e1051a39Sopenharmony_ci if (l < tl) 251e1051a39Sopenharmony_ci th++; 252e1051a39Sopenharmony_ci l -= tl; 253e1051a39Sopenharmony_ci if (h < th) { 254e1051a39Sopenharmony_ci h += d; 255e1051a39Sopenharmony_ci q--; 256e1051a39Sopenharmony_ci } 257e1051a39Sopenharmony_ci h -= th; 258e1051a39Sopenharmony_ci 259e1051a39Sopenharmony_ci if (--count == 0) 260e1051a39Sopenharmony_ci break; 261e1051a39Sopenharmony_ci 262e1051a39Sopenharmony_ci ret = q << BN_BITS4; 263e1051a39Sopenharmony_ci h = ((h << BN_BITS4) | (l >> BN_BITS4)) & BN_MASK2; 264e1051a39Sopenharmony_ci l = (l & BN_MASK2l) << BN_BITS4; 265e1051a39Sopenharmony_ci } 266e1051a39Sopenharmony_ci ret |= q; 267e1051a39Sopenharmony_ci return ret; 268e1051a39Sopenharmony_ci} 269e1051a39Sopenharmony_ci#endif /* !defined(BN_LLONG) && defined(BN_DIV2W) */ 270e1051a39Sopenharmony_ci 271e1051a39Sopenharmony_ci#ifdef BN_LLONG 272e1051a39Sopenharmony_ciBN_ULONG bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, 273e1051a39Sopenharmony_ci int n) 274e1051a39Sopenharmony_ci{ 275e1051a39Sopenharmony_ci BN_ULLONG ll = 0; 276e1051a39Sopenharmony_ci 277e1051a39Sopenharmony_ci assert(n >= 0); 278e1051a39Sopenharmony_ci if (n <= 0) 279e1051a39Sopenharmony_ci return (BN_ULONG)0; 280e1051a39Sopenharmony_ci 281e1051a39Sopenharmony_ci# ifndef OPENSSL_SMALL_FOOTPRINT 282e1051a39Sopenharmony_ci while (n & ~3) { 283e1051a39Sopenharmony_ci ll += (BN_ULLONG) a[0] + b[0]; 284e1051a39Sopenharmony_ci r[0] = (BN_ULONG)ll & BN_MASK2; 285e1051a39Sopenharmony_ci ll >>= BN_BITS2; 286e1051a39Sopenharmony_ci ll += (BN_ULLONG) a[1] + b[1]; 287e1051a39Sopenharmony_ci r[1] = (BN_ULONG)ll & BN_MASK2; 288e1051a39Sopenharmony_ci ll >>= BN_BITS2; 289e1051a39Sopenharmony_ci ll += (BN_ULLONG) a[2] + b[2]; 290e1051a39Sopenharmony_ci r[2] = (BN_ULONG)ll & BN_MASK2; 291e1051a39Sopenharmony_ci ll >>= BN_BITS2; 292e1051a39Sopenharmony_ci ll += (BN_ULLONG) a[3] + b[3]; 293e1051a39Sopenharmony_ci r[3] = (BN_ULONG)ll & BN_MASK2; 294e1051a39Sopenharmony_ci ll >>= BN_BITS2; 295e1051a39Sopenharmony_ci a += 4; 296e1051a39Sopenharmony_ci b += 4; 297e1051a39Sopenharmony_ci r += 4; 298e1051a39Sopenharmony_ci n -= 4; 299e1051a39Sopenharmony_ci } 300e1051a39Sopenharmony_ci# endif 301e1051a39Sopenharmony_ci while (n) { 302e1051a39Sopenharmony_ci ll += (BN_ULLONG) a[0] + b[0]; 303e1051a39Sopenharmony_ci r[0] = (BN_ULONG)ll & BN_MASK2; 304e1051a39Sopenharmony_ci ll >>= BN_BITS2; 305e1051a39Sopenharmony_ci a++; 306e1051a39Sopenharmony_ci b++; 307e1051a39Sopenharmony_ci r++; 308e1051a39Sopenharmony_ci n--; 309e1051a39Sopenharmony_ci } 310e1051a39Sopenharmony_ci return (BN_ULONG)ll; 311e1051a39Sopenharmony_ci} 312e1051a39Sopenharmony_ci#else /* !BN_LLONG */ 313e1051a39Sopenharmony_ciBN_ULONG bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, 314e1051a39Sopenharmony_ci int n) 315e1051a39Sopenharmony_ci{ 316e1051a39Sopenharmony_ci BN_ULONG c, l, t; 317e1051a39Sopenharmony_ci 318e1051a39Sopenharmony_ci assert(n >= 0); 319e1051a39Sopenharmony_ci if (n <= 0) 320e1051a39Sopenharmony_ci return (BN_ULONG)0; 321e1051a39Sopenharmony_ci 322e1051a39Sopenharmony_ci c = 0; 323e1051a39Sopenharmony_ci# ifndef OPENSSL_SMALL_FOOTPRINT 324e1051a39Sopenharmony_ci while (n & ~3) { 325e1051a39Sopenharmony_ci t = a[0]; 326e1051a39Sopenharmony_ci t = (t + c) & BN_MASK2; 327e1051a39Sopenharmony_ci c = (t < c); 328e1051a39Sopenharmony_ci l = (t + b[0]) & BN_MASK2; 329e1051a39Sopenharmony_ci c += (l < t); 330e1051a39Sopenharmony_ci r[0] = l; 331e1051a39Sopenharmony_ci t = a[1]; 332e1051a39Sopenharmony_ci t = (t + c) & BN_MASK2; 333e1051a39Sopenharmony_ci c = (t < c); 334e1051a39Sopenharmony_ci l = (t + b[1]) & BN_MASK2; 335e1051a39Sopenharmony_ci c += (l < t); 336e1051a39Sopenharmony_ci r[1] = l; 337e1051a39Sopenharmony_ci t = a[2]; 338e1051a39Sopenharmony_ci t = (t + c) & BN_MASK2; 339e1051a39Sopenharmony_ci c = (t < c); 340e1051a39Sopenharmony_ci l = (t + b[2]) & BN_MASK2; 341e1051a39Sopenharmony_ci c += (l < t); 342e1051a39Sopenharmony_ci r[2] = l; 343e1051a39Sopenharmony_ci t = a[3]; 344e1051a39Sopenharmony_ci t = (t + c) & BN_MASK2; 345e1051a39Sopenharmony_ci c = (t < c); 346e1051a39Sopenharmony_ci l = (t + b[3]) & BN_MASK2; 347e1051a39Sopenharmony_ci c += (l < t); 348e1051a39Sopenharmony_ci r[3] = l; 349e1051a39Sopenharmony_ci a += 4; 350e1051a39Sopenharmony_ci b += 4; 351e1051a39Sopenharmony_ci r += 4; 352e1051a39Sopenharmony_ci n -= 4; 353e1051a39Sopenharmony_ci } 354e1051a39Sopenharmony_ci# endif 355e1051a39Sopenharmony_ci while (n) { 356e1051a39Sopenharmony_ci t = a[0]; 357e1051a39Sopenharmony_ci t = (t + c) & BN_MASK2; 358e1051a39Sopenharmony_ci c = (t < c); 359e1051a39Sopenharmony_ci l = (t + b[0]) & BN_MASK2; 360e1051a39Sopenharmony_ci c += (l < t); 361e1051a39Sopenharmony_ci r[0] = l; 362e1051a39Sopenharmony_ci a++; 363e1051a39Sopenharmony_ci b++; 364e1051a39Sopenharmony_ci r++; 365e1051a39Sopenharmony_ci n--; 366e1051a39Sopenharmony_ci } 367e1051a39Sopenharmony_ci return (BN_ULONG)c; 368e1051a39Sopenharmony_ci} 369e1051a39Sopenharmony_ci#endif /* !BN_LLONG */ 370e1051a39Sopenharmony_ci 371e1051a39Sopenharmony_ciBN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, 372e1051a39Sopenharmony_ci int n) 373e1051a39Sopenharmony_ci{ 374e1051a39Sopenharmony_ci BN_ULONG t1, t2; 375e1051a39Sopenharmony_ci int c = 0; 376e1051a39Sopenharmony_ci 377e1051a39Sopenharmony_ci assert(n >= 0); 378e1051a39Sopenharmony_ci if (n <= 0) 379e1051a39Sopenharmony_ci return (BN_ULONG)0; 380e1051a39Sopenharmony_ci 381e1051a39Sopenharmony_ci#ifndef OPENSSL_SMALL_FOOTPRINT 382e1051a39Sopenharmony_ci while (n & ~3) { 383e1051a39Sopenharmony_ci t1 = a[0]; 384e1051a39Sopenharmony_ci t2 = (t1 - c) & BN_MASK2; 385e1051a39Sopenharmony_ci c = (t2 > t1); 386e1051a39Sopenharmony_ci t1 = b[0]; 387e1051a39Sopenharmony_ci t1 = (t2 - t1) & BN_MASK2; 388e1051a39Sopenharmony_ci r[0] = t1; 389e1051a39Sopenharmony_ci c += (t1 > t2); 390e1051a39Sopenharmony_ci t1 = a[1]; 391e1051a39Sopenharmony_ci t2 = (t1 - c) & BN_MASK2; 392e1051a39Sopenharmony_ci c = (t2 > t1); 393e1051a39Sopenharmony_ci t1 = b[1]; 394e1051a39Sopenharmony_ci t1 = (t2 - t1) & BN_MASK2; 395e1051a39Sopenharmony_ci r[1] = t1; 396e1051a39Sopenharmony_ci c += (t1 > t2); 397e1051a39Sopenharmony_ci t1 = a[2]; 398e1051a39Sopenharmony_ci t2 = (t1 - c) & BN_MASK2; 399e1051a39Sopenharmony_ci c = (t2 > t1); 400e1051a39Sopenharmony_ci t1 = b[2]; 401e1051a39Sopenharmony_ci t1 = (t2 - t1) & BN_MASK2; 402e1051a39Sopenharmony_ci r[2] = t1; 403e1051a39Sopenharmony_ci c += (t1 > t2); 404e1051a39Sopenharmony_ci t1 = a[3]; 405e1051a39Sopenharmony_ci t2 = (t1 - c) & BN_MASK2; 406e1051a39Sopenharmony_ci c = (t2 > t1); 407e1051a39Sopenharmony_ci t1 = b[3]; 408e1051a39Sopenharmony_ci t1 = (t2 - t1) & BN_MASK2; 409e1051a39Sopenharmony_ci r[3] = t1; 410e1051a39Sopenharmony_ci c += (t1 > t2); 411e1051a39Sopenharmony_ci a += 4; 412e1051a39Sopenharmony_ci b += 4; 413e1051a39Sopenharmony_ci r += 4; 414e1051a39Sopenharmony_ci n -= 4; 415e1051a39Sopenharmony_ci } 416e1051a39Sopenharmony_ci#endif 417e1051a39Sopenharmony_ci while (n) { 418e1051a39Sopenharmony_ci t1 = a[0]; 419e1051a39Sopenharmony_ci t2 = (t1 - c) & BN_MASK2; 420e1051a39Sopenharmony_ci c = (t2 > t1); 421e1051a39Sopenharmony_ci t1 = b[0]; 422e1051a39Sopenharmony_ci t1 = (t2 - t1) & BN_MASK2; 423e1051a39Sopenharmony_ci r[0] = t1; 424e1051a39Sopenharmony_ci c += (t1 > t2); 425e1051a39Sopenharmony_ci a++; 426e1051a39Sopenharmony_ci b++; 427e1051a39Sopenharmony_ci r++; 428e1051a39Sopenharmony_ci n--; 429e1051a39Sopenharmony_ci } 430e1051a39Sopenharmony_ci return c; 431e1051a39Sopenharmony_ci} 432e1051a39Sopenharmony_ci 433e1051a39Sopenharmony_ci#if defined(BN_MUL_COMBA) && !defined(OPENSSL_SMALL_FOOTPRINT) 434e1051a39Sopenharmony_ci 435e1051a39Sopenharmony_ci# undef bn_mul_comba8 436e1051a39Sopenharmony_ci# undef bn_mul_comba4 437e1051a39Sopenharmony_ci# undef bn_sqr_comba8 438e1051a39Sopenharmony_ci# undef bn_sqr_comba4 439e1051a39Sopenharmony_ci 440e1051a39Sopenharmony_ci/* mul_add_c(a,b,c0,c1,c2) -- c+=a*b for three word number c=(c2,c1,c0) */ 441e1051a39Sopenharmony_ci/* mul_add_c2(a,b,c0,c1,c2) -- c+=2*a*b for three word number c=(c2,c1,c0) */ 442e1051a39Sopenharmony_ci/* sqr_add_c(a,i,c0,c1,c2) -- c+=a[i]^2 for three word number c=(c2,c1,c0) */ 443e1051a39Sopenharmony_ci/* 444e1051a39Sopenharmony_ci * sqr_add_c2(a,i,c0,c1,c2) -- c+=2*a[i]*a[j] for three word number 445e1051a39Sopenharmony_ci * c=(c2,c1,c0) 446e1051a39Sopenharmony_ci */ 447e1051a39Sopenharmony_ci 448e1051a39Sopenharmony_ci# ifdef BN_LLONG 449e1051a39Sopenharmony_ci/* 450e1051a39Sopenharmony_ci * Keep in mind that additions to multiplication result can not 451e1051a39Sopenharmony_ci * overflow, because its high half cannot be all-ones. 452e1051a39Sopenharmony_ci */ 453e1051a39Sopenharmony_ci# define mul_add_c(a,b,c0,c1,c2) do { \ 454e1051a39Sopenharmony_ci BN_ULONG hi; \ 455e1051a39Sopenharmony_ci BN_ULLONG t = (BN_ULLONG)(a)*(b); \ 456e1051a39Sopenharmony_ci t += c0; /* no carry */ \ 457e1051a39Sopenharmony_ci c0 = (BN_ULONG)Lw(t); \ 458e1051a39Sopenharmony_ci hi = (BN_ULONG)Hw(t); \ 459e1051a39Sopenharmony_ci c1 = (c1+hi)&BN_MASK2; c2 += (c1<hi); \ 460e1051a39Sopenharmony_ci } while(0) 461e1051a39Sopenharmony_ci 462e1051a39Sopenharmony_ci# define mul_add_c2(a,b,c0,c1,c2) do { \ 463e1051a39Sopenharmony_ci BN_ULONG hi; \ 464e1051a39Sopenharmony_ci BN_ULLONG t = (BN_ULLONG)(a)*(b); \ 465e1051a39Sopenharmony_ci BN_ULLONG tt = t+c0; /* no carry */ \ 466e1051a39Sopenharmony_ci c0 = (BN_ULONG)Lw(tt); \ 467e1051a39Sopenharmony_ci hi = (BN_ULONG)Hw(tt); \ 468e1051a39Sopenharmony_ci c1 = (c1+hi)&BN_MASK2; c2 += (c1<hi); \ 469e1051a39Sopenharmony_ci t += c0; /* no carry */ \ 470e1051a39Sopenharmony_ci c0 = (BN_ULONG)Lw(t); \ 471e1051a39Sopenharmony_ci hi = (BN_ULONG)Hw(t); \ 472e1051a39Sopenharmony_ci c1 = (c1+hi)&BN_MASK2; c2 += (c1<hi); \ 473e1051a39Sopenharmony_ci } while(0) 474e1051a39Sopenharmony_ci 475e1051a39Sopenharmony_ci# define sqr_add_c(a,i,c0,c1,c2) do { \ 476e1051a39Sopenharmony_ci BN_ULONG hi; \ 477e1051a39Sopenharmony_ci BN_ULLONG t = (BN_ULLONG)a[i]*a[i]; \ 478e1051a39Sopenharmony_ci t += c0; /* no carry */ \ 479e1051a39Sopenharmony_ci c0 = (BN_ULONG)Lw(t); \ 480e1051a39Sopenharmony_ci hi = (BN_ULONG)Hw(t); \ 481e1051a39Sopenharmony_ci c1 = (c1+hi)&BN_MASK2; c2 += (c1<hi); \ 482e1051a39Sopenharmony_ci } while(0) 483e1051a39Sopenharmony_ci 484e1051a39Sopenharmony_ci# define sqr_add_c2(a,i,j,c0,c1,c2) \ 485e1051a39Sopenharmony_ci mul_add_c2((a)[i],(a)[j],c0,c1,c2) 486e1051a39Sopenharmony_ci 487e1051a39Sopenharmony_ci# elif defined(BN_UMULT_LOHI) 488e1051a39Sopenharmony_ci/* 489e1051a39Sopenharmony_ci * Keep in mind that additions to hi can not overflow, because 490e1051a39Sopenharmony_ci * the high word of a multiplication result cannot be all-ones. 491e1051a39Sopenharmony_ci */ 492e1051a39Sopenharmony_ci# define mul_add_c(a,b,c0,c1,c2) do { \ 493e1051a39Sopenharmony_ci BN_ULONG ta = (a), tb = (b); \ 494e1051a39Sopenharmony_ci BN_ULONG lo, hi; \ 495e1051a39Sopenharmony_ci BN_UMULT_LOHI(lo,hi,ta,tb); \ 496e1051a39Sopenharmony_ci c0 += lo; hi += (c0<lo); \ 497e1051a39Sopenharmony_ci c1 += hi; c2 += (c1<hi); \ 498e1051a39Sopenharmony_ci } while(0) 499e1051a39Sopenharmony_ci 500e1051a39Sopenharmony_ci# define mul_add_c2(a,b,c0,c1,c2) do { \ 501e1051a39Sopenharmony_ci BN_ULONG ta = (a), tb = (b); \ 502e1051a39Sopenharmony_ci BN_ULONG lo, hi, tt; \ 503e1051a39Sopenharmony_ci BN_UMULT_LOHI(lo,hi,ta,tb); \ 504e1051a39Sopenharmony_ci c0 += lo; tt = hi + (c0<lo); \ 505e1051a39Sopenharmony_ci c1 += tt; c2 += (c1<tt); \ 506e1051a39Sopenharmony_ci c0 += lo; hi += (c0<lo); \ 507e1051a39Sopenharmony_ci c1 += hi; c2 += (c1<hi); \ 508e1051a39Sopenharmony_ci } while(0) 509e1051a39Sopenharmony_ci 510e1051a39Sopenharmony_ci# define sqr_add_c(a,i,c0,c1,c2) do { \ 511e1051a39Sopenharmony_ci BN_ULONG ta = (a)[i]; \ 512e1051a39Sopenharmony_ci BN_ULONG lo, hi; \ 513e1051a39Sopenharmony_ci BN_UMULT_LOHI(lo,hi,ta,ta); \ 514e1051a39Sopenharmony_ci c0 += lo; hi += (c0<lo); \ 515e1051a39Sopenharmony_ci c1 += hi; c2 += (c1<hi); \ 516e1051a39Sopenharmony_ci } while(0) 517e1051a39Sopenharmony_ci 518e1051a39Sopenharmony_ci# define sqr_add_c2(a,i,j,c0,c1,c2) \ 519e1051a39Sopenharmony_ci mul_add_c2((a)[i],(a)[j],c0,c1,c2) 520e1051a39Sopenharmony_ci 521e1051a39Sopenharmony_ci# elif defined(BN_UMULT_HIGH) 522e1051a39Sopenharmony_ci/* 523e1051a39Sopenharmony_ci * Keep in mind that additions to hi can not overflow, because 524e1051a39Sopenharmony_ci * the high word of a multiplication result cannot be all-ones. 525e1051a39Sopenharmony_ci */ 526e1051a39Sopenharmony_ci# define mul_add_c(a,b,c0,c1,c2) do { \ 527e1051a39Sopenharmony_ci BN_ULONG ta = (a), tb = (b); \ 528e1051a39Sopenharmony_ci BN_ULONG lo = ta * tb; \ 529e1051a39Sopenharmony_ci BN_ULONG hi = BN_UMULT_HIGH(ta,tb); \ 530e1051a39Sopenharmony_ci c0 += lo; hi += (c0<lo); \ 531e1051a39Sopenharmony_ci c1 += hi; c2 += (c1<hi); \ 532e1051a39Sopenharmony_ci } while(0) 533e1051a39Sopenharmony_ci 534e1051a39Sopenharmony_ci# define mul_add_c2(a,b,c0,c1,c2) do { \ 535e1051a39Sopenharmony_ci BN_ULONG ta = (a), tb = (b), tt; \ 536e1051a39Sopenharmony_ci BN_ULONG lo = ta * tb; \ 537e1051a39Sopenharmony_ci BN_ULONG hi = BN_UMULT_HIGH(ta,tb); \ 538e1051a39Sopenharmony_ci c0 += lo; tt = hi + (c0<lo); \ 539e1051a39Sopenharmony_ci c1 += tt; c2 += (c1<tt); \ 540e1051a39Sopenharmony_ci c0 += lo; hi += (c0<lo); \ 541e1051a39Sopenharmony_ci c1 += hi; c2 += (c1<hi); \ 542e1051a39Sopenharmony_ci } while(0) 543e1051a39Sopenharmony_ci 544e1051a39Sopenharmony_ci# define sqr_add_c(a,i,c0,c1,c2) do { \ 545e1051a39Sopenharmony_ci BN_ULONG ta = (a)[i]; \ 546e1051a39Sopenharmony_ci BN_ULONG lo = ta * ta; \ 547e1051a39Sopenharmony_ci BN_ULONG hi = BN_UMULT_HIGH(ta,ta); \ 548e1051a39Sopenharmony_ci c0 += lo; hi += (c0<lo); \ 549e1051a39Sopenharmony_ci c1 += hi; c2 += (c1<hi); \ 550e1051a39Sopenharmony_ci } while(0) 551e1051a39Sopenharmony_ci 552e1051a39Sopenharmony_ci# define sqr_add_c2(a,i,j,c0,c1,c2) \ 553e1051a39Sopenharmony_ci mul_add_c2((a)[i],(a)[j],c0,c1,c2) 554e1051a39Sopenharmony_ci 555e1051a39Sopenharmony_ci# else /* !BN_LLONG */ 556e1051a39Sopenharmony_ci/* 557e1051a39Sopenharmony_ci * Keep in mind that additions to hi can not overflow, because 558e1051a39Sopenharmony_ci * the high word of a multiplication result cannot be all-ones. 559e1051a39Sopenharmony_ci */ 560e1051a39Sopenharmony_ci# define mul_add_c(a,b,c0,c1,c2) do { \ 561e1051a39Sopenharmony_ci BN_ULONG lo = LBITS(a), hi = HBITS(a); \ 562e1051a39Sopenharmony_ci BN_ULONG bl = LBITS(b), bh = HBITS(b); \ 563e1051a39Sopenharmony_ci mul64(lo,hi,bl,bh); \ 564e1051a39Sopenharmony_ci c0 = (c0+lo)&BN_MASK2; hi += (c0<lo); \ 565e1051a39Sopenharmony_ci c1 = (c1+hi)&BN_MASK2; c2 += (c1<hi); \ 566e1051a39Sopenharmony_ci } while(0) 567e1051a39Sopenharmony_ci 568e1051a39Sopenharmony_ci# define mul_add_c2(a,b,c0,c1,c2) do { \ 569e1051a39Sopenharmony_ci BN_ULONG tt; \ 570e1051a39Sopenharmony_ci BN_ULONG lo = LBITS(a), hi = HBITS(a); \ 571e1051a39Sopenharmony_ci BN_ULONG bl = LBITS(b), bh = HBITS(b); \ 572e1051a39Sopenharmony_ci mul64(lo,hi,bl,bh); \ 573e1051a39Sopenharmony_ci tt = hi; \ 574e1051a39Sopenharmony_ci c0 = (c0+lo)&BN_MASK2; tt += (c0<lo); \ 575e1051a39Sopenharmony_ci c1 = (c1+tt)&BN_MASK2; c2 += (c1<tt); \ 576e1051a39Sopenharmony_ci c0 = (c0+lo)&BN_MASK2; hi += (c0<lo); \ 577e1051a39Sopenharmony_ci c1 = (c1+hi)&BN_MASK2; c2 += (c1<hi); \ 578e1051a39Sopenharmony_ci } while(0) 579e1051a39Sopenharmony_ci 580e1051a39Sopenharmony_ci# define sqr_add_c(a,i,c0,c1,c2) do { \ 581e1051a39Sopenharmony_ci BN_ULONG lo, hi; \ 582e1051a39Sopenharmony_ci sqr64(lo,hi,(a)[i]); \ 583e1051a39Sopenharmony_ci c0 = (c0+lo)&BN_MASK2; hi += (c0<lo); \ 584e1051a39Sopenharmony_ci c1 = (c1+hi)&BN_MASK2; c2 += (c1<hi); \ 585e1051a39Sopenharmony_ci } while(0) 586e1051a39Sopenharmony_ci 587e1051a39Sopenharmony_ci# define sqr_add_c2(a,i,j,c0,c1,c2) \ 588e1051a39Sopenharmony_ci mul_add_c2((a)[i],(a)[j],c0,c1,c2) 589e1051a39Sopenharmony_ci# endif /* !BN_LLONG */ 590e1051a39Sopenharmony_ci 591e1051a39Sopenharmony_civoid bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) 592e1051a39Sopenharmony_ci{ 593e1051a39Sopenharmony_ci BN_ULONG c1, c2, c3; 594e1051a39Sopenharmony_ci 595e1051a39Sopenharmony_ci c1 = 0; 596e1051a39Sopenharmony_ci c2 = 0; 597e1051a39Sopenharmony_ci c3 = 0; 598e1051a39Sopenharmony_ci mul_add_c(a[0], b[0], c1, c2, c3); 599e1051a39Sopenharmony_ci r[0] = c1; 600e1051a39Sopenharmony_ci c1 = 0; 601e1051a39Sopenharmony_ci mul_add_c(a[0], b[1], c2, c3, c1); 602e1051a39Sopenharmony_ci mul_add_c(a[1], b[0], c2, c3, c1); 603e1051a39Sopenharmony_ci r[1] = c2; 604e1051a39Sopenharmony_ci c2 = 0; 605e1051a39Sopenharmony_ci mul_add_c(a[2], b[0], c3, c1, c2); 606e1051a39Sopenharmony_ci mul_add_c(a[1], b[1], c3, c1, c2); 607e1051a39Sopenharmony_ci mul_add_c(a[0], b[2], c3, c1, c2); 608e1051a39Sopenharmony_ci r[2] = c3; 609e1051a39Sopenharmony_ci c3 = 0; 610e1051a39Sopenharmony_ci mul_add_c(a[0], b[3], c1, c2, c3); 611e1051a39Sopenharmony_ci mul_add_c(a[1], b[2], c1, c2, c3); 612e1051a39Sopenharmony_ci mul_add_c(a[2], b[1], c1, c2, c3); 613e1051a39Sopenharmony_ci mul_add_c(a[3], b[0], c1, c2, c3); 614e1051a39Sopenharmony_ci r[3] = c1; 615e1051a39Sopenharmony_ci c1 = 0; 616e1051a39Sopenharmony_ci mul_add_c(a[4], b[0], c2, c3, c1); 617e1051a39Sopenharmony_ci mul_add_c(a[3], b[1], c2, c3, c1); 618e1051a39Sopenharmony_ci mul_add_c(a[2], b[2], c2, c3, c1); 619e1051a39Sopenharmony_ci mul_add_c(a[1], b[3], c2, c3, c1); 620e1051a39Sopenharmony_ci mul_add_c(a[0], b[4], c2, c3, c1); 621e1051a39Sopenharmony_ci r[4] = c2; 622e1051a39Sopenharmony_ci c2 = 0; 623e1051a39Sopenharmony_ci mul_add_c(a[0], b[5], c3, c1, c2); 624e1051a39Sopenharmony_ci mul_add_c(a[1], b[4], c3, c1, c2); 625e1051a39Sopenharmony_ci mul_add_c(a[2], b[3], c3, c1, c2); 626e1051a39Sopenharmony_ci mul_add_c(a[3], b[2], c3, c1, c2); 627e1051a39Sopenharmony_ci mul_add_c(a[4], b[1], c3, c1, c2); 628e1051a39Sopenharmony_ci mul_add_c(a[5], b[0], c3, c1, c2); 629e1051a39Sopenharmony_ci r[5] = c3; 630e1051a39Sopenharmony_ci c3 = 0; 631e1051a39Sopenharmony_ci mul_add_c(a[6], b[0], c1, c2, c3); 632e1051a39Sopenharmony_ci mul_add_c(a[5], b[1], c1, c2, c3); 633e1051a39Sopenharmony_ci mul_add_c(a[4], b[2], c1, c2, c3); 634e1051a39Sopenharmony_ci mul_add_c(a[3], b[3], c1, c2, c3); 635e1051a39Sopenharmony_ci mul_add_c(a[2], b[4], c1, c2, c3); 636e1051a39Sopenharmony_ci mul_add_c(a[1], b[5], c1, c2, c3); 637e1051a39Sopenharmony_ci mul_add_c(a[0], b[6], c1, c2, c3); 638e1051a39Sopenharmony_ci r[6] = c1; 639e1051a39Sopenharmony_ci c1 = 0; 640e1051a39Sopenharmony_ci mul_add_c(a[0], b[7], c2, c3, c1); 641e1051a39Sopenharmony_ci mul_add_c(a[1], b[6], c2, c3, c1); 642e1051a39Sopenharmony_ci mul_add_c(a[2], b[5], c2, c3, c1); 643e1051a39Sopenharmony_ci mul_add_c(a[3], b[4], c2, c3, c1); 644e1051a39Sopenharmony_ci mul_add_c(a[4], b[3], c2, c3, c1); 645e1051a39Sopenharmony_ci mul_add_c(a[5], b[2], c2, c3, c1); 646e1051a39Sopenharmony_ci mul_add_c(a[6], b[1], c2, c3, c1); 647e1051a39Sopenharmony_ci mul_add_c(a[7], b[0], c2, c3, c1); 648e1051a39Sopenharmony_ci r[7] = c2; 649e1051a39Sopenharmony_ci c2 = 0; 650e1051a39Sopenharmony_ci mul_add_c(a[7], b[1], c3, c1, c2); 651e1051a39Sopenharmony_ci mul_add_c(a[6], b[2], c3, c1, c2); 652e1051a39Sopenharmony_ci mul_add_c(a[5], b[3], c3, c1, c2); 653e1051a39Sopenharmony_ci mul_add_c(a[4], b[4], c3, c1, c2); 654e1051a39Sopenharmony_ci mul_add_c(a[3], b[5], c3, c1, c2); 655e1051a39Sopenharmony_ci mul_add_c(a[2], b[6], c3, c1, c2); 656e1051a39Sopenharmony_ci mul_add_c(a[1], b[7], c3, c1, c2); 657e1051a39Sopenharmony_ci r[8] = c3; 658e1051a39Sopenharmony_ci c3 = 0; 659e1051a39Sopenharmony_ci mul_add_c(a[2], b[7], c1, c2, c3); 660e1051a39Sopenharmony_ci mul_add_c(a[3], b[6], c1, c2, c3); 661e1051a39Sopenharmony_ci mul_add_c(a[4], b[5], c1, c2, c3); 662e1051a39Sopenharmony_ci mul_add_c(a[5], b[4], c1, c2, c3); 663e1051a39Sopenharmony_ci mul_add_c(a[6], b[3], c1, c2, c3); 664e1051a39Sopenharmony_ci mul_add_c(a[7], b[2], c1, c2, c3); 665e1051a39Sopenharmony_ci r[9] = c1; 666e1051a39Sopenharmony_ci c1 = 0; 667e1051a39Sopenharmony_ci mul_add_c(a[7], b[3], c2, c3, c1); 668e1051a39Sopenharmony_ci mul_add_c(a[6], b[4], c2, c3, c1); 669e1051a39Sopenharmony_ci mul_add_c(a[5], b[5], c2, c3, c1); 670e1051a39Sopenharmony_ci mul_add_c(a[4], b[6], c2, c3, c1); 671e1051a39Sopenharmony_ci mul_add_c(a[3], b[7], c2, c3, c1); 672e1051a39Sopenharmony_ci r[10] = c2; 673e1051a39Sopenharmony_ci c2 = 0; 674e1051a39Sopenharmony_ci mul_add_c(a[4], b[7], c3, c1, c2); 675e1051a39Sopenharmony_ci mul_add_c(a[5], b[6], c3, c1, c2); 676e1051a39Sopenharmony_ci mul_add_c(a[6], b[5], c3, c1, c2); 677e1051a39Sopenharmony_ci mul_add_c(a[7], b[4], c3, c1, c2); 678e1051a39Sopenharmony_ci r[11] = c3; 679e1051a39Sopenharmony_ci c3 = 0; 680e1051a39Sopenharmony_ci mul_add_c(a[7], b[5], c1, c2, c3); 681e1051a39Sopenharmony_ci mul_add_c(a[6], b[6], c1, c2, c3); 682e1051a39Sopenharmony_ci mul_add_c(a[5], b[7], c1, c2, c3); 683e1051a39Sopenharmony_ci r[12] = c1; 684e1051a39Sopenharmony_ci c1 = 0; 685e1051a39Sopenharmony_ci mul_add_c(a[6], b[7], c2, c3, c1); 686e1051a39Sopenharmony_ci mul_add_c(a[7], b[6], c2, c3, c1); 687e1051a39Sopenharmony_ci r[13] = c2; 688e1051a39Sopenharmony_ci c2 = 0; 689e1051a39Sopenharmony_ci mul_add_c(a[7], b[7], c3, c1, c2); 690e1051a39Sopenharmony_ci r[14] = c3; 691e1051a39Sopenharmony_ci r[15] = c1; 692e1051a39Sopenharmony_ci} 693e1051a39Sopenharmony_ci 694e1051a39Sopenharmony_civoid bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) 695e1051a39Sopenharmony_ci{ 696e1051a39Sopenharmony_ci BN_ULONG c1, c2, c3; 697e1051a39Sopenharmony_ci 698e1051a39Sopenharmony_ci c1 = 0; 699e1051a39Sopenharmony_ci c2 = 0; 700e1051a39Sopenharmony_ci c3 = 0; 701e1051a39Sopenharmony_ci mul_add_c(a[0], b[0], c1, c2, c3); 702e1051a39Sopenharmony_ci r[0] = c1; 703e1051a39Sopenharmony_ci c1 = 0; 704e1051a39Sopenharmony_ci mul_add_c(a[0], b[1], c2, c3, c1); 705e1051a39Sopenharmony_ci mul_add_c(a[1], b[0], c2, c3, c1); 706e1051a39Sopenharmony_ci r[1] = c2; 707e1051a39Sopenharmony_ci c2 = 0; 708e1051a39Sopenharmony_ci mul_add_c(a[2], b[0], c3, c1, c2); 709e1051a39Sopenharmony_ci mul_add_c(a[1], b[1], c3, c1, c2); 710e1051a39Sopenharmony_ci mul_add_c(a[0], b[2], c3, c1, c2); 711e1051a39Sopenharmony_ci r[2] = c3; 712e1051a39Sopenharmony_ci c3 = 0; 713e1051a39Sopenharmony_ci mul_add_c(a[0], b[3], c1, c2, c3); 714e1051a39Sopenharmony_ci mul_add_c(a[1], b[2], c1, c2, c3); 715e1051a39Sopenharmony_ci mul_add_c(a[2], b[1], c1, c2, c3); 716e1051a39Sopenharmony_ci mul_add_c(a[3], b[0], c1, c2, c3); 717e1051a39Sopenharmony_ci r[3] = c1; 718e1051a39Sopenharmony_ci c1 = 0; 719e1051a39Sopenharmony_ci mul_add_c(a[3], b[1], c2, c3, c1); 720e1051a39Sopenharmony_ci mul_add_c(a[2], b[2], c2, c3, c1); 721e1051a39Sopenharmony_ci mul_add_c(a[1], b[3], c2, c3, c1); 722e1051a39Sopenharmony_ci r[4] = c2; 723e1051a39Sopenharmony_ci c2 = 0; 724e1051a39Sopenharmony_ci mul_add_c(a[2], b[3], c3, c1, c2); 725e1051a39Sopenharmony_ci mul_add_c(a[3], b[2], c3, c1, c2); 726e1051a39Sopenharmony_ci r[5] = c3; 727e1051a39Sopenharmony_ci c3 = 0; 728e1051a39Sopenharmony_ci mul_add_c(a[3], b[3], c1, c2, c3); 729e1051a39Sopenharmony_ci r[6] = c1; 730e1051a39Sopenharmony_ci r[7] = c2; 731e1051a39Sopenharmony_ci} 732e1051a39Sopenharmony_ci 733e1051a39Sopenharmony_civoid bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a) 734e1051a39Sopenharmony_ci{ 735e1051a39Sopenharmony_ci BN_ULONG c1, c2, c3; 736e1051a39Sopenharmony_ci 737e1051a39Sopenharmony_ci c1 = 0; 738e1051a39Sopenharmony_ci c2 = 0; 739e1051a39Sopenharmony_ci c3 = 0; 740e1051a39Sopenharmony_ci sqr_add_c(a, 0, c1, c2, c3); 741e1051a39Sopenharmony_ci r[0] = c1; 742e1051a39Sopenharmony_ci c1 = 0; 743e1051a39Sopenharmony_ci sqr_add_c2(a, 1, 0, c2, c3, c1); 744e1051a39Sopenharmony_ci r[1] = c2; 745e1051a39Sopenharmony_ci c2 = 0; 746e1051a39Sopenharmony_ci sqr_add_c(a, 1, c3, c1, c2); 747e1051a39Sopenharmony_ci sqr_add_c2(a, 2, 0, c3, c1, c2); 748e1051a39Sopenharmony_ci r[2] = c3; 749e1051a39Sopenharmony_ci c3 = 0; 750e1051a39Sopenharmony_ci sqr_add_c2(a, 3, 0, c1, c2, c3); 751e1051a39Sopenharmony_ci sqr_add_c2(a, 2, 1, c1, c2, c3); 752e1051a39Sopenharmony_ci r[3] = c1; 753e1051a39Sopenharmony_ci c1 = 0; 754e1051a39Sopenharmony_ci sqr_add_c(a, 2, c2, c3, c1); 755e1051a39Sopenharmony_ci sqr_add_c2(a, 3, 1, c2, c3, c1); 756e1051a39Sopenharmony_ci sqr_add_c2(a, 4, 0, c2, c3, c1); 757e1051a39Sopenharmony_ci r[4] = c2; 758e1051a39Sopenharmony_ci c2 = 0; 759e1051a39Sopenharmony_ci sqr_add_c2(a, 5, 0, c3, c1, c2); 760e1051a39Sopenharmony_ci sqr_add_c2(a, 4, 1, c3, c1, c2); 761e1051a39Sopenharmony_ci sqr_add_c2(a, 3, 2, c3, c1, c2); 762e1051a39Sopenharmony_ci r[5] = c3; 763e1051a39Sopenharmony_ci c3 = 0; 764e1051a39Sopenharmony_ci sqr_add_c(a, 3, c1, c2, c3); 765e1051a39Sopenharmony_ci sqr_add_c2(a, 4, 2, c1, c2, c3); 766e1051a39Sopenharmony_ci sqr_add_c2(a, 5, 1, c1, c2, c3); 767e1051a39Sopenharmony_ci sqr_add_c2(a, 6, 0, c1, c2, c3); 768e1051a39Sopenharmony_ci r[6] = c1; 769e1051a39Sopenharmony_ci c1 = 0; 770e1051a39Sopenharmony_ci sqr_add_c2(a, 7, 0, c2, c3, c1); 771e1051a39Sopenharmony_ci sqr_add_c2(a, 6, 1, c2, c3, c1); 772e1051a39Sopenharmony_ci sqr_add_c2(a, 5, 2, c2, c3, c1); 773e1051a39Sopenharmony_ci sqr_add_c2(a, 4, 3, c2, c3, c1); 774e1051a39Sopenharmony_ci r[7] = c2; 775e1051a39Sopenharmony_ci c2 = 0; 776e1051a39Sopenharmony_ci sqr_add_c(a, 4, c3, c1, c2); 777e1051a39Sopenharmony_ci sqr_add_c2(a, 5, 3, c3, c1, c2); 778e1051a39Sopenharmony_ci sqr_add_c2(a, 6, 2, c3, c1, c2); 779e1051a39Sopenharmony_ci sqr_add_c2(a, 7, 1, c3, c1, c2); 780e1051a39Sopenharmony_ci r[8] = c3; 781e1051a39Sopenharmony_ci c3 = 0; 782e1051a39Sopenharmony_ci sqr_add_c2(a, 7, 2, c1, c2, c3); 783e1051a39Sopenharmony_ci sqr_add_c2(a, 6, 3, c1, c2, c3); 784e1051a39Sopenharmony_ci sqr_add_c2(a, 5, 4, c1, c2, c3); 785e1051a39Sopenharmony_ci r[9] = c1; 786e1051a39Sopenharmony_ci c1 = 0; 787e1051a39Sopenharmony_ci sqr_add_c(a, 5, c2, c3, c1); 788e1051a39Sopenharmony_ci sqr_add_c2(a, 6, 4, c2, c3, c1); 789e1051a39Sopenharmony_ci sqr_add_c2(a, 7, 3, c2, c3, c1); 790e1051a39Sopenharmony_ci r[10] = c2; 791e1051a39Sopenharmony_ci c2 = 0; 792e1051a39Sopenharmony_ci sqr_add_c2(a, 7, 4, c3, c1, c2); 793e1051a39Sopenharmony_ci sqr_add_c2(a, 6, 5, c3, c1, c2); 794e1051a39Sopenharmony_ci r[11] = c3; 795e1051a39Sopenharmony_ci c3 = 0; 796e1051a39Sopenharmony_ci sqr_add_c(a, 6, c1, c2, c3); 797e1051a39Sopenharmony_ci sqr_add_c2(a, 7, 5, c1, c2, c3); 798e1051a39Sopenharmony_ci r[12] = c1; 799e1051a39Sopenharmony_ci c1 = 0; 800e1051a39Sopenharmony_ci sqr_add_c2(a, 7, 6, c2, c3, c1); 801e1051a39Sopenharmony_ci r[13] = c2; 802e1051a39Sopenharmony_ci c2 = 0; 803e1051a39Sopenharmony_ci sqr_add_c(a, 7, c3, c1, c2); 804e1051a39Sopenharmony_ci r[14] = c3; 805e1051a39Sopenharmony_ci r[15] = c1; 806e1051a39Sopenharmony_ci} 807e1051a39Sopenharmony_ci 808e1051a39Sopenharmony_civoid bn_sqr_comba4(BN_ULONG *r, const BN_ULONG *a) 809e1051a39Sopenharmony_ci{ 810e1051a39Sopenharmony_ci BN_ULONG c1, c2, c3; 811e1051a39Sopenharmony_ci 812e1051a39Sopenharmony_ci c1 = 0; 813e1051a39Sopenharmony_ci c2 = 0; 814e1051a39Sopenharmony_ci c3 = 0; 815e1051a39Sopenharmony_ci sqr_add_c(a, 0, c1, c2, c3); 816e1051a39Sopenharmony_ci r[0] = c1; 817e1051a39Sopenharmony_ci c1 = 0; 818e1051a39Sopenharmony_ci sqr_add_c2(a, 1, 0, c2, c3, c1); 819e1051a39Sopenharmony_ci r[1] = c2; 820e1051a39Sopenharmony_ci c2 = 0; 821e1051a39Sopenharmony_ci sqr_add_c(a, 1, c3, c1, c2); 822e1051a39Sopenharmony_ci sqr_add_c2(a, 2, 0, c3, c1, c2); 823e1051a39Sopenharmony_ci r[2] = c3; 824e1051a39Sopenharmony_ci c3 = 0; 825e1051a39Sopenharmony_ci sqr_add_c2(a, 3, 0, c1, c2, c3); 826e1051a39Sopenharmony_ci sqr_add_c2(a, 2, 1, c1, c2, c3); 827e1051a39Sopenharmony_ci r[3] = c1; 828e1051a39Sopenharmony_ci c1 = 0; 829e1051a39Sopenharmony_ci sqr_add_c(a, 2, c2, c3, c1); 830e1051a39Sopenharmony_ci sqr_add_c2(a, 3, 1, c2, c3, c1); 831e1051a39Sopenharmony_ci r[4] = c2; 832e1051a39Sopenharmony_ci c2 = 0; 833e1051a39Sopenharmony_ci sqr_add_c2(a, 3, 2, c3, c1, c2); 834e1051a39Sopenharmony_ci r[5] = c3; 835e1051a39Sopenharmony_ci c3 = 0; 836e1051a39Sopenharmony_ci sqr_add_c(a, 3, c1, c2, c3); 837e1051a39Sopenharmony_ci r[6] = c1; 838e1051a39Sopenharmony_ci r[7] = c2; 839e1051a39Sopenharmony_ci} 840e1051a39Sopenharmony_ci 841e1051a39Sopenharmony_ci# ifdef OPENSSL_NO_ASM 842e1051a39Sopenharmony_ci# ifdef OPENSSL_BN_ASM_MONT 843e1051a39Sopenharmony_ci# include <alloca.h> 844e1051a39Sopenharmony_ci/* 845e1051a39Sopenharmony_ci * This is essentially reference implementation, which may or may not 846e1051a39Sopenharmony_ci * result in performance improvement. E.g. on IA-32 this routine was 847e1051a39Sopenharmony_ci * observed to give 40% faster rsa1024 private key operations and 10% 848e1051a39Sopenharmony_ci * faster rsa4096 ones, while on AMD64 it improves rsa1024 sign only 849e1051a39Sopenharmony_ci * by 10% and *worsens* rsa4096 sign by 15%. Once again, it's a 850e1051a39Sopenharmony_ci * reference implementation, one to be used as starting point for 851e1051a39Sopenharmony_ci * platform-specific assembler. Mentioned numbers apply to compiler 852e1051a39Sopenharmony_ci * generated code compiled with and without -DOPENSSL_BN_ASM_MONT and 853e1051a39Sopenharmony_ci * can vary not only from platform to platform, but even for compiler 854e1051a39Sopenharmony_ci * versions. Assembler vs. assembler improvement coefficients can 855e1051a39Sopenharmony_ci * [and are known to] differ and are to be documented elsewhere. 856e1051a39Sopenharmony_ci */ 857e1051a39Sopenharmony_ciint bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, 858e1051a39Sopenharmony_ci const BN_ULONG *np, const BN_ULONG *n0p, int num) 859e1051a39Sopenharmony_ci{ 860e1051a39Sopenharmony_ci BN_ULONG c0, c1, ml, *tp, n0; 861e1051a39Sopenharmony_ci# ifdef mul64 862e1051a39Sopenharmony_ci BN_ULONG mh; 863e1051a39Sopenharmony_ci# endif 864e1051a39Sopenharmony_ci volatile BN_ULONG *vp; 865e1051a39Sopenharmony_ci int i = 0, j; 866e1051a39Sopenharmony_ci 867e1051a39Sopenharmony_ci# if 0 /* template for platform-specific 868e1051a39Sopenharmony_ci * implementation */ 869e1051a39Sopenharmony_ci if (ap == bp) 870e1051a39Sopenharmony_ci return bn_sqr_mont(rp, ap, np, n0p, num); 871e1051a39Sopenharmony_ci# endif 872e1051a39Sopenharmony_ci vp = tp = alloca((num + 2) * sizeof(BN_ULONG)); 873e1051a39Sopenharmony_ci 874e1051a39Sopenharmony_ci n0 = *n0p; 875e1051a39Sopenharmony_ci 876e1051a39Sopenharmony_ci c0 = 0; 877e1051a39Sopenharmony_ci ml = bp[0]; 878e1051a39Sopenharmony_ci# ifdef mul64 879e1051a39Sopenharmony_ci mh = HBITS(ml); 880e1051a39Sopenharmony_ci ml = LBITS(ml); 881e1051a39Sopenharmony_ci for (j = 0; j < num; ++j) 882e1051a39Sopenharmony_ci mul(tp[j], ap[j], ml, mh, c0); 883e1051a39Sopenharmony_ci# else 884e1051a39Sopenharmony_ci for (j = 0; j < num; ++j) 885e1051a39Sopenharmony_ci mul(tp[j], ap[j], ml, c0); 886e1051a39Sopenharmony_ci# endif 887e1051a39Sopenharmony_ci 888e1051a39Sopenharmony_ci tp[num] = c0; 889e1051a39Sopenharmony_ci tp[num + 1] = 0; 890e1051a39Sopenharmony_ci goto enter; 891e1051a39Sopenharmony_ci 892e1051a39Sopenharmony_ci for (i = 0; i < num; i++) { 893e1051a39Sopenharmony_ci c0 = 0; 894e1051a39Sopenharmony_ci ml = bp[i]; 895e1051a39Sopenharmony_ci# ifdef mul64 896e1051a39Sopenharmony_ci mh = HBITS(ml); 897e1051a39Sopenharmony_ci ml = LBITS(ml); 898e1051a39Sopenharmony_ci for (j = 0; j < num; ++j) 899e1051a39Sopenharmony_ci mul_add(tp[j], ap[j], ml, mh, c0); 900e1051a39Sopenharmony_ci# else 901e1051a39Sopenharmony_ci for (j = 0; j < num; ++j) 902e1051a39Sopenharmony_ci mul_add(tp[j], ap[j], ml, c0); 903e1051a39Sopenharmony_ci# endif 904e1051a39Sopenharmony_ci c1 = (tp[num] + c0) & BN_MASK2; 905e1051a39Sopenharmony_ci tp[num] = c1; 906e1051a39Sopenharmony_ci tp[num + 1] = (c1 < c0 ? 1 : 0); 907e1051a39Sopenharmony_ci enter: 908e1051a39Sopenharmony_ci c1 = tp[0]; 909e1051a39Sopenharmony_ci ml = (c1 * n0) & BN_MASK2; 910e1051a39Sopenharmony_ci c0 = 0; 911e1051a39Sopenharmony_ci# ifdef mul64 912e1051a39Sopenharmony_ci mh = HBITS(ml); 913e1051a39Sopenharmony_ci ml = LBITS(ml); 914e1051a39Sopenharmony_ci mul_add(c1, np[0], ml, mh, c0); 915e1051a39Sopenharmony_ci# else 916e1051a39Sopenharmony_ci mul_add(c1, ml, np[0], c0); 917e1051a39Sopenharmony_ci# endif 918e1051a39Sopenharmony_ci for (j = 1; j < num; j++) { 919e1051a39Sopenharmony_ci c1 = tp[j]; 920e1051a39Sopenharmony_ci# ifdef mul64 921e1051a39Sopenharmony_ci mul_add(c1, np[j], ml, mh, c0); 922e1051a39Sopenharmony_ci# else 923e1051a39Sopenharmony_ci mul_add(c1, ml, np[j], c0); 924e1051a39Sopenharmony_ci# endif 925e1051a39Sopenharmony_ci tp[j - 1] = c1 & BN_MASK2; 926e1051a39Sopenharmony_ci } 927e1051a39Sopenharmony_ci c1 = (tp[num] + c0) & BN_MASK2; 928e1051a39Sopenharmony_ci tp[num - 1] = c1; 929e1051a39Sopenharmony_ci tp[num] = tp[num + 1] + (c1 < c0 ? 1 : 0); 930e1051a39Sopenharmony_ci } 931e1051a39Sopenharmony_ci 932e1051a39Sopenharmony_ci if (tp[num] != 0 || tp[num - 1] >= np[num - 1]) { 933e1051a39Sopenharmony_ci c0 = bn_sub_words(rp, tp, np, num); 934e1051a39Sopenharmony_ci if (tp[num] != 0 || c0 == 0) { 935e1051a39Sopenharmony_ci for (i = 0; i < num + 2; i++) 936e1051a39Sopenharmony_ci vp[i] = 0; 937e1051a39Sopenharmony_ci return 1; 938e1051a39Sopenharmony_ci } 939e1051a39Sopenharmony_ci } 940e1051a39Sopenharmony_ci for (i = 0; i < num; i++) 941e1051a39Sopenharmony_ci rp[i] = tp[i], vp[i] = 0; 942e1051a39Sopenharmony_ci vp[num] = 0; 943e1051a39Sopenharmony_ci vp[num + 1] = 0; 944e1051a39Sopenharmony_ci return 1; 945e1051a39Sopenharmony_ci} 946e1051a39Sopenharmony_ci# else 947e1051a39Sopenharmony_ci/* 948e1051a39Sopenharmony_ci * Return value of 0 indicates that multiplication/convolution was not 949e1051a39Sopenharmony_ci * performed to signal the caller to fall down to alternative/original 950e1051a39Sopenharmony_ci * code-path. 951e1051a39Sopenharmony_ci */ 952e1051a39Sopenharmony_ciint bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, 953e1051a39Sopenharmony_ci const BN_ULONG *np, const BN_ULONG *n0, int num) 954e1051a39Sopenharmony_ci{ 955e1051a39Sopenharmony_ci return 0; 956e1051a39Sopenharmony_ci} 957e1051a39Sopenharmony_ci# endif /* OPENSSL_BN_ASM_MONT */ 958e1051a39Sopenharmony_ci# endif 959e1051a39Sopenharmony_ci 960e1051a39Sopenharmony_ci#else /* !BN_MUL_COMBA */ 961e1051a39Sopenharmony_ci 962e1051a39Sopenharmony_ci/* hmm... is it faster just to do a multiply? */ 963e1051a39Sopenharmony_ci# undef bn_sqr_comba4 964e1051a39Sopenharmony_ci# undef bn_sqr_comba8 965e1051a39Sopenharmony_civoid bn_sqr_comba4(BN_ULONG *r, const BN_ULONG *a) 966e1051a39Sopenharmony_ci{ 967e1051a39Sopenharmony_ci BN_ULONG t[8]; 968e1051a39Sopenharmony_ci bn_sqr_normal(r, a, 4, t); 969e1051a39Sopenharmony_ci} 970e1051a39Sopenharmony_ci 971e1051a39Sopenharmony_civoid bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a) 972e1051a39Sopenharmony_ci{ 973e1051a39Sopenharmony_ci BN_ULONG t[16]; 974e1051a39Sopenharmony_ci bn_sqr_normal(r, a, 8, t); 975e1051a39Sopenharmony_ci} 976e1051a39Sopenharmony_ci 977e1051a39Sopenharmony_civoid bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) 978e1051a39Sopenharmony_ci{ 979e1051a39Sopenharmony_ci r[4] = bn_mul_words(&(r[0]), a, 4, b[0]); 980e1051a39Sopenharmony_ci r[5] = bn_mul_add_words(&(r[1]), a, 4, b[1]); 981e1051a39Sopenharmony_ci r[6] = bn_mul_add_words(&(r[2]), a, 4, b[2]); 982e1051a39Sopenharmony_ci r[7] = bn_mul_add_words(&(r[3]), a, 4, b[3]); 983e1051a39Sopenharmony_ci} 984e1051a39Sopenharmony_ci 985e1051a39Sopenharmony_civoid bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) 986e1051a39Sopenharmony_ci{ 987e1051a39Sopenharmony_ci r[8] = bn_mul_words(&(r[0]), a, 8, b[0]); 988e1051a39Sopenharmony_ci r[9] = bn_mul_add_words(&(r[1]), a, 8, b[1]); 989e1051a39Sopenharmony_ci r[10] = bn_mul_add_words(&(r[2]), a, 8, b[2]); 990e1051a39Sopenharmony_ci r[11] = bn_mul_add_words(&(r[3]), a, 8, b[3]); 991e1051a39Sopenharmony_ci r[12] = bn_mul_add_words(&(r[4]), a, 8, b[4]); 992e1051a39Sopenharmony_ci r[13] = bn_mul_add_words(&(r[5]), a, 8, b[5]); 993e1051a39Sopenharmony_ci r[14] = bn_mul_add_words(&(r[6]), a, 8, b[6]); 994e1051a39Sopenharmony_ci r[15] = bn_mul_add_words(&(r[7]), a, 8, b[7]); 995e1051a39Sopenharmony_ci} 996e1051a39Sopenharmony_ci 997e1051a39Sopenharmony_ci# ifdef OPENSSL_NO_ASM 998e1051a39Sopenharmony_ci# ifdef OPENSSL_BN_ASM_MONT 999e1051a39Sopenharmony_ci# include <alloca.h> 1000e1051a39Sopenharmony_ciint bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, 1001e1051a39Sopenharmony_ci const BN_ULONG *np, const BN_ULONG *n0p, int num) 1002e1051a39Sopenharmony_ci{ 1003e1051a39Sopenharmony_ci BN_ULONG c0, c1, *tp, n0 = *n0p; 1004e1051a39Sopenharmony_ci volatile BN_ULONG *vp; 1005e1051a39Sopenharmony_ci int i = 0, j; 1006e1051a39Sopenharmony_ci 1007e1051a39Sopenharmony_ci vp = tp = alloca((num + 2) * sizeof(BN_ULONG)); 1008e1051a39Sopenharmony_ci 1009e1051a39Sopenharmony_ci for (i = 0; i <= num; i++) 1010e1051a39Sopenharmony_ci tp[i] = 0; 1011e1051a39Sopenharmony_ci 1012e1051a39Sopenharmony_ci for (i = 0; i < num; i++) { 1013e1051a39Sopenharmony_ci c0 = bn_mul_add_words(tp, ap, num, bp[i]); 1014e1051a39Sopenharmony_ci c1 = (tp[num] + c0) & BN_MASK2; 1015e1051a39Sopenharmony_ci tp[num] = c1; 1016e1051a39Sopenharmony_ci tp[num + 1] = (c1 < c0 ? 1 : 0); 1017e1051a39Sopenharmony_ci 1018e1051a39Sopenharmony_ci c0 = bn_mul_add_words(tp, np, num, tp[0] * n0); 1019e1051a39Sopenharmony_ci c1 = (tp[num] + c0) & BN_MASK2; 1020e1051a39Sopenharmony_ci tp[num] = c1; 1021e1051a39Sopenharmony_ci tp[num + 1] += (c1 < c0 ? 1 : 0); 1022e1051a39Sopenharmony_ci for (j = 0; j <= num; j++) 1023e1051a39Sopenharmony_ci tp[j] = tp[j + 1]; 1024e1051a39Sopenharmony_ci } 1025e1051a39Sopenharmony_ci 1026e1051a39Sopenharmony_ci if (tp[num] != 0 || tp[num - 1] >= np[num - 1]) { 1027e1051a39Sopenharmony_ci c0 = bn_sub_words(rp, tp, np, num); 1028e1051a39Sopenharmony_ci if (tp[num] != 0 || c0 == 0) { 1029e1051a39Sopenharmony_ci for (i = 0; i < num + 2; i++) 1030e1051a39Sopenharmony_ci vp[i] = 0; 1031e1051a39Sopenharmony_ci return 1; 1032e1051a39Sopenharmony_ci } 1033e1051a39Sopenharmony_ci } 1034e1051a39Sopenharmony_ci for (i = 0; i < num; i++) 1035e1051a39Sopenharmony_ci rp[i] = tp[i], vp[i] = 0; 1036e1051a39Sopenharmony_ci vp[num] = 0; 1037e1051a39Sopenharmony_ci vp[num + 1] = 0; 1038e1051a39Sopenharmony_ci return 1; 1039e1051a39Sopenharmony_ci} 1040e1051a39Sopenharmony_ci# else 1041e1051a39Sopenharmony_ciint bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, 1042e1051a39Sopenharmony_ci const BN_ULONG *np, const BN_ULONG *n0, int num) 1043e1051a39Sopenharmony_ci{ 1044e1051a39Sopenharmony_ci return 0; 1045e1051a39Sopenharmony_ci} 1046e1051a39Sopenharmony_ci# endif /* OPENSSL_BN_ASM_MONT */ 1047e1051a39Sopenharmony_ci# endif 1048e1051a39Sopenharmony_ci 1049e1051a39Sopenharmony_ci#endif /* !BN_MUL_COMBA */ 1050