/* mpi-div.c  -  MPI functions
 * Copyright (C) 1994, 1996, 1998, 2001, 2002,
 *               2003 Free Software Foundation, Inc.
 *
 * This file is part of Libgcrypt.
 *
 * 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.
 */

#include "mpi-internal.h"
#include "longlong.h"

int mpi_tdiv_qr(MPI quot, MPI rem, MPI num, MPI den);

int mpi_fdiv_r(MPI rem, MPI dividend, MPI divisor)
{
	int divisor_sign = divisor->sign;
	MPI temp_divisor = NULL;
	int err;

	/* 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) {
		temp_divisor = mpi_copy(divisor);
		if (!temp_divisor)
			return -ENOMEM;
		divisor = temp_divisor;
	}

	err = mpi_tdiv_r(rem, dividend, divisor);
	if (err)
		goto free_temp_divisor;

	if (((divisor_sign?1:0) ^ (dividend->sign?1:0)) && rem->nlimbs)
		err = mpi_add(rem, rem, divisor);

free_temp_divisor:
	mpi_free(temp_divisor);

	return err;
}

/* 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)
{
	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 int normalization_steps;
	mpi_limb_t q_limb;
	mpi_ptr_t marker[5];
	int markidx = 0;
	int err;

	/* 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;
	err = mpi_resize(rem, rsize);
	if (err)
		return err;

	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) {
		err = mpi_resize(quot, qsize);
		if (err)
			return err;
	}

	/* 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;
	}

	err = -ENOMEM;
	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 out_free_marker;
			MPN_COPY(np, qp, nsize);
		}
	} else /* Put quotient at top of remainder. */
		qp = rp + dsize;

	normalization_steps = count_leading_zeros(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 out_free_marker;
		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 out_free_marker;
			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;

	err = 0;

out_free_marker:
	while (markidx) {
		markidx--;
		mpi_free_limb_space(marker[markidx]);
	}

	return err;
}
