1 /* mpi-add.c - MPI functions 1 /* mpi-add.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 int mpi_add(MPI w, MPI u, MPI v) !! 16 /**************** >> 17 * Add the unsigned integer V to the mpi-integer U and store the >> 18 * result in W. U and V may be the same. >> 19 */ >> 20 void mpi_add_ui(MPI w, MPI u, unsigned long v) >> 21 { >> 22 mpi_ptr_t wp, up; >> 23 mpi_size_t usize, wsize; >> 24 int usign, wsign; >> 25 >> 26 usize = u->nlimbs; >> 27 usign = u->sign; >> 28 wsign = 0; >> 29 >> 30 /* If not space for W (and possible carry), increase space. */ >> 31 wsize = usize + 1; >> 32 if (w->alloced < wsize) >> 33 mpi_resize(w, wsize); >> 34 >> 35 /* These must be after realloc (U may be the same as W). */ >> 36 up = u->d; >> 37 wp = w->d; >> 38 >> 39 if (!usize) { /* simple */ >> 40 wp[0] = v; >> 41 wsize = v ? 1:0; >> 42 } else if (!usign) { /* mpi is not negative */ >> 43 mpi_limb_t cy; >> 44 cy = mpihelp_add_1(wp, up, usize, v); >> 45 wp[usize] = cy; >> 46 wsize = usize + cy; >> 47 } else { >> 48 /* The signs are different. Need exact comparison to determine >> 49 * which operand to subtract from which. >> 50 */ >> 51 if (usize == 1 && up[0] < v) { >> 52 wp[0] = v - up[0]; >> 53 wsize = 1; >> 54 } else { >> 55 mpihelp_sub_1(wp, up, usize, v); >> 56 /* Size can decrease with at most one limb. */ >> 57 wsize = usize - (wp[usize-1] == 0); >> 58 wsign = 1; >> 59 } >> 60 } >> 61 >> 62 w->nlimbs = wsize; >> 63 w->sign = wsign; >> 64 } >> 65 >> 66 >> 67 void mpi_add(MPI w, MPI u, MPI v) 17 { 68 { 18 mpi_ptr_t wp, up, vp; 69 mpi_ptr_t wp, up, vp; 19 mpi_size_t usize, vsize, wsize; 70 mpi_size_t usize, vsize, wsize; 20 int usign, vsign, wsign; 71 int usign, vsign, wsign; 21 int err; << 22 72 23 if (u->nlimbs < v->nlimbs) { /* Swap U 73 if (u->nlimbs < v->nlimbs) { /* Swap U and V. */ 24 usize = v->nlimbs; 74 usize = v->nlimbs; 25 usign = v->sign; 75 usign = v->sign; 26 vsize = u->nlimbs; 76 vsize = u->nlimbs; 27 vsign = u->sign; 77 vsign = u->sign; 28 wsize = usize + 1; 78 wsize = usize + 1; 29 err = RESIZE_IF_NEEDED(w, wsiz !! 79 RESIZE_IF_NEEDED(w, wsize); 30 if (err) << 31 return err; << 32 /* These must be after realloc 80 /* These must be after realloc (u or v may be the same as w). */ 33 up = v->d; 81 up = v->d; 34 vp = u->d; 82 vp = u->d; 35 } else { 83 } else { 36 usize = u->nlimbs; 84 usize = u->nlimbs; 37 usign = u->sign; 85 usign = u->sign; 38 vsize = v->nlimbs; 86 vsize = v->nlimbs; 39 vsign = v->sign; 87 vsign = v->sign; 40 wsize = usize + 1; 88 wsize = usize + 1; 41 err = RESIZE_IF_NEEDED(w, wsiz !! 89 RESIZE_IF_NEEDED(w, wsize); 42 if (err) << 43 return err; << 44 /* These must be after realloc 90 /* These must be after realloc (u or v may be the same as w). */ 45 up = u->d; 91 up = u->d; 46 vp = v->d; 92 vp = v->d; 47 } 93 } 48 wp = w->d; 94 wp = w->d; 49 wsign = 0; 95 wsign = 0; 50 96 51 if (!vsize) { /* simple */ 97 if (!vsize) { /* simple */ 52 MPN_COPY(wp, up, usize); 98 MPN_COPY(wp, up, usize); 53 wsize = usize; 99 wsize = usize; 54 wsign = usign; 100 wsign = usign; 55 } else if (usign != vsign) { /* differ 101 } else if (usign != vsign) { /* different sign */ 56 /* This test is right since US 102 /* This test is right since USIZE >= VSIZE */ 57 if (usize != vsize) { 103 if (usize != vsize) { 58 mpihelp_sub(wp, up, us 104 mpihelp_sub(wp, up, usize, vp, vsize); 59 wsize = usize; 105 wsize = usize; 60 MPN_NORMALIZE(wp, wsiz 106 MPN_NORMALIZE(wp, wsize); 61 wsign = usign; 107 wsign = usign; 62 } else if (mpihelp_cmp(up, vp, 108 } else if (mpihelp_cmp(up, vp, usize) < 0) { 63 mpihelp_sub_n(wp, vp, 109 mpihelp_sub_n(wp, vp, up, usize); 64 wsize = usize; 110 wsize = usize; 65 MPN_NORMALIZE(wp, wsiz 111 MPN_NORMALIZE(wp, wsize); 66 if (!usign) 112 if (!usign) 67 wsign = 1; 113 wsign = 1; 68 } else { 114 } else { 69 mpihelp_sub_n(wp, up, 115 mpihelp_sub_n(wp, up, vp, usize); 70 wsize = usize; 116 wsize = usize; 71 MPN_NORMALIZE(wp, wsiz 117 MPN_NORMALIZE(wp, wsize); 72 if (usign) 118 if (usign) 73 wsign = 1; 119 wsign = 1; 74 } 120 } 75 } else { /* U and V have same sign. Ad 121 } else { /* U and V have same sign. Add them. */ 76 mpi_limb_t cy = mpihelp_add(wp 122 mpi_limb_t cy = mpihelp_add(wp, up, usize, vp, vsize); 77 wp[usize] = cy; 123 wp[usize] = cy; 78 wsize = usize + cy; 124 wsize = usize + cy; 79 if (usign) 125 if (usign) 80 wsign = 1; 126 wsign = 1; 81 } 127 } 82 128 83 w->nlimbs = wsize; 129 w->nlimbs = wsize; 84 w->sign = wsign; 130 w->sign = wsign; 85 return 0; << 86 } 131 } 87 EXPORT_SYMBOL_GPL(mpi_add); 132 EXPORT_SYMBOL_GPL(mpi_add); 88 133 89 int mpi_sub(MPI w, MPI u, MPI v) !! 134 void mpi_sub(MPI w, MPI u, MPI v) 90 { 135 { 91 int err; !! 136 MPI vv = mpi_copy(v); 92 MPI vv; << 93 << 94 vv = mpi_copy(v); << 95 if (!vv) << 96 return -ENOMEM; << 97 << 98 vv->sign = !vv->sign; 137 vv->sign = !vv->sign; 99 err = mpi_add(w, u, vv); !! 138 mpi_add(w, u, vv); 100 mpi_free(vv); 139 mpi_free(vv); 101 << 102 return err; << 103 } 140 } 104 EXPORT_SYMBOL_GPL(mpi_sub); 141 EXPORT_SYMBOL_GPL(mpi_sub); 105 142 106 int mpi_addm(MPI w, MPI u, MPI v, MPI m) !! 143 void mpi_addm(MPI w, MPI u, MPI v, MPI m) 107 { 144 { 108 return mpi_add(w, u, v) ?: !! 145 mpi_add(w, u, v); 109 mpi_mod(w, w, m); !! 146 mpi_mod(w, w, m); 110 } 147 } 111 EXPORT_SYMBOL_GPL(mpi_addm); 148 EXPORT_SYMBOL_GPL(mpi_addm); 112 149 113 int mpi_subm(MPI w, MPI u, MPI v, MPI m) !! 150 void mpi_subm(MPI w, MPI u, MPI v, MPI m) 114 { 151 { 115 return mpi_sub(w, u, v) ?: !! 152 mpi_sub(w, u, v); 116 mpi_mod(w, w, m); !! 153 mpi_mod(w, w, m); 117 } 154 } 118 EXPORT_SYMBOL_GPL(mpi_subm); 155 EXPORT_SYMBOL_GPL(mpi_subm); 119 156
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.