-
+ F70DDD8CDF793CD1A95B6C84A9C73BFF0EF7BE6BB56483AAE08E26AAF004AAB695E34F4CD0982BF5D188374E9FD07241B225BA763EFACB78EDA586FC84E3CBE2
smg_comms/mpi/mpi-mul.c
(0 . 0)(1 . 209)
4834 /* mpi-mul.c - MPI functions
4835 * Modified by No Such Labs. (C) 2015. See README.
4836 *
4837 * This file was originally part of Gnu Privacy Guard (GPG), ver. 1.4.10,
4838 * SHA256(gnupg-1.4.10.tar.gz):
4839 * 0bfd74660a2f6cedcf7d8256db4a63c996ffebbcdc2cf54397bfb72878c5a85a
4840 * (C) 1994-2005 Free Software Foundation, Inc.
4841 *
4842 * This program is free software: you can redistribute it and/or modify
4843 * it under the terms of the GNU General Public License as published by
4844 * the Free Software Foundation, either version 3 of the License, or
4845 * (at your option) any later version.
4846 *
4847 * This program is distributed in the hope that it will be useful,
4848 * but WITHOUT ANY WARRANTY; without even the implied warranty of
4849 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4850 * GNU General Public License for more details.
4851 *
4852 * You should have received a copy of the GNU General Public License
4853 * along with this program. If not, see <http://www.gnu.org/licenses/>.
4854 */
4855
4856 #include <stdio.h>
4857 #include <stdlib.h>
4858
4859 #include "knobs.h"
4860 #include "mpi-internal.h"
4861
4862
4863 void
4864 mpi_mul_ui( MPI prod, MPI mult, unsigned long small_mult )
4865 {
4866 mpi_size_t size, prod_size;
4867 mpi_ptr_t prod_ptr;
4868 mpi_limb_t cy;
4869 int sign;
4870
4871 size = mult->nlimbs;
4872 sign = mult->sign;
4873
4874 if( !size || !small_mult ) {
4875 prod->nlimbs = 0;
4876 prod->sign = 0;
4877 return;
4878 }
4879
4880 prod_size = size + 1;
4881 if( prod->alloced < prod_size )
4882 mpi_resize( prod, prod_size );
4883 prod_ptr = prod->d;
4884
4885 cy = mpihelp_mul_1( prod_ptr, mult->d, size, (mpi_limb_t)small_mult );
4886 if( cy )
4887 prod_ptr[size++] = cy;
4888 prod->nlimbs = size;
4889 prod->sign = sign;
4890 }
4891
4892
4893 void
4894 mpi_mul_2exp( MPI w, MPI u, unsigned long cnt)
4895 {
4896 mpi_size_t usize, wsize, limb_cnt;
4897 mpi_ptr_t wp;
4898 mpi_limb_t wlimb;
4899 int usign, wsign;
4900
4901 usize = u->nlimbs;
4902 usign = u->sign;
4903
4904 if( !usize ) {
4905 w->nlimbs = 0;
4906 w->sign = 0;
4907 return;
4908 }
4909
4910 limb_cnt = cnt / BITS_PER_MPI_LIMB;
4911 wsize = usize + limb_cnt + 1;
4912 if( w->alloced < wsize )
4913 mpi_resize(w, wsize );
4914 wp = w->d;
4915 wsize = usize + limb_cnt;
4916 wsign = usign;
4917
4918 cnt %= BITS_PER_MPI_LIMB;
4919 if( cnt ) {
4920 wlimb = mpihelp_lshift( wp + limb_cnt, u->d, usize, cnt );
4921 if( wlimb ) {
4922 wp[wsize] = wlimb;
4923 wsize++;
4924 }
4925 }
4926 else {
4927 MPN_COPY_DECR( wp + limb_cnt, u->d, usize );
4928 }
4929
4930 /* Zero all whole limbs at low end. Do it here and not before calling
4931 * mpn_lshift, not to lose for U == W. */
4932 MPN_ZERO( wp, limb_cnt );
4933
4934 w->nlimbs = wsize;
4935 w->sign = wsign;
4936 }
4937
4938
4939
4940 void
4941 mpi_mul( MPI w, MPI u, MPI v)
4942 {
4943 mpi_size_t usize, vsize, wsize;
4944 mpi_ptr_t up, vp, wp;
4945 mpi_limb_t cy;
4946 int usign, vsign, usecure, vsecure, sign_product;
4947 int assign_wp=0;
4948 mpi_ptr_t tmp_limb=NULL;
4949
4950
4951 if( u->nlimbs < v->nlimbs ) { /* Swap U and V. */
4952 usize = v->nlimbs;
4953 usign = v->sign;
4954 usecure = mpi_is_secure(v);
4955 up = v->d;
4956 vsize = u->nlimbs;
4957 vsign = u->sign;
4958 vsecure = mpi_is_secure(u);
4959 vp = u->d;
4960 }
4961 else {
4962 usize = u->nlimbs;
4963 usign = u->sign;
4964 usecure = mpi_is_secure(u);
4965 up = u->d;
4966 vsize = v->nlimbs;
4967 vsign = v->sign;
4968 vsecure = mpi_is_secure(v);
4969 vp = v->d;
4970 }
4971 sign_product = usign ^ vsign;
4972 wp = w->d;
4973
4974 /* Ensure W has space enough to store the result. */
4975 wsize = usize + vsize;
4976 if ( !mpi_is_secure (w) && (mpi_is_secure (u) || mpi_is_secure (v)) ) {
4977 /* w is not allocated in secure space but u or v is. To make sure
4978 * that no temporray results are stored in w, we temporary use
4979 * a newly allocated limb space for w */
4980 wp = mpi_alloc_limb_space( wsize, 1 );
4981 assign_wp = 2; /* mark it as 2 so that we can later copy it back to
4982 * mormal memory */
4983 }
4984 else if( w->alloced < wsize ) {
4985 if( wp == up || wp == vp ) {
4986 wp = mpi_alloc_limb_space( wsize, mpi_is_secure(w) );
4987 assign_wp = 1;
4988 }
4989 else {
4990 mpi_resize(w, wsize );
4991 wp = w->d;
4992 }
4993 }
4994 else { /* Make U and V not overlap with W. */
4995 if( wp == up ) {
4996 /* W and U are identical. Allocate temporary space for U. */
4997 up = tmp_limb = mpi_alloc_limb_space( usize, usecure );
4998 /* Is V identical too? Keep it identical with U. */
4999 if( wp == vp )
5000 vp = up;
5001 /* Copy to the temporary space. */
5002 MPN_COPY( up, wp, usize );
5003 }
5004 else if( wp == vp ) {
5005 /* W and V are identical. Allocate temporary space for V. */
5006 vp = tmp_limb = mpi_alloc_limb_space( vsize, vsecure );
5007 /* Copy to the temporary space. */
5008 MPN_COPY( vp, wp, vsize );
5009 }
5010 }
5011
5012 if( !vsize )
5013 wsize = 0;
5014 else {
5015 cy = mpihelp_mul( wp, up, usize, vp, vsize );
5016 wsize -= cy? 0:1;
5017 }
5018
5019 if( assign_wp ) {
5020 if (assign_wp == 2) {
5021 /* copy the temp wp from secure memory back to normal memory */
5022 mpi_ptr_t tmp_wp = mpi_alloc_limb_space (wsize, 0);
5023 MPN_COPY (tmp_wp, wp, wsize);
5024 mpi_free_limb_space (wp);
5025 wp = tmp_wp;
5026 }
5027 mpi_assign_limb_space( w, wp, wsize );
5028 }
5029 w->nlimbs = wsize;
5030 w->sign = sign_product;
5031 if( tmp_limb )
5032 mpi_free_limb_space( tmp_limb );
5033 }
5034
5035
5036 void
5037 mpi_mulm( MPI w, MPI u, MPI v, MPI m)
5038 {
5039 mpi_mul(w, u, v);
5040 mpi_fdiv_r( w, w, m );
5041 }
5042