Linux Audio

Check our new training course

Loading...
v6.13.7
  1/* mpi-mul.c  -  MPI functions
  2 * 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 the
  9 *	 way the data is stored; this is to support the abstraction
 10 *	 of an optional secure memory allocation which may be used
 11 *	 to avoid revealing of sensitive data due to paging etc.
 12 */
 13
 14#include "mpi-internal.h"
 15
 16int mpi_mul(MPI w, MPI u, MPI v)
 17{
 18	mpi_size_t usize, vsize, wsize;
 19	mpi_ptr_t up, vp, wp;
 20	mpi_limb_t cy;
 21	int usign, vsign, sign_product;
 22	int assign_wp = 0;
 23	mpi_ptr_t tmp_limb = NULL;
 24	int err = 0;
 25
 26	if (u->nlimbs < v->nlimbs) {
 27		/* Swap U and V. */
 28		usize = v->nlimbs;
 29		usign = v->sign;
 30		up    = v->d;
 31		vsize = u->nlimbs;
 32		vsign = u->sign;
 33		vp    = u->d;
 34	} else {
 35		usize = u->nlimbs;
 36		usign = u->sign;
 37		up    = u->d;
 38		vsize = v->nlimbs;
 39		vsign = v->sign;
 40		vp    = v->d;
 41	}
 42	sign_product = usign ^ vsign;
 43	wp = w->d;
 44
 45	/* Ensure W has space enough to store the result.  */
 46	wsize = usize + vsize;
 47	if (w->alloced < wsize) {
 48		if (wp == up || wp == vp) {
 49			wp = mpi_alloc_limb_space(wsize);
 50			if (!wp)
 51				return -ENOMEM;
 52			assign_wp = 1;
 53		} else {
 54			err = mpi_resize(w, wsize);
 55			if (err)
 56				return err;
 57			wp = w->d;
 58		}
 59	} else { /* Make U and V not overlap with W.	*/
 60		if (wp == up) {
 61			/* W and U are identical.  Allocate temporary space for U. */
 62			up = tmp_limb = mpi_alloc_limb_space(usize);
 63			if (!up)
 64				return -ENOMEM;
 65			/* Is V identical too?  Keep it identical with U.  */
 66			if (wp == vp)
 67				vp = up;
 68			/* Copy to the temporary space.  */
 69			MPN_COPY(up, wp, usize);
 70		} else if (wp == vp) {
 71			/* W and V are identical.  Allocate temporary space for V. */
 72			vp = tmp_limb = mpi_alloc_limb_space(vsize);
 73			if (!vp)
 74				return -ENOMEM;
 75			/* Copy to the temporary space.  */
 76			MPN_COPY(vp, wp, vsize);
 77		}
 78	}
 79
 80	if (!vsize)
 81		wsize = 0;
 82	else {
 83		err = mpihelp_mul(wp, up, usize, vp, vsize, &cy);
 84		if (err) {
 85			if (assign_wp)
 86				mpi_free_limb_space(wp);
 87			goto free_tmp_limb;
 88		}
 89		wsize -= cy ? 0:1;
 90	}
 91
 92	if (assign_wp)
 93		mpi_assign_limb_space(w, wp, wsize);
 94	w->nlimbs = wsize;
 95	w->sign = sign_product;
 96
 97free_tmp_limb:
 98	if (tmp_limb)
 99		mpi_free_limb_space(tmp_limb);
100	return err;
101}
102EXPORT_SYMBOL_GPL(mpi_mul);
103
104int mpi_mulm(MPI w, MPI u, MPI v, MPI m)
105{
106	return mpi_mul(w, u, v) ?:
107	       mpi_tdiv_r(w, w, m);
108}
109EXPORT_SYMBOL_GPL(mpi_mulm);
v6.8
 1/* mpi-mul.c  -  MPI functions
 2 * 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 the
 9 *	 way the data is stored; this is to support the abstraction
10 *	 of an optional secure memory allocation which may be used
11 *	 to avoid revealing of sensitive data due to paging etc.
12 */
13
14#include "mpi-internal.h"
15
16void mpi_mul(MPI w, MPI u, MPI v)
17{
18	mpi_size_t usize, vsize, wsize;
19	mpi_ptr_t up, vp, wp;
20	mpi_limb_t cy;
21	int usign, vsign, sign_product;
22	int assign_wp = 0;
23	mpi_ptr_t tmp_limb = NULL;
 
24
25	if (u->nlimbs < v->nlimbs) {
26		/* Swap U and V. */
27		usize = v->nlimbs;
28		usign = v->sign;
29		up    = v->d;
30		vsize = u->nlimbs;
31		vsign = u->sign;
32		vp    = u->d;
33	} else {
34		usize = u->nlimbs;
35		usign = u->sign;
36		up    = u->d;
37		vsize = v->nlimbs;
38		vsign = v->sign;
39		vp    = v->d;
40	}
41	sign_product = usign ^ vsign;
42	wp = w->d;
43
44	/* Ensure W has space enough to store the result.  */
45	wsize = usize + vsize;
46	if (w->alloced < wsize) {
47		if (wp == up || wp == vp) {
48			wp = mpi_alloc_limb_space(wsize);
 
 
49			assign_wp = 1;
50		} else {
51			mpi_resize(w, wsize);
 
 
52			wp = w->d;
53		}
54	} else { /* Make U and V not overlap with W.	*/
55		if (wp == up) {
56			/* W and U are identical.  Allocate temporary space for U. */
57			up = tmp_limb = mpi_alloc_limb_space(usize);
 
 
58			/* Is V identical too?  Keep it identical with U.  */
59			if (wp == vp)
60				vp = up;
61			/* Copy to the temporary space.  */
62			MPN_COPY(up, wp, usize);
63		} else if (wp == vp) {
64			/* W and V are identical.  Allocate temporary space for V. */
65			vp = tmp_limb = mpi_alloc_limb_space(vsize);
 
 
66			/* Copy to the temporary space.  */
67			MPN_COPY(vp, wp, vsize);
68		}
69	}
70
71	if (!vsize)
72		wsize = 0;
73	else {
74		mpihelp_mul(wp, up, usize, vp, vsize, &cy);
 
 
 
 
 
75		wsize -= cy ? 0:1;
76	}
77
78	if (assign_wp)
79		mpi_assign_limb_space(w, wp, wsize);
80	w->nlimbs = wsize;
81	w->sign = sign_product;
 
 
82	if (tmp_limb)
83		mpi_free_limb_space(tmp_limb);
 
84}
85EXPORT_SYMBOL_GPL(mpi_mul);
86
87void mpi_mulm(MPI w, MPI u, MPI v, MPI m)
88{
89	mpi_mul(w, u, v);
90	mpi_tdiv_r(w, w, m);
91}
92EXPORT_SYMBOL_GPL(mpi_mulm);