rustaesinteger-overflow

Attempt to multiply with overflow


Rust panicked: attempt to multiply with overflow

I'm trying to make a polynomial for the "AES" encryption algorithm. The fn new() is meant to construct the bit vector representation of a number x of whatever galois_field, in order to use it for the add and multiplication of an extension_field (from the AES algo).

#[derive(Debug)]
struct polynomial(Vec<u8>);

impl polynomial {
    fn new(mut x: i16) -> Self {
        println!("polynomial::new() --> Start");

        let mut poly: Vec<u8> = Vec::new();

        for e in 0..16 {
            poly.push(0);
        }

        for e in (0..16).rev() {
            println!("polynomial::new() :: loop :: --> In ");

            if x > 0 {
                if x - 2_i16.pow(e) >= 2_i16.pow(e - 1) || x - 2_i16.pow(e) == 0 {
                    x -= 2_i16.pow(e);
                    poly[e as usize] = 1;
                }
            } else {
                if x - 1 == 0 {
                    poly[e as usize] = 1;
                    println!("x : {x}");
                    println!("polynomial : {poly:#?}");
                }
            }
        }

        println!("polynomial::new() --> End");
        return Self(poly);
    }
}

fn main() {
    let x = polynomial::new(7);
    let y = polynomial::new(41);

    let z = polynomial::add(x, y);
    println!("z : {z:#?}");
}

When I run the code I know that the error occurs in the second println! macro, but I don't know in which if statement. This is the output at runtime:

polynomial::new() --> Start
polynomial::new() :: loop :: --> In 
thread 'main' panicked at /usr/src/debug/rust/rustc-1.78.0-src/library/core/src/num/mod.rs:324:5:
attempt to multiply with overflow

I have no idea why it happens. I wanted to set RUST_BACKTRACE = 1 but I don't know how.


Solution

  • Actually the solution was very easy. I only had to change the primitive values to i32 and not let it overflow the max value of a u16.

    fn new(mut x: i32) -> Result<Self, ()> {
        if x > std::u16::MAX.into() {
            println!("x must be equal or lower than u16::MAX");
            return Err(());
        }
    
        let mut poly: Vec<u8> = Vec::new();
    
        for e in 0..16 {
            poly.push(0);
        }
    
        for e in (0..16).rev() {
           if x - 2_i32.pow(e) > -1 {
              x -= 2_i32.pow(e);
              poly[e as usize] = 1;
           }
        }