1use alloc::vec::Vec;
3
4use crate::arith::{
5 fixed_base::FixedBase,
6 monty::{Modulus, Residue},
7 multiexp::multiexp_vartime,
8 sbig::SBig,
9};
10use crate::error::Result;
11
12pub struct DfParams {
14 modulus: Modulus,
15 t: Residue,
16 s1: Residue,
17 s2: Residue,
18 tables: Option<[FixedBase; 3]>,
19}
20
21impl DfParams {
22 pub fn new(modulus: Modulus, t: Residue, s1: Residue, s2: Residue) -> Self {
23 Self {
24 modulus,
25 t,
26 s1,
27 s2,
28 tables: None,
29 }
30 }
31
32 pub fn modulus(&self) -> &Modulus {
33 &self.modulus
34 }
35 pub fn t(&self) -> &Residue {
36 &self.t
37 }
38 pub fn s1(&self) -> &Residue {
39 &self.s1
40 }
41 pub fn s2(&self) -> &Residue {
42 &self.s2
43 }
44
45 pub fn with_tables(mut self, max_bits: u32, window: u32) -> Self {
47 let m = &self.modulus;
48 self.tables = Some([
49 FixedBase::new(m, &self.t, max_bits, window),
50 FixedBase::new(m, &self.s1, max_bits, window),
51 FixedBase::new(m, &self.s2, max_bits, window),
52 ]);
53 self
54 }
55
56 pub fn with_tables_sized(mut self, max_bits: [u32; 3], window: u32) -> Self {
58 let m = &self.modulus;
59 self.tables = Some([
60 FixedBase::new(m, &self.t, max_bits[0], window),
61 FixedBase::new(m, &self.s1, max_bits[1], window),
62 FixedBase::new(m, &self.s2, max_bits[2], window),
63 ]);
64 self
65 }
66
67 pub fn tables_size_bytes(&self) -> usize {
69 self.tables
70 .as_ref()
71 .map_or(0, |t| t.iter().map(FixedBase::size_bytes).sum())
72 }
73
74 pub fn commit_ct(&self, a: &SBig, b: &SBig, r: &SBig, bits: [u32; 3]) -> Result<Residue> {
76 let (x, y, z) = match &self.tables {
77 Some([_, s1, s2]) if bits[0] <= s1.max_bits() && bits[1] <= s2.max_bits() => {
78 (s1.pow_ct(a)?, s2.pow_ct(b)?, self.pow_t_ct(r, bits[2])?)
79 }
80 _ => (
81 self.modulus.pow_ct(&self.s1, a, bits[0])?,
82 self.modulus.pow_ct(&self.s2, b, bits[1])?,
83 self.modulus.pow_ct(&self.t, r, bits[2])?,
84 ),
85 };
86 Ok(x.mul(&y).mul(&z))
87 }
88
89 fn pow_t_ct(&self, r: &SBig, bits: u32) -> Result<Residue> {
90 match &self.tables {
91 Some([t, _, _]) if bits <= t.max_bits() => t.pow_ct(r),
92 _ => self.modulus.pow_ct(&self.t, r, bits),
93 }
94 }
95
96 pub fn commit_vartime(&self, a: &SBig, b: &SBig, r: &SBig) -> Result<Residue> {
98 multiexp_vartime(&self.modulus, &[(&self.s1, a), (&self.s2, b), (&self.t, r)])
99 }
100
101 pub fn elements(&self) -> Vec<&Residue> {
103 alloc::vec![&self.t, &self.s1, &self.s2]
104 }
105}