Renamed from `rsa-decrypt', since the name was no longer appropriate.
[u/mdw/catacomb] / mpmul.c
CommitLineData
da38281c 1/* -*-c-*-
2 *
3 * $Id: mpmul.c,v 1.1 2000/07/01 11:21:39 mdw Exp $
4 *
5 * Multiply many small numbers together
6 *
7 * (c) 2000 Straylight/Edgeware
8 */
9
10/*----- Licensing notice --------------------------------------------------*
11 *
12 * This file is part of Catacomb.
13 *
14 * Catacomb is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU Library General Public License as
16 * published by the Free Software Foundation; either version 2 of the
17 * License, or (at your option) any later version.
18 *
19 * Catacomb is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU Library General Public License for more details.
23 *
24 * You should have received a copy of the GNU Library General Public
25 * License along with Catacomb; if not, write to the Free
26 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
27 * MA 02111-1307, USA.
28 */
29
30/*----- Revision history --------------------------------------------------*
31 *
32 * $Log: mpmul.c,v $
33 * Revision 1.1 2000/07/01 11:21:39 mdw
34 * New interface for computing products of many (small) integers.
35 *
36 */
37
38/*----- Header files ------------------------------------------------------*/
39
40#include "mp.h"
41#include "mpint.h"
42#include "mpmul.h"
43
44/*----- Main code ---------------------------------------------------------*/
45
46/* --- @mpmul_init@ --- *
47 *
48 * Arguments: @mpmul *b@ = pointer to multiplier context to initialize
49 *
50 * Returns: ---
51 *
52 * Use: Initializes a big multiplier context for use.
53 */
54
55void mpmul_init(mpmul *b)
56{
57 b->i = 0;
58}
59
60/* --- @mpmul_add@ --- *
61 *
62 * Arguments: @mpmul *b@ = pointer to multiplier context
63 * @mp *x@ = the next factor to multiply in
64 *
65 * Returns: ---
66 *
67 * Use: Contributes another factor to the mix. It's important that
68 * the integer lasts at least as long as the multiplication
69 * context; this sort of rules out @mp_build@ integers.
70 */
71
72void mpmul_add(mpmul *b, mp *x)
73{
74 size_t i = b->i;
75
76 /* --- Now do the reduction step --- */
77
78 x = MP_COPY(x);
79
80 while (i > 0) {
81 if (MP_LEN(b->v[i - 1]) > MP_LEN(x))
82 break;
83 i--;
84 x = mp_mul(x, x, b->v[i]);
85 MP_DROP(b->v[i]);
86 }
87
88 if (i > HWM) {
89 while (i > LWM) {
90 i--;
91 x = mp_mul(x, x, b->v[i]);
92 MP_DROP(b->v[i]);
93 }
94 }
95
96 b->v[i] = x;
97 b->i = i;
98}
99
100/* --- @mpmul_done@ --- *
101 *
102 * Arguments: @mpmul *b@ = pointer to big multiplication context
103 *
104 * Returns: The product of all the numbers contributed.
105 *
106 * Use: Returns a (large) product of numbers. The context is
107 * deallocated.
108 */
109
110mp *mpmul_done(mpmul *b)
111{
112 size_t i = b->i;
113 mp *x;
114
115 if (!i)
116 return (MP_ONE);
117 i--;
118 x = b->v[i];
119 while (i > 0) {
120 i--;
121 x = mp_mul(x, x, b->v[i]);
122 MP_DROP(b->v[i]);
123 }
124 return (x);
125}
126
127/* --- @mp_factorial@ --- *
128 *
129 * Arguments: @unsigned long i@ = number whose factorial should be
130 * computed.
131 *
132 * Returns: The requested factorial.
133 */
134
135mp *mp_factorial(unsigned long i)
136{
137 unsigned long j;
138 mp *x = MP_NEW;
139 mpmul b = MPMUL_INIT;
140
141 for (j = 1; j <= i; j++) {
142 x = mp_fromulong(x, j);
143 mpmul_add(&b, x);
144 }
145 mp_drop(x);
146 return (mpmul_done(&b));
147}
148
149/*----- That's all, folks -------------------------------------------------*/