pub struct Params { /* private fields */ }Expand description
Fixed ring settings used by cryptographic constructions over R_q = Z_q[x] / (f(x)).
Construction validates:
- polynomial metadata and modulus,
- modulus polynomial properties,
- NTT suitability for multiplying degree-bounded polynomials,
- primitive root compatibility with the chosen NTT length.
Implementations§
Source§impl Params
impl Params
Sourcepub fn new(
max_degree: usize,
modulus: u64,
modulus_poly_coeffs: &[u64],
primitive_root: u64,
) -> Result<Self, ParamsError>
pub fn new( max_degree: usize, modulus: u64, modulus_poly_coeffs: &[u64], primitive_root: u64, ) -> Result<Self, ParamsError>
Builds validated ring parameters.
modulus_poly_coeffs must define a non-constant polynomial whose degree equals
max_degree, with invertible leading coefficient in Z_q.
Sourcepub fn max_degree(&self) -> usize
pub fn max_degree(&self) -> usize
Maximum supported polynomial degree.
Examples found in repository?
examples/common/codec.rs (line 137)
132pub fn decode_message_scaled_bits_example(
133 element: &RingElem,
134 output_len_bytes: usize,
135) -> Result<Vec<u8>, CodecError> {
136 // Decode limit follows the same bit-capacity convention used at encode time.
137 let capacity_bits = element.params().max_degree();
138 let requested_bits = output_len_bytes.saturating_mul(8);
139 if requested_bits > capacity_bits {
140 return Err(CodecError::DecodeLengthTooLong {
141 requested_bits,
142 capacity_bits,
143 });
144 }
145
146 let q = element.params().modulus();
147 // Threshold window near middle of modulus range.
148 // Values in `[q/4, 3q/4)` decode to 1; others decode to 0.
149 let lower = q / 4;
150 let upper = (3 * q) / 4;
151
152 let mut out = vec![0_u8; output_len_bytes];
153 for bit_index in 0..requested_bits {
154 let coeff = element.coefficients()[bit_index];
155 let bit = coeff >= lower && coeff < upper;
156 if bit {
157 // Restore little-endian bit position.
158 out[bit_index / 8] |= 1_u8 << (bit_index % 8);
159 }
160 }
161
162 Ok(out)
163}Sourcepub fn modulus(&self) -> u64
pub fn modulus(&self) -> u64
Coefficient modulus q.
Examples found in repository?
examples/common/codec.rs (line 146)
132pub fn decode_message_scaled_bits_example(
133 element: &RingElem,
134 output_len_bytes: usize,
135) -> Result<Vec<u8>, CodecError> {
136 // Decode limit follows the same bit-capacity convention used at encode time.
137 let capacity_bits = element.params().max_degree();
138 let requested_bits = output_len_bytes.saturating_mul(8);
139 if requested_bits > capacity_bits {
140 return Err(CodecError::DecodeLengthTooLong {
141 requested_bits,
142 capacity_bits,
143 });
144 }
145
146 let q = element.params().modulus();
147 // Threshold window near middle of modulus range.
148 // Values in `[q/4, 3q/4)` decode to 1; others decode to 0.
149 let lower = q / 4;
150 let upper = (3 * q) / 4;
151
152 let mut out = vec![0_u8; output_len_bytes];
153 for bit_index in 0..requested_bits {
154 let coeff = element.coefficients()[bit_index];
155 let bit = coeff >= lower && coeff < upper;
156 if bit {
157 // Restore little-endian bit position.
158 out[bit_index / 8] |= 1_u8 << (bit_index % 8);
159 }
160 }
161
162 Ok(out)
163}
164
165/// Compresses one coefficient into `bits` bits.
166pub fn compress_coefficient_example(value: u64, modulus: u64, bits: u8) -> Result<u16, CodecError> {
167 validate_compression_bits(bits)?;
168
169 // Quantization levels = 2^bits.
170 let levels = 1_u128 << bits;
171 let q = modulus as u128;
172 let v = (value % modulus) as u128;
173
174 // Rounded scaling from `[0, q)` into `[0, 2^bits)`.
175 let compressed = ((v * levels + (q / 2)) / q) % levels;
176 Ok(compressed as u16)
177}
178
179/// Decompresses one `bits`-bit coefficient back into `Z_q`.
180pub fn decompress_coefficient_example(
181 compressed: u16,
182 modulus: u64,
183 bits: u8,
184) -> Result<u64, CodecError> {
185 validate_compression_bits(bits)?;
186
187 let levels = 1_u128 << bits;
188 let q = modulus as u128;
189 let c = (compressed as u128) % levels;
190
191 // Rounded inverse scaling from `[0, 2^bits)` back into `[0, q)`.
192 let decompressed = (c * q + (levels / 2)) / levels;
193 Ok((decompressed % q) as u64)
194}
195
196/// Compresses all coefficients of a ring element into `bits` bits each.
197pub fn compress_ring_elem_example(element: &RingElem, bits: u8) -> Result<Vec<u16>, CodecError> {
198 validate_compression_bits(bits)?;
199
200 let q = element.params().modulus();
201 // Compress each coefficient independently.
202 let mut packed = Vec::with_capacity(element.coefficients().len());
203 for &coeff in element.coefficients() {
204 packed.push(compress_coefficient_example(coeff, q, bits)?);
205 }
206 Ok(packed)
207}Sourcepub fn modulus_poly(&self) -> &Polynomial
pub fn modulus_poly(&self) -> &Polynomial
Ring modulus polynomial f(x).
Sourcepub fn primitive_root(&self) -> u64
pub fn primitive_root(&self) -> u64
Primitive root used to derive NTT roots of unity.
Sourcepub fn ntt_length(&self) -> usize
pub fn ntt_length(&self) -> usize
NTT length derived from max_degree for exact product convolutions.
Trait Implementations§
impl Eq for Params
impl StructuralPartialEq for Params
Auto Trait Implementations§
impl Freeze for Params
impl RefUnwindSafe for Params
impl Send for Params
impl Sync for Params
impl Unpin for Params
impl UnwindSafe for Params
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more