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 */ 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 */ 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 */ 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 */ 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 */ 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