xref: /netbsd-src/crypto/external/bsd/heimdal/dist/lib/hcrypto/libtommath/bn_mp_mul_2d.c (revision d3273b5b76f5afaafe308cead5511dbb8df8c5e9)
1 /*	$NetBSD: bn_mp_mul_2d.c,v 1.2 2017/01/28 21:31:47 christos Exp $	*/
2 
3 #include <tommath.h>
4 #ifdef BN_MP_MUL_2D_C
5 /* LibTomMath, multiple-precision integer library -- Tom St Denis
6  *
7  * LibTomMath is a library that provides multiple-precision
8  * integer arithmetic as well as number theoretic functionality.
9  *
10  * The library was designed directly after the MPI library by
11  * Michael Fromberger but has been written from scratch with
12  * additional optimizations in place.
13  *
14  * The library is free for all purposes without any express
15  * guarantee it works.
16  *
17  * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
18  */
19 
20 /* shift left by a certain bit count */
mp_mul_2d(mp_int * a,int b,mp_int * c)21 int mp_mul_2d (mp_int * a, int b, mp_int * c)
22 {
23   mp_digit d;
24   int      res;
25 
26   /* copy */
27   if (a != c) {
28      if ((res = mp_copy (a, c)) != MP_OKAY) {
29        return res;
30      }
31   }
32 
33   if (c->alloc < (int)(c->used + b/DIGIT_BIT + 1)) {
34      if ((res = mp_grow (c, c->used + b / DIGIT_BIT + 1)) != MP_OKAY) {
35        return res;
36      }
37   }
38 
39   /* shift by as many digits in the bit count */
40   if (b >= (int)DIGIT_BIT) {
41     if ((res = mp_lshd (c, b / DIGIT_BIT)) != MP_OKAY) {
42       return res;
43     }
44   }
45 
46   /* shift any bit count < DIGIT_BIT */
47   d = (mp_digit) (b % DIGIT_BIT);
48   if (d != 0) {
49     register mp_digit *tmpc, shift, mask, r, rr;
50     register int x;
51 
52     /* bitmask for carries */
53     mask = (((mp_digit)1) << d) - 1;
54 
55     /* shift for msbs */
56     shift = DIGIT_BIT - d;
57 
58     /* alias */
59     tmpc = c->dp;
60 
61     /* carry */
62     r    = 0;
63     for (x = 0; x < c->used; x++) {
64       /* get the higher bits of the current word */
65       rr = (*tmpc >> shift) & mask;
66 
67       /* shift the current word and OR in the carry */
68       *tmpc = ((*tmpc << d) | r) & MP_MASK;
69       ++tmpc;
70 
71       /* set the carry to the carry bits of the current word */
72       r = rr;
73     }
74 
75     /* set final carry */
76     if (r != 0) {
77        c->dp[(c->used)++] = r;
78     }
79   }
80   mp_clamp (c);
81   return MP_OKAY;
82 }
83 #endif
84 
85 /* Source: /cvs/libtom/libtommath/bn_mp_mul_2d.c,v  */
86 /* Revision: 1.4  */
87 /* Date: 2006/12/28 01:25:13  */
88