forked from mirrors/linux
		
	Revert "crypto: GnuPG based MPI lib - additional sources (part 4)"
This reverts commit 7e8dec918e.
RSA verification implementation does not use this code.
James Morris has asked to remove that.
Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@intel.com>
Requested-by: James Morris <james.l.morris@oracle.com>
Signed-off-by: James Morris <james.l.morris@oracle.com>
			
			
This commit is contained in:
		
							parent
							
								
									423b978802
								
							
						
					
					
						commit
						9e235dcaf4
					
				
					 12 changed files with 0 additions and 1404 deletions
				
			
		|  | @ -361,14 +361,6 @@ config MPILIB | |||
| 	  It is used to implement RSA digital signature verification, | ||||
| 	  which is used by IMA/EVM digital signature extension. | ||||
| 
 | ||||
| config MPILIB_EXTRA | ||||
| 	bool | ||||
| 	depends on MPILIB | ||||
| 	help | ||||
| 	  Additional sources of multiprecision maths library from GnuPG. | ||||
| 	  This code is unnecessary for RSA digital signature verification, | ||||
| 	  but can be compiled if needed. | ||||
| 
 | ||||
| config SIGNATURE | ||||
| 	tristate | ||||
| 	depends on KEYS && CRYPTO | ||||
|  |  | |||
|  | @ -19,14 +19,3 @@ mpi-y = \ | |||
| 	mpih-mul.o			\
 | ||||
| 	mpi-pow.o			\
 | ||||
| 	mpiutil.o | ||||
| 
 | ||||
| mpi-$(CONFIG_MPILIB_EXTRA) += \
 | ||||
| 	mpi-add.o			\
 | ||||
| 	mpi-div.o			\
 | ||||
| 	mpi-cmp.o			\
 | ||||
| 	mpi-gcd.o			\
 | ||||
| 	mpi-inline.o			\
 | ||||
| 	mpi-inv.o			\
 | ||||
| 	mpi-mpow.o			\
 | ||||
| 	mpi-mul.o			\
 | ||||
| 	mpi-scan.o | ||||
|  |  | |||
|  | @ -1,4 +0,0 @@ | |||
| /* This file defines some basic constants for the MPI machinery.  We
 | ||||
|  * need to define the types on a per-CPU basis, so it is done with | ||||
|  * this file here.  */ | ||||
| #define BYTES_PER_MPI_LIMB  (SIZEOF_UNSIGNED_LONG) | ||||
|  | @ -1,234 +0,0 @@ | |||
| /* mpi-add.c  -  MPI functions
 | ||||
|  *	Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. | ||||
|  *	Copyright (C) 1994, 1996 Free Software Foundation, Inc. | ||||
|  * | ||||
|  * This file is part of GnuPG. | ||||
|  * | ||||
|  * GnuPG is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation; either version 2 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * GnuPG is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA | ||||
|  * | ||||
|  * Note: This code is heavily based on the GNU MP Library. | ||||
|  *	 Actually it's the same code with only minor changes in the | ||||
|  *	 way the data is stored; this is to support the abstraction | ||||
|  *	 of an optional secure memory allocation which may be used | ||||
|  *	 to avoid revealing of sensitive data due to paging etc. | ||||
|  *	 The GNU MP Library itself is published under the LGPL; | ||||
|  *	 however I decided to publish this code under the plain GPL. | ||||
|  */ | ||||
| 
 | ||||
| #include "mpi-internal.h" | ||||
| 
 | ||||
| /****************
 | ||||
|  * Add the unsigned integer V to the mpi-integer U and store the | ||||
|  * result in W. U and V may be the same. | ||||
|  */ | ||||
| int mpi_add_ui(MPI w, const MPI u, unsigned long v) | ||||
| { | ||||
| 	mpi_ptr_t wp, up; | ||||
| 	mpi_size_t usize, wsize; | ||||
| 	int usign, wsign; | ||||
| 
 | ||||
| 	usize = u->nlimbs; | ||||
| 	usign = u->sign; | ||||
| 	wsign = 0; | ||||
| 
 | ||||
| 	/* If not space for W (and possible carry), increase space.  */ | ||||
| 	wsize = usize + 1; | ||||
| 	if (w->alloced < wsize) | ||||
| 		if (mpi_resize(w, wsize) < 0) | ||||
| 			return -ENOMEM; | ||||
| 
 | ||||
| 	/* These must be after realloc (U may be the same as W).  */ | ||||
| 	up = u->d; | ||||
| 	wp = w->d; | ||||
| 
 | ||||
| 	if (!usize) {		/* simple */ | ||||
| 		wp[0] = v; | ||||
| 		wsize = v ? 1 : 0; | ||||
| 	} else if (!usign) {	/* mpi is not negative */ | ||||
| 		mpi_limb_t cy; | ||||
| 		cy = mpihelp_add_1(wp, up, usize, v); | ||||
| 		wp[usize] = cy; | ||||
| 		wsize = usize + cy; | ||||
| 	} else {		/* The signs are different.  Need exact comparison to determine
 | ||||
| 				 * which operand to subtract from which.  */ | ||||
| 		if (usize == 1 && up[0] < v) { | ||||
| 			wp[0] = v - up[0]; | ||||
| 			wsize = 1; | ||||
| 		} else { | ||||
| 			mpihelp_sub_1(wp, up, usize, v); | ||||
| 			/* Size can decrease with at most one limb. */ | ||||
| 			wsize = usize - (wp[usize - 1] == 0); | ||||
| 			wsign = 1; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	w->nlimbs = wsize; | ||||
| 	w->sign = wsign; | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| int mpi_add(MPI w, MPI u, MPI v) | ||||
| { | ||||
| 	mpi_ptr_t wp, up, vp; | ||||
| 	mpi_size_t usize, vsize, wsize; | ||||
| 	int usign, vsign, wsign; | ||||
| 
 | ||||
| 	if (u->nlimbs < v->nlimbs) {	/* Swap U and V. */ | ||||
| 		usize = v->nlimbs; | ||||
| 		usign = v->sign; | ||||
| 		vsize = u->nlimbs; | ||||
| 		vsign = u->sign; | ||||
| 		wsize = usize + 1; | ||||
| 		if (RESIZE_IF_NEEDED(w, wsize) < 0) | ||||
| 			return -ENOMEM; | ||||
| 		/* These must be after realloc (u or v may be the same as w).  */ | ||||
| 		up = v->d; | ||||
| 		vp = u->d; | ||||
| 	} else { | ||||
| 		usize = u->nlimbs; | ||||
| 		usign = u->sign; | ||||
| 		vsize = v->nlimbs; | ||||
| 		vsign = v->sign; | ||||
| 		wsize = usize + 1; | ||||
| 		if (RESIZE_IF_NEEDED(w, wsize) < 0) | ||||
| 			return -ENOMEM; | ||||
| 		/* These must be after realloc (u or v may be the same as w).  */ | ||||
| 		up = u->d; | ||||
| 		vp = v->d; | ||||
| 	} | ||||
| 	wp = w->d; | ||||
| 	wsign = 0; | ||||
| 
 | ||||
| 	if (!vsize) {		/* simple */ | ||||
| 		MPN_COPY(wp, up, usize); | ||||
| 		wsize = usize; | ||||
| 		wsign = usign; | ||||
| 	} else if (usign != vsign) {	/* different sign */ | ||||
| 		/* This test is right since USIZE >= VSIZE */ | ||||
| 		if (usize != vsize) { | ||||
| 			mpihelp_sub(wp, up, usize, vp, vsize); | ||||
| 			wsize = usize; | ||||
| 			MPN_NORMALIZE(wp, wsize); | ||||
| 			wsign = usign; | ||||
| 		} else if (mpihelp_cmp(up, vp, usize) < 0) { | ||||
| 			mpihelp_sub_n(wp, vp, up, usize); | ||||
| 			wsize = usize; | ||||
| 			MPN_NORMALIZE(wp, wsize); | ||||
| 			if (!usign) | ||||
| 				wsign = 1; | ||||
| 		} else { | ||||
| 			mpihelp_sub_n(wp, up, vp, usize); | ||||
| 			wsize = usize; | ||||
| 			MPN_NORMALIZE(wp, wsize); | ||||
| 			if (usign) | ||||
| 				wsign = 1; | ||||
| 		} | ||||
| 	} else {		/* U and V have same sign. Add them. */ | ||||
| 		mpi_limb_t cy = mpihelp_add(wp, up, usize, vp, vsize); | ||||
| 		wp[usize] = cy; | ||||
| 		wsize = usize + cy; | ||||
| 		if (usign) | ||||
| 			wsign = 1; | ||||
| 	} | ||||
| 
 | ||||
| 	w->nlimbs = wsize; | ||||
| 	w->sign = wsign; | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| /****************
 | ||||
|  * Subtract the unsigned integer V from the mpi-integer U and store the | ||||
|  * result in W. | ||||
|  */ | ||||
| int mpi_sub_ui(MPI w, MPI u, unsigned long v) | ||||
| { | ||||
| 	mpi_ptr_t wp, up; | ||||
| 	mpi_size_t usize, wsize; | ||||
| 	int usign, wsign; | ||||
| 
 | ||||
| 	usize = u->nlimbs; | ||||
| 	usign = u->sign; | ||||
| 	wsign = 0; | ||||
| 
 | ||||
| 	/* If not space for W (and possible carry), increase space.  */ | ||||
| 	wsize = usize + 1; | ||||
| 	if (w->alloced < wsize) | ||||
| 		if (mpi_resize(w, wsize) < 0) | ||||
| 			return -ENOMEM; | ||||
| 
 | ||||
| 	/* These must be after realloc (U may be the same as W).  */ | ||||
| 	up = u->d; | ||||
| 	wp = w->d; | ||||
| 
 | ||||
| 	if (!usize) {		/* simple */ | ||||
| 		wp[0] = v; | ||||
| 		wsize = v ? 1 : 0; | ||||
| 		wsign = 1; | ||||
| 	} else if (usign) {	/* mpi and v are negative */ | ||||
| 		mpi_limb_t cy; | ||||
| 		cy = mpihelp_add_1(wp, up, usize, v); | ||||
| 		wp[usize] = cy; | ||||
| 		wsize = usize + cy; | ||||
| 	} else {		/* The signs are different.  Need exact comparison to determine
 | ||||
| 				 * which operand to subtract from which.  */ | ||||
| 		if (usize == 1 && up[0] < v) { | ||||
| 			wp[0] = v - up[0]; | ||||
| 			wsize = 1; | ||||
| 			wsign = 1; | ||||
| 		} else { | ||||
| 			mpihelp_sub_1(wp, up, usize, v); | ||||
| 			/* Size can decrease with at most one limb. */ | ||||
| 			wsize = usize - (wp[usize - 1] == 0); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	w->nlimbs = wsize; | ||||
| 	w->sign = wsign; | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| int mpi_sub(MPI w, MPI u, MPI v) | ||||
| { | ||||
| 	int rc; | ||||
| 
 | ||||
| 	if (w == v) { | ||||
| 		MPI vv; | ||||
| 		if (mpi_copy(&vv, v) < 0) | ||||
| 			return -ENOMEM; | ||||
| 		vv->sign = !vv->sign; | ||||
| 		rc = mpi_add(w, u, vv); | ||||
| 		mpi_free(vv); | ||||
| 	} else { | ||||
| 		/* fixme: this is not thread-save (we temp. modify v) */ | ||||
| 		v->sign = !v->sign; | ||||
| 		rc = mpi_add(w, u, v); | ||||
| 		v->sign = !v->sign; | ||||
| 	} | ||||
| 	return rc; | ||||
| } | ||||
| 
 | ||||
| int mpi_addm(MPI w, MPI u, MPI v, MPI m) | ||||
| { | ||||
| 	if (mpi_add(w, u, v) < 0 || mpi_fdiv_r(w, w, m) < 0) | ||||
| 		return -ENOMEM; | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| int mpi_subm(MPI w, MPI u, MPI v, MPI m) | ||||
| { | ||||
| 	if (mpi_sub(w, u, v) < 0 || mpi_fdiv_r(w, w, m) < 0) | ||||
| 		return -ENOMEM; | ||||
| 	return 0; | ||||
| } | ||||
|  | @ -1,68 +0,0 @@ | |||
| /* mpi-cmp.c  -  MPI functions
 | ||||
|  * Copyright (C) 1998, 1999 Free Software Foundation, Inc. | ||||
|  * | ||||
|  * This file is part of GnuPG. | ||||
|  * | ||||
|  * GnuPG is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation; either version 2 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * GnuPG is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA | ||||
|  */ | ||||
| 
 | ||||
| #include "mpi-internal.h" | ||||
| 
 | ||||
| int mpi_cmp_ui(MPI u, unsigned long v) | ||||
| { | ||||
| 	mpi_limb_t limb = v; | ||||
| 
 | ||||
| 	mpi_normalize(u); | ||||
| 	if (!u->nlimbs && !limb) | ||||
| 		return 0; | ||||
| 	if (u->sign) | ||||
| 		return -1; | ||||
| 	if (u->nlimbs > 1) | ||||
| 		return 1; | ||||
| 
 | ||||
| 	if (u->d[0] == limb) | ||||
| 		return 0; | ||||
| 	else if (u->d[0] > limb) | ||||
| 		return 1; | ||||
| 	else | ||||
| 		return -1; | ||||
| } | ||||
| 
 | ||||
| int mpi_cmp(MPI u, MPI v) | ||||
| { | ||||
| 	mpi_size_t usize, vsize; | ||||
| 	int cmp; | ||||
| 
 | ||||
| 	mpi_normalize(u); | ||||
| 	mpi_normalize(v); | ||||
| 	usize = u->nlimbs; | ||||
| 	vsize = v->nlimbs; | ||||
| 	if (!u->sign && v->sign) | ||||
| 		return 1; | ||||
| 	if (u->sign && !v->sign) | ||||
| 		return -1; | ||||
| 	if (usize != vsize && !u->sign && !v->sign) | ||||
| 		return usize - vsize; | ||||
| 	if (usize != vsize && u->sign && v->sign) | ||||
| 		return vsize + usize; | ||||
| 	if (!usize) | ||||
| 		return 0; | ||||
| 	cmp = mpihelp_cmp(u->d, v->d, usize); | ||||
| 	if (!cmp) | ||||
| 		return 0; | ||||
| 	if ((cmp < 0 ? 1 : 0) == (u->sign ? 1 : 0)) | ||||
| 		return 1; | ||||
| 	return -1; | ||||
| } | ||||
|  | @ -1,338 +0,0 @@ | |||
| /* mpi-div.c  -  MPI functions
 | ||||
|  *	Copyright (C) 1994, 1996 Free Software Foundation, Inc. | ||||
|  *	Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. | ||||
|  * | ||||
|  * This file is part of GnuPG. | ||||
|  * | ||||
|  * GnuPG is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation; either version 2 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * GnuPG is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA | ||||
|  * | ||||
|  * Note: This code is heavily based on the GNU MP Library. | ||||
|  *	 Actually it's the same code with only minor changes in the | ||||
|  *	 way the data is stored; this is to support the abstraction | ||||
|  *	 of an optional secure memory allocation which may be used | ||||
|  *	 to avoid revealing of sensitive data due to paging etc. | ||||
|  *	 The GNU MP Library itself is published under the LGPL; | ||||
|  *	 however I decided to publish this code under the plain GPL. | ||||
|  */ | ||||
| 
 | ||||
| #include <linux/string.h> | ||||
| #include "mpi-internal.h" | ||||
| #include "longlong.h" | ||||
| 
 | ||||
| int mpi_fdiv_r(MPI rem, MPI dividend, MPI divisor) | ||||
| { | ||||
| 	int rc = -ENOMEM; | ||||
| 	int divisor_sign = divisor->sign; | ||||
| 	MPI temp_divisor = NULL; | ||||
| 
 | ||||
| 	/* We need the original value of the divisor after the remainder has been
 | ||||
| 	 * preliminary calculated.      We have to copy it to temporary space if it's | ||||
| 	 * the same variable as REM.  */ | ||||
| 	if (rem == divisor) { | ||||
| 		if (mpi_copy(&temp_divisor, divisor) < 0) | ||||
| 			goto nomem; | ||||
| 		divisor = temp_divisor; | ||||
| 	} | ||||
| 
 | ||||
| 	if (mpi_tdiv_qr(NULL, rem, dividend, divisor) < 0) | ||||
| 		goto nomem; | ||||
| 	if (((divisor_sign ? 1 : 0) ^ (dividend->sign ? 1 : 0)) && rem->nlimbs) | ||||
| 		if (mpi_add(rem, rem, divisor) < 0) | ||||
| 			goto nomem; | ||||
| 
 | ||||
| 	rc = 0; | ||||
| 
 | ||||
| nomem: | ||||
| 	if (temp_divisor) | ||||
| 		mpi_free(temp_divisor); | ||||
| 	return rc; | ||||
| } | ||||
| 
 | ||||
| /****************
 | ||||
|  * Division rounding the quotient towards -infinity. | ||||
|  * The remainder gets the same sign as the denominator. | ||||
|  * rem is optional | ||||
|  */ | ||||
| 
 | ||||
| ulong mpi_fdiv_r_ui(MPI rem, MPI dividend, ulong divisor) | ||||
| { | ||||
| 	mpi_limb_t rlimb; | ||||
| 
 | ||||
| 	rlimb = mpihelp_mod_1(dividend->d, dividend->nlimbs, divisor); | ||||
| 	if (rlimb && dividend->sign) | ||||
| 		rlimb = divisor - rlimb; | ||||
| 
 | ||||
| 	if (rem) { | ||||
| 		rem->d[0] = rlimb; | ||||
| 		rem->nlimbs = rlimb ? 1 : 0; | ||||
| 	} | ||||
| 	return rlimb; | ||||
| } | ||||
| 
 | ||||
| int mpi_fdiv_q(MPI quot, MPI dividend, MPI divisor) | ||||
| { | ||||
| 	MPI tmp = mpi_alloc(mpi_get_nlimbs(quot)); | ||||
| 	if (!tmp) | ||||
| 		return -ENOMEM; | ||||
| 	mpi_fdiv_qr(quot, tmp, dividend, divisor); | ||||
| 	mpi_free(tmp); | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| int mpi_fdiv_qr(MPI quot, MPI rem, MPI dividend, MPI divisor) | ||||
| { | ||||
| 	int divisor_sign = divisor->sign; | ||||
| 	MPI temp_divisor = NULL; | ||||
| 
 | ||||
| 	if (quot == divisor || rem == divisor) { | ||||
| 		if (mpi_copy(&temp_divisor, divisor) < 0) | ||||
| 			return -ENOMEM; | ||||
| 		divisor = temp_divisor; | ||||
| 	} | ||||
| 
 | ||||
| 	if (mpi_tdiv_qr(quot, rem, dividend, divisor) < 0) | ||||
| 		goto nomem; | ||||
| 
 | ||||
| 	if ((divisor_sign ^ dividend->sign) && rem->nlimbs) { | ||||
| 		if (mpi_sub_ui(quot, quot, 1) < 0) | ||||
| 			goto nomem; | ||||
| 		if (mpi_add(rem, rem, divisor) < 0) | ||||
| 			goto nomem; | ||||
| 	} | ||||
| 
 | ||||
| 	if (temp_divisor) | ||||
| 		mpi_free(temp_divisor); | ||||
| 
 | ||||
| 	return 0; | ||||
| 
 | ||||
| nomem: | ||||
| 	mpi_free(temp_divisor); | ||||
| 	return -ENOMEM; | ||||
| } | ||||
| 
 | ||||
| /* If den == quot, den needs temporary storage.
 | ||||
|  * If den == rem, den needs temporary storage. | ||||
|  * If num == quot, num needs temporary storage. | ||||
|  * If den has temporary storage, it can be normalized while being copied, | ||||
|  *   i.e no extra storage should be allocated. | ||||
|  */ | ||||
| 
 | ||||
| int mpi_tdiv_r(MPI rem, MPI num, MPI den) | ||||
| { | ||||
| 	return mpi_tdiv_qr(NULL, rem, num, den); | ||||
| } | ||||
| 
 | ||||
| int mpi_tdiv_qr(MPI quot, MPI rem, MPI num, MPI den) | ||||
| { | ||||
| 	int rc = -ENOMEM; | ||||
| 	mpi_ptr_t np, dp; | ||||
| 	mpi_ptr_t qp, rp; | ||||
| 	mpi_size_t nsize = num->nlimbs; | ||||
| 	mpi_size_t dsize = den->nlimbs; | ||||
| 	mpi_size_t qsize, rsize; | ||||
| 	mpi_size_t sign_remainder = num->sign; | ||||
| 	mpi_size_t sign_quotient = num->sign ^ den->sign; | ||||
| 	unsigned normalization_steps; | ||||
| 	mpi_limb_t q_limb; | ||||
| 	mpi_ptr_t marker[5]; | ||||
| 	int markidx = 0; | ||||
| 
 | ||||
| 	if (!dsize) | ||||
| 		return -EINVAL; | ||||
| 
 | ||||
| 	memset(marker, 0, sizeof(marker)); | ||||
| 
 | ||||
| 	/* Ensure space is enough for quotient and remainder.
 | ||||
| 	 * We need space for an extra limb in the remainder, because it's | ||||
| 	 * up-shifted (normalized) below.  */ | ||||
| 	rsize = nsize + 1; | ||||
| 	if (mpi_resize(rem, rsize) < 0) | ||||
| 		goto nomem; | ||||
| 
 | ||||
| 	qsize = rsize - dsize;	/* qsize cannot be bigger than this.  */ | ||||
| 	if (qsize <= 0) { | ||||
| 		if (num != rem) { | ||||
| 			rem->nlimbs = num->nlimbs; | ||||
| 			rem->sign = num->sign; | ||||
| 			MPN_COPY(rem->d, num->d, nsize); | ||||
| 		} | ||||
| 		if (quot) { | ||||
| 			/* This needs to follow the assignment to rem, in case the
 | ||||
| 			 * numerator and quotient are the same.  */ | ||||
| 			quot->nlimbs = 0; | ||||
| 			quot->sign = 0; | ||||
| 		} | ||||
| 		return 0; | ||||
| 	} | ||||
| 
 | ||||
| 	if (quot) | ||||
| 		if (mpi_resize(quot, qsize) < 0) | ||||
| 			goto nomem; | ||||
| 
 | ||||
| 	/* Read pointers here, when reallocation is finished.  */ | ||||
| 	np = num->d; | ||||
| 	dp = den->d; | ||||
| 	rp = rem->d; | ||||
| 
 | ||||
| 	/* Optimize division by a single-limb divisor.  */ | ||||
| 	if (dsize == 1) { | ||||
| 		mpi_limb_t rlimb; | ||||
| 		if (quot) { | ||||
| 			qp = quot->d; | ||||
| 			rlimb = mpihelp_divmod_1(qp, np, nsize, dp[0]); | ||||
| 			qsize -= qp[qsize - 1] == 0; | ||||
| 			quot->nlimbs = qsize; | ||||
| 			quot->sign = sign_quotient; | ||||
| 		} else | ||||
| 			rlimb = mpihelp_mod_1(np, nsize, dp[0]); | ||||
| 		rp[0] = rlimb; | ||||
| 		rsize = rlimb != 0 ? 1 : 0; | ||||
| 		rem->nlimbs = rsize; | ||||
| 		rem->sign = sign_remainder; | ||||
| 		return 0; | ||||
| 	} | ||||
| 
 | ||||
| 	if (quot) { | ||||
| 		qp = quot->d; | ||||
| 		/* Make sure QP and NP point to different objects.  Otherwise the
 | ||||
| 		 * numerator would be gradually overwritten by the quotient limbs.  */ | ||||
| 		if (qp == np) {	/* Copy NP object to temporary space.  */ | ||||
| 			np = marker[markidx++] = mpi_alloc_limb_space(nsize); | ||||
| 			if (!np) | ||||
| 				goto nomem; | ||||
| 			MPN_COPY(np, qp, nsize); | ||||
| 		} | ||||
| 	} else			/* Put quotient at top of remainder. */ | ||||
| 		qp = rp + dsize; | ||||
| 
 | ||||
| 	count_leading_zeros(normalization_steps, dp[dsize - 1]); | ||||
| 
 | ||||
| 	/* Normalize the denominator, i.e. make its most significant bit set by
 | ||||
| 	 * shifting it NORMALIZATION_STEPS bits to the left.  Also shift the | ||||
| 	 * numerator the same number of steps (to keep the quotient the same!). | ||||
| 	 */ | ||||
| 	if (normalization_steps) { | ||||
| 		mpi_ptr_t tp; | ||||
| 		mpi_limb_t nlimb; | ||||
| 
 | ||||
| 		/* Shift up the denominator setting the most significant bit of
 | ||||
| 		 * the most significant word.  Use temporary storage not to clobber | ||||
| 		 * the original contents of the denominator.  */ | ||||
| 		tp = marker[markidx++] = mpi_alloc_limb_space(dsize); | ||||
| 		if (!tp) | ||||
| 			goto nomem; | ||||
| 		mpihelp_lshift(tp, dp, dsize, normalization_steps); | ||||
| 		dp = tp; | ||||
| 
 | ||||
| 		/* Shift up the numerator, possibly introducing a new most
 | ||||
| 		 * significant word.  Move the shifted numerator in the remainder | ||||
| 		 * meanwhile.  */ | ||||
| 		nlimb = mpihelp_lshift(rp, np, nsize, normalization_steps); | ||||
| 		if (nlimb) { | ||||
| 			rp[nsize] = nlimb; | ||||
| 			rsize = nsize + 1; | ||||
| 		} else | ||||
| 			rsize = nsize; | ||||
| 	} else { | ||||
| 		/* The denominator is already normalized, as required.  Copy it to
 | ||||
| 		 * temporary space if it overlaps with the quotient or remainder.  */ | ||||
| 		if (dp == rp || (quot && (dp == qp))) { | ||||
| 			mpi_ptr_t tp; | ||||
| 
 | ||||
| 			tp = marker[markidx++] = mpi_alloc_limb_space(dsize); | ||||
| 			if (!tp) | ||||
| 				goto nomem; | ||||
| 			MPN_COPY(tp, dp, dsize); | ||||
| 			dp = tp; | ||||
| 		} | ||||
| 
 | ||||
| 		/* Move the numerator to the remainder.  */ | ||||
| 		if (rp != np) | ||||
| 			MPN_COPY(rp, np, nsize); | ||||
| 
 | ||||
| 		rsize = nsize; | ||||
| 	} | ||||
| 
 | ||||
| 	q_limb = mpihelp_divrem(qp, 0, rp, rsize, dp, dsize); | ||||
| 
 | ||||
| 	if (quot) { | ||||
| 		qsize = rsize - dsize; | ||||
| 		if (q_limb) { | ||||
| 			qp[qsize] = q_limb; | ||||
| 			qsize += 1; | ||||
| 		} | ||||
| 
 | ||||
| 		quot->nlimbs = qsize; | ||||
| 		quot->sign = sign_quotient; | ||||
| 	} | ||||
| 
 | ||||
| 	rsize = dsize; | ||||
| 	MPN_NORMALIZE(rp, rsize); | ||||
| 
 | ||||
| 	if (normalization_steps && rsize) { | ||||
| 		mpihelp_rshift(rp, rp, rsize, normalization_steps); | ||||
| 		rsize -= rp[rsize - 1] == 0 ? 1 : 0; | ||||
| 	} | ||||
| 
 | ||||
| 	rem->nlimbs = rsize; | ||||
| 	rem->sign = sign_remainder; | ||||
| 
 | ||||
| 	rc = 0; | ||||
| nomem: | ||||
| 	while (markidx) | ||||
| 		mpi_free_limb_space(marker[--markidx]); | ||||
| 	return rc; | ||||
| } | ||||
| 
 | ||||
| int mpi_tdiv_q_2exp(MPI w, MPI u, unsigned count) | ||||
| { | ||||
| 	mpi_size_t usize, wsize; | ||||
| 	mpi_size_t limb_cnt; | ||||
| 
 | ||||
| 	usize = u->nlimbs; | ||||
| 	limb_cnt = count / BITS_PER_MPI_LIMB; | ||||
| 	wsize = usize - limb_cnt; | ||||
| 	if (limb_cnt >= usize) | ||||
| 		w->nlimbs = 0; | ||||
| 	else { | ||||
| 		mpi_ptr_t wp; | ||||
| 		mpi_ptr_t up; | ||||
| 
 | ||||
| 		if (RESIZE_IF_NEEDED(w, wsize) < 0) | ||||
| 			return -ENOMEM; | ||||
| 		wp = w->d; | ||||
| 		up = u->d; | ||||
| 
 | ||||
| 		count %= BITS_PER_MPI_LIMB; | ||||
| 		if (count) { | ||||
| 			mpihelp_rshift(wp, up + limb_cnt, wsize, count); | ||||
| 			wsize -= !wp[wsize - 1]; | ||||
| 		} else { | ||||
| 			MPN_COPY_INCR(wp, up + limb_cnt, wsize); | ||||
| 		} | ||||
| 
 | ||||
| 		w->nlimbs = wsize; | ||||
| 	} | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| /****************
 | ||||
|  * Check whether dividend is divisible by divisor | ||||
|  * (note: divisor must fit into a limb) | ||||
|  */ | ||||
| int mpi_divisible_ui(MPI dividend, ulong divisor) | ||||
| { | ||||
| 	return !mpihelp_mod_1(dividend->d, dividend->nlimbs, divisor); | ||||
| } | ||||
|  | @ -1,59 +0,0 @@ | |||
| /* mpi-gcd.c  -  MPI functions
 | ||||
|  * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. | ||||
|  * | ||||
|  * This file is part of GnuPG. | ||||
|  * | ||||
|  * GnuPG is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation; either version 2 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * GnuPG is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA | ||||
|  */ | ||||
| 
 | ||||
| #include "mpi-internal.h" | ||||
| 
 | ||||
| /****************
 | ||||
|  * Find the greatest common divisor G of A and B. | ||||
|  * Return: true if this 1, false in all other cases | ||||
|  */ | ||||
| int mpi_gcd(MPI g, const MPI xa, const MPI xb) | ||||
| { | ||||
| 	MPI a = NULL, b = NULL; | ||||
| 
 | ||||
| 	if (mpi_copy(&a, xa) < 0) | ||||
| 		goto nomem; | ||||
| 
 | ||||
| 	if (mpi_copy(&b, xb) < 0) | ||||
| 		goto nomem; | ||||
| 
 | ||||
| 	/* TAOCP Vol II, 4.5.2, Algorithm A */ | ||||
| 	a->sign = 0; | ||||
| 	b->sign = 0; | ||||
| 	while (mpi_cmp_ui(b, 0)) { | ||||
| 		if (mpi_fdiv_r(g, a, b) < 0)	/* g used as temorary variable */ | ||||
| 			goto nomem; | ||||
| 		if (mpi_set(a, b) < 0) | ||||
| 			goto nomem; | ||||
| 		if (mpi_set(b, g) < 0) | ||||
| 			goto nomem; | ||||
| 	} | ||||
| 	if (mpi_set(g, a) < 0) | ||||
| 		goto nomem; | ||||
| 
 | ||||
| 	mpi_free(a); | ||||
| 	mpi_free(b); | ||||
| 	return !mpi_cmp_ui(g, 1); | ||||
| 
 | ||||
| nomem: | ||||
| 	mpi_free(a); | ||||
| 	mpi_free(b); | ||||
| 	return -ENOMEM; | ||||
| } | ||||
|  | @ -1,31 +0,0 @@ | |||
| /* mpi-inline.c
 | ||||
|  * Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc. | ||||
|  * | ||||
|  * This file is part of GnuPG. | ||||
|  * | ||||
|  * GnuPG is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation; either version 2 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * GnuPG is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA | ||||
|  */ | ||||
| 
 | ||||
| /* put the inline functions as real functions into the lib */ | ||||
| #define G10_MPI_INLINE_DECL | ||||
| 
 | ||||
| #include "mpi-internal.h" | ||||
| 
 | ||||
| /* always include the header becuase it is only
 | ||||
|  * included by mpi-internal if __GCC__ is defined but we | ||||
|  * need it here in all cases and the above definition of | ||||
|  * of the macro allows us to do so | ||||
|  */ | ||||
| #include "mpi-inline.h" | ||||
|  | @ -1,187 +0,0 @@ | |||
| /* mpi-inv.c  -  MPI functions
 | ||||
|  * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. | ||||
|  * | ||||
|  * This file is part of GnuPG. | ||||
|  * | ||||
|  * GnuPG is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation; either version 2 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * GnuPG is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA | ||||
|  */ | ||||
| 
 | ||||
| #include "mpi-internal.h" | ||||
| 
 | ||||
| /****************
 | ||||
|  * Calculate the multiplicative inverse X of A mod N | ||||
|  * That is: Find the solution x for | ||||
|  *		1 = (a*x) mod n | ||||
|  */ | ||||
| int mpi_invm(MPI x, const MPI a, const MPI n) | ||||
| { | ||||
| 	/* Extended Euclid's algorithm (See TAOPC Vol II, 4.5.2, Alg X)
 | ||||
| 	 * modified according to Michael Penk's solution for Exercice 35 | ||||
| 	 * with further enhancement */ | ||||
| 	MPI u = NULL, v = NULL; | ||||
| 	MPI u1 = NULL, u2 = NULL, u3 = NULL; | ||||
| 	MPI v1 = NULL, v2 = NULL, v3 = NULL; | ||||
| 	MPI t1 = NULL, t2 = NULL, t3 = NULL; | ||||
| 	unsigned k; | ||||
| 	int sign; | ||||
| 	int odd = 0; | ||||
| 	int rc = -ENOMEM; | ||||
| 
 | ||||
| 	if (mpi_copy(&u, a) < 0) | ||||
| 		goto cleanup; | ||||
| 	if (mpi_copy(&v, n) < 0) | ||||
| 		goto cleanup; | ||||
| 
 | ||||
| 	for (k = 0; !mpi_test_bit(u, 0) && !mpi_test_bit(v, 0); k++) { | ||||
| 		if (mpi_rshift(u, u, 1) < 0) | ||||
| 			goto cleanup; | ||||
| 		if (mpi_rshift(v, v, 1) < 0) | ||||
| 			goto cleanup; | ||||
| 	} | ||||
| 	odd = mpi_test_bit(v, 0); | ||||
| 
 | ||||
| 	u1 = mpi_alloc_set_ui(1); | ||||
| 	if (!u1) | ||||
| 		goto cleanup; | ||||
| 	if (!odd) { | ||||
| 		u2 = mpi_alloc_set_ui(0); | ||||
| 		if (!u2) | ||||
| 			goto cleanup; | ||||
| 	} | ||||
| 	if (mpi_copy(&u3, u) < 0) | ||||
| 		goto cleanup; | ||||
| 	if (mpi_copy(&v1, v) < 0) | ||||
| 		goto cleanup; | ||||
| 	if (!odd) { | ||||
| 		v2 = mpi_alloc(mpi_get_nlimbs(u)); | ||||
| 		if (!v2) | ||||
| 			goto cleanup; | ||||
| 		if (mpi_sub(v2, u1, u) < 0) | ||||
| 			goto cleanup;	/* U is used as const 1 */ | ||||
| 	} | ||||
| 	if (mpi_copy(&v3, v) < 0) | ||||
| 		goto cleanup; | ||||
| 	if (mpi_test_bit(u, 0)) {	/* u is odd */ | ||||
| 		t1 = mpi_alloc_set_ui(0); | ||||
| 		if (!t1) | ||||
| 			goto cleanup; | ||||
| 		if (!odd) { | ||||
| 			t2 = mpi_alloc_set_ui(1); | ||||
| 			if (!t2) | ||||
| 				goto cleanup; | ||||
| 			t2->sign = 1; | ||||
| 		} | ||||
| 		if (mpi_copy(&t3, v) < 0) | ||||
| 			goto cleanup; | ||||
| 		t3->sign = !t3->sign; | ||||
| 		goto Y4; | ||||
| 	} else { | ||||
| 		t1 = mpi_alloc_set_ui(1); | ||||
| 		if (!t1) | ||||
| 			goto cleanup; | ||||
| 		if (!odd) { | ||||
| 			t2 = mpi_alloc_set_ui(0); | ||||
| 			if (!t2) | ||||
| 				goto cleanup; | ||||
| 		} | ||||
| 		if (mpi_copy(&t3, u) < 0) | ||||
| 			goto cleanup; | ||||
| 	} | ||||
| 	do { | ||||
| 		do { | ||||
| 			if (!odd) { | ||||
| 				if (mpi_test_bit(t1, 0) || mpi_test_bit(t2, 0)) {	/* one is odd */ | ||||
| 					if (mpi_add(t1, t1, v) < 0) | ||||
| 						goto cleanup; | ||||
| 					if (mpi_sub(t2, t2, u) < 0) | ||||
| 						goto cleanup; | ||||
| 				} | ||||
| 				if (mpi_rshift(t1, t1, 1) < 0) | ||||
| 					goto cleanup; | ||||
| 				if (mpi_rshift(t2, t2, 1) < 0) | ||||
| 					goto cleanup; | ||||
| 				if (mpi_rshift(t3, t3, 1) < 0) | ||||
| 					goto cleanup; | ||||
| 			} else { | ||||
| 				if (mpi_test_bit(t1, 0)) | ||||
| 					if (mpi_add(t1, t1, v) < 0) | ||||
| 						goto cleanup; | ||||
| 				if (mpi_rshift(t1, t1, 1) < 0) | ||||
| 					goto cleanup; | ||||
| 				if (mpi_rshift(t3, t3, 1) < 0) | ||||
| 					goto cleanup; | ||||
| 			} | ||||
| Y4: | ||||
| 			; | ||||
| 		} while (!mpi_test_bit(t3, 0));	/* while t3 is even */ | ||||
| 
 | ||||
| 		if (!t3->sign) { | ||||
| 			if (mpi_set(u1, t1) < 0) | ||||
| 				goto cleanup; | ||||
| 			if (!odd) | ||||
| 				if (mpi_set(u2, t2) < 0) | ||||
| 					goto cleanup; | ||||
| 			if (mpi_set(u3, t3) < 0) | ||||
| 				goto cleanup; | ||||
| 		} else { | ||||
| 			if (mpi_sub(v1, v, t1) < 0) | ||||
| 				goto cleanup; | ||||
| 			sign = u->sign; | ||||
| 			u->sign = !u->sign; | ||||
| 			if (!odd) | ||||
| 				if (mpi_sub(v2, u, t2) < 0) | ||||
| 					goto cleanup; | ||||
| 			u->sign = sign; | ||||
| 			sign = t3->sign; | ||||
| 			t3->sign = !t3->sign; | ||||
| 			if (mpi_set(v3, t3) < 0) | ||||
| 				goto cleanup; | ||||
| 			t3->sign = sign; | ||||
| 		} | ||||
| 		if (mpi_sub(t1, u1, v1) < 0) | ||||
| 			goto cleanup; | ||||
| 		if (!odd) | ||||
| 			if (mpi_sub(t2, u2, v2) < 0) | ||||
| 				goto cleanup; | ||||
| 		if (mpi_sub(t3, u3, v3) < 0) | ||||
| 			goto cleanup; | ||||
| 		if (t1->sign) { | ||||
| 			if (mpi_add(t1, t1, v) < 0) | ||||
| 				goto cleanup; | ||||
| 			if (!odd) | ||||
| 				if (mpi_sub(t2, t2, u) < 0) | ||||
| 					goto cleanup; | ||||
| 		} | ||||
| 	} while (mpi_cmp_ui(t3, 0));	/* while t3 != 0 */ | ||||
| 	/* mpi_lshift( u3, k ); */ | ||||
| 	rc = mpi_set(x, u1); | ||||
| 
 | ||||
| cleanup: | ||||
| 	mpi_free(u1); | ||||
| 	mpi_free(v1); | ||||
| 	mpi_free(t1); | ||||
| 	if (!odd) { | ||||
| 		mpi_free(u2); | ||||
| 		mpi_free(v2); | ||||
| 		mpi_free(t2); | ||||
| 	} | ||||
| 	mpi_free(u3); | ||||
| 	mpi_free(v3); | ||||
| 	mpi_free(t3); | ||||
| 
 | ||||
| 	mpi_free(u); | ||||
| 	mpi_free(v); | ||||
| 	return rc; | ||||
| } | ||||
|  | @ -1,134 +0,0 @@ | |||
| /* mpi-mpow.c  -  MPI functions
 | ||||
|  * Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc. | ||||
|  * | ||||
|  * This file is part of GnuPG. | ||||
|  * | ||||
|  * GnuPG is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation; either version 2 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * GnuPG is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA | ||||
|  */ | ||||
| 
 | ||||
| #include "mpi-internal.h" | ||||
| #include "longlong.h" | ||||
| 
 | ||||
| static int build_index(const MPI *exparray, int k, int i, int t) | ||||
| { | ||||
| 	int j, bitno; | ||||
| 	int index = 0; | ||||
| 
 | ||||
| 	bitno = t - i; | ||||
| 	for (j = k - 1; j >= 0; j--) { | ||||
| 		index <<= 1; | ||||
| 		if (mpi_test_bit(exparray[j], bitno)) | ||||
| 			index |= 1; | ||||
| 	} | ||||
| 	return index; | ||||
| } | ||||
| 
 | ||||
| /****************
 | ||||
|  * RES = (BASE[0] ^ EXP[0]) *  (BASE[1] ^ EXP[1]) * ... * mod M | ||||
|  */ | ||||
| int mpi_mulpowm(MPI res, MPI *basearray, MPI *exparray, MPI m) | ||||
| { | ||||
| 	int rc = -ENOMEM; | ||||
| 	int k;			/* number of elements */ | ||||
| 	int t;			/* bit size of largest exponent */ | ||||
| 	int i, j, idx; | ||||
| 	MPI *G = NULL;		/* table with precomputed values of size 2^k */ | ||||
| 	MPI tmp = NULL; | ||||
| 
 | ||||
| 	for (k = 0; basearray[k]; k++) | ||||
| 		; | ||||
| 	if (!k) { | ||||
| 		pr_emerg("mpi_mulpowm: assert(k) failed\n"); | ||||
| 		BUG(); | ||||
| 	} | ||||
| 	for (t = 0, i = 0; (tmp = exparray[i]); i++) { | ||||
| 		j = mpi_get_nbits(tmp); | ||||
| 		if (j > t) | ||||
| 			t = j; | ||||
| 	} | ||||
| 	if (i != k) { | ||||
| 		pr_emerg("mpi_mulpowm: assert(i==k) failed\n"); | ||||
| 		BUG(); | ||||
| 	} | ||||
| 	if (!t) { | ||||
| 		pr_emerg("mpi_mulpowm: assert(t) failed\n"); | ||||
| 		BUG(); | ||||
| 	} | ||||
| 	if (k >= 10) { | ||||
| 		pr_emerg("mpi_mulpowm: assert(k<10) failed\n"); | ||||
| 		BUG(); | ||||
| 	} | ||||
| 
 | ||||
| 	G = kzalloc((1 << k) * sizeof *G, GFP_KERNEL); | ||||
| 	if (!G) | ||||
| 		goto err_out; | ||||
| 
 | ||||
| 	/* and calculate */ | ||||
| 	tmp = mpi_alloc(mpi_get_nlimbs(m) + 1); | ||||
| 	if (!tmp) | ||||
| 		goto nomem; | ||||
| 	if (mpi_set_ui(res, 1) < 0) | ||||
| 		goto nomem; | ||||
| 	for (i = 1; i <= t; i++) { | ||||
| 		if (mpi_mulm(tmp, res, res, m) < 0) | ||||
| 			goto nomem; | ||||
| 		idx = build_index(exparray, k, i, t); | ||||
| 		if (!(idx >= 0 && idx < (1 << k))) { | ||||
| 			pr_emerg("mpi_mulpowm: assert(idx >= 0 && idx < (1<<k)) failed\n"); | ||||
| 			BUG(); | ||||
| 		} | ||||
| 		if (!G[idx]) { | ||||
| 			if (!idx) { | ||||
| 				G[0] = mpi_alloc_set_ui(1); | ||||
| 				if (!G[0]) | ||||
| 					goto nomem; | ||||
| 			} else { | ||||
| 				for (j = 0; j < k; j++) { | ||||
| 					if ((idx & (1 << j))) { | ||||
| 						if (!G[idx]) { | ||||
| 							if (mpi_copy | ||||
| 							    (&G[idx], | ||||
| 							     basearray[j]) < 0) | ||||
| 								goto nomem; | ||||
| 						} else { | ||||
| 							if (mpi_mulm | ||||
| 							    (G[idx], G[idx], | ||||
| 							     basearray[j], | ||||
| 							     m) < 0) | ||||
| 								goto nomem; | ||||
| 						} | ||||
| 					} | ||||
| 				} | ||||
| 				if (!G[idx]) { | ||||
| 					G[idx] = mpi_alloc(0); | ||||
| 					if (!G[idx]) | ||||
| 						goto nomem; | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		if (mpi_mulm(res, tmp, G[idx], m) < 0) | ||||
| 			goto nomem; | ||||
| 	} | ||||
| 
 | ||||
| 	rc = 0; | ||||
| nomem: | ||||
| 	/* cleanup */ | ||||
| 	mpi_free(tmp); | ||||
| 	for (i = 0; i < (1 << k); i++) | ||||
| 		mpi_free(G[i]); | ||||
| 	kfree(G); | ||||
| err_out: | ||||
| 	return rc; | ||||
| } | ||||
|  | @ -1,194 +0,0 @@ | |||
| /* mpi-mul.c  -  MPI functions
 | ||||
|  *	Copyright (C) 1994, 1996 Free Software Foundation, Inc. | ||||
|  *	Copyright (C) 1998, 2001 Free Software Foundation, Inc. | ||||
|  * | ||||
|  * This file is part of GnuPG. | ||||
|  * | ||||
|  * GnuPG is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation; either version 2 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * GnuPG is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA | ||||
|  * | ||||
|  * Note: This code is heavily based on the GNU MP Library. | ||||
|  *	 Actually it's the same code with only minor changes in the | ||||
|  *	 way the data is stored; this is to support the abstraction | ||||
|  *	 of an optional secure memory allocation which may be used | ||||
|  *	 to avoid revealing of sensitive data due to paging etc. | ||||
|  *	 The GNU MP Library itself is published under the LGPL; | ||||
|  *	 however I decided to publish this code under the plain GPL. | ||||
|  */ | ||||
| 
 | ||||
| #include "mpi-internal.h" | ||||
| 
 | ||||
| int mpi_mul_ui(MPI prod, MPI mult, unsigned long small_mult) | ||||
| { | ||||
| 	mpi_size_t size, prod_size; | ||||
| 	mpi_ptr_t prod_ptr; | ||||
| 	mpi_limb_t cy; | ||||
| 	int sign; | ||||
| 
 | ||||
| 	size = mult->nlimbs; | ||||
| 	sign = mult->sign; | ||||
| 
 | ||||
| 	if (!size || !small_mult) { | ||||
| 		prod->nlimbs = 0; | ||||
| 		prod->sign = 0; | ||||
| 		return 0; | ||||
| 	} | ||||
| 
 | ||||
| 	prod_size = size + 1; | ||||
| 	if (prod->alloced < prod_size) | ||||
| 		if (mpi_resize(prod, prod_size) < 0) | ||||
| 			return -ENOMEM; | ||||
| 	prod_ptr = prod->d; | ||||
| 
 | ||||
| 	cy = mpihelp_mul_1(prod_ptr, mult->d, size, (mpi_limb_t) small_mult); | ||||
| 	if (cy) | ||||
| 		prod_ptr[size++] = cy; | ||||
| 	prod->nlimbs = size; | ||||
| 	prod->sign = sign; | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| int mpi_mul_2exp(MPI w, MPI u, unsigned long cnt) | ||||
| { | ||||
| 	mpi_size_t usize, wsize, limb_cnt; | ||||
| 	mpi_ptr_t wp; | ||||
| 	mpi_limb_t wlimb; | ||||
| 	int usign, wsign; | ||||
| 
 | ||||
| 	usize = u->nlimbs; | ||||
| 	usign = u->sign; | ||||
| 
 | ||||
| 	if (!usize) { | ||||
| 		w->nlimbs = 0; | ||||
| 		w->sign = 0; | ||||
| 		return 0; | ||||
| 	} | ||||
| 
 | ||||
| 	limb_cnt = cnt / BITS_PER_MPI_LIMB; | ||||
| 	wsize = usize + limb_cnt + 1; | ||||
| 	if (w->alloced < wsize) | ||||
| 		if (mpi_resize(w, wsize) < 0) | ||||
| 			return -ENOMEM; | ||||
| 	wp = w->d; | ||||
| 	wsize = usize + limb_cnt; | ||||
| 	wsign = usign; | ||||
| 
 | ||||
| 	cnt %= BITS_PER_MPI_LIMB; | ||||
| 	if (cnt) { | ||||
| 		wlimb = mpihelp_lshift(wp + limb_cnt, u->d, usize, cnt); | ||||
| 		if (wlimb) { | ||||
| 			wp[wsize] = wlimb; | ||||
| 			wsize++; | ||||
| 		} | ||||
| 	} else { | ||||
| 		MPN_COPY_DECR(wp + limb_cnt, u->d, usize); | ||||
| 	} | ||||
| 
 | ||||
| 	/* Zero all whole limbs at low end.  Do it here and not before calling
 | ||||
| 	 * mpn_lshift, not to lose for U == W.  */ | ||||
| 	MPN_ZERO(wp, limb_cnt); | ||||
| 
 | ||||
| 	w->nlimbs = wsize; | ||||
| 	w->sign = wsign; | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| int mpi_mul(MPI w, MPI u, MPI v) | ||||
| { | ||||
| 	int rc = -ENOMEM; | ||||
| 	mpi_size_t usize, vsize, wsize; | ||||
| 	mpi_ptr_t up, vp, wp; | ||||
| 	mpi_limb_t cy; | ||||
| 	int usign, vsign, sign_product; | ||||
| 	int assign_wp = 0; | ||||
| 	mpi_ptr_t tmp_limb = NULL; | ||||
| 
 | ||||
| 	if (u->nlimbs < v->nlimbs) {	/* Swap U and V. */ | ||||
| 		usize = v->nlimbs; | ||||
| 		usign = v->sign; | ||||
| 		up = v->d; | ||||
| 		vsize = u->nlimbs; | ||||
| 		vsign = u->sign; | ||||
| 		vp = u->d; | ||||
| 	} else { | ||||
| 		usize = u->nlimbs; | ||||
| 		usign = u->sign; | ||||
| 		up = u->d; | ||||
| 		vsize = v->nlimbs; | ||||
| 		vsign = v->sign; | ||||
| 		vp = v->d; | ||||
| 	} | ||||
| 	sign_product = usign ^ vsign; | ||||
| 	wp = w->d; | ||||
| 
 | ||||
| 	/* Ensure W has space enough to store the result.  */ | ||||
| 	wsize = usize + vsize; | ||||
| 	if (w->alloced < (size_t) wsize) { | ||||
| 		if (wp == up || wp == vp) { | ||||
| 			wp = mpi_alloc_limb_space(wsize); | ||||
| 			if (!wp) | ||||
| 				goto nomem; | ||||
| 			assign_wp = 1; | ||||
| 		} else { | ||||
| 			if (mpi_resize(w, wsize) < 0) | ||||
| 				goto nomem; | ||||
| 			wp = w->d; | ||||
| 		} | ||||
| 	} else {		/* Make U and V not overlap with W.      */ | ||||
| 		if (wp == up) { | ||||
| 			/* W and U are identical.  Allocate temporary space for U.      */ | ||||
| 			up = tmp_limb = mpi_alloc_limb_space(usize); | ||||
| 			if (!up) | ||||
| 				goto nomem; | ||||
| 			/* Is V identical too?  Keep it identical with U.  */ | ||||
| 			if (wp == vp) | ||||
| 				vp = up; | ||||
| 			/* Copy to the temporary space.  */ | ||||
| 			MPN_COPY(up, wp, usize); | ||||
| 		} else if (wp == vp) { | ||||
| 			/* W and V are identical.  Allocate temporary space for V.      */ | ||||
| 			vp = tmp_limb = mpi_alloc_limb_space(vsize); | ||||
| 			if (!vp) | ||||
| 				goto nomem; | ||||
| 			/* Copy to the temporary space.  */ | ||||
| 			MPN_COPY(vp, wp, vsize); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if (!vsize) | ||||
| 		wsize = 0; | ||||
| 	else { | ||||
| 		if (mpihelp_mul(wp, up, usize, vp, vsize, &cy) < 0) | ||||
| 			goto nomem; | ||||
| 		wsize -= cy ? 0 : 1; | ||||
| 	} | ||||
| 
 | ||||
| 	if (assign_wp) | ||||
| 		mpi_assign_limb_space(w, wp, wsize); | ||||
| 
 | ||||
| 	w->nlimbs = wsize; | ||||
| 	w->sign = sign_product; | ||||
| 	rc = 0; | ||||
| nomem: | ||||
| 	if (tmp_limb) | ||||
| 		mpi_free_limb_space(tmp_limb); | ||||
| 	return rc; | ||||
| } | ||||
| 
 | ||||
| int mpi_mulm(MPI w, MPI u, MPI v, MPI m) | ||||
| { | ||||
| 	if (mpi_mul(w, u, v) < 0) | ||||
| 		return -ENOMEM; | ||||
| 	return mpi_fdiv_r(w, w, m); | ||||
| } | ||||
|  | @ -1,136 +0,0 @@ | |||
| /* mpi-scan.c  -  MPI functions
 | ||||
|  * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. | ||||
|  * | ||||
|  * This file is part of GnuPG. | ||||
|  * | ||||
|  * GnuPG is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation; either version 2 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * GnuPG is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA | ||||
|  */ | ||||
| 
 | ||||
| #include "mpi-internal.h" | ||||
| #include "longlong.h" | ||||
| 
 | ||||
| /****************
 | ||||
|  * Scan through an mpi and return byte for byte. a -1 is returned to indicate | ||||
|  * the end of the mpi. Scanning is done from the lsb to the msb, returned | ||||
|  * values are in the range of 0 .. 255. | ||||
|  * | ||||
|  * FIXME: This code is VERY ugly! | ||||
|  */ | ||||
| int mpi_getbyte(const MPI a, unsigned idx) | ||||
| { | ||||
| 	int i, j; | ||||
| 	unsigned n; | ||||
| 	mpi_ptr_t ap; | ||||
| 	mpi_limb_t limb; | ||||
| 
 | ||||
| 	ap = a->d; | ||||
| 	for (n = 0, i = 0; i < a->nlimbs; i++) { | ||||
| 		limb = ap[i]; | ||||
| 		for (j = 0; j < BYTES_PER_MPI_LIMB; j++, n++) | ||||
| 			if (n == idx) | ||||
| 				return (limb >> j * 8) & 0xff; | ||||
| 	} | ||||
| 	return -1; | ||||
| } | ||||
| 
 | ||||
| /****************
 | ||||
|  * Put a value at position IDX into A. idx counts from lsb to msb | ||||
|  */ | ||||
| void mpi_putbyte(MPI a, unsigned idx, int xc) | ||||
| { | ||||
| 	int i, j; | ||||
| 	unsigned n; | ||||
| 	mpi_ptr_t ap; | ||||
| 	mpi_limb_t limb, c; | ||||
| 
 | ||||
| 	c = xc & 0xff; | ||||
| 	ap = a->d; | ||||
| 	for (n = 0, i = 0; i < a->alloced; i++) { | ||||
| 		limb = ap[i]; | ||||
| 		for (j = 0; j < BYTES_PER_MPI_LIMB; j++, n++) | ||||
| 			if (n == idx) { | ||||
| #if BYTES_PER_MPI_LIMB == 4 | ||||
| 				if (j == 0) | ||||
| 					limb = (limb & 0xffffff00) | c; | ||||
| 				else if (j == 1) | ||||
| 					limb = (limb & 0xffff00ff) | (c << 8); | ||||
| 				else if (j == 2) | ||||
| 					limb = (limb & 0xff00ffff) | (c << 16); | ||||
| 				else | ||||
| 					limb = (limb & 0x00ffffff) | (c << 24); | ||||
| #elif BYTES_PER_MPI_LIMB == 8 | ||||
| 				if (j == 0) | ||||
| 					limb = (limb & 0xffffffffffffff00) | c; | ||||
| 				else if (j == 1) | ||||
| 					limb = | ||||
| 					    (limb & 0xffffffffffff00ff) | (c << | ||||
| 									   8); | ||||
| 				else if (j == 2) | ||||
| 					limb = | ||||
| 					    (limb & 0xffffffffff00ffff) | (c << | ||||
| 									   16); | ||||
| 				else if (j == 3) | ||||
| 					limb = | ||||
| 					    (limb & 0xffffffff00ffffff) | (c << | ||||
| 									   24); | ||||
| 				else if (j == 4) | ||||
| 					limb = | ||||
| 					    (limb & 0xffffff00ffffffff) | (c << | ||||
| 									   32); | ||||
| 				else if (j == 5) | ||||
| 					limb = | ||||
| 					    (limb & 0xffff00ffffffffff) | (c << | ||||
| 									   40); | ||||
| 				else if (j == 6) | ||||
| 					limb = | ||||
| 					    (limb & 0xff00ffffffffffff) | (c << | ||||
| 									   48); | ||||
| 				else | ||||
| 					limb = | ||||
| 					    (limb & 0x00ffffffffffffff) | (c << | ||||
| 									   56); | ||||
| #else | ||||
| #error please enhance this function, its ugly - i know. | ||||
| #endif | ||||
| 				if (a->nlimbs <= i) | ||||
| 					a->nlimbs = i + 1; | ||||
| 				ap[i] = limb; | ||||
| 				return; | ||||
| 			} | ||||
| 	} | ||||
| 	log_bug("index out of range\n"); | ||||
| } | ||||
| 
 | ||||
| /****************
 | ||||
|  * Count the number of zerobits at the low end of A | ||||
|  */ | ||||
| unsigned mpi_trailing_zeros(const MPI a) | ||||
| { | ||||
| 	unsigned n, count = 0; | ||||
| 
 | ||||
| 	for (n = 0; n < a->nlimbs; n++) { | ||||
| 		if (a->d[n]) { | ||||
| 			unsigned nn; | ||||
| 			mpi_limb_t alimb = a->d[n]; | ||||
| 
 | ||||
| 			count_trailing_zeros(nn, alimb); | ||||
| 			count += nn; | ||||
| 			break; | ||||
| 		} | ||||
| 		count += BITS_PER_MPI_LIMB; | ||||
| 	} | ||||
| 	return count; | ||||
| 
 | ||||
| } | ||||
		Loading…
	
		Reference in a new issue
	
	 Dmitry Kasatkin
						Dmitry Kasatkin