1 /*
2 * Copyright (c) 2018, Henry Corrigan-Gibbs
3 *
4 * This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
7 */
8
9 #include <mprio.h>
10 #include <stdlib.h>
11
12 #include "config.h"
13 #include "mparray.h"
14 #include "share.h"
15 #include "util.h"
16
17 MPArray
MPArray_new(int len)18 MPArray_new(int len)
19 {
20 SECStatus rv = SECSuccess;
21 MPArray arr = malloc(sizeof *arr);
22 if (!arr)
23 return NULL;
24
25 arr->data = NULL;
26 arr->len = len;
27
28 P_CHECKA(arr->data = calloc(len, sizeof(mp_int)));
29
30 // Initialize these to NULL so that we can figure
31 // out which allocations failed (if any)
32 for (int i = 0; i < len; i++) {
33 MP_DIGITS(&arr->data[i]) = NULL;
34 }
35
36 for (int i = 0; i < len; i++) {
37 MP_CHECKC(mp_init(&arr->data[i]));
38 }
39
40 cleanup:
41 if (rv != SECSuccess) {
42 MPArray_clear(arr);
43 return NULL;
44 }
45
46 return arr;
47 }
48
49 MPArray
MPArray_new_bool(int len,const bool * data_in)50 MPArray_new_bool(int len, const bool* data_in)
51 {
52 MPArray arr = MPArray_new(len);
53 if (arr == NULL)
54 return NULL;
55
56 for (int i = 0; i < len; i++) {
57 mp_set(&arr->data[i], data_in[i]);
58 }
59
60 return arr;
61 }
62
63 SECStatus
MPArray_resize(MPArray arr,int newlen)64 MPArray_resize(MPArray arr, int newlen)
65 {
66 SECStatus rv = SECSuccess;
67 const int oldlen = arr->len;
68
69 if (oldlen == newlen)
70 return rv;
71
72 // TODO: Use realloc for this?
73 mp_int* newdata = calloc(newlen, sizeof(mp_int));
74 if (newdata == NULL)
75 return SECFailure;
76
77 for (int i = 0; i < newlen; i++) {
78 MP_DIGITS(&newdata[i]) = NULL;
79 }
80
81 // Initialize new array
82 for (int i = 0; i < newlen; i++) {
83 MP_CHECKC(mp_init(&newdata[i]));
84 }
85
86 // Copy old data into new array
87 for (int i = 0; i < newlen && i < oldlen; i++) {
88 MP_CHECKC(mp_copy(&arr->data[i], &newdata[i]));
89 }
90
91 // Free old data
92 for (int i = 0; i < oldlen; i++) {
93 mp_clear(&arr->data[i]);
94 }
95 free(arr->data);
96 arr->data = newdata;
97 arr->len = newlen;
98
99 cleanup:
100 if (rv != SECSuccess) {
101 for (int i = 0; i < newlen; i++) {
102 mp_clear(&newdata[i]);
103 }
104 free(newdata);
105 }
106
107 return rv;
108 }
109
110 MPArray
MPArray_dup(const_MPArray src)111 MPArray_dup(const_MPArray src)
112 {
113 MPArray dst = MPArray_new(src->len);
114 if (!dst)
115 return NULL;
116
117 SECStatus rv = MPArray_copy(dst, src);
118 if (rv == SECSuccess) {
119 return dst;
120 } else {
121 MPArray_clear(dst);
122 return NULL;
123 }
124 }
125
126 SECStatus
MPArray_copy(MPArray dst,const_MPArray src)127 MPArray_copy(MPArray dst, const_MPArray src)
128 {
129 if (dst->len != src->len)
130 return SECFailure;
131
132 for (int i = 0; i < src->len; i++) {
133 if (mp_copy(&src->data[i], &dst->data[i]) != MP_OKAY) {
134 return SECFailure;
135 }
136 }
137
138 return SECSuccess;
139 }
140
141 SECStatus
MPArray_set_share(MPArray arrA,MPArray arrB,const_MPArray src,const_PrioConfig cfg)142 MPArray_set_share(MPArray arrA, MPArray arrB, const_MPArray src,
143 const_PrioConfig cfg)
144 {
145 SECStatus rv = SECSuccess;
146 if (arrA->len != src->len || arrB->len != src->len)
147 return SECFailure;
148
149 const int len = src->len;
150
151 for (int i = 0; i < len; i++) {
152 P_CHECK(share_int(cfg, &src->data[i], &arrA->data[i], &arrB->data[i]));
153 }
154
155 return rv;
156 }
157
158 void
MPArray_clear(MPArray arr)159 MPArray_clear(MPArray arr)
160 {
161 if (arr == NULL)
162 return;
163
164 if (arr->data != NULL) {
165 for (int i = 0; i < arr->len; i++) {
166 mp_clear(&arr->data[i]);
167 }
168 free(arr->data);
169 }
170 free(arr);
171 }
172
173 SECStatus
MPArray_addmod(MPArray dst,const_MPArray to_add,const mp_int * mod)174 MPArray_addmod(MPArray dst, const_MPArray to_add, const mp_int* mod)
175 {
176 if (dst->len != to_add->len)
177 return SECFailure;
178
179 for (int i = 0; i < dst->len; i++) {
180 MP_CHECK(mp_addmod(&dst->data[i], &to_add->data[i], mod, &dst->data[i]));
181 }
182
183 return SECSuccess;
184 }
185
186 bool
MPArray_areEqual(const_MPArray arr1,const_MPArray arr2)187 MPArray_areEqual(const_MPArray arr1, const_MPArray arr2)
188 {
189 if (arr1->len != arr2->len)
190 return false;
191
192 for (int i = 0; i < arr1->len; i++) {
193 if (mp_cmp(&arr1->data[i], &arr2->data[i]))
194 return false;
195 }
196
197 return true;
198 }
199