lib/mpi: Extend the MPI library
Expand the mpi library based on libgcrypt, and the ECC algorithm of mpi based on libgcrypt requires these functions. Some other algorithms will be developed based on mpi ecc, such as SM2. Signed-off-by: Tianjia Zhang <tianjia.zhang@linux.alibaba.com> Tested-by: Xufeng Zhang <yunbo.xufeng@linux.alibaba.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
committed by
Herbert Xu
parent
f49282870f
commit
a8ea8bdd9d
94
lib/mpi/mpi-mul.c
Normal file
94
lib/mpi/mpi-mul.c
Normal file
@@ -0,0 +1,94 @@
|
||||
/* mpi-mul.c - MPI functions
|
||||
* Copyright (C) 1994, 1996, 1998, 2001, 2002,
|
||||
* 2003 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of Libgcrypt.
|
||||
*
|
||||
* Note: This code is heavily based on the GNU MP Library.
|
||||
* Actually it's the same code with only minor changes in the
|
||||
* way the data is stored; this is to support the abstraction
|
||||
* of an optional secure memory allocation which may be used
|
||||
* to avoid revealing of sensitive data due to paging etc.
|
||||
*/
|
||||
|
||||
#include "mpi-internal.h"
|
||||
|
||||
void mpi_mul(MPI w, MPI u, MPI v)
|
||||
{
|
||||
mpi_size_t usize, vsize, wsize;
|
||||
mpi_ptr_t up, vp, wp;
|
||||
mpi_limb_t cy;
|
||||
int usign, vsign, sign_product;
|
||||
int assign_wp = 0;
|
||||
mpi_ptr_t tmp_limb = NULL;
|
||||
unsigned int tmp_limb_nlimbs = 0;
|
||||
|
||||
if (u->nlimbs < v->nlimbs) {
|
||||
/* Swap U and V. */
|
||||
usize = v->nlimbs;
|
||||
usign = v->sign;
|
||||
up = v->d;
|
||||
vsize = u->nlimbs;
|
||||
vsign = u->sign;
|
||||
vp = u->d;
|
||||
} else {
|
||||
usize = u->nlimbs;
|
||||
usign = u->sign;
|
||||
up = u->d;
|
||||
vsize = v->nlimbs;
|
||||
vsign = v->sign;
|
||||
vp = v->d;
|
||||
}
|
||||
sign_product = usign ^ vsign;
|
||||
wp = w->d;
|
||||
|
||||
/* Ensure W has space enough to store the result. */
|
||||
wsize = usize + vsize;
|
||||
if (w->alloced < wsize) {
|
||||
if (wp == up || wp == vp) {
|
||||
wp = mpi_alloc_limb_space(wsize);
|
||||
assign_wp = 1;
|
||||
} else {
|
||||
mpi_resize(w, wsize);
|
||||
wp = w->d;
|
||||
}
|
||||
} else { /* Make U and V not overlap with W. */
|
||||
if (wp == up) {
|
||||
/* W and U are identical. Allocate temporary space for U. */
|
||||
tmp_limb_nlimbs = usize;
|
||||
up = tmp_limb = mpi_alloc_limb_space(usize);
|
||||
/* Is V identical too? Keep it identical with U. */
|
||||
if (wp == vp)
|
||||
vp = up;
|
||||
/* Copy to the temporary space. */
|
||||
MPN_COPY(up, wp, usize);
|
||||
} else if (wp == vp) {
|
||||
/* W and V are identical. Allocate temporary space for V. */
|
||||
tmp_limb_nlimbs = vsize;
|
||||
vp = tmp_limb = mpi_alloc_limb_space(vsize);
|
||||
/* Copy to the temporary space. */
|
||||
MPN_COPY(vp, wp, vsize);
|
||||
}
|
||||
}
|
||||
|
||||
if (!vsize)
|
||||
wsize = 0;
|
||||
else {
|
||||
mpihelp_mul(wp, up, usize, vp, vsize, &cy);
|
||||
wsize -= cy ? 0:1;
|
||||
}
|
||||
|
||||
if (assign_wp)
|
||||
mpi_assign_limb_space(w, wp, wsize);
|
||||
w->nlimbs = wsize;
|
||||
w->sign = sign_product;
|
||||
if (tmp_limb)
|
||||
mpi_free_limb_space(tmp_limb);
|
||||
}
|
||||
|
||||
void mpi_mulm(MPI w, MPI u, MPI v, MPI m)
|
||||
{
|
||||
mpi_mul(w, u, v);
|
||||
mpi_tdiv_r(w, w, m);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mpi_mulm);
|
||||
Reference in New Issue
Block a user