diff options
Diffstat (limited to 'pbn_mulus_add.c')
-rw-r--r-- | pbn_mulus_add.c | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/pbn_mulus_add.c b/pbn_mulus_add.c new file mode 100644 index 0000000..23ec240 --- /dev/null +++ b/pbn_mulus_add.c @@ -0,0 +1,51 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 2007 H. Peter Anvin - All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, Inc., + * 59 Temple Place Ste 330, Boston MA 02111-1307, USA; version 2.1, + * incorporated herein by reference. + * + * ----------------------------------------------------------------------- */ + +/* + * pbn_mulus_add.c + * + * Multiply a PBN with a single limb unsigned number, and add a single + * limb unsigned number. + */ + +#include "pbnint.h" + +struct pbn *pbn_mulus_add(struct pbn *s1, pbn_limb_t s2, pbn_limb_t c) +{ + size_t i, len; + struct pbn *d; + pbn_limb_t *s1p, *dp; + pbn_2limb_t t; + + if (unlikely(s1->bits == 0)) { + pbn_free(s1); + return pbn_uint(c); + } + + len = (s1->bits+PBN_LIMB_BITS-1) >> PBN_LIMB_SHIFT; + + d = pbn_new(len+1); + d->minus = s1->minus; + + s1p = s1->num; + dp = d->num; + for (i = 0; i < len; i++) { + t = (pbn_2limb_t)*s1p++ * s2 + c; + *dp++ = (pbn_limb_t)t; + c = t >> PBN_LIMB_BITS; + } + *dp = c; + + pbn_free(s1); + + return pbn_adjust_bits(d); +} |