Noise propagation in shortints

Hi, as I understand it, the noise measurement in shortints is on a logarithmic scale? Hence it seems a bit unintuitive that multiplying a shortint by a scalar multiplies the noise and adding two shortints adds the noises:

pub(crate) fn unchecked_scalar_mul_assign(
    ct: &mut Ciphertext,
    scalar: u8,
    max_noise_level: MaxNoiseLevel,
) {
    let scalar = u64::from(scalar);
    ct.set_noise_level(ct.noise_level() * scalar, max_noise_level);
    ct.degree = Degree::new(ct.degree.get() * scalar);

    match scalar {
        0 => {
            trivially_encrypt_lwe_ciphertext(&mut ct.ct, Plaintext(0));
        }
        1 => {
            // Multiplication by one is the identity
        }
        scalar => {
            let cleartext_scalar = Cleartext(scalar);
            lwe_ciphertext_cleartext_mul_assign(&mut ct.ct, cleartext_scalar);
        }
    }
}


pub(crate) fn unchecked_add_assign(
    ct_left: &mut Ciphertext,
    ct_right: &Ciphertext,
    max_noise_level: MaxNoiseLevel,
) {
    lwe_ciphertext_add_assign(&mut ct_left.ct, &ct_right.ct);
    ct_left.degree = Degree::new(ct_left.degree.get() + ct_right.degree.get());
    ct_left.set_noise_level(
        ct_left.noise_level() + ct_right.noise_level(),
        max_noise_level,
    );
}


Can you clarify a bit on how shortint::Ciphertext::noise_level works, what it measures and what the scale is it measures on?

hello @Allan

Max Noise level indicates how full the noise can be wrt to a base noise level.

Adding/subtracting multiplies the noise by 2, multipliying by a scalar multiplies the noise by said scalar.

apply_lookup_table resets the noise to its nominal level.

That’s all there is to it.