-
+ F70DDD8CDF793CD1A95B6C84A9C73BFF0EF7BE6BB56483AAE08E26AAF004AAB695E34F4CD0982BF5D188374E9FD07241B225BA763EFACB78EDA586FC84E3CBE2
eucrypt/mpi/mpi-mul.c
(0 . 0)(1 . 209)
4095 /* mpi-mul.c - MPI functions
4096 * Modified by No Such Labs. (C) 2015. See README.
4097 *
4098 * This file was originally part of Gnu Privacy Guard (GPG), ver. 1.4.10,
4099 * SHA256(gnupg-1.4.10.tar.gz):
4100 * 0bfd74660a2f6cedcf7d8256db4a63c996ffebbcdc2cf54397bfb72878c5a85a
4101 * (C) 1994-2005 Free Software Foundation, Inc.
4102 *
4103 * This program is free software: you can redistribute it and/or modify
4104 * it under the terms of the GNU General Public License as published by
4105 * the Free Software Foundation, either version 3 of the License, or
4106 * (at your option) any later version.
4107 *
4108 * This program is distributed in the hope that it will be useful,
4109 * but WITHOUT ANY WARRANTY; without even the implied warranty of
4110 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4111 * GNU General Public License for more details.
4112 *
4113 * You should have received a copy of the GNU General Public License
4114 * along with this program. If not, see <http://www.gnu.org/licenses/>.
4115 */
4116
4117 #include <stdio.h>
4118 #include <stdlib.h>
4119
4120 #include "knobs.h"
4121 #include "mpi-internal.h"
4122
4123
4124 void
4125 mpi_mul_ui( MPI prod, MPI mult, unsigned long small_mult )
4126 {
4127 mpi_size_t size, prod_size;
4128 mpi_ptr_t prod_ptr;
4129 mpi_limb_t cy;
4130 int sign;
4131
4132 size = mult->nlimbs;
4133 sign = mult->sign;
4134
4135 if( !size || !small_mult ) {
4136 prod->nlimbs = 0;
4137 prod->sign = 0;
4138 return;
4139 }
4140
4141 prod_size = size + 1;
4142 if( prod->alloced < prod_size )
4143 mpi_resize( prod, prod_size );
4144 prod_ptr = prod->d;
4145
4146 cy = mpihelp_mul_1( prod_ptr, mult->d, size, (mpi_limb_t)small_mult );
4147 if( cy )
4148 prod_ptr[size++] = cy;
4149 prod->nlimbs = size;
4150 prod->sign = sign;
4151 }
4152
4153
4154 void
4155 mpi_mul_2exp( MPI w, MPI u, unsigned long cnt)
4156 {
4157 mpi_size_t usize, wsize, limb_cnt;
4158 mpi_ptr_t wp;
4159 mpi_limb_t wlimb;
4160 int usign, wsign;
4161
4162 usize = u->nlimbs;
4163 usign = u->sign;
4164
4165 if( !usize ) {
4166 w->nlimbs = 0;
4167 w->sign = 0;
4168 return;
4169 }
4170
4171 limb_cnt = cnt / BITS_PER_MPI_LIMB;
4172 wsize = usize + limb_cnt + 1;
4173 if( w->alloced < wsize )
4174 mpi_resize(w, wsize );
4175 wp = w->d;
4176 wsize = usize + limb_cnt;
4177 wsign = usign;
4178
4179 cnt %= BITS_PER_MPI_LIMB;
4180 if( cnt ) {
4181 wlimb = mpihelp_lshift( wp + limb_cnt, u->d, usize, cnt );
4182 if( wlimb ) {
4183 wp[wsize] = wlimb;
4184 wsize++;
4185 }
4186 }
4187 else {
4188 MPN_COPY_DECR( wp + limb_cnt, u->d, usize );
4189 }
4190
4191 /* Zero all whole limbs at low end. Do it here and not before calling
4192 * mpn_lshift, not to lose for U == W. */
4193 MPN_ZERO( wp, limb_cnt );
4194
4195 w->nlimbs = wsize;
4196 w->sign = wsign;
4197 }
4198
4199
4200
4201 void
4202 mpi_mul( MPI w, MPI u, MPI v)
4203 {
4204 mpi_size_t usize, vsize, wsize;
4205 mpi_ptr_t up, vp, wp;
4206 mpi_limb_t cy;
4207 int usign, vsign, usecure, vsecure, sign_product;
4208 int assign_wp=0;
4209 mpi_ptr_t tmp_limb=NULL;
4210
4211
4212 if( u->nlimbs < v->nlimbs ) { /* Swap U and V. */
4213 usize = v->nlimbs;
4214 usign = v->sign;
4215 usecure = mpi_is_secure(v);
4216 up = v->d;
4217 vsize = u->nlimbs;
4218 vsign = u->sign;
4219 vsecure = mpi_is_secure(u);
4220 vp = u->d;
4221 }
4222 else {
4223 usize = u->nlimbs;
4224 usign = u->sign;
4225 usecure = mpi_is_secure(u);
4226 up = u->d;
4227 vsize = v->nlimbs;
4228 vsign = v->sign;
4229 vsecure = mpi_is_secure(v);
4230 vp = v->d;
4231 }
4232 sign_product = usign ^ vsign;
4233 wp = w->d;
4234
4235 /* Ensure W has space enough to store the result. */
4236 wsize = usize + vsize;
4237 if ( !mpi_is_secure (w) && (mpi_is_secure (u) || mpi_is_secure (v)) ) {
4238 /* w is not allocated in secure space but u or v is. To make sure
4239 * that no temporray results are stored in w, we temporary use
4240 * a newly allocated limb space for w */
4241 wp = mpi_alloc_limb_space( wsize, 1 );
4242 assign_wp = 2; /* mark it as 2 so that we can later copy it back to
4243 * mormal memory */
4244 }
4245 else if( w->alloced < wsize ) {
4246 if( wp == up || wp == vp ) {
4247 wp = mpi_alloc_limb_space( wsize, mpi_is_secure(w) );
4248 assign_wp = 1;
4249 }
4250 else {
4251 mpi_resize(w, wsize );
4252 wp = w->d;
4253 }
4254 }
4255 else { /* Make U and V not overlap with W. */
4256 if( wp == up ) {
4257 /* W and U are identical. Allocate temporary space for U. */
4258 up = tmp_limb = mpi_alloc_limb_space( usize, usecure );
4259 /* Is V identical too? Keep it identical with U. */
4260 if( wp == vp )
4261 vp = up;
4262 /* Copy to the temporary space. */
4263 MPN_COPY( up, wp, usize );
4264 }
4265 else if( wp == vp ) {
4266 /* W and V are identical. Allocate temporary space for V. */
4267 vp = tmp_limb = mpi_alloc_limb_space( vsize, vsecure );
4268 /* Copy to the temporary space. */
4269 MPN_COPY( vp, wp, vsize );
4270 }
4271 }
4272
4273 if( !vsize )
4274 wsize = 0;
4275 else {
4276 cy = mpihelp_mul( wp, up, usize, vp, vsize );
4277 wsize -= cy? 0:1;
4278 }
4279
4280 if( assign_wp ) {
4281 if (assign_wp == 2) {
4282 /* copy the temp wp from secure memory back to normal memory */
4283 mpi_ptr_t tmp_wp = mpi_alloc_limb_space (wsize, 0);
4284 MPN_COPY (tmp_wp, wp, wsize);
4285 mpi_free_limb_space (wp);
4286 wp = tmp_wp;
4287 }
4288 mpi_assign_limb_space( w, wp, wsize );
4289 }
4290 w->nlimbs = wsize;
4291 w->sign = sign_product;
4292 if( tmp_limb )
4293 mpi_free_limb_space( tmp_limb );
4294 }
4295
4296
4297 void
4298 mpi_mulm( MPI w, MPI u, MPI v, MPI m)
4299 {
4300 mpi_mul(w, u, v);
4301 mpi_fdiv_r( w, w, m );
4302 }
4303