1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
use crate::silent_ot::get_reg_noise_weight;
use crate::silent_ot::pprf::PprfConfig;
use libote::SilverCode;
use num_integer::Integer;

#[derive(Debug)]
pub struct SilverEncoder {
    pub(crate) enc: libote::SilverEncoder,
    pub(crate) conf: SilverConf,
}

#[derive(Debug, Copy, Clone)]
pub struct SilverConf {
    #[allow(unused)]
    pub(crate) code: SilverCode,
    pub(crate) gap: usize,
    /// the number of OTs being requested.
    pub(crate) requested_num_ots: usize,
    /// The dense vector size, this will be at least as big as mRequestedNumOts.
    pub(crate) N: usize,
    /// The sparse vector size, this will be mN * mScaler.
    pub(crate) N2: usize,
    /// The size of each regular section of the sparse vector.
    pub(crate) size_per: usize,
    /// The number of regular section of the sparse vector.
    pub(crate) num_partitions: usize,
}

impl SilverConf {
    pub fn configure(num_ots: usize, weight: usize, sec_param: usize) -> Self {
        let code = match weight {
            5 => SilverCode::Weight5,
            11 => SilverCode::Weight11,
            _ => panic!("Unsupported weight."),
        };
        let scaler = 2;
        let gap = code.gap() as usize;
        let num_partitions = get_reg_noise_weight(0.2, sec_param) as usize;
        let size_per = Integer::next_multiple_of(
            &((num_ots * scaler + num_partitions - 1) / num_partitions),
            &8,
        );
        let N2 = size_per * num_partitions + gap;
        let N = N2 / scaler;
        Self {
            code,
            gap,
            requested_num_ots: num_ots,
            N,
            N2,
            size_per,
            num_partitions,
        }
    }
}

impl From<SilverConf> for PprfConfig {
    fn from(value: SilverConf) -> Self {
        PprfConfig::new(value.size_per, value.num_partitions)
    }
}