如何更改此功能的返回类型?

时间:2015-05-26 02:42:42

标签: rust

我正在使用rust matasano crypto challenges,使用rust-crypto进行AES实现。我有这个功能来进行基本的ECB模式加密(基本上几乎逐字逐句地从rust-crypto repository's example开始):

pub fn aes_enc_ecb_128(key: &[u8], data: &[u8]) 
                       -> Result<Vec<u8>, symmetriccipher::SymmetricCipherError> {
    let mut encryptor = aes::ecb_encryptor(
            aes::KeySize::KeySize128,
            key,
            blockmodes::NoPadding);
    let mut final_result = Vec::<u8>::new();
    let mut read_buffer = buffer::RefReadBuffer::new(data);
    let mut buffer = [0; 4096];
    let mut write_buffer = buffer::RefWriteBuffer::new(&mut buffer);

    loop {
        let result = encryptor.encrypt(&mut read_buffer,
                                       &mut write_buffer,
                                       true);

        final_result.extend(write_buffer
                            .take_read_buffer()
                            .take_remaining().iter().map(|&i| i));
        match result {
            Ok(BufferResult::BufferUnderflow) => break,
            Ok(_) => {},
            Err(e) => return Err(e)
        }
    }

    Ok(final_result)
}

以上版本编译没有问题,并按预期工作。但是,为了使其适合我的错误处理方案的其余部分,我想将返回类型更改为Result<Vec<u8>,&'static str>。这是应用该更改的功能:

pub fn aes_enc_ecb_128(key: &[u8], data: &[u8]) 
                       -> Result<Vec<u8>, &'static str> {
    let mut encryptor = aes::ecb_encryptor(
            aes::KeySize::KeySize128,
            key,
            blockmodes::NoPadding);
    let mut final_result = Vec::<u8>::new();
    let mut read_buffer = buffer::RefReadBuffer::new(data);
    let mut buffer = [0; 4096];
    let mut write_buffer = buffer::RefWriteBuffer::new(&mut buffer);

    loop {
        let result = encryptor.encrypt(&mut read_buffer,
                                       &mut write_buffer,
                                       true);

        final_result.extend(write_buffer
                            .take_read_buffer()
                            .take_remaining().iter().map(|&i| i));
        match result {
            Ok(BufferResult::BufferUnderflow) => break,
            Ok(_) => {},
            Err(_) => return Err("Encryption failed")
        }
    }

    Ok(final_result)
}

当我尝试编译此版本时,出现以下错误(为清晰起见,删除了路径):

error: source trait is private
         let result = encryptor.encrypt(&mut read_buffer,
                                        &mut write_buffer,
                                        true);
error: source trait is private
let r = decryptor.decrypt(&mut read_buffer, &mut write_buffer, true);
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

我能够改变这种类型的唯一方法是将原始函数包装在这样的转换函数中:

pub fn converted_enc(key: &[u8], data: &[u8]) 
                       -> Result<Vec<u8>, &'static str> {
   match aes_enc_ecb_128(key,data) {
       Ok(v) => Ok(v),
       Err(_) => Err("Encryption failed")
   } 
}

为了使返回值适合我的其余API,我应该做什么而不是上面的内容,以及为什么更直接的方法失败?

我正在使用以下版本的铁锈/货物:

rustc 1.2.0-nightly (0cc99f9cc 2015-05-17) (built 2015-05-18)
cargo 0.2.0-nightly (ac61996 2015-05-17) (built 2015-05-17)

1 个答案:

答案 0 :(得分:2)

我认为您遇到了编译器的错误。你的代码应该编译

您可以use crypto::symmetriccipher::Encryptor;作为解决方法:

pub fn aes_enc_ecb_128(key: &[u8], data: &[u8]) 
                       -> Result<Vec<u8>, &'static str> {
    use crypto::symmetriccipher::Encryptor;
    let mut encryptor = aes::ecb_encryptor(
            aes::KeySize::KeySize128,
            key,
            blockmodes::NoPadding);
    let mut final_result = Vec::<u8>::new();
    let mut read_buffer = buffer::RefReadBuffer::new(data);
    let mut buffer = [0; 4096];
    let mut write_buffer = buffer::RefWriteBuffer::new(&mut buffer);

    loop {
        let result = encryptor.encrypt(&mut read_buffer,
                                       &mut write_buffer,
                                       true);

        final_result.extend(write_buffer
                            .take_read_buffer()
                            .take_remaining().iter().map(|&i| i));
        match result {
            Ok(BufferResult::BufferUnderflow) => break,
            Ok(_) => {},
            Err(_) => return Err("Encryption failed")
        }
    }

    Ok(final_result)
}