cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

mpi-add.c (3490B)


      1/* mpi-add.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
     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 */
     20void 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
     67void mpi_add(MPI w, MPI u, MPI v)
     68{
     69	mpi_ptr_t wp, up, vp;
     70	mpi_size_t usize, vsize, wsize;
     71	int usign, vsign, wsign;
     72
     73	if (u->nlimbs < v->nlimbs) { /* Swap U and V. */
     74		usize = v->nlimbs;
     75		usign = v->sign;
     76		vsize = u->nlimbs;
     77		vsign = u->sign;
     78		wsize = usize + 1;
     79		RESIZE_IF_NEEDED(w, wsize);
     80		/* These must be after realloc (u or v may be the same as w).  */
     81		up = v->d;
     82		vp = u->d;
     83	} else {
     84		usize = u->nlimbs;
     85		usign = u->sign;
     86		vsize = v->nlimbs;
     87		vsign = v->sign;
     88		wsize = usize + 1;
     89		RESIZE_IF_NEEDED(w, wsize);
     90		/* These must be after realloc (u or v may be the same as w).  */
     91		up = u->d;
     92		vp = v->d;
     93	}
     94	wp = w->d;
     95	wsign = 0;
     96
     97	if (!vsize) {  /* simple */
     98		MPN_COPY(wp, up, usize);
     99		wsize = usize;
    100		wsign = usign;
    101	} else if (usign != vsign) { /* different sign */
    102		/* This test is right since USIZE >= VSIZE */
    103		if (usize != vsize) {
    104			mpihelp_sub(wp, up, usize, vp, vsize);
    105			wsize = usize;
    106			MPN_NORMALIZE(wp, wsize);
    107			wsign = usign;
    108		} else if (mpihelp_cmp(up, vp, usize) < 0) {
    109			mpihelp_sub_n(wp, vp, up, usize);
    110			wsize = usize;
    111			MPN_NORMALIZE(wp, wsize);
    112			if (!usign)
    113				wsign = 1;
    114		} else {
    115			mpihelp_sub_n(wp, up, vp, usize);
    116			wsize = usize;
    117			MPN_NORMALIZE(wp, wsize);
    118			if (usign)
    119				wsign = 1;
    120		}
    121	} else { /* U and V have same sign. Add them. */
    122		mpi_limb_t cy = mpihelp_add(wp, up, usize, vp, vsize);
    123		wp[usize] = cy;
    124		wsize = usize + cy;
    125		if (usign)
    126			wsign = 1;
    127	}
    128
    129	w->nlimbs = wsize;
    130	w->sign = wsign;
    131}
    132EXPORT_SYMBOL_GPL(mpi_add);
    133
    134void mpi_sub(MPI w, MPI u, MPI v)
    135{
    136	MPI vv = mpi_copy(v);
    137	vv->sign = !vv->sign;
    138	mpi_add(w, u, vv);
    139	mpi_free(vv);
    140}
    141
    142
    143void mpi_addm(MPI w, MPI u, MPI v, MPI m)
    144{
    145	mpi_add(w, u, v);
    146	mpi_mod(w, w, m);
    147}
    148EXPORT_SYMBOL_GPL(mpi_addm);
    149
    150void mpi_subm(MPI w, MPI u, MPI v, MPI m)
    151{
    152	mpi_sub(w, u, v);
    153	mpi_mod(w, w, m);
    154}
    155EXPORT_SYMBOL_GPL(mpi_subm);