/* tmp must have 2*n words */ void bn_sqr_normal(BN_ULONG *r, BN_ULONG *a, int n, BN_ULONG *tmp) { int i,j,max; BN_ULONG *ap,*rp; max=n*2; ap=a; rp=r; rp[0]=rp[max-1]=0; rp++; j=n; if (--j > 0) { ap++; rp[j]=bn_mul_words(rp,ap,j,ap[-1]); rp+=2; } for (i=n-2; i>0; i--) { j--; ap++; rp[j]=bn_mul_add_words(rp,ap,j,ap[-1]); rp+=2; } 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); }
// tmp must have 2*n words static void bn_sqr_normal(BN_ULONG *r, const BN_ULONG *a, size_t n, BN_ULONG *tmp) { if (n == 0) { return; } size_t max = n * 2; const BN_ULONG *ap = a; BN_ULONG *rp = r; rp[0] = rp[max - 1] = 0; rp++; // Compute the contribution of a[i] * a[j] for all i < j. if (n > 1) { ap++; rp[n - 1] = bn_mul_words(rp, ap, n - 1, ap[-1]); rp += 2; } if (n > 2) { for (size_t i = n - 2; i > 0; i--) { ap++; rp[i] = bn_mul_add_words(rp, ap, i, ap[-1]); rp += 2; } } // The final result fits in |max| words, so none of the following operations // will overflow. // Double |r|, giving the contribution of a[i] * a[j] for all i != j. bn_add_words(r, r, r, max); // Add in the contribution of a[i] * a[i] for all i. bn_sqr_words(tmp, a, n); bn_add_words(r, r, tmp, max); }