2018-07-17 21:26:39 +03:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2018, Henry Corrigan-Gibbs
|
2018-08-29 23:47:18 +03:00
|
|
|
*
|
2018-07-17 21:26:39 +03:00
|
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
2018-08-29 23:47:18 +03:00
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
2018-07-17 21:26:39 +03:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include <mprio.h>
|
2018-08-11 18:35:19 +03:00
|
|
|
#include <stdlib.h>
|
2018-07-17 21:26:39 +03:00
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
#include "mparray.h"
|
2018-08-29 23:47:18 +03:00
|
|
|
#include "params.h"
|
2018-07-17 21:26:39 +03:00
|
|
|
#include "rand.h"
|
|
|
|
#include "util.h"
|
|
|
|
|
2018-11-08 01:24:04 +03:00
|
|
|
int
|
|
|
|
PrioConfig_maxDataFields(void)
|
|
|
|
{
|
|
|
|
const int n_roots = 1 << Generator2Order;
|
|
|
|
return (n_roots >> 1) - 1;
|
|
|
|
}
|
|
|
|
|
2020-05-19 13:30:30 +03:00
|
|
|
int
|
2020-05-23 21:11:23 +03:00
|
|
|
PrioConfig_maxUIntEntries(int prec)
|
2020-05-19 13:30:30 +03:00
|
|
|
{
|
2020-05-21 18:16:22 +03:00
|
|
|
if (prec <= 0)
|
|
|
|
return 0;
|
|
|
|
if (prec > BBIT_PREC_MAX)
|
|
|
|
return 0;
|
|
|
|
|
2020-05-19 13:30:30 +03:00
|
|
|
return PrioConfig_maxDataFields() / prec;
|
|
|
|
}
|
|
|
|
|
2018-08-29 23:47:18 +03:00
|
|
|
PrioConfig
|
2020-06-02 09:38:23 +03:00
|
|
|
PrioConfig_new(int n_fields,
|
|
|
|
PublicKey server_a,
|
|
|
|
PublicKey server_b,
|
|
|
|
const unsigned char* batch_id,
|
|
|
|
unsigned int batch_id_len)
|
2018-07-17 21:26:39 +03:00
|
|
|
{
|
|
|
|
SECStatus rv = SECSuccess;
|
2018-08-29 23:47:18 +03:00
|
|
|
PrioConfig cfg = malloc(sizeof(*cfg));
|
2018-07-17 21:26:39 +03:00
|
|
|
if (!cfg)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
cfg->batch_id = NULL;
|
|
|
|
cfg->batch_id_len = batch_id_len;
|
|
|
|
cfg->server_a_pub = server_a;
|
|
|
|
cfg->server_b_pub = server_b;
|
|
|
|
cfg->num_data_fields = n_fields;
|
|
|
|
cfg->n_roots = 1 << Generator2Order;
|
|
|
|
MP_DIGITS(&cfg->modulus) = NULL;
|
|
|
|
MP_DIGITS(&cfg->inv2) = NULL;
|
2019-03-28 07:34:20 +03:00
|
|
|
MP_DIGITS(&cfg->generator) = NULL;
|
2018-07-17 21:26:39 +03:00
|
|
|
|
2018-11-08 01:24:04 +03:00
|
|
|
P_CHECKCB(cfg->n_roots > 1);
|
|
|
|
P_CHECKCB(cfg->num_data_fields <= PrioConfig_maxDataFields());
|
2018-07-17 21:26:39 +03:00
|
|
|
|
2018-08-29 23:47:18 +03:00
|
|
|
P_CHECKA(cfg->batch_id = malloc(batch_id_len));
|
|
|
|
strncpy((char*)cfg->batch_id, (char*)batch_id, batch_id_len);
|
2018-07-17 21:26:39 +03:00
|
|
|
|
2018-08-29 23:47:18 +03:00
|
|
|
MP_CHECKC(mp_init(&cfg->modulus));
|
|
|
|
MP_CHECKC(mp_read_radix(&cfg->modulus, Modulus, 16));
|
2018-07-17 21:26:39 +03:00
|
|
|
|
2019-03-28 07:34:20 +03:00
|
|
|
MP_CHECKC(mp_init(&cfg->generator));
|
|
|
|
MP_CHECKC(mp_read_radix(&cfg->generator, Generator, 16));
|
|
|
|
|
2018-07-17 21:26:39 +03:00
|
|
|
// Compute 2^{-1} modulo M
|
2018-08-29 23:47:18 +03:00
|
|
|
MP_CHECKC(mp_init(&cfg->inv2));
|
|
|
|
mp_set(&cfg->inv2, 2);
|
|
|
|
MP_CHECKC(mp_invmod(&cfg->inv2, &cfg->modulus, &cfg->inv2));
|
2018-07-17 21:26:39 +03:00
|
|
|
|
|
|
|
cleanup:
|
|
|
|
if (rv != SECSuccess) {
|
2018-08-29 23:47:18 +03:00
|
|
|
PrioConfig_clear(cfg);
|
2018-07-17 21:26:39 +03:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return cfg;
|
|
|
|
}
|
|
|
|
|
2020-05-19 13:30:30 +03:00
|
|
|
PrioConfig
|
2020-06-02 09:38:23 +03:00
|
|
|
PrioConfig_new_uint(int num_uints,
|
|
|
|
int prec,
|
|
|
|
PublicKey server_a,
|
|
|
|
PublicKey server_b,
|
|
|
|
const unsigned char* batch_id,
|
2020-05-23 21:11:23 +03:00
|
|
|
unsigned int batch_id_len)
|
2020-05-19 13:30:30 +03:00
|
|
|
{
|
2020-05-21 18:16:22 +03:00
|
|
|
if (prec <= 0)
|
|
|
|
return NULL;
|
|
|
|
if (prec > BBIT_PREC_MAX)
|
|
|
|
return NULL;
|
|
|
|
|
2020-06-02 09:38:23 +03:00
|
|
|
return PrioConfig_new(
|
|
|
|
num_uints * prec, server_a, server_b, batch_id, batch_id_len);
|
2020-05-19 13:30:30 +03:00
|
|
|
}
|
|
|
|
|
2018-08-29 23:47:18 +03:00
|
|
|
PrioConfig
|
|
|
|
PrioConfig_newTest(int nFields)
|
2018-07-17 21:26:39 +03:00
|
|
|
{
|
2018-08-29 23:47:18 +03:00
|
|
|
return PrioConfig_new(nFields, NULL, NULL, (unsigned char*)"testBatch", 9);
|
2018-07-17 21:26:39 +03:00
|
|
|
}
|
|
|
|
|
2018-08-29 23:47:18 +03:00
|
|
|
void
|
|
|
|
PrioConfig_clear(PrioConfig cfg)
|
2018-07-17 21:26:39 +03:00
|
|
|
{
|
2018-08-29 23:47:18 +03:00
|
|
|
if (!cfg)
|
|
|
|
return;
|
|
|
|
if (cfg->batch_id)
|
|
|
|
free(cfg->batch_id);
|
|
|
|
mp_clear(&cfg->modulus);
|
|
|
|
mp_clear(&cfg->inv2);
|
2019-03-28 07:34:20 +03:00
|
|
|
mp_clear(&cfg->generator);
|
2018-08-29 23:47:18 +03:00
|
|
|
free(cfg);
|
2018-07-17 21:26:39 +03:00
|
|
|
}
|
|
|
|
|
2018-08-29 23:47:18 +03:00
|
|
|
int
|
|
|
|
PrioConfig_numDataFields(const_PrioConfig cfg)
|
2018-07-17 21:26:39 +03:00
|
|
|
{
|
|
|
|
return cfg->num_data_fields;
|
|
|
|
}
|
|
|
|
|
2020-05-19 13:30:30 +03:00
|
|
|
int
|
2020-05-23 21:11:23 +03:00
|
|
|
PrioConfig_numUIntEntries(const_PrioConfig cfg, int prec)
|
2020-05-19 13:30:30 +03:00
|
|
|
{
|
2020-05-21 18:16:22 +03:00
|
|
|
if (prec <= 0)
|
|
|
|
return 0;
|
|
|
|
if (prec > BBIT_PREC_MAX)
|
|
|
|
return 0;
|
2020-05-19 13:30:30 +03:00
|
|
|
return cfg->num_data_fields / prec;
|
|
|
|
}
|
|
|
|
|
2018-08-29 23:47:18 +03:00
|
|
|
SECStatus
|
|
|
|
Prio_init(void)
|
2018-07-17 21:26:39 +03:00
|
|
|
{
|
2018-08-29 23:47:18 +03:00
|
|
|
return rand_init();
|
2018-07-17 21:26:39 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2018-08-29 23:47:18 +03:00
|
|
|
Prio_clear(void)
|
2018-07-17 21:26:39 +03:00
|
|
|
{
|
2018-08-29 23:47:18 +03:00
|
|
|
rand_clear();
|
2018-07-17 21:26:39 +03:00
|
|
|
}
|
|
|
|
|
2018-08-29 23:47:18 +03:00
|
|
|
int
|
|
|
|
PrioConfig_hPoints(const_PrioConfig cfg)
|
2018-07-17 21:26:39 +03:00
|
|
|
{
|
|
|
|
const int mul_gates = cfg->num_data_fields + 1;
|
2018-08-29 23:47:18 +03:00
|
|
|
const int N = next_power_of_two(mul_gates);
|
2018-07-17 21:26:39 +03:00
|
|
|
return N;
|
|
|
|
}
|