//! 此密码库实现了中华人民共和国国家密码管理局发布的商用密码算法。
//!
//! This cryptographic library implements the ShangMi algorithms
//! which issued by the State Cryptography Administration of the People's Republic of China.
//!
//! ## SM3杂凑值计算示例（SM3 Hash Calculation Example）
//!
//! ```rust
//! use neuedu_cryptos::hash_functions::SM3;
//!
//! let mut sm3 = SM3::new();
//! sm3.update("abc".as_bytes());
//! let digest = sm3.r#final();
//!
//! assert_eq!(digest, [
//!     0x66, 0xC7, 0xF0, 0xF4, 0x62, 0xEE, 0xED, 0xD9,
//!     0xD1, 0xF2, 0xD4, 0x6B, 0xDC, 0x10, 0xE4, 0xE2,
//!     0x41, 0x67, 0xC4, 0x87, 0x5C, 0xF2, 0xF7, 0xA2,
//!     0x29, 0x7D, 0xA0, 0x2B, 0x8F, 0x4B, 0xA8, 0xE0,
//! ]);
//! ```
//!
//! ## SM4加密示例（SM4 Encryption Example）
//!
//! ```rust
//! use neuedu_cryptos::block_ciphers::{Operation, SM4};
//!
//! const KEY: [u8; 16] = [
//!     0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
//!     0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
//! ];
//! const PLAIN_MESSAGE: [u8; 16] = [
//!     0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
//!     0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
//! ];
//! let mut sm4 = SM4::new(KEY, Operation::Encrypt, None, None);
//!
//! let mut cipher_message = Vec::<u8>::new();
//! cipher_message.extend(&sm4.update(&PLAIN_MESSAGE));
//! cipher_message.extend(&sm4.r#final());
//!
//! assert_eq!(cipher_message, [
//!     0x68, 0x1E, 0xDF, 0x34, 0xD2, 0x06, 0x96, 0x5E,
//!     0x86, 0xB3, 0xE9, 0x4F, 0x53, 0x6E, 0x42, 0x46,
//! ]);
//! ```
//!
//! ## SM4解密示例（SM4 Decryption Example）
//!
//! ```rust
//! use neuedu_cryptos::block_ciphers::{Operation, SM4};
//!
//! const KEY: [u8; 16] = [
//!     0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
//!     0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
//! ];
//! const CIPHER_MESSAGE: [u8; 16] = [
//!     0x68, 0x1E, 0xDF, 0x34, 0xD2, 0x06, 0x96, 0x5E,
//!     0x86, 0xB3, 0xE9, 0x4F, 0x53, 0x6E, 0x42, 0x46,
//! ];
//! let mut sm4 = SM4::new(KEY, Operation::Decrypt, None, None);
//!
//! let mut plain_message = Vec::<u8>::new();
//! plain_message.extend(&sm4.update(&CIPHER_MESSAGE));
//! plain_message.extend(&sm4.r#final());
//!
//! assert_eq!(plain_message, [
//!     0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
//!     0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
//! ]);
//! ```

pub mod block_ciphers;
pub mod hash_functions;
mod libs;


#[cfg(test)]
mod tests {

    #[test]
    fn sm3_3() {
        use crate::hash_functions::SM3;

        let mut sm3 = SM3::new();
        sm3.update("abc".as_bytes());
        let digest = sm3.r#final();

        assert_eq!(digest, [
            0x66, 0xC7, 0xF0, 0xF4, 0x62, 0xEE, 0xED, 0xD9, 0xD1, 0xF2, 0xD4, 0x6B, 0xDC, 0x10, 0xE4, 0xE2,
            0x41, 0x67, 0xC4, 0x87, 0x5C, 0xF2, 0xF7, 0xA2, 0x29, 0x7D, 0xA0, 0x2B, 0x8F, 0x4B, 0xA8, 0xE0,
        ]);
    }

    #[test]
    fn sm3_512() {
        use crate::hash_functions::SM3;

        const MESSAGE: &str = "abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd";

        let mut sm3 = SM3::new();
        sm3.update(MESSAGE.as_bytes());
        let digest = sm3.r#final();
        assert_eq!(digest, [
            222, 190, 159, 249, 34, 117, 184, 161, 56, 96, 72, 137, 193, 142, 90, 77,
            111, 219, 112, 229, 56, 126, 87, 101, 41, 61, 203, 163, 156, 12, 87, 50,
        ]);
    }

    #[test]
    fn sm4_ecb_padding_none() {
        use crate::block_ciphers::{Operation, OperationMode};
        use crate::block_ciphers::SM4;

        const KEY: [u8; 16] = [0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10];
        const MESSAGE: [u8; 16] = [0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10];

        let mut sm4 = SM4::new(KEY, Operation::Encrypt, Some(OperationMode::ECB), None);
        let mut encrypt_result = Vec::<u8>::new();
        encrypt_result.extend(&sm4.update(&MESSAGE));
        encrypt_result.extend(&sm4.update(&MESSAGE));
        encrypt_result.extend(&sm4.r#final());
        assert_eq!(encrypt_result, [
            0x68, 0x1E, 0xDF, 0x34, 0xD2, 0x06, 0x96, 0x5E, 0x86, 0xB3, 0xE9, 0x4F, 0x53, 0x6E, 0x42, 0x46,
            0x68, 0x1E, 0xDF, 0x34, 0xD2, 0x06, 0x96, 0x5E, 0x86, 0xB3, 0xE9, 0x4F, 0x53, 0x6E, 0x42, 0x46,
        ]);

        let mut sm4 = SM4::new(KEY, Operation::Decrypt, Some(OperationMode::ECB), None);
        let mut decrypt_result = Vec::<u8>::new();
        decrypt_result.extend(&sm4.update(&encrypt_result));
        decrypt_result.extend(&sm4.r#final());
        assert_eq!(decrypt_result, [
            0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
            0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
        ]);
    }

    #[test]
    fn sm4_ecb_padding_pkcs7() {
        use crate::block_ciphers::{Operation, OperationMode, PaddingMode};
        use crate::block_ciphers::SM4;

        const KEY: [u8; 16] = [0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10];
        const MESSAGE_ALIGN: [u8; 16] = [0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10];
        const MESSAGE_UNALIGN: [u8; 15] = [0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32];

        let mut sm4 = SM4::new(KEY, Operation::Encrypt, Some(OperationMode::ECB), Some(PaddingMode::Mode1));
        let mut encrypt_result = Vec::<u8>::new();
        encrypt_result.extend(&sm4.update(&MESSAGE_ALIGN));
        encrypt_result.extend(&sm4.r#final());

        assert_eq!(encrypt_result, [
            104, 30, 223, 52, 210, 6, 150, 94, 134, 179, 233, 79, 83, 110, 66, 70,
            0, 42, 138, 78, 250, 134, 60, 202, 208, 36, 172, 3, 0, 187, 64, 210,
        ]);

        let mut sm4 = SM4::new(KEY, Operation::Decrypt, Some(OperationMode::ECB), Some(PaddingMode::Mode1));
        let mut decrypt_result = Vec::<u8>::new();
        decrypt_result.extend(&sm4.update(&encrypt_result));
        decrypt_result.extend(&sm4.r#final());
        assert_eq!(decrypt_result, [
            0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
        ]);

        let mut sm4 = SM4::new(KEY, Operation::Encrypt, Some(OperationMode::ECB), Some(PaddingMode::Mode1));
        let mut encrypt_result = Vec::<u8>::new();
        encrypt_result.extend(&sm4.update(&MESSAGE_ALIGN));
        encrypt_result.extend(&sm4.update(&MESSAGE_UNALIGN));
        encrypt_result.extend(&sm4.r#final());

        assert_eq!(encrypt_result, [
            104, 30, 223, 52, 210, 6, 150, 94, 134, 179, 233, 79, 83, 110, 66, 70,
            236, 33, 220, 50, 174, 93, 235, 26, 85, 223, 83, 247, 213, 117, 161, 33
        ]);

        let mut sm4 = SM4::new(KEY, Operation::Decrypt, Some(OperationMode::ECB), Some(PaddingMode::Mode1));
        let mut decrypt_result = Vec::<u8>::new();
        decrypt_result.extend(&sm4.update(&encrypt_result));
        decrypt_result.extend(&sm4.r#final());
        assert_eq!(decrypt_result, [
            0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
            0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32,
        ]);
    }

    #[test]
    fn sm4_ecb_padding_bit() {
        use crate::block_ciphers::{Operation, OperationMode, PaddingMode};
        use crate::block_ciphers::SM4;

        const KEY: [u8; 16] = [0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10];
        const MESSAGE_ALIGN: [u8; 16] = [0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10];
        const MESSAGE_UNALIGN: [u8; 15] = [0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32];

        let mut sm4 = SM4::new(KEY, Operation::Encrypt, Some(OperationMode::ECB), Some(PaddingMode::Mode2));
        let mut encrypt_result = Vec::<u8>::new();
        encrypt_result.extend(&sm4.update(&MESSAGE_ALIGN));
        encrypt_result.extend(&sm4.r#final());

        assert_eq!(encrypt_result, [
            104, 30, 223, 52, 210, 6, 150, 94, 134, 179, 233, 79, 83, 110, 66, 70,
            140, 51, 142, 90, 39, 227, 73, 190, 174, 57, 33, 79, 237, 169, 112, 153,
        ]);

        let mut sm4 = SM4::new(KEY, Operation::Decrypt, Some(OperationMode::ECB), Some(PaddingMode::Mode2));
        let mut decrypt_result = Vec::<u8>::new();
        decrypt_result.extend(&sm4.update(&encrypt_result));
        decrypt_result.extend(&sm4.r#final());
        assert_eq!(decrypt_result, [
            0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
        ]);

        let mut sm4 = SM4::new(KEY, Operation::Encrypt, Some(OperationMode::ECB), Some(PaddingMode::Mode2));
        let mut encrypt_result = Vec::<u8>::new();
        encrypt_result.extend(&sm4.update(&MESSAGE_ALIGN));
        encrypt_result.extend(&sm4.update(&MESSAGE_UNALIGN));
        encrypt_result.extend(&sm4.r#final());

        assert_eq!(encrypt_result, [
            104, 30, 223, 52, 210, 6, 150, 94, 134, 179, 233, 79, 83, 110, 66, 70,
            213, 115, 115, 28, 246, 131, 231, 82, 134, 205, 123, 10, 160, 214, 47, 172,
        ]);

        let mut sm4 = SM4::new(KEY, Operation::Decrypt, Some(OperationMode::ECB), Some(PaddingMode::Mode2));
        let mut decrypt_result = Vec::<u8>::new();
        decrypt_result.extend(&sm4.update(&encrypt_result));
        decrypt_result.extend(&sm4.r#final());
        assert_eq!(decrypt_result, [
            0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
            0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32,
        ]);
    }

    #[test]
    fn sm4_ecb_padding_zero() {
        use crate::block_ciphers::{Operation, OperationMode, PaddingMode};
        use crate::block_ciphers::SM4;

        const KEY: [u8; 16] = [0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10];
        const MESSAGE_ALIGN: [u8; 16] = [0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10];
        const MESSAGE_UNALIGN: [u8; 15] = [0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32];

        let mut sm4 = SM4::new(KEY, Operation::Encrypt, Some(OperationMode::ECB), Some(PaddingMode::Mode3(Some(16))));
        let mut encrypt_result = Vec::<u8>::new();
        encrypt_result.extend(&sm4.update(&MESSAGE_ALIGN));
        encrypt_result.extend(&sm4.r#final());

        assert_eq!(encrypt_result, [
            241, 86, 129, 190, 244, 59, 116, 121, 124, 134, 38, 210, 89, 145, 43, 5,
            104, 30, 223, 52, 210, 6, 150, 94, 134, 179, 233, 79, 83, 110, 66, 70,
        ]);

        let mut sm4 = SM4::new(KEY, Operation::Decrypt, Some(OperationMode::ECB), Some(PaddingMode::Mode3(None)));
        let mut decrypt_result = Vec::<u8>::new();
        decrypt_result.extend(&sm4.update(&encrypt_result));
        decrypt_result.extend(&sm4.r#final());
        assert_eq!(decrypt_result, [
            0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
        ]);

        let mut sm4 = SM4::new(KEY, Operation::Encrypt, Some(OperationMode::ECB), Some(PaddingMode::Mode3(Some(31))));
        let mut encrypt_result = Vec::<u8>::new();
        encrypt_result.extend(&sm4.update(&MESSAGE_ALIGN));
        encrypt_result.extend(&sm4.update(&MESSAGE_UNALIGN));
        encrypt_result.extend(&sm4.r#final());

        assert_eq!(encrypt_result, [
            129, 54, 60, 179, 132, 116, 209, 232, 79, 173, 131, 22, 242, 230, 175, 244,
            104, 30, 223, 52, 210, 6, 150, 94, 134, 179, 233, 79, 83, 110, 66, 70,
            201, 182, 145, 178, 19, 105, 17, 254, 68, 57, 146, 28, 163, 250, 129, 95,
        ]);

        let mut sm4 = SM4::new(KEY, Operation::Decrypt, Some(OperationMode::ECB), Some(PaddingMode::Mode3(None)));
        let mut decrypt_result = Vec::<u8>::new();
        decrypt_result.extend(&sm4.update(&encrypt_result));
        decrypt_result.extend(&sm4.r#final());
        assert_eq!(decrypt_result, [
            0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
            0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32,
        ]);
    }

    #[test]
    fn sm4_cbc_padding_none() {
        use crate::block_ciphers::{Operation, OperationMode};
        use crate::block_ciphers::SM4;

        const KEY: [u8; 16] = [0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10];
        const IV: [u8; 16] = [0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10];
        const MESSAGE: [u8; 16] = [0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10];

        let mut sm4 = SM4::new(KEY, Operation::Encrypt, Some(OperationMode::CBC(IV.to_vec())), None);
        let mut encrypt_result = Vec::<u8>::new();
        encrypt_result.extend(&sm4.update(&MESSAGE));
        encrypt_result.extend(&sm4.update(&MESSAGE));
        encrypt_result.extend(&sm4.r#final());
        assert_eq!(encrypt_result, [
            0x26, 0x77, 0xF4, 0x6B, 0x09, 0xC1, 0x22, 0xCC, 0x97, 0x55, 0x33, 0x10, 0x5B, 0xD4, 0xA2, 0x2A,
            0xF6, 0x12, 0x5F, 0x72, 0x75, 0xCE, 0x55, 0x2C, 0x3A, 0x2B, 0xBC, 0xF5, 0x33, 0xDE, 0x8A, 0x3B,
        ]);

        let mut sm4 = SM4::new(KEY, Operation::Decrypt, Some(OperationMode::CBC(IV.to_vec())), None);
        let mut decrypt_result = Vec::<u8>::new();
        decrypt_result.extend(&sm4.update(&encrypt_result));
        decrypt_result.extend(&sm4.r#final());
        assert_eq!(decrypt_result, [
            0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
            0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
        ]);
    }

    #[test]
    fn sm4_cfb_padding_none() {
        use crate::block_ciphers::{Operation, OperationMode};
        use crate::block_ciphers::SM4;

        const KEY: [u8; 16] = [0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10];
        const IV: [u8; 16] = [0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10];
        const MESSAGE: [u8; 16] = [0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10];

        let mut sm4 = SM4::new(KEY, Operation::Encrypt, Some(OperationMode::CFB(IV.to_vec())), None);
        let mut encrypt_result = Vec::<u8>::new();
        encrypt_result.extend(&sm4.update(&MESSAGE));
        encrypt_result.extend(&sm4.update(&MESSAGE));
        encrypt_result.extend(&sm4.r#final());
        assert_eq!(encrypt_result, [
            0x69, 0x3D, 0x9A, 0x53, 0x5B, 0xAD, 0x5B, 0xB1, 0x78, 0x6F, 0x53, 0xD7, 0x25, 0x3A, 0x70, 0x56,
            0x9E, 0xD2, 0x58, 0xA8, 0x5A, 0x04, 0x67, 0xCC, 0x92, 0xAA, 0xB3, 0x93, 0xDD, 0x97, 0x89, 0x95,
        ]);

        let mut sm4 = SM4::new(KEY, Operation::Decrypt, Some(OperationMode::CFB(IV.to_vec())), None);
        let mut decrypt_result = Vec::<u8>::new();
        decrypt_result.extend(&sm4.update(&encrypt_result));
        decrypt_result.extend(&sm4.r#final());
        assert_eq!(decrypt_result, [
            0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
            0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
        ]);
    }

    #[test]
    fn sm4_ofb_padding_none() {
        use crate::block_ciphers::{Operation, OperationMode};
        use crate::block_ciphers::SM4;

        const KEY: [u8; 16] = [0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10];
        const IV: [u8; 16] = [0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10];
        const MESSAGE: [u8; 16] = [0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10];

        let mut sm4 = SM4::new(KEY, Operation::Encrypt, Some(OperationMode::OFB(IV.to_vec())), None);
        let mut encrypt_result = Vec::<u8>::new();
        encrypt_result.extend(&sm4.update(&MESSAGE));
        encrypt_result.extend(&sm4.update(&MESSAGE));
        encrypt_result.extend(&sm4.r#final());
        assert_eq!(encrypt_result, [
            0x69, 0x3D, 0x9A, 0x53, 0x5B, 0xAD, 0x5B, 0xB1, 0x78, 0x6F, 0x53, 0xD7, 0x25, 0x3A, 0x70, 0x56,
            0xF2, 0x07, 0x5D, 0x28, 0xB5, 0x23, 0x5F, 0x58, 0xD5, 0x00, 0x27, 0xE4, 0x17, 0x7D, 0x2B, 0xCE,
        ]);

        let mut sm4 = SM4::new(KEY, Operation::Decrypt, Some(OperationMode::OFB(IV.to_vec())), None);
        let mut decrypt_result = Vec::<u8>::new();
        decrypt_result.extend(&sm4.update(&encrypt_result));
        decrypt_result.extend(&sm4.r#final());
        assert_eq!(decrypt_result, [
            0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
            0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
        ]);
    }
}
