LCOV - code coverage report
Current view: top level - third_party/heimdal/lib/hcrypto/libtommath - bn_s_mp_sqr_fast.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 36 37 97.3 %
Date: 2024-04-21 15:09:00 Functions: 1 1 100.0 %

          Line data    Source code
       1             : #include "tommath_private.h"
       2             : #ifdef BN_S_MP_SQR_FAST_C
       3             : /* LibTomMath, multiple-precision integer library -- Tom St Denis */
       4             : /* SPDX-License-Identifier: Unlicense */
       5             : 
       6             : /* the jist of squaring...
       7             :  * you do like mult except the offset of the tmpx [one that
       8             :  * starts closer to zero] can't equal the offset of tmpy.
       9             :  * So basically you set up iy like before then you min it with
      10             :  * (ty-tx) so that it never happens.  You double all those
      11             :  * you add in the inner loop
      12             : 
      13             : After that loop you do the squares and add them in.
      14             : */
      15             : 
      16      715863 : mp_err s_mp_sqr_fast(const mp_int *a, mp_int *b)
      17             : {
      18       33132 :    int       olduse, pa, ix, iz;
      19       33132 :    mp_digit  W[MP_WARRAY], *tmpx;
      20       33132 :    mp_word   W1;
      21       33132 :    mp_err    err;
      22             : 
      23             :    /* grow the destination as required */
      24      715863 :    pa = a->used + a->used;
      25      715863 :    if (b->alloc < pa) {
      26        1702 :       if ((err = mp_grow(b, pa)) != MP_OKAY) {
      27           0 :          return err;
      28             :       }
      29             :    }
      30             : 
      31             :    /* number of output digits to produce */
      32      682731 :    W1 = 0;
      33    43086829 :    for (ix = 0; ix < pa; ix++) {
      34     2339642 :       int      tx, ty, iy;
      35     2339642 :       mp_word  _W;
      36     2339642 :       mp_digit *tmpy;
      37             : 
      38             :       /* clear counter */
      39    42370966 :       _W = 0;
      40             : 
      41             :       /* get offsets into the two bignums */
      42    42370966 :       ty = MP_MIN(a->used-1, ix);
      43    42370966 :       tx = ix - ty;
      44             : 
      45             :       /* setup temp aliases */
      46    42370966 :       tmpx = a->dp + tx;
      47    42370966 :       tmpy = a->dp + ty;
      48             : 
      49             :       /* this is the number of times the loop will iterrate, essentially
      50             :          while (tx++ < a->used && ty-- >= 0) { ... }
      51             :        */
      52    42370966 :       iy = MP_MIN(a->used-tx, ty+1);
      53             : 
      54             :       /* now for squaring tx can never equal ty
      55             :        * we halve the distance since they approach at a rate of 2x
      56             :        * and we have to round because odd cases need to be executed
      57             :        */
      58    42370966 :       iy = MP_MIN(iy, ((ty-tx)+1)>>1);
      59             : 
      60             :       /* execute loop */
      61   377915793 :       for (iz = 0; iz < iy; iz++) {
      62   335544827 :          _W += (mp_word)*tmpx++ * (mp_word)*tmpy--;
      63             :       }
      64             : 
      65             :       /* double the inner product and add carry */
      66    42370966 :       _W = _W + _W + W1;
      67             : 
      68             :       /* even columns have the square term in them */
      69    42370966 :       if (((unsigned)ix & 1u) == 0u) {
      70    21185483 :          _W += (mp_word)a->dp[ix>>1] * (mp_word)a->dp[ix>>1];
      71             :       }
      72             : 
      73             :       /* store it */
      74    42370966 :       W[ix] = (mp_digit)_W & MP_MASK;
      75             : 
      76             :       /* make next carry */
      77    42370966 :       W1 = _W >> (mp_word)MP_DIGIT_BIT;
      78             :    }
      79             : 
      80             :    /* setup dest */
      81      715863 :    olduse  = b->used;
      82      715863 :    b->used = a->used+a->used;
      83             : 
      84             :    {
      85       33132 :       mp_digit *tmpb;
      86      715863 :       tmpb = b->dp;
      87    43086829 :       for (ix = 0; ix < pa; ix++) {
      88    42370966 :          *tmpb++ = W[ix] & MP_MASK;
      89             :       }
      90             : 
      91             :       /* clear unused digits [that existed in the old copy of c] */
      92      715863 :       MP_ZERO_DIGITS(tmpb, olduse - ix);
      93             :    }
      94      715863 :    mp_clamp(b);
      95      715863 :    return MP_OKAY;
      96             : }
      97             : #endif

Generated by: LCOV version 1.14