1 /*
2 * Copyright (C) 2017 - This file is part of libecc project
3 *
4 * Authors:
5 * Ryad BENADJILA <ryadbenadjila@gmail.com>
6 * Arnaud EBALARD <arnaud.ebalard@ssi.gouv.fr>
7 * Jean-Pierre FLORI <jean-pierre.flori@ssi.gouv.fr>
8 *
9 * Contributors:
10 * Nicolas VIVET <nicolas.vivet@ssi.gouv.fr>
11 * Karim KHALFALLAH <karim.khalfallah@ssi.gouv.fr>
12 *
13 * This software is licensed under a dual BSD and GPL v2 license.
14 * See LICENSE file at the root folder of the project.
15 */
16 #include <libecc/fp/fp_add.h>
17 #include <libecc/nn/nn_add.h>
18
19 /*
20 * Compute out = in1 + in2 mod p. 'out' parameter must have been initialized
21 * by the caller. Returns 0 on success, -1 on error.
22 *
23 * Aliasing is supported.
24 */
fp_add(fp_t out,fp_src_t in1,fp_src_t in2)25 int fp_add(fp_t out, fp_src_t in1, fp_src_t in2)
26 {
27 int ret, cmp;
28
29 ret = fp_check_initialized(out); EG(ret, err);
30 ret = fp_check_initialized(in1); EG(ret, err);
31 ret = fp_check_initialized(in2); EG(ret, err);
32
33 MUST_HAVE(((&(in1->ctx->p)) == (&(in2->ctx->p))), ret, err);
34 MUST_HAVE(((&(in1->ctx->p)) == (&(out->ctx->p))), ret, err);
35 FORCE_USED_VAR(cmp); /* silence warning when macro results in nothing */
36 SHOULD_HAVE(!nn_cmp(&in1->fp_val, &(in1->ctx->p), &cmp) && (cmp < 0), ret, err);
37 SHOULD_HAVE(!nn_cmp(&in2->fp_val, &(in2->ctx->p), &cmp) && (cmp < 0), ret, err);
38
39 ret = nn_mod_add(&(out->fp_val), &(in1->fp_val),
40 &(in2->fp_val), &(in1->ctx->p));
41
42 err:
43 return ret;
44 }
45
46 /*
47 * Compute out = in + 1 mod p. 'out' parameter must have been initialized
48 * by the caller. Returns 0 on success, -1 on error.
49 *
50 * Aliasing is supported.
51 */
fp_inc(fp_t out,fp_src_t in)52 int fp_inc(fp_t out, fp_src_t in)
53 {
54 int ret, cmp;
55
56 ret = fp_check_initialized(in); EG(ret, err);
57 ret = fp_check_initialized(out); EG(ret, err);
58
59 MUST_HAVE(((&(in->ctx->p)) == (&(out->ctx->p))), ret, err);
60 FORCE_USED_VAR(cmp); /* silence warning when macro results in nothing */
61 SHOULD_HAVE(!nn_cmp(&in->fp_val, &(in->ctx->p), &cmp) && (cmp < 0), ret, err);
62
63 ret = nn_mod_inc(&(out->fp_val), &(in->fp_val), &(in->ctx->p));
64
65 err:
66 return ret;
67 }
68
69 /*
70 * Compute out = in1 - in2 mod p. 'out' parameter must have been initialized
71 * by the caller. Returns 0 on success, -1 on error.
72 *
73 * Aliasing is supported.
74 */
fp_sub(fp_t out,fp_src_t in1,fp_src_t in2)75 int fp_sub(fp_t out, fp_src_t in1, fp_src_t in2)
76 {
77 int ret, cmp;
78
79 ret = fp_check_initialized(out); EG(ret, err);
80 ret = fp_check_initialized(in1); EG(ret, err);
81 ret = fp_check_initialized(in2); EG(ret, err);
82
83 MUST_HAVE(((&(in1->ctx->p)) == (&(in2->ctx->p))), ret, err);
84 MUST_HAVE(((&(in1->ctx->p)) == (&(out->ctx->p))), ret, err);
85 FORCE_USED_VAR(cmp); /* silence warning when macro results in nothing */
86 SHOULD_HAVE(!nn_cmp(&in1->fp_val, &(in1->ctx->p), &cmp) && (cmp < 0), ret, err);
87 SHOULD_HAVE(!nn_cmp(&in2->fp_val, &(in2->ctx->p), &cmp) && (cmp < 0), ret, err);
88
89 ret = nn_mod_sub(&(out->fp_val), &(in1->fp_val),
90 &(in2->fp_val), &(in1->ctx->p));
91
92 err:
93 return ret;
94 }
95
96 /*
97 * Compute out = in - 1 mod p. 'out' parameter must have been initialized
98 * by the caller. Returns 0 on success, -1 on error.
99 *
100 * Aliasing is supported.
101 */
fp_dec(fp_t out,fp_src_t in)102 int fp_dec(fp_t out, fp_src_t in)
103 {
104 int ret, cmp;
105
106 ret = fp_check_initialized(out); EG(ret, err);
107 ret = fp_check_initialized(in); EG(ret, err);
108
109 MUST_HAVE(((&(in->ctx->p)) == (&(out->ctx->p))), ret, err);
110 FORCE_USED_VAR(cmp); /* silence warning when macro results in nothing */
111 SHOULD_HAVE(!nn_cmp(&in->fp_val, &(in->ctx->p), &cmp) && (cmp < 0), ret, err);
112
113 ret = nn_mod_dec(&(out->fp_val), &(in->fp_val), &(in->ctx->p));
114
115 err:
116 return ret;
117 }
118
119 /*
120 * Compute out = -in mod p = (p - in) mod p. 'out' parameter must have been
121 * initialized by the caller. Returns 0 on success, -1 on error.
122 *
123 * Aliasing is supported.
124 */
fp_neg(fp_t out,fp_src_t in)125 int fp_neg(fp_t out, fp_src_t in)
126 {
127 int ret, cmp;
128
129 ret = fp_check_initialized(in); EG(ret, err);
130 ret = fp_check_initialized(out); EG(ret, err);
131
132 MUST_HAVE(((&(in->ctx->p)) == (&(out->ctx->p))), ret, err);
133 FORCE_USED_VAR(cmp); /* silence warning when macro results in nothing */
134 SHOULD_HAVE(!nn_cmp(&in->fp_val, &(in->ctx->p), &cmp) && (cmp < 0), ret, err);
135
136 ret = nn_sub(&(out->fp_val), &(in->ctx->p), &(in->fp_val));
137
138 err:
139 return ret;
140 }
141