Remove all variable-length arrays on the stack (#45)

* Remove all variable-length arrays

* Fix indenting
This commit is contained in:
Henry Corrigan-Gibbs 2018-09-24 09:34:53 -07:00 коммит произвёл Robert Helmer
Родитель 919088a37a
Коммит 02a81fb652
13 изменённых файлов: 354 добавлений и 299 удалений

Просмотреть файл

@ -30,7 +30,7 @@ if env["DEBUG"]:
env.Append(
LIBS = ["mprio", "mpi", "nss3", "nspr4"],
LIBPATH = ['#build/prio', "#build/mpi"],
CFLAGS = [ "-Wall", "-Werror", "-Wextra", "-O3", "-std=c99",
CFLAGS = [ "-Wall", "-Werror", "-Wextra", "-O3", "-std=c99", "-Wvla",
"-I/usr/include/nspr", "-I/usr/include/nss", "-Impi", "-DDO_PR_CLEANUP"])
env.Append(CPPPATH = ["#include", "#."])

Просмотреть файл

@ -40,6 +40,9 @@ verify_full(void)
const unsigned char* batch_id = (unsigned char*)"prio_batch_2018-04-17";
const unsigned int batch_id_len = strlen((char*)batch_id);
unsigned long* output = NULL;
bool* data_items = NULL;
// Initialize NSS random number generator.
P_CHECKC(Prio_init());
@ -49,118 +52,116 @@ verify_full(void)
// Number of clients to simulate.
const int nclients = 10;
// New scope to avoid goto weirdness
{
bool data_items[ndata];
P_CHECKA(output = calloc(ndata, sizeof(unsigned long)));
P_CHECKA(data_items = calloc(ndata, sizeof(bool)));
// Generate keypairs for servers
P_CHECKC(Keypair_new(&skA, &pkA));
P_CHECKC(Keypair_new(&skB, &pkB));
// Generate keypairs for servers
P_CHECKC(Keypair_new(&skA, &pkA));
P_CHECKC(Keypair_new(&skB, &pkB));
// Use the default configuration parameters.
P_CHECKA(cfg = PrioConfig_new(ndata, pkA, pkB, batch_id, batch_id_len));
// Use the default configuration parameters.
P_CHECKA(cfg = PrioConfig_new(ndata, pkA, pkB, batch_id, batch_id_len));
PrioPRGSeed server_secret;
P_CHECKC(PrioPRGSeed_randomize(&server_secret));
PrioPRGSeed server_secret;
P_CHECKC(PrioPRGSeed_randomize(&server_secret));
// Initialize two server objects. The role of the servers need not
// be symmetric. In a deployment, we envision that:
// * Server A is the main telemetry server that is always online.
// Clients send their encrypted data packets to Server A and
// Server A stores them.
// * Server B only comes online when the two servers want to compute
// the final aggregate statistics.
P_CHECKA(sA = PrioServer_new(cfg, PRIO_SERVER_A, skA, server_secret));
P_CHECKA(sB = PrioServer_new(cfg, PRIO_SERVER_B, skB, server_secret));
// Initialize two server objects. The role of the servers need not
// be symmetric. In a deployment, we envision that:
// * Server A is the main telemetry server that is always online.
// Clients send their encrypted data packets to Server A and
// Server A stores them.
// * Server B only comes online when the two servers want to compute
// the final aggregate statistics.
P_CHECKA(sA = PrioServer_new(cfg, PRIO_SERVER_A, skA, server_secret));
P_CHECKA(sB = PrioServer_new(cfg, PRIO_SERVER_B, skB, server_secret));
// Initialize empty verifier objects
P_CHECKA(vA = PrioVerifier_new(sA));
P_CHECKA(vB = PrioVerifier_new(sB));
// Initialize empty verifier objects
P_CHECKA(vA = PrioVerifier_new(sA));
P_CHECKA(vB = PrioVerifier_new(sB));
// Initialize shares of final aggregate statistics
P_CHECKA(tA = PrioTotalShare_new());
P_CHECKA(tB = PrioTotalShare_new());
// Initialize shares of final aggregate statistics
P_CHECKA(tA = PrioTotalShare_new());
P_CHECKA(tB = PrioTotalShare_new());
// Initialize shares of verification packets
P_CHECKA(p1A = PrioPacketVerify1_new());
P_CHECKA(p1B = PrioPacketVerify1_new());
P_CHECKA(p2A = PrioPacketVerify2_new());
P_CHECKA(p2B = PrioPacketVerify2_new());
// Initialize shares of verification packets
P_CHECKA(p1A = PrioPacketVerify1_new());
P_CHECKA(p1B = PrioPacketVerify1_new());
P_CHECKA(p2A = PrioPacketVerify2_new());
P_CHECKA(p2B = PrioPacketVerify2_new());
// Generate client data packets.
for (int c = 0; c < nclients; c++) {
// Generate client data packets.
for (int c = 0; c < nclients; c++) {
// The client's data submission is an arbitrary boolean vector.
for (int i = 0; i < ndata; i++) {
// Arbitrary data
data_items[i] = (i % 3 == 1) || (c % 5 == 3);
}
// I. CLIENT DATA SUBMISSION.
//
// Construct the client data packets.
unsigned int aLen, bLen;
P_CHECKC(PrioClient_encode(cfg, data_items, &for_server_a, &aLen,
&for_server_b, &bLen));
// The Prio servers A and B can come online later (e.g., at the end of
// each day) to download the encrypted telemetry packets from the
// telemetry server and run the protocol that computes the aggregate
// statistics. In this way, the client only needs to send a
// single message (the pair of encrypted ClientPacketData packets)
// to a single server (the telemetry-data-collection server).
// THE CLIENT'S JOB IS DONE. The rest of the processing just takes place
// between the two servers A and B.
// II. VALIDATION PROTOCOL. (at servers)
//
// The servers now run a short 2-step protocol to check each
// client's packet:
// 1) Servers A and B broadcast one message (PrioPacketVerify1)
// to each other.
// 2) Servers A and B broadcast another message (PrioPacketVerify2)
// to each other.
// 3) Servers A and B can both determine whether the client's data
// submission is well-formed (in which case they add it to their
// running total of aggregate statistics) or ill-formed
// (in which case they ignore it).
// These messages must be sent over an authenticated channel, so
// that each server is assured that every received message came
// from its peer.
// Set up a Prio verifier object.
P_CHECKC(PrioVerifier_set_data(vA, for_server_a, aLen));
P_CHECKC(PrioVerifier_set_data(vB, for_server_b, bLen));
// Both servers produce a packet1. Server A sends p1A to Server B
// and vice versa.
P_CHECKC(PrioPacketVerify1_set_data(p1A, vA));
P_CHECKC(PrioPacketVerify1_set_data(p1B, vB));
// Both servers produce a packet2. Server A sends p2A to Server B
// and vice versa.
P_CHECKC(PrioPacketVerify2_set_data(p2A, vA, p1A, p1B));
P_CHECKC(PrioPacketVerify2_set_data(p2B, vB, p1A, p1B));
// Using p2A and p2B, the servers can determine whether the request
// is valid. (In fact, only Server A needs to perform this
// check, since Server A can just tell Server B whether the check
// succeeded or failed.)
P_CHECKC(PrioVerifier_isValid(vA, p2A, p2B));
P_CHECKC(PrioVerifier_isValid(vB, p2A, p2B));
// If we get here, the client packet is valid, so add it to the aggregate
// statistic counter for both servers.
P_CHECKC(PrioServer_aggregate(sA, vA));
P_CHECKC(PrioServer_aggregate(sB, vB));
free(for_server_a);
free(for_server_b);
for_server_a = NULL;
for_server_b = NULL;
// The client's data submission is an arbitrary boolean vector.
for (int i = 0; i < ndata; i++) {
// Arbitrary data
data_items[i] = (i % 3 == 1) || (c % 5 == 3);
}
// I. CLIENT DATA SUBMISSION.
//
// Construct the client data packets.
unsigned int aLen, bLen;
P_CHECKC(PrioClient_encode(cfg, data_items, &for_server_a, &aLen,
&for_server_b, &bLen));
// The Prio servers A and B can come online later (e.g., at the end of
// each day) to download the encrypted telemetry packets from the
// telemetry server and run the protocol that computes the aggregate
// statistics. In this way, the client only needs to send a
// single message (the pair of encrypted ClientPacketData packets)
// to a single server (the telemetry-data-collection server).
// THE CLIENT'S JOB IS DONE. The rest of the processing just takes place
// between the two servers A and B.
// II. VALIDATION PROTOCOL. (at servers)
//
// The servers now run a short 2-step protocol to check each
// client's packet:
// 1) Servers A and B broadcast one message (PrioPacketVerify1)
// to each other.
// 2) Servers A and B broadcast another message (PrioPacketVerify2)
// to each other.
// 3) Servers A and B can both determine whether the client's data
// submission is well-formed (in which case they add it to their
// running total of aggregate statistics) or ill-formed
// (in which case they ignore it).
// These messages must be sent over an authenticated channel, so
// that each server is assured that every received message came
// from its peer.
// Set up a Prio verifier object.
P_CHECKC(PrioVerifier_set_data(vA, for_server_a, aLen));
P_CHECKC(PrioVerifier_set_data(vB, for_server_b, bLen));
// Both servers produce a packet1. Server A sends p1A to Server B
// and vice versa.
P_CHECKC(PrioPacketVerify1_set_data(p1A, vA));
P_CHECKC(PrioPacketVerify1_set_data(p1B, vB));
// Both servers produce a packet2. Server A sends p2A to Server B
// and vice versa.
P_CHECKC(PrioPacketVerify2_set_data(p2A, vA, p1A, p1B));
P_CHECKC(PrioPacketVerify2_set_data(p2B, vB, p1A, p1B));
// Using p2A and p2B, the servers can determine whether the request
// is valid. (In fact, only Server A needs to perform this
// check, since Server A can just tell Server B whether the check
// succeeded or failed.)
P_CHECKC(PrioVerifier_isValid(vA, p2A, p2B));
P_CHECKC(PrioVerifier_isValid(vB, p2A, p2B));
// If we get here, the client packet is valid, so add it to the aggregate
// statistic counter for both servers.
P_CHECKC(PrioServer_aggregate(sA, vA));
P_CHECKC(PrioServer_aggregate(sB, vB));
free(for_server_a);
free(for_server_b);
for_server_a = NULL;
for_server_b = NULL;
// The servers repeat the steps above for each client submission.
// III. PRODUCTION OF AGGREGATE STATISTICS.
@ -174,7 +175,6 @@ verify_full(void)
// Once Server A has tA and tB, it can learn the aggregate statistics
// in the clear.
unsigned long output[ndata];
P_CHECKC(PrioTotalShare_final(cfg, output, tA, tB));
// Now the output[i] contains a counter that indicates how many clients
@ -192,6 +192,10 @@ cleanup:
free(for_server_a);
if (for_server_b)
free(for_server_b);
if (output)
free(output);
if (data_items)
free(data_items);
PrioTotalShare_clear(tA);
PrioTotalShare_clear(tB);

Просмотреть файл

@ -95,15 +95,17 @@ PublicKey_import(PublicKey* pk, const unsigned char* data, unsigned int dataLen)
SECStatus rv = SECSuccess;
CERTSubjectPublicKeyInfo* pkinfo = NULL;
*pk = NULL;
unsigned char* key_bytes = NULL;
uint8_t* spki_data = NULL;
if (dataLen != CURVE25519_KEY_LEN)
return SECFailure;
unsigned char key_bytes[dataLen];
P_CHECKA(key_bytes = calloc(dataLen, sizeof(unsigned char)));
memcpy(key_bytes, data, dataLen);
const int spki_len = sizeof(curve25519_spki_zeros);
uint8_t spki_data[spki_len];
P_CHECKA(spki_data = calloc(spki_len, sizeof(uint8_t)));
memcpy(spki_data, curve25519_spki_zeros, spki_len);
SECItem spki_item = { siBuffer, spki_data, spki_len };
@ -116,6 +118,10 @@ PublicKey_import(PublicKey* pk, const unsigned char* data, unsigned int dataLen)
memcpy((*pk)->u.ec.publicValue.data, data, CURVE25519_KEY_LEN);
cleanup:
if (key_bytes)
free(key_bytes);
if (spki_data)
free(spki_data);
if (pkinfo)
SECKEY_DestroySubjectPublicKeyInfo(pkinfo);

Просмотреть файл

@ -63,25 +63,19 @@ fft_interpolate_raw(mp_int* out, const mp_int* ys, int nPoints,
const mp_int* roots, const mp_int* mod, bool invert)
{
SECStatus rv = SECSuccess;
mp_int tmp[nPoints];
mp_int ySub[nPoints];
mp_int rootsSub[nPoints];
for (int i = 0; i < nPoints; i++) {
MP_DIGITS(&tmp[i]) = NULL;
MP_DIGITS(&ySub[i]) = NULL;
MP_DIGITS(&rootsSub[i]) = NULL;
}
MPArray tmp = NULL;
MPArray ySub = NULL;
MPArray rootsSub = NULL;
P_CHECKA(tmp = MPArray_new(nPoints));
P_CHECKA(ySub = MPArray_new(nPoints));
P_CHECKA(rootsSub = MPArray_new(nPoints));
mp_int n_inverse;
MP_DIGITS(&n_inverse) = NULL;
for (int i = 0; i < nPoints; i++) {
MP_CHECKC(mp_init(&tmp[i]));
MP_CHECKC(mp_init(&ySub[i]));
MP_CHECKC(mp_init(&rootsSub[i]));
}
MP_CHECK(fft_recurse(out, mod, nPoints, roots, ys, tmp, ySub, rootsSub));
MP_CHECK(fft_recurse(out, mod, nPoints, roots, ys, tmp->data, ySub->data,
rootsSub->data));
if (invert) {
MP_CHECKC(mp_init(&n_inverse));
@ -94,12 +88,10 @@ fft_interpolate_raw(mp_int* out, const mp_int* ys, int nPoints,
}
cleanup:
MPArray_clear(tmp);
MPArray_clear(ySub);
MPArray_clear(rootsSub);
mp_clear(&n_inverse);
for (int i = 0; i < nPoints; i++) {
mp_clear(&tmp[i]);
mp_clear(&ySub[i]);
mp_clear(&rootsSub[i]);
}
return rv;
}
@ -132,6 +124,8 @@ poly_fft(MPArray points_out, const_MPArray points_in, const_PrioConfig cfg,
{
SECStatus rv = SECSuccess;
const int n_points = points_in->len;
mp_int* scaled_roots = NULL;
if (points_out->len != points_in->len)
return SECFailure;
if (n_points > cfg->n_roots)
@ -139,12 +133,16 @@ poly_fft(MPArray points_out, const_MPArray points_in, const_PrioConfig cfg,
if (cfg->n_roots % n_points != 0)
return SECFailure;
mp_int scaled_roots[n_points];
P_CHECK(poly_fft_get_roots(scaled_roots, n_points, cfg, invert));
P_CHECKA(scaled_roots = calloc(n_points, sizeof(mp_int)));
P_CHECKC(poly_fft_get_roots(scaled_roots, n_points, cfg, invert));
MP_CHECK(fft_interpolate_raw(points_out->data, points_in->data, n_points,
P_CHECKC(fft_interpolate_raw(points_out->data, points_in->data, n_points,
scaled_roots, &cfg->modulus, invert));
cleanup:
if (scaled_roots)
free(scaled_roots);
return SECSuccess;
}
@ -172,9 +170,10 @@ poly_interp_evaluate(mp_int* value, const_MPArray poly_points,
{
SECStatus rv;
MPArray coeffs = NULL;
mp_int* roots = NULL;
const int N = poly_points->len;
mp_int roots[N];
P_CHECKA(roots = calloc(N, sizeof(mp_int)));
P_CHECKA(coeffs = MPArray_new(N));
P_CHECKC(poly_fft_get_roots(roots, N, cfg, false));
@ -183,6 +182,8 @@ poly_interp_evaluate(mp_int* value, const_MPArray poly_points,
P_CHECKC(poly_eval(value, coeffs, eval_at, cfg));
cleanup:
if (roots)
free(roots);
MPArray_clear(coeffs);
return rv;
}

Просмотреть файл

@ -89,14 +89,22 @@ PRG_clear(PRG prg)
static SECStatus
PRG_get_bytes_internal(void* prg_vp, unsigned char* bytes, size_t len)
{
SECStatus rv = SECSuccess;
PRG prg = (PRG)prg_vp;
unsigned char* in = NULL;
unsigned char in[len];
P_CHECKA(in = calloc(len, sizeof(unsigned char)));
memset(in, 0, len);
int outlen;
SECStatus rv = PK11_CipherOp(prg->ctx, bytes, &outlen, len, in, len);
return (rv != SECSuccess || (size_t)outlen != len) ? SECFailure : SECSuccess;
P_CHECKC(PK11_CipherOp(prg->ctx, bytes, &outlen, len, in, len));
P_CHECKCB((size_t)outlen == len);
cleanup:
if (in)
free(in);
return rv;
}
SECStatus

Просмотреть файл

@ -80,6 +80,8 @@ rand_int_rng(mp_int* out, const mp_int* max, RandBytesFunc rng_func,
void* user_data)
{
SECStatus rv = SECSuccess;
unsigned char* max_bytes = NULL;
unsigned char* buf = NULL;
// Ensure max value is > 0
if (mp_cmp_z(max) == 0)
@ -87,32 +89,38 @@ rand_int_rng(mp_int* out, const mp_int* max, RandBytesFunc rng_func,
// Compute max-1, which tells us the largest
// value we will ever need to generate.
MP_CHECK(mp_sub_d(max, 1, out));
MP_CHECKC(mp_sub_d(max, 1, out));
const int nbytes = mp_unsigned_octet_size(out);
// Figure out how many MSBs we need to get in the
// most-significant byte.
unsigned char max_bytes[nbytes];
MP_CHECK(mp_to_fixlen_octets(out, max_bytes, nbytes));
P_CHECKA(max_bytes = calloc(nbytes, sizeof(unsigned char)));
MP_CHECKC(mp_to_fixlen_octets(out, max_bytes, nbytes));
const unsigned char mask = msb_mask(max_bytes[0]);
// Buffer to store the pseudo-random bytes
unsigned char buf[nbytes];
P_CHECKA(buf = calloc(nbytes, sizeof(unsigned char)));
do {
// Use rejection sampling to find a value strictly less than max.
P_CHECK(rng_func(user_data, buf, nbytes));
P_CHECKC(rng_func(user_data, buf, nbytes));
// Mask off high-order bits that we will never need.
P_CHECK(rng_func(user_data, &buf[0], 1));
P_CHECKC(rng_func(user_data, &buf[0], 1));
if (mask)
buf[0] &= mask;
MP_CHECK(mp_read_unsigned_octets(out, buf, nbytes));
MP_CHECKC(mp_read_unsigned_octets(out, buf, nbytes));
} while (mp_cmp(out, max) != -1);
return 0;
cleanup:
if (max_bytes)
free(max_bytes);
if (buf)
free(buf);
return rv;
}
void

Просмотреть файл

@ -22,12 +22,16 @@ serial_write_mp_int(msgpack_packer* pk, const mp_int* n)
{
SECStatus rv = SECSuccess;
unsigned int n_size = mp_unsigned_octet_size(n);
unsigned char* data = NULL;
unsigned char data[n_size];
MP_CHECK(mp_to_fixlen_octets(n, data, n_size));
P_CHECKA(data = calloc(n_size, sizeof(unsigned char)));
MP_CHECKC(mp_to_fixlen_octets(n, data, n_size));
P_CHECK(msgpack_pack_str(pk, n_size));
P_CHECK(msgpack_pack_str_body(pk, data, n_size));
P_CHECKC(msgpack_pack_str(pk, n_size));
P_CHECKC(msgpack_pack_str_body(pk, data, n_size));
cleanup:
if (data)
free(data);
return rv;
}

Просмотреть файл

@ -20,25 +20,26 @@ mu_test_client__new(void)
PrioConfig cfg = NULL;
PrioPacketClient pA = NULL;
PrioPacketClient pB = NULL;
bool* data_items = NULL;
P_CHECKA(cfg = PrioConfig_newTest(23));
P_CHECKA(pA = PrioPacketClient_new(cfg, PRIO_SERVER_A));
P_CHECKA(pB = PrioPacketClient_new(cfg, PRIO_SERVER_B));
{
const int ndata = PrioConfig_numDataFields(cfg);
bool data_items[ndata];
const int ndata = PrioConfig_numDataFields(cfg);
P_CHECKA(data_items = calloc(ndata, sizeof(bool)));
for (int i = 0; i < ndata; i++) {
// Arbitrary data
data_items[i] = (i % 3 == 1) || (i % 5 == 3);
}
P_CHECKC(PrioPacketClient_set_data(cfg, data_items, pA, pB));
for (int i = 0; i < ndata; i++) {
// Arbitrary data
data_items[i] = (i % 3 == 1) || (i % 5 == 3);
}
P_CHECKC(PrioPacketClient_set_data(cfg, data_items, pA, pB));
cleanup:
mu_check(rv == SECSuccess);
if (data_items)
free(data_items);
PrioPacketClient_clear(pA);
PrioPacketClient_clear(pB);
@ -64,6 +65,8 @@ test_client_agg(int nclients)
unsigned char* for_b = NULL;
const unsigned char* batch_id = (unsigned char*)"test_batch";
unsigned int batch_id_len = strlen((char*)batch_id);
bool* data_items = NULL;
unsigned long* output = NULL;
PrioPRGSeed seed;
P_CHECKC(PrioPRGSeed_randomize(&seed));
@ -80,47 +83,45 @@ test_client_agg(int nclients)
const int ndata = PrioConfig_numDataFields(cfg);
{
bool data_items[ndata];
for (int i = 0; i < ndata; i++) {
// Arbitrary data
data_items[i] = (i % 3 == 1) || (i % 5 == 3);
}
for (int i = 0; i < nclients; i++) {
unsigned int aLen, bLen;
P_CHECKC(
PrioClient_encode(cfg, data_items, &for_a, &aLen, &for_b, &bLen));
P_CHECKC(PrioVerifier_set_data(vA, for_a, aLen));
P_CHECKC(PrioVerifier_set_data(vB, for_b, bLen));
mu_check(PrioServer_aggregate(sA, vA) == SECSuccess);
mu_check(PrioServer_aggregate(sB, vB) == SECSuccess);
free(for_a);
free(for_b);
for_a = NULL;
for_b = NULL;
}
mu_check(PrioTotalShare_set_data(tA, sA) == SECSuccess);
mu_check(PrioTotalShare_set_data(tB, sB) == SECSuccess);
unsigned long output[ndata];
mu_check(PrioTotalShare_final(cfg, output, tA, tB) == SECSuccess);
for (int i = 0; i < ndata; i++) {
unsigned long v = ((i % 3 == 1) || (i % 5 == 3));
mu_check(output[i] == v * nclients);
}
P_CHECKA(data_items = calloc(ndata, sizeof(bool)));
for (int i = 0; i < ndata; i++) {
// Arbitrary data
data_items[i] = (i % 3 == 1) || (i % 5 == 3);
}
// rv = SECFailure;
// goto cleanup;
for (int i = 0; i < nclients; i++) {
unsigned int aLen, bLen;
P_CHECKC(PrioClient_encode(cfg, data_items, &for_a, &aLen, &for_b, &bLen));
P_CHECKC(PrioVerifier_set_data(vA, for_a, aLen));
P_CHECKC(PrioVerifier_set_data(vB, for_b, bLen));
mu_check(PrioServer_aggregate(sA, vA) == SECSuccess);
mu_check(PrioServer_aggregate(sB, vB) == SECSuccess);
free(for_a);
free(for_b);
for_a = NULL;
for_b = NULL;
}
mu_check(PrioTotalShare_set_data(tA, sA) == SECSuccess);
mu_check(PrioTotalShare_set_data(tB, sB) == SECSuccess);
P_CHECKA(output = calloc(ndata, sizeof(unsigned long)));
mu_check(PrioTotalShare_final(cfg, output, tA, tB) == SECSuccess);
for (int i = 0; i < ndata; i++) {
unsigned long v = ((i % 3 == 1) || (i % 5 == 3));
mu_check(output[i] == v * nclients);
}
cleanup:
mu_check(rv == SECSuccess);
if (data_items)
free(data_items);
if (output)
free(output);
if (for_a)
free(for_a);
if (for_b)

Просмотреть файл

@ -76,18 +76,17 @@ mu_test__fft_simple(void)
PrioConfig cfg = NULL;
MPArray points_in = NULL;
MPArray points_out = NULL;
mp_int* roots = NULL;
mp_int should_be, tmp;
mp_int roots[nPoints];
MP_DIGITS(&should_be) = NULL;
MP_DIGITS(&tmp) = NULL;
for (int i = 0; i < nPoints; i++) {
MP_DIGITS(&roots[i]) = NULL;
}
P_CHECKA(cfg = PrioConfig_newTest(140));
P_CHECKA(points_in = MPArray_new(nPoints));
P_CHECKA(points_out = MPArray_new(nPoints));
P_CHECKA(roots = calloc(nPoints, sizeof(mp_int)));
MP_CHECKC(mp_init(&should_be));
MP_CHECKC(mp_init(&tmp));
@ -121,6 +120,8 @@ mu_test__fft_simple(void)
cleanup:
mu_check(rv == SECSuccess);
if (roots)
free(roots);
mp_clear(&tmp);
mp_clear(&should_be);
MPArray_clear(points_in);
@ -138,12 +139,13 @@ mu_test__fft_invert(void)
MPArray points_in = NULL;
MPArray points_out = NULL;
MPArray points_out2 = NULL;
mp_int roots[nPoints];
mp_int* roots = NULL;
P_CHECKA(cfg = PrioConfig_newTest(91));
P_CHECKA(points_in = MPArray_new(nPoints));
P_CHECKA(points_out = MPArray_new(nPoints));
P_CHECKA(points_out2 = MPArray_new(nPoints));
P_CHECKA(roots = calloc(nPoints, sizeof(mp_int)));
poly_fft_get_roots(roots, nPoints, cfg, false);
@ -165,6 +167,8 @@ mu_test__fft_invert(void)
cleanup:
mu_check(rv == SECSuccess);
if (roots)
free(roots);
MPArray_clear(points_in);
MPArray_clear(points_out);
MPArray_clear(points_out2);

Просмотреть файл

@ -32,19 +32,21 @@ mu_test__prg_repeat(void)
{
SECStatus rv = SECSuccess;
const int buflen = 10000;
unsigned char buf1[buflen];
unsigned char buf2[buflen];
unsigned char* buf1 = NULL;
unsigned char* buf2 = NULL;
PrioPRGSeed key;
PRG prg1 = NULL;
PRG prg2 = NULL;
buf1[3] = 'a';
buf2[3] = 'b';
P_CHECKC(PrioPRGSeed_randomize(&key));
P_CHECKA(prg1 = PRG_new(key));
P_CHECKA(prg2 = PRG_new(key));
P_CHECKA(buf1 = calloc(buflen, sizeof(unsigned char)));
P_CHECKA(buf2 = calloc(buflen, sizeof(unsigned char)));
buf1[3] = 'a';
buf2[3] = 'b';
P_CHECKC(PRG_get_bytes(prg1, buf1, buflen));
P_CHECKC(PRG_get_bytes(prg2, buf2, buflen));
@ -59,6 +61,10 @@ mu_test__prg_repeat(void)
cleanup:
mu_check(rv == SECSuccess);
if (buf1)
free(buf1);
if (buf2)
free(buf2);
PRG_clear(prg1);
PRG_clear(prg2);
}
@ -173,7 +179,7 @@ mu_test_prg__bit(void)
void
test_prg_distribution(int limit)
{
int bins[limit];
int* bins = NULL;
SECStatus rv = SECSuccess;
PrioPRGSeed key;
mp_int max;
@ -185,6 +191,7 @@ test_prg_distribution(int limit)
P_CHECKC(PrioPRGSeed_randomize(&key));
P_CHECKA(prg = PRG_new(key));
P_CHECKA(bins = calloc(limit, sizeof(int)));
MP_CHECKC(mp_init(&max));
MP_CHECKC(mp_init(&out));
@ -215,6 +222,8 @@ test_prg_distribution(int limit)
cleanup:
mu_check(rv == SECSuccess);
if (bins)
free(bins);
mp_clear(&max);
mp_clear(&out);
PRG_clear(prg);
@ -242,7 +251,7 @@ void
test_prg_distribution_large(mp_int* max)
{
const int limit = 16;
int bins[limit];
int* bins = NULL;
SECStatus rv = SECSuccess;
PrioPRGSeed key;
mp_int out;
@ -252,6 +261,7 @@ test_prg_distribution_large(mp_int* max)
P_CHECKC(PrioPRGSeed_randomize(&key));
P_CHECKA(prg = PRG_new(key));
P_CHECKA(bins = calloc(limit, sizeof(int)));
MP_CHECKC(mp_init(&out));
@ -275,6 +285,8 @@ test_prg_distribution_large(mp_int* max)
cleanup:
mu_check(rv == SECSuccess);
if (bins)
free(bins);
mp_clear(&out);
PRG_clear(prg);
}

Просмотреть файл

@ -81,7 +81,7 @@ void
test_rand_distribution(int limit)
{
SECStatus rv = SECSuccess;
int bins[limit];
int* bins = NULL;
mp_int max;
mp_int out;
@ -89,6 +89,8 @@ test_rand_distribution(int limit)
MP_DIGITS(&max) = NULL;
MP_DIGITS(&out) = NULL;
P_CHECKA(bins = calloc(limit, sizeof(int)));
MP_CHECKC(mp_init(&max));
MP_CHECKC(mp_init(&out));
@ -118,6 +120,8 @@ test_rand_distribution(int limit)
cleanup:
mu_check(rv == SECSuccess);
if (bins)
free(bins);
mp_clear(&max);
mp_clear(&out);
}
@ -145,11 +149,12 @@ test_rand_distribution_large(mp_int* max)
{
SECStatus rv = SECSuccess;
int limit = 16;
int bins[limit];
int* bins = NULL;
mp_int out;
MP_DIGITS(&out) = NULL;
MP_CHECKC(mp_init(&out));
P_CHECKA(bins = calloc(limit, sizeof(int)));
for (int i = 0; i < limit; i++) {
bins[i] = 0;
@ -171,6 +176,8 @@ test_rand_distribution_large(mp_int* max)
cleanup:
mu_check(rv == SECSuccess);
if (bins)
free(bins);
mp_clear(&out);
}

Просмотреть файл

@ -24,7 +24,8 @@ gen_client_packets(const_PrioConfig cfg, PrioPacketClient pA,
SECStatus rv = SECSuccess;
const int ndata = cfg->num_data_fields;
bool data_items[ndata];
bool* data_items = NULL;
P_CHECKA(data_items = calloc(ndata, sizeof(bool)));
for (int i = 0; i < ndata; i++) {
data_items[i] = (i % 3 == 1) || (i % 5 == 3);
@ -33,6 +34,8 @@ gen_client_packets(const_PrioConfig cfg, PrioPacketClient pA,
P_CHECKC(PrioPacketClient_set_data(cfg, data_items, pA, pB));
cleanup:
if (data_items)
free(data_items);
return rv;
}

Просмотреть файл

@ -63,6 +63,7 @@ mu_test__verify_new(void)
PrioVerifier vB = NULL;
unsigned char* for_a = NULL;
unsigned char* for_b = NULL;
bool* data_items = NULL;
mp_int fR, gR, hR;
MP_DIGITS(&fR) = NULL;
@ -77,53 +78,48 @@ mu_test__verify_new(void)
P_CHECKA(cfg = PrioConfig_new(214, pkA, pkB, (unsigned char*)"testbatch", 9));
const int ndata = PrioConfig_numDataFields(cfg);
{
bool data_items[ndata];
for (int i = 0; i < ndata; i++) {
// Arbitrary data
data_items[i] = (i % 3 == 1) || (i % 5 == 3);
}
P_CHECKA(sA = PrioServer_new(cfg, 0, skA, seed));
P_CHECKA(sB = PrioServer_new(cfg, 1, skB, seed));
unsigned int aLen, bLen;
P_CHECKC(PrioClient_encode(cfg, data_items, &for_a, &aLen, &for_b, &bLen));
MP_CHECKC(mp_init(&fR));
MP_CHECKC(mp_init(&gR));
MP_CHECKC(mp_init(&hR));
P_CHECKA(vA = PrioVerifier_new(sA));
P_CHECKA(vB = PrioVerifier_new(sB));
P_CHECKC(PrioVerifier_set_data(vA, for_a, aLen));
P_CHECKC(PrioVerifier_set_data(vB, for_b, bLen));
PrioPacketClient pA = vA->clientp;
PrioPacketClient pB = vB->clientp;
MP_CHECKC(mp_addmod(&pA->f0_share, &pB->f0_share, &cfg->modulus, &fR));
MP_CHECKC(mp_addmod(&pA->g0_share, &pB->g0_share, &cfg->modulus, &gR));
MP_CHECKC(mp_addmod(&pA->h0_share, &pB->h0_share, &cfg->modulus, &hR));
MP_CHECKC(mp_mulmod(&fR, &gR, &cfg->modulus, &fR));
mu_check(mp_cmp(&fR, &hR) == 0);
MP_CHECKC(mp_addmod(&vA->share_fR, &vB->share_fR, &cfg->modulus, &fR));
MP_CHECKC(mp_addmod(&vA->share_gR, &vB->share_gR, &cfg->modulus, &gR));
MP_CHECKC(mp_addmod(&vA->share_hR, &vB->share_hR, &cfg->modulus, &hR));
MP_CHECKC(mp_mulmod(&fR, &gR, &cfg->modulus, &fR));
// puts ("fR");
// mp_print (&fR, stdout);
// puts ("hR");
// mp_print (&hR, stdout);
mu_check(mp_cmp(&fR, &hR) == 0);
P_CHECKA(data_items = calloc(ndata, sizeof(bool)));
for (int i = 0; i < ndata; i++) {
// Arbitrary data
data_items[i] = (i % 3 == 1) || (i % 5 == 3);
}
P_CHECKA(sA = PrioServer_new(cfg, 0, skA, seed));
P_CHECKA(sB = PrioServer_new(cfg, 1, skB, seed));
unsigned int aLen, bLen;
P_CHECKC(PrioClient_encode(cfg, data_items, &for_a, &aLen, &for_b, &bLen));
MP_CHECKC(mp_init(&fR));
MP_CHECKC(mp_init(&gR));
MP_CHECKC(mp_init(&hR));
P_CHECKA(vA = PrioVerifier_new(sA));
P_CHECKA(vB = PrioVerifier_new(sB));
P_CHECKC(PrioVerifier_set_data(vA, for_a, aLen));
P_CHECKC(PrioVerifier_set_data(vB, for_b, bLen));
PrioPacketClient pA = vA->clientp;
PrioPacketClient pB = vB->clientp;
MP_CHECKC(mp_addmod(&pA->f0_share, &pB->f0_share, &cfg->modulus, &fR));
MP_CHECKC(mp_addmod(&pA->g0_share, &pB->g0_share, &cfg->modulus, &gR));
MP_CHECKC(mp_addmod(&pA->h0_share, &pB->h0_share, &cfg->modulus, &hR));
MP_CHECKC(mp_mulmod(&fR, &gR, &cfg->modulus, &fR));
mu_check(mp_cmp(&fR, &hR) == 0);
MP_CHECKC(mp_addmod(&vA->share_fR, &vB->share_fR, &cfg->modulus, &fR));
MP_CHECKC(mp_addmod(&vA->share_gR, &vB->share_gR, &cfg->modulus, &gR));
MP_CHECKC(mp_addmod(&vA->share_hR, &vB->share_hR, &cfg->modulus, &hR));
MP_CHECKC(mp_mulmod(&fR, &gR, &cfg->modulus, &fR));
mu_check(mp_cmp(&fR, &hR) == 0);
cleanup:
mu_check(rv == SECSuccess);
if (data_items)
free(data_items);
if (for_a)
free(for_a);
if (for_b)
@ -165,6 +161,7 @@ verify_full(int tweak)
PrioPacketVerify2 p2B = NULL;
unsigned char* for_a = NULL;
unsigned char* for_b = NULL;
bool* data_items = NULL;
mp_int fR, gR, hR;
MP_DIGITS(&fR) = NULL;
@ -179,66 +176,66 @@ verify_full(int tweak)
P_CHECKA(cfg = PrioConfig_new(47, pkA, pkB, (unsigned char*)"test4", 5));
const int ndata = PrioConfig_numDataFields(cfg);
{
bool data_items[ndata];
for (int i = 0; i < ndata; i++) {
// Arbitrary data
data_items[i] = (i % 3 == 1) || (i % 5 == 3);
}
P_CHECKA(sA = PrioServer_new(cfg, 0, skA, seed));
P_CHECKA(sB = PrioServer_new(cfg, 1, skB, seed));
unsigned int aLen, bLen;
P_CHECKC(PrioClient_encode(cfg, data_items, &for_a, &aLen, &for_b, &bLen));
if (tweak == 5) {
for_a[3] = 3;
for_a[4] = 4;
}
P_CHECKA(vA = PrioVerifier_new(sA));
P_CHECKA(vB = PrioVerifier_new(sB));
P_CHECKC(PrioVerifier_set_data(vA, for_a, aLen));
P_CHECKC(PrioVerifier_set_data(vB, for_b, bLen));
if (tweak == 3) {
mp_add_d(&vA->share_fR, 1, &vA->share_fR);
}
if (tweak == 4) {
mp_add_d(&vB->share_gR, 1, &vB->share_gR);
}
P_CHECKA(p1A = PrioPacketVerify1_new());
P_CHECKA(p1B = PrioPacketVerify1_new());
P_CHECKC(PrioPacketVerify1_set_data(p1A, vA));
P_CHECKC(PrioPacketVerify1_set_data(p1B, vB));
if (tweak == 1) {
mp_add_d(&p1B->share_d, 1, &p1B->share_d);
}
P_CHECKA(p2A = PrioPacketVerify2_new());
P_CHECKA(p2B = PrioPacketVerify2_new());
P_CHECKC(PrioPacketVerify2_set_data(p2A, vA, p1A, p1B));
P_CHECKC(PrioPacketVerify2_set_data(p2B, vB, p1A, p1B));
if (tweak == 2) {
mp_add_d(&p2A->share_out, 1, &p2B->share_out);
}
int shouldBe = tweak ? SECFailure : SECSuccess;
mu_check(PrioVerifier_isValid(vA, p2A, p2B) == shouldBe);
mu_check(PrioVerifier_isValid(vB, p2A, p2B) == shouldBe);
P_CHECKA(data_items = calloc(ndata, sizeof(bool)));
for (int i = 0; i < ndata; i++) {
// Arbitrary data
data_items[i] = (i % 3 == 1) || (i % 5 == 3);
}
P_CHECKA(sA = PrioServer_new(cfg, 0, skA, seed));
P_CHECKA(sB = PrioServer_new(cfg, 1, skB, seed));
unsigned int aLen, bLen;
P_CHECKC(PrioClient_encode(cfg, data_items, &for_a, &aLen, &for_b, &bLen));
if (tweak == 5) {
for_a[3] = 3;
for_a[4] = 4;
}
P_CHECKA(vA = PrioVerifier_new(sA));
P_CHECKA(vB = PrioVerifier_new(sB));
P_CHECKC(PrioVerifier_set_data(vA, for_a, aLen));
P_CHECKC(PrioVerifier_set_data(vB, for_b, bLen));
if (tweak == 3) {
mp_add_d(&vA->share_fR, 1, &vA->share_fR);
}
if (tweak == 4) {
mp_add_d(&vB->share_gR, 1, &vB->share_gR);
}
P_CHECKA(p1A = PrioPacketVerify1_new());
P_CHECKA(p1B = PrioPacketVerify1_new());
P_CHECKC(PrioPacketVerify1_set_data(p1A, vA));
P_CHECKC(PrioPacketVerify1_set_data(p1B, vB));
if (tweak == 1) {
mp_add_d(&p1B->share_d, 1, &p1B->share_d);
}
P_CHECKA(p2A = PrioPacketVerify2_new());
P_CHECKA(p2B = PrioPacketVerify2_new());
P_CHECKC(PrioPacketVerify2_set_data(p2A, vA, p1A, p1B));
P_CHECKC(PrioPacketVerify2_set_data(p2B, vB, p1A, p1B));
if (tweak == 2) {
mp_add_d(&p2A->share_out, 1, &p2B->share_out);
}
int shouldBe = tweak ? SECFailure : SECSuccess;
mu_check(PrioVerifier_isValid(vA, p2A, p2B) == shouldBe);
mu_check(PrioVerifier_isValid(vB, p2A, p2B) == shouldBe);
cleanup:
if (!tweak) {
mu_check(rv == SECSuccess);
}
if (data_items)
free(data_items);
if (for_a)
free(for_a);
if (for_b)