Coverage Report

Created: 2026-07-25 06:49

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/relic/src/bn/relic_bn_mem.c
Line
Count
Source
1
/*
2
 * RELIC is an Efficient LIbrary for Cryptography
3
 * Copyright (c) 2009 RELIC Authors
4
 *
5
 * This file is part of RELIC. RELIC is legal property of its developers,
6
 * whose names are not listed here. Please refer to the COPYRIGHT file
7
 * for contact information.
8
 *
9
 * RELIC is free software; you can redistribute it and/or modify it under the
10
 * terms of the version 2.1 (or later) of the GNU Lesser General Public License
11
 * as published by the Free Software Foundation; or version 2.0 of the Apache
12
 * License as published by the Apache Software Foundation. See the LICENSE files
13
 * for more details.
14
 *
15
 * RELIC is distributed in the hope that it will be useful, but WITHOUT ANY
16
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
17
 * A PARTICULAR PURPOSE. See the LICENSE files for more details.
18
 *
19
 * You should have received a copy of the GNU Lesser General Public or the
20
 * Apache License along with RELIC. If not, see <https://www.gnu.org/licenses/>
21
 * or <https://www.apache.org/licenses/>.
22
 */
23
24
/**
25
 * @file
26
 *
27
 * Implementation of the multiple precision integer memory management routines.
28
 *
29
 * @ingroup bn
30
 */
31
32
#include <errno.h>
33
34
#if ALLOC != AUTO
35
#include <malloc.h>
36
#endif
37
38
#include "relic_core.h"
39
40
/*============================================================================*/
41
/* Public definitions                                                         */
42
/*============================================================================*/
43
44
39.2M
void bn_make(bn_t a, size_t digits) {
45
39.2M
  if (digits < 0) {
46
0
    RLC_THROW(ERR_NO_VALID);
47
0
  }
48
  /* Allocate at least one digit. */
49
39.2M
  digits = RLC_MAX(digits, 1);
50
51
39.2M
#if ALLOC == DYNAMIC
52
39.2M
  if (digits % RLC_BN_SIZE != 0) {
53
    /* Pad the number of digits to a multiple of the block. */
54
33.6M
    digits += (RLC_BN_SIZE - digits % RLC_BN_SIZE);
55
33.6M
  }
56
57
39.2M
  if (a != NULL) {
58
39.2M
    a->dp = NULL;
59
39.2M
#if ALIGN == 1
60
39.2M
    a->dp = (dig_t *)malloc(digits * sizeof(dig_t));
61
#elif OPSYS == WINDOWS
62
    a->dp = _aligned_malloc(digits * sizeof(dig_t), ALIGN);
63
#else
64
    int r = posix_memalign((void **)&a->dp, ALIGN, digits * sizeof(dig_t));
65
    if (r == ENOMEM) {
66
      RLC_THROW(ERR_NO_MEMORY);
67
    }
68
    if (r == EINVAL) {
69
      RLC_THROW(ERR_NO_VALID);
70
    }
71
#endif /* ALIGN */
72
39.2M
  }
73
74
39.2M
  if (a->dp == NULL) {
75
0
    free((void *)a);
76
0
    RLC_THROW(ERR_NO_MEMORY);
77
0
  }
78
#else
79
  /* Verify if the number of digits is sane. */
80
  if (digits > RLC_BN_SIZE) {
81
    RLC_THROW(ERR_NO_PRECI);
82
    return;
83
  } else {
84
    digits = RLC_BN_SIZE;
85
  }
86
#endif
87
39.2M
  if (a != NULL) {
88
39.2M
    a->used = 1;
89
39.2M
    a->dp[0] = 0;
90
39.2M
    a->alloc = digits;
91
39.2M
    a->sign = RLC_POS;
92
39.2M
  }
93
39.2M
}
94
95
39.2M
void bn_clean(bn_t a) {
96
39.2M
#if ALLOC == DYNAMIC
97
39.2M
  if (a != NULL) {
98
39.2M
    if (a->dp != NULL) {
99
#if OPSYS == WINDOWS && ALIGN > 1
100
      _aligned_free(a->dp);
101
#else
102
39.2M
      free(a->dp);
103
39.2M
#endif
104
39.2M
      a->dp = NULL;
105
39.2M
    }
106
39.2M
    a->alloc = 0;
107
39.2M
  }
108
39.2M
#endif
109
39.2M
  if (a != NULL) {
110
39.2M
    a->used = 0;
111
39.2M
    a->sign = RLC_POS;
112
39.2M
  }
113
39.2M
}
114
115
87.5M
void bn_grow(bn_t a, size_t digits) {
116
87.5M
#if ALLOC == DYNAMIC
117
87.5M
  dig_t *t = NULL;
118
119
87.5M
  if (a->alloc < digits) {
120
2.10M
    size_t pad = (RLC_BN_SIZE * 2) - (digits % RLC_BN_SIZE);
121
    /* Check overflow. */
122
2.10M
        if (digits > SIZE_MAX - pad) {
123
0
      RLC_THROW(ERR_NO_MEMORY);
124
0
      return;
125
0
        }
126
    /* At least add RLC_BN_SIZE more digits. */
127
2.10M
    digits += pad;
128
2.10M
    t = (dig_t *)realloc(a->dp, (RLC_DIG / 8) * digits);
129
2.10M
    if (t == NULL) {
130
63
      RLC_THROW(ERR_NO_MEMORY);
131
63
      return;
132
63
    }
133
2.10M
    a->dp = t;
134
    /* Set the newly allocated digits to zero. */
135
2.10M
    a->alloc = digits;
136
2.10M
  }
137
#elif ALLOC == AUTO
138
  if (digits > RLC_BN_SIZE) {
139
    RLC_THROW(ERR_NO_PRECI);
140
    return;
141
  }
142
  (void)a;
143
#endif
144
87.5M
}
145
146
111M
void bn_trim(bn_t a) {
147
111M
  if (a->used <= a->alloc) {
148
127M
    while (a->used > 0 && a->dp[a->used - 1] == 0) {
149
16.1M
      --(a->used);
150
16.1M
    }
151
    /* Zero can't be negative. */
152
111M
    if (a->used == 0) {
153
861k
      a->used = 1;
154
861k
      a->dp[0] = 0;
155
861k
      a->sign = RLC_POS;
156
861k
    }
157
111M
  }
158
111M
}