brintos

brintos / linux-shallow public Read only

0
0
Text · 2.5 KiB · 3015140 Raw
119 lines · c
1/* mpi-add.c  -  MPI functions2 * Copyright (C) 1994, 1996, 1998, 2001, 2002,3 *               2003 Free Software Foundation, Inc.4 *5 * This file is part of Libgcrypt.6 *7 * Note: This code is heavily based on the GNU MP Library.8 *	 Actually it's the same code with only minor changes in the9 *	 way the data is stored; this is to support the abstraction10 *	 of an optional secure memory allocation which may be used11 *	 to avoid revealing of sensitive data due to paging etc.12 */13 14#include "mpi-internal.h"15 16int mpi_add(MPI w, MPI u, MPI v)17{18	mpi_ptr_t wp, up, vp;19	mpi_size_t usize, vsize, wsize;20	int usign, vsign, wsign;21	int err;22 23	if (u->nlimbs < v->nlimbs) { /* Swap U and V. */24		usize = v->nlimbs;25		usign = v->sign;26		vsize = u->nlimbs;27		vsign = u->sign;28		wsize = usize + 1;29		err = RESIZE_IF_NEEDED(w, wsize);30		if (err)31			return err;32		/* These must be after realloc (u or v may be the same as w).  */33		up = v->d;34		vp = u->d;35	} else {36		usize = u->nlimbs;37		usign = u->sign;38		vsize = v->nlimbs;39		vsign = v->sign;40		wsize = usize + 1;41		err = RESIZE_IF_NEEDED(w, wsize);42		if (err)43			return err;44		/* These must be after realloc (u or v may be the same as w).  */45		up = u->d;46		vp = v->d;47	}48	wp = w->d;49	wsign = 0;50 51	if (!vsize) {  /* simple */52		MPN_COPY(wp, up, usize);53		wsize = usize;54		wsign = usign;55	} else if (usign != vsign) { /* different sign */56		/* This test is right since USIZE >= VSIZE */57		if (usize != vsize) {58			mpihelp_sub(wp, up, usize, vp, vsize);59			wsize = usize;60			MPN_NORMALIZE(wp, wsize);61			wsign = usign;62		} else if (mpihelp_cmp(up, vp, usize) < 0) {63			mpihelp_sub_n(wp, vp, up, usize);64			wsize = usize;65			MPN_NORMALIZE(wp, wsize);66			if (!usign)67				wsign = 1;68		} else {69			mpihelp_sub_n(wp, up, vp, usize);70			wsize = usize;71			MPN_NORMALIZE(wp, wsize);72			if (usign)73				wsign = 1;74		}75	} else { /* U and V have same sign. Add them. */76		mpi_limb_t cy = mpihelp_add(wp, up, usize, vp, vsize);77		wp[usize] = cy;78		wsize = usize + cy;79		if (usign)80			wsign = 1;81	}82 83	w->nlimbs = wsize;84	w->sign = wsign;85	return 0;86}87EXPORT_SYMBOL_GPL(mpi_add);88 89int mpi_sub(MPI w, MPI u, MPI v)90{91	int err;92	MPI vv;93 94	vv = mpi_copy(v);95	if (!vv)96		return -ENOMEM;97 98	vv->sign = !vv->sign;99	err = mpi_add(w, u, vv);100	mpi_free(vv);101 102	return err;103}104EXPORT_SYMBOL_GPL(mpi_sub);105 106int mpi_addm(MPI w, MPI u, MPI v, MPI m)107{108	return mpi_add(w, u, v) ?:109	       mpi_mod(w, w, m);110}111EXPORT_SYMBOL_GPL(mpi_addm);112 113int mpi_subm(MPI w, MPI u, MPI v, MPI m)114{115	return mpi_sub(w, u, v) ?:116	       mpi_mod(w, w, m);117}118EXPORT_SYMBOL_GPL(mpi_subm);119