Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/third_party/prio/prio/config.c
Line
Count
Source (jump to first uncovered line)
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 "params.h"
15
#include "rand.h"
16
#include "util.h"
17
18
// The PrioConfig object stores "2^k-th roots of unity" modulo
19
// the prime modulus we use for all arithmetic. We use
20
// these roots to perform fast FFT-style polynomial
21
// interpolation and evaluation.
22
//
23
// In particular, we use a prime modulus p such that
24
//    p = (2^k)q + 1.
25
// The roots are integers such that r^{2^k} = 1 mod p.
26
static SECStatus
27
initialize_roots(MPArray arr, const char* values[])
28
0
{
29
0
  // TODO: Read in only the number of roots of unity we need.
30
0
  // Right now we read in all 4096 roots whether or not we use
31
0
  // them all.
32
0
  for (int i = 0; i < arr->len; i++) {
33
0
    MP_CHECK(mp_read_radix(&arr->data[i], values[i], 16));
34
0
  }
35
0
36
0
  return SECSuccess;
37
0
}
38
39
PrioConfig
40
PrioConfig_new(int n_fields, PublicKey server_a, PublicKey server_b,
41
               const unsigned char* batch_id, unsigned int batch_id_len)
42
0
{
43
0
  SECStatus rv = SECSuccess;
44
0
  PrioConfig cfg = malloc(sizeof(*cfg));
45
0
  if (!cfg)
46
0
    return NULL;
47
0
48
0
  cfg->batch_id = NULL;
49
0
  cfg->batch_id_len = batch_id_len;
50
0
  cfg->server_a_pub = server_a;
51
0
  cfg->server_b_pub = server_b;
52
0
  cfg->num_data_fields = n_fields;
53
0
  cfg->n_roots = 1 << Generator2Order;
54
0
  MP_DIGITS(&cfg->modulus) = NULL;
55
0
  MP_DIGITS(&cfg->inv2) = NULL;
56
0
  cfg->roots = NULL;
57
0
  cfg->rootsInv = NULL;
58
0
59
0
  if (cfg->num_data_fields >= cfg->n_roots) {
60
0
    rv = SECFailure;
61
0
    goto cleanup;
62
0
  }
63
0
64
0
  P_CHECKA(cfg->batch_id = malloc(batch_id_len));
65
0
  strncpy((char*)cfg->batch_id, (char*)batch_id, batch_id_len);
66
0
67
0
  MP_CHECKC(mp_init(&cfg->modulus));
68
0
  MP_CHECKC(mp_read_radix(&cfg->modulus, Modulus, 16));
69
0
70
0
  // Compute  2^{-1} modulo M
71
0
  MP_CHECKC(mp_init(&cfg->inv2));
72
0
  mp_set(&cfg->inv2, 2);
73
0
  MP_CHECKC(mp_invmod(&cfg->inv2, &cfg->modulus, &cfg->inv2));
74
0
75
0
  P_CHECKA(cfg->roots = MPArray_new(cfg->n_roots));
76
0
  P_CHECKA(cfg->rootsInv = MPArray_new(cfg->n_roots));
77
0
  MP_CHECKC(initialize_roots(cfg->roots, Roots));
78
0
  MP_CHECKC(initialize_roots(cfg->rootsInv, RootsInv));
79
0
80
0
cleanup:
81
0
  if (rv != SECSuccess) {
82
0
    PrioConfig_clear(cfg);
83
0
    return NULL;
84
0
  }
85
0
86
0
  return cfg;
87
0
}
88
89
PrioConfig
90
PrioConfig_newTest(int nFields)
91
0
{
92
0
  return PrioConfig_new(nFields, NULL, NULL, (unsigned char*)"testBatch", 9);
93
0
}
94
95
void
96
PrioConfig_clear(PrioConfig cfg)
97
0
{
98
0
  if (!cfg)
99
0
    return;
100
0
  if (cfg->batch_id)
101
0
    free(cfg->batch_id);
102
0
  MPArray_clear(cfg->roots);
103
0
  MPArray_clear(cfg->rootsInv);
104
0
  mp_clear(&cfg->modulus);
105
0
  mp_clear(&cfg->inv2);
106
0
  free(cfg);
107
0
}
108
109
int
110
PrioConfig_numDataFields(const_PrioConfig cfg)
111
0
{
112
0
  return cfg->num_data_fields;
113
0
}
114
115
SECStatus
116
Prio_init(void)
117
0
{
118
0
  return rand_init();
119
0
}
120
121
void
122
Prio_clear(void)
123
0
{
124
0
  rand_clear();
125
0
}
126
127
int
128
PrioConfig_hPoints(const_PrioConfig cfg)
129
0
{
130
0
  const int mul_gates = cfg->num_data_fields + 1;
131
0
  const int N = next_power_of_two(mul_gates);
132
0
  return N;
133
0
}