1 /* mpi-mul.c - MPI functions 1 /* mpi-mul.c - MPI functions 2 * Copyright (C) 1994, 1996, 1998, 2001, 2002, 2 * Copyright (C) 1994, 1996, 1998, 2001, 2002, 3 * 2003 Free Software Foundation 3 * 2003 Free Software Foundation, Inc. 4 * 4 * 5 * This file is part of Libgcrypt. 5 * This file is part of Libgcrypt. 6 * 6 * 7 * Note: This code is heavily based on the GNU 7 * Note: This code is heavily based on the GNU MP Library. 8 * Actually it's the same code with only 8 * Actually it's the same code with only minor changes in the 9 * way the data is stored; this is to su 9 * way the data is stored; this is to support the abstraction 10 * of an optional secure memory allocati 10 * of an optional secure memory allocation which may be used 11 * to avoid revealing of sensitive data 11 * to avoid revealing of sensitive data due to paging etc. 12 */ 12 */ 13 13 14 #include "mpi-internal.h" 14 #include "mpi-internal.h" 15 15 16 void mpi_mul(MPI w, MPI u, MPI v) 16 void mpi_mul(MPI w, MPI u, MPI v) 17 { 17 { 18 mpi_size_t usize, vsize, wsize; 18 mpi_size_t usize, vsize, wsize; 19 mpi_ptr_t up, vp, wp; 19 mpi_ptr_t up, vp, wp; 20 mpi_limb_t cy; 20 mpi_limb_t cy; 21 int usign, vsign, sign_product; 21 int usign, vsign, sign_product; 22 int assign_wp = 0; 22 int assign_wp = 0; 23 mpi_ptr_t tmp_limb = NULL; 23 mpi_ptr_t tmp_limb = NULL; 24 24 25 if (u->nlimbs < v->nlimbs) { 25 if (u->nlimbs < v->nlimbs) { 26 /* Swap U and V. */ 26 /* Swap U and V. */ 27 usize = v->nlimbs; 27 usize = v->nlimbs; 28 usign = v->sign; 28 usign = v->sign; 29 up = v->d; 29 up = v->d; 30 vsize = u->nlimbs; 30 vsize = u->nlimbs; 31 vsign = u->sign; 31 vsign = u->sign; 32 vp = u->d; 32 vp = u->d; 33 } else { 33 } else { 34 usize = u->nlimbs; 34 usize = u->nlimbs; 35 usign = u->sign; 35 usign = u->sign; 36 up = u->d; 36 up = u->d; 37 vsize = v->nlimbs; 37 vsize = v->nlimbs; 38 vsign = v->sign; 38 vsign = v->sign; 39 vp = v->d; 39 vp = v->d; 40 } 40 } 41 sign_product = usign ^ vsign; 41 sign_product = usign ^ vsign; 42 wp = w->d; 42 wp = w->d; 43 43 44 /* Ensure W has space enough to store 44 /* Ensure W has space enough to store the result. */ 45 wsize = usize + vsize; 45 wsize = usize + vsize; 46 if (w->alloced < wsize) { 46 if (w->alloced < wsize) { 47 if (wp == up || wp == vp) { 47 if (wp == up || wp == vp) { 48 wp = mpi_alloc_limb_sp 48 wp = mpi_alloc_limb_space(wsize); 49 assign_wp = 1; 49 assign_wp = 1; 50 } else { 50 } else { 51 mpi_resize(w, wsize); 51 mpi_resize(w, wsize); 52 wp = w->d; 52 wp = w->d; 53 } 53 } 54 } else { /* Make U and V not overlap w 54 } else { /* Make U and V not overlap with W. */ 55 if (wp == up) { 55 if (wp == up) { 56 /* W and U are identic 56 /* W and U are identical. Allocate temporary space for U. */ 57 up = tmp_limb = mpi_al 57 up = tmp_limb = mpi_alloc_limb_space(usize); 58 /* Is V identical too? 58 /* Is V identical too? Keep it identical with U. */ 59 if (wp == vp) 59 if (wp == vp) 60 vp = up; 60 vp = up; 61 /* Copy to the tempora 61 /* Copy to the temporary space. */ 62 MPN_COPY(up, wp, usize 62 MPN_COPY(up, wp, usize); 63 } else if (wp == vp) { 63 } else if (wp == vp) { 64 /* W and V are identic 64 /* W and V are identical. Allocate temporary space for V. */ 65 vp = tmp_limb = mpi_al 65 vp = tmp_limb = mpi_alloc_limb_space(vsize); 66 /* Copy to the tempora 66 /* Copy to the temporary space. */ 67 MPN_COPY(vp, wp, vsize 67 MPN_COPY(vp, wp, vsize); 68 } 68 } 69 } 69 } 70 70 71 if (!vsize) 71 if (!vsize) 72 wsize = 0; 72 wsize = 0; 73 else { 73 else { 74 mpihelp_mul(wp, up, usize, vp, 74 mpihelp_mul(wp, up, usize, vp, vsize, &cy); 75 wsize -= cy ? 0:1; 75 wsize -= cy ? 0:1; 76 } 76 } 77 77 78 if (assign_wp) 78 if (assign_wp) 79 mpi_assign_limb_space(w, wp, w 79 mpi_assign_limb_space(w, wp, wsize); 80 w->nlimbs = wsize; 80 w->nlimbs = wsize; 81 w->sign = sign_product; 81 w->sign = sign_product; 82 if (tmp_limb) 82 if (tmp_limb) 83 mpi_free_limb_space(tmp_limb); 83 mpi_free_limb_space(tmp_limb); 84 } 84 } 85 EXPORT_SYMBOL_GPL(mpi_mul); 85 EXPORT_SYMBOL_GPL(mpi_mul); 86 86 87 void mpi_mulm(MPI w, MPI u, MPI v, MPI m) 87 void mpi_mulm(MPI w, MPI u, MPI v, MPI m) 88 { 88 { 89 mpi_mul(w, u, v); 89 mpi_mul(w, u, v); 90 mpi_tdiv_r(w, w, m); 90 mpi_tdiv_r(w, w, m); 91 } 91 } 92 EXPORT_SYMBOL_GPL(mpi_mulm); 92 EXPORT_SYMBOL_GPL(mpi_mulm); 93 93
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.