Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/lib/crypto/mpi/mpi-add.c
29278 views
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 <linux/export.h>
15
16
#include "mpi-internal.h"
17
18
int mpi_add(MPI w, MPI u, MPI v)
19
{
20
mpi_ptr_t wp, up, vp;
21
mpi_size_t usize, vsize, wsize;
22
int usign, vsign, wsign;
23
int err;
24
25
if (u->nlimbs < v->nlimbs) { /* Swap U and V. */
26
usize = v->nlimbs;
27
usign = v->sign;
28
vsize = u->nlimbs;
29
vsign = u->sign;
30
wsize = usize + 1;
31
err = RESIZE_IF_NEEDED(w, wsize);
32
if (err)
33
return err;
34
/* These must be after realloc (u or v may be the same as w). */
35
up = v->d;
36
vp = u->d;
37
} else {
38
usize = u->nlimbs;
39
usign = u->sign;
40
vsize = v->nlimbs;
41
vsign = v->sign;
42
wsize = usize + 1;
43
err = RESIZE_IF_NEEDED(w, wsize);
44
if (err)
45
return err;
46
/* These must be after realloc (u or v may be the same as w). */
47
up = u->d;
48
vp = v->d;
49
}
50
wp = w->d;
51
wsign = 0;
52
53
if (!vsize) { /* simple */
54
MPN_COPY(wp, up, usize);
55
wsize = usize;
56
wsign = usign;
57
} else if (usign != vsign) { /* different sign */
58
/* This test is right since USIZE >= VSIZE */
59
if (usize != vsize) {
60
mpihelp_sub(wp, up, usize, vp, vsize);
61
wsize = usize;
62
MPN_NORMALIZE(wp, wsize);
63
wsign = usign;
64
} else if (mpihelp_cmp(up, vp, usize) < 0) {
65
mpihelp_sub_n(wp, vp, up, usize);
66
wsize = usize;
67
MPN_NORMALIZE(wp, wsize);
68
if (!usign)
69
wsign = 1;
70
} else {
71
mpihelp_sub_n(wp, up, vp, usize);
72
wsize = usize;
73
MPN_NORMALIZE(wp, wsize);
74
if (usign)
75
wsign = 1;
76
}
77
} else { /* U and V have same sign. Add them. */
78
mpi_limb_t cy = mpihelp_add(wp, up, usize, vp, vsize);
79
wp[usize] = cy;
80
wsize = usize + cy;
81
if (usign)
82
wsign = 1;
83
}
84
85
w->nlimbs = wsize;
86
w->sign = wsign;
87
return 0;
88
}
89
EXPORT_SYMBOL_GPL(mpi_add);
90
91
int mpi_sub(MPI w, MPI u, MPI v)
92
{
93
int err;
94
MPI vv;
95
96
vv = mpi_copy(v);
97
if (!vv)
98
return -ENOMEM;
99
100
vv->sign = !vv->sign;
101
err = mpi_add(w, u, vv);
102
mpi_free(vv);
103
104
return err;
105
}
106
EXPORT_SYMBOL_GPL(mpi_sub);
107
108
int mpi_addm(MPI w, MPI u, MPI v, MPI m)
109
{
110
return mpi_add(w, u, v) ?:
111
mpi_mod(w, w, m);
112
}
113
EXPORT_SYMBOL_GPL(mpi_addm);
114
115
int mpi_subm(MPI w, MPI u, MPI v, MPI m)
116
{
117
return mpi_sub(w, u, v) ?:
118
mpi_mod(w, w, m);
119
}
120
EXPORT_SYMBOL_GPL(mpi_subm);
121
122