| File: | out/../deps/openssl/openssl/crypto/bn/bn_mod.c |
| Warning: | line 76, column 26 The left operand of '&' is a garbage value |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | /* | |||
| 2 | * Copyright 1998-2021 The OpenSSL Project Authors. All Rights Reserved. | |||
| 3 | * | |||
| 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use | |||
| 5 | * this file except in compliance with the License. You can obtain a copy | |||
| 6 | * in the file LICENSE in the source distribution or at | |||
| 7 | * https://www.openssl.org/source/license.html | |||
| 8 | */ | |||
| 9 | ||||
| 10 | #include "internal/cryptlib.h" | |||
| 11 | #include "bn_local.h" | |||
| 12 | ||||
| 13 | int BN_nnmod(BIGNUM *r, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx) | |||
| 14 | { | |||
| 15 | /* | |||
| 16 | * like BN_mod, but returns non-negative remainder (i.e., 0 <= r < |d| | |||
| 17 | * always holds) | |||
| 18 | */ | |||
| 19 | ||||
| 20 | if (!(BN_mod(r, m, d, ctx)BN_div(((void*)0),(r),(m),(d),(ctx)))) | |||
| 21 | return 0; | |||
| 22 | if (!r->neg) | |||
| 23 | return 1; | |||
| 24 | /* now -|d| < r < 0, so we have to set r := r + |d| */ | |||
| 25 | return (d->neg ? BN_sub : BN_add) (r, r, d); | |||
| 26 | } | |||
| 27 | ||||
| 28 | int BN_mod_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, | |||
| 29 | BN_CTX *ctx) | |||
| 30 | { | |||
| 31 | if (!BN_add(r, a, b)) | |||
| 32 | return 0; | |||
| 33 | return BN_nnmod(r, r, m, ctx); | |||
| 34 | } | |||
| 35 | ||||
| 36 | /* | |||
| 37 | * BN_mod_add variant that may be used if both a and b are non-negative and | |||
| 38 | * less than m. The original algorithm was | |||
| 39 | * | |||
| 40 | * if (!BN_uadd(r, a, b)) | |||
| 41 | * return 0; | |||
| 42 | * if (BN_ucmp(r, m) >= 0) | |||
| 43 | * return BN_usub(r, r, m); | |||
| 44 | * | |||
| 45 | * which is replaced with addition, subtracting modulus, and conditional | |||
| 46 | * move depending on whether or not subtraction borrowed. | |||
| 47 | */ | |||
| 48 | int bn_mod_add_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, | |||
| 49 | const BIGNUM *m) | |||
| 50 | { | |||
| 51 | size_t i, ai, bi, mtop = m->top; | |||
| 52 | BN_ULONGunsigned long storage[1024 / BN_BITS2(8 * 8)]; | |||
| 53 | BN_ULONGunsigned long carry, temp, mask, *rp, *tp = storage; | |||
| 54 | const BN_ULONGunsigned long *ap, *bp; | |||
| 55 | ||||
| 56 | if (bn_wexpand(r, mtop) == NULL((void*)0)) | |||
| 57 | return 0; | |||
| 58 | ||||
| 59 | if (mtop > sizeof(storage) / sizeof(storage[0])) { | |||
| 60 | tp = OPENSSL_malloc(mtop * sizeof(BN_ULONG))CRYPTO_malloc(mtop * sizeof(unsigned long), "../deps/openssl/openssl/crypto/bn/bn_mod.c" , 60); | |||
| 61 | if (tp == NULL((void*)0)) { | |||
| 62 | ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE)(ERR_new(), ERR_set_debug("../deps/openssl/openssl/crypto/bn/bn_mod.c" ,62,__func__), ERR_set_error)((3),((256|((0x1 << 18L)|( 0x2 << 18L)))),((void*)0)); | |||
| 63 | return 0; | |||
| 64 | } | |||
| 65 | } | |||
| 66 | ||||
| 67 | ap = a->d != NULL((void*)0) ? a->d : tp; | |||
| 68 | bp = b->d != NULL((void*)0) ? b->d : tp; | |||
| 69 | ||||
| 70 | for (i = 0, ai = 0, bi = 0, carry = 0; i < mtop;) { | |||
| 71 | mask = (BN_ULONGunsigned long)0 - ((i - a->top) >> (8 * sizeof(i) - 1)); | |||
| 72 | temp = ((ap[ai] & mask) + carry) & BN_MASK2(0xffffffffffffffffL); | |||
| 73 | carry = (temp < carry); | |||
| 74 | ||||
| 75 | mask = (BN_ULONGunsigned long)0 - ((i - b->top) >> (8 * sizeof(i) - 1)); | |||
| 76 | tp[i] = ((bp[bi] & mask) + temp) & BN_MASK2(0xffffffffffffffffL); | |||
| ||||
| 77 | carry += (tp[i] < temp); | |||
| 78 | ||||
| 79 | i++; | |||
| 80 | ai += (i - a->dmax) >> (8 * sizeof(i) - 1); | |||
| 81 | bi += (i - b->dmax) >> (8 * sizeof(i) - 1); | |||
| 82 | } | |||
| 83 | rp = r->d; | |||
| 84 | carry -= bn_sub_words(rp, tp, m->d, mtop); | |||
| 85 | for (i = 0; i < mtop; i++) { | |||
| 86 | rp[i] = (carry & tp[i]) | (~carry & rp[i]); | |||
| 87 | ((volatile BN_ULONGunsigned long *)tp)[i] = 0; | |||
| 88 | } | |||
| 89 | r->top = mtop; | |||
| 90 | r->flags |= BN_FLG_FIXED_TOP0; | |||
| 91 | r->neg = 0; | |||
| 92 | ||||
| 93 | if (tp != storage) | |||
| 94 | OPENSSL_free(tp)CRYPTO_free(tp, "../deps/openssl/openssl/crypto/bn/bn_mod.c", 94); | |||
| 95 | ||||
| 96 | return 1; | |||
| 97 | } | |||
| 98 | ||||
| 99 | int BN_mod_add_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, | |||
| 100 | const BIGNUM *m) | |||
| 101 | { | |||
| 102 | int ret = bn_mod_add_fixed_top(r, a, b, m); | |||
| ||||
| 103 | ||||
| 104 | if (ret) | |||
| 105 | bn_correct_top(r); | |||
| 106 | ||||
| 107 | return ret; | |||
| 108 | } | |||
| 109 | ||||
| 110 | int BN_mod_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, | |||
| 111 | BN_CTX *ctx) | |||
| 112 | { | |||
| 113 | if (!BN_sub(r, a, b)) | |||
| 114 | return 0; | |||
| 115 | return BN_nnmod(r, r, m, ctx); | |||
| 116 | } | |||
| 117 | ||||
| 118 | /* | |||
| 119 | * BN_mod_sub variant that may be used if both a and b are non-negative, | |||
| 120 | * a is less than m, while b is of same bit width as m. It's implemented | |||
| 121 | * as subtraction followed by two conditional additions. | |||
| 122 | * | |||
| 123 | * 0 <= a < m | |||
| 124 | * 0 <= b < 2^w < 2*m | |||
| 125 | * | |||
| 126 | * after subtraction | |||
| 127 | * | |||
| 128 | * -2*m < r = a - b < m | |||
| 129 | * | |||
| 130 | * Thus it takes up to two conditional additions to make |r| positive. | |||
| 131 | */ | |||
| 132 | int bn_mod_sub_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, | |||
| 133 | const BIGNUM *m) | |||
| 134 | { | |||
| 135 | size_t i, ai, bi, mtop = m->top; | |||
| 136 | BN_ULONGunsigned long borrow, carry, ta, tb, mask, *rp; | |||
| 137 | const BN_ULONGunsigned long *ap, *bp; | |||
| 138 | ||||
| 139 | if (bn_wexpand(r, mtop) == NULL((void*)0)) | |||
| 140 | return 0; | |||
| 141 | ||||
| 142 | rp = r->d; | |||
| 143 | ap = a->d != NULL((void*)0) ? a->d : rp; | |||
| 144 | bp = b->d != NULL((void*)0) ? b->d : rp; | |||
| 145 | ||||
| 146 | for (i = 0, ai = 0, bi = 0, borrow = 0; i < mtop;) { | |||
| 147 | mask = (BN_ULONGunsigned long)0 - ((i - a->top) >> (8 * sizeof(i) - 1)); | |||
| 148 | ta = ap[ai] & mask; | |||
| 149 | ||||
| 150 | mask = (BN_ULONGunsigned long)0 - ((i - b->top) >> (8 * sizeof(i) - 1)); | |||
| 151 | tb = bp[bi] & mask; | |||
| 152 | rp[i] = ta - tb - borrow; | |||
| 153 | if (ta != tb) | |||
| 154 | borrow = (ta < tb); | |||
| 155 | ||||
| 156 | i++; | |||
| 157 | ai += (i - a->dmax) >> (8 * sizeof(i) - 1); | |||
| 158 | bi += (i - b->dmax) >> (8 * sizeof(i) - 1); | |||
| 159 | } | |||
| 160 | ap = m->d; | |||
| 161 | for (i = 0, mask = 0 - borrow, carry = 0; i < mtop; i++) { | |||
| 162 | ta = ((ap[i] & mask) + carry) & BN_MASK2(0xffffffffffffffffL); | |||
| 163 | carry = (ta < carry); | |||
| 164 | rp[i] = (rp[i] + ta) & BN_MASK2(0xffffffffffffffffL); | |||
| 165 | carry += (rp[i] < ta); | |||
| 166 | } | |||
| 167 | borrow -= carry; | |||
| 168 | for (i = 0, mask = 0 - borrow, carry = 0; i < mtop; i++) { | |||
| 169 | ta = ((ap[i] & mask) + carry) & BN_MASK2(0xffffffffffffffffL); | |||
| 170 | carry = (ta < carry); | |||
| 171 | rp[i] = (rp[i] + ta) & BN_MASK2(0xffffffffffffffffL); | |||
| 172 | carry += (rp[i] < ta); | |||
| 173 | } | |||
| 174 | ||||
| 175 | r->top = mtop; | |||
| 176 | r->flags |= BN_FLG_FIXED_TOP0; | |||
| 177 | r->neg = 0; | |||
| 178 | ||||
| 179 | return 1; | |||
| 180 | } | |||
| 181 | ||||
| 182 | /* | |||
| 183 | * BN_mod_sub variant that may be used if both a and b are non-negative and | |||
| 184 | * less than m | |||
| 185 | */ | |||
| 186 | int BN_mod_sub_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, | |||
| 187 | const BIGNUM *m) | |||
| 188 | { | |||
| 189 | if (!BN_sub(r, a, b)) | |||
| 190 | return 0; | |||
| 191 | if (r->neg) | |||
| 192 | return BN_add(r, r, m); | |||
| 193 | return 1; | |||
| 194 | } | |||
| 195 | ||||
| 196 | /* slow but works */ | |||
| 197 | int BN_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, | |||
| 198 | BN_CTX *ctx) | |||
| 199 | { | |||
| 200 | BIGNUM *t; | |||
| 201 | int ret = 0; | |||
| 202 | ||||
| 203 | bn_check_top(a); | |||
| 204 | bn_check_top(b); | |||
| 205 | bn_check_top(m); | |||
| 206 | ||||
| 207 | BN_CTX_start(ctx); | |||
| 208 | if ((t = BN_CTX_get(ctx)) == NULL((void*)0)) | |||
| 209 | goto err; | |||
| 210 | if (a == b) { | |||
| 211 | if (!BN_sqr(t, a, ctx)) | |||
| 212 | goto err; | |||
| 213 | } else { | |||
| 214 | if (!BN_mul(t, a, b, ctx)) | |||
| 215 | goto err; | |||
| 216 | } | |||
| 217 | if (!BN_nnmod(r, t, m, ctx)) | |||
| 218 | goto err; | |||
| 219 | bn_check_top(r); | |||
| 220 | ret = 1; | |||
| 221 | err: | |||
| 222 | BN_CTX_end(ctx); | |||
| 223 | return ret; | |||
| 224 | } | |||
| 225 | ||||
| 226 | int BN_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx) | |||
| 227 | { | |||
| 228 | if (!BN_sqr(r, a, ctx)) | |||
| 229 | return 0; | |||
| 230 | /* r->neg == 0, thus we don't need BN_nnmod */ | |||
| 231 | return BN_mod(r, r, m, ctx)BN_div(((void*)0),(r),(r),(m),(ctx)); | |||
| 232 | } | |||
| 233 | ||||
| 234 | int BN_mod_lshift1(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx) | |||
| 235 | { | |||
| 236 | if (!BN_lshift1(r, a)) | |||
| 237 | return 0; | |||
| 238 | bn_check_top(r); | |||
| 239 | return BN_nnmod(r, r, m, ctx); | |||
| 240 | } | |||
| 241 | ||||
| 242 | /* | |||
| 243 | * BN_mod_lshift1 variant that may be used if a is non-negative and less than | |||
| 244 | * m | |||
| 245 | */ | |||
| 246 | int BN_mod_lshift1_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *m) | |||
| 247 | { | |||
| 248 | if (!BN_lshift1(r, a)) | |||
| 249 | return 0; | |||
| 250 | bn_check_top(r); | |||
| 251 | if (BN_cmp(r, m) >= 0) | |||
| 252 | return BN_sub(r, r, m); | |||
| 253 | return 1; | |||
| 254 | } | |||
| 255 | ||||
| 256 | int BN_mod_lshift(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m, | |||
| 257 | BN_CTX *ctx) | |||
| 258 | { | |||
| 259 | BIGNUM *abs_m = NULL((void*)0); | |||
| 260 | int ret; | |||
| 261 | ||||
| 262 | if (!BN_nnmod(r, a, m, ctx)) | |||
| 263 | return 0; | |||
| 264 | ||||
| 265 | if (m->neg) { | |||
| 266 | abs_m = BN_dup(m); | |||
| 267 | if (abs_m == NULL((void*)0)) | |||
| 268 | return 0; | |||
| 269 | abs_m->neg = 0; | |||
| 270 | } | |||
| 271 | ||||
| 272 | ret = BN_mod_lshift_quick(r, r, n, (abs_m ? abs_m : m)); | |||
| 273 | bn_check_top(r); | |||
| 274 | ||||
| 275 | BN_free(abs_m); | |||
| 276 | return ret; | |||
| 277 | } | |||
| 278 | ||||
| 279 | /* | |||
| 280 | * BN_mod_lshift variant that may be used if a is non-negative and less than | |||
| 281 | * m | |||
| 282 | */ | |||
| 283 | int BN_mod_lshift_quick(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m) | |||
| 284 | { | |||
| 285 | if (r != a) { | |||
| 286 | if (BN_copy(r, a) == NULL((void*)0)) | |||
| 287 | return 0; | |||
| 288 | } | |||
| 289 | ||||
| 290 | while (n > 0) { | |||
| 291 | int max_shift; | |||
| 292 | ||||
| 293 | /* 0 < r < m */ | |||
| 294 | max_shift = BN_num_bits(m) - BN_num_bits(r); | |||
| 295 | /* max_shift >= 0 */ | |||
| 296 | ||||
| 297 | if (max_shift < 0) { | |||
| 298 | ERR_raise(ERR_LIB_BN, BN_R_INPUT_NOT_REDUCED)(ERR_new(), ERR_set_debug("../deps/openssl/openssl/crypto/bn/bn_mod.c" ,298,__func__), ERR_set_error)((3),(110),((void*)0)); | |||
| 299 | return 0; | |||
| 300 | } | |||
| 301 | ||||
| 302 | if (max_shift > n) | |||
| 303 | max_shift = n; | |||
| 304 | ||||
| 305 | if (max_shift) { | |||
| 306 | if (!BN_lshift(r, r, max_shift)) | |||
| 307 | return 0; | |||
| 308 | n -= max_shift; | |||
| 309 | } else { | |||
| 310 | if (!BN_lshift1(r, r)) | |||
| 311 | return 0; | |||
| 312 | --n; | |||
| 313 | } | |||
| 314 | ||||
| 315 | /* BN_num_bits(r) <= BN_num_bits(m) */ | |||
| 316 | ||||
| 317 | if (BN_cmp(r, m) >= 0) { | |||
| 318 | if (!BN_sub(r, r, m)) | |||
| 319 | return 0; | |||
| 320 | } | |||
| 321 | } | |||
| 322 | bn_check_top(r); | |||
| 323 | ||||
| 324 | return 1; | |||
| 325 | } |