编程语言
首页 > 编程语言> > 实现SM4-ECB、CBC、CFB、OFB算法(大数据版)

实现SM4-ECB、CBC、CFB、OFB算法(大数据版)

作者:互联网

base_sm4类参考:

实现SM4算法(16字节版)

sm4.h

#pragma once
#include <algorithm>
#include <iostream>
#include "D:\C++\实现SM4算法(16字节版)\base_sm4.h"

constexpr bool SM4_ENCRYPT = 1;             //进行加密运算
constexpr bool SM4_DECRYPT = 0;             //进行解密运算
constexpr unsigned SM4_BLOCK_SIZE = 16;     //每个分组的大小为16字节,32位

class sm4 :
    public base_sm4
{
public:
    /*
    ECB模式的SM4算法
    ECB模式是最早采用的简单模式,它将加密的数据分成若干组,每组的大小跟加密密钥长度相同,然后每组都用相同的密钥进行加密。相同的明文会产生相同的密文。
    每个分组的运算(加密或解密)都是独立的,每个分组加密只需要密钥和明文分组即可,每个分组解密也只需要密钥和密文分组即可。

    in:明文或者密文
    out:存储明文或者密文,要求out有足够的空间,且长度不低于in的长度
    lenght:in的长度
    key:16字节长度的秘钥
    type:指定为加密或者解密
    */
    void sm4Ecb(std::vector<unsigned char>& in, std::vector<unsigned char>& out, const size_t lenght, std::vector<unsigned char>& key, const bool type);
    /*
    CBC模式的SM4算法
    初始向量(或称初向量)是一个固定长度的比特串。一般使用时会要求它是随机数或伪随机数。使用随机数产生的初始向量,使得同一个密钥加密的结果每次都不同,这样攻击者难以对同一把密钥的密文进行破解。
    加密时,第一个明文块和初始向量进行异或后,再用key进行加密,以后每个明文块与前一个分组结果(密文)块进行异或后,再用key进行加密。
    解密时,第一个密文块先用key解密,得到的中间结果再与初始向量进行异或后得到第一个明文分组(第一个分组的最终明文结果),后面每个密文块也是先用key解密,得到的中间结果再与前一个密文分组(注意是解密之前的密文分组)进行异或后得到本次明文分组。
    in:明文或者密文
    out:存储明文或者密文,要求out有足够的空间,且长度不低于in的长度
    lenght:in的长度
    key:16字节长度的秘钥
    ivec:初始向量,16字节
    type:指定为加密或者解密
    */
    void sm4Cbc(std::vector<unsigned char>& in, std::vector<unsigned char>& out, const size_t lenght, std::vector<unsigned char>& key, std::vector<unsigned char>&ivec, const bool type);
    /*
    CFB模式的SM4算法
    也需要初始向量。
    加密第一个分组时,先对初始向量进行加密,得到的中间结果再与第一个明文分组进行异或得到第一个密文分组;加密后面的分组时,把前一个密文分组作为向量先加密,得到的中间结果再与当前明文分组进行异或得到密文分组。
    解密第一个分组时,先对初始向量进行加密运算(注意,用的是加密算法),得到的中间结果再与第一个密文分组进行异或得到明文分组;解密后面的分组时,把上一个密文分组当作向量进行加密运算(注意,用的还是加密算法),得到的中间结果再与本次的密文分组进行异或得到本次的明文分组。
    in:明文或者密文
    out:存储明文或者密文,要求out有足够的空间,且长度不低于in的长度
    lenght:in的长度
    key:16字节长度的秘钥
    ivec:初始向量,16字节
    type:指定为加密或者解密
    */
    void sm4Cfb(std::vector<unsigned char>& in, std::vector<unsigned char>& out, const size_t lenght, std::vector<unsigned char>& key, std::vector<unsigned char>& ivec, const bool type);
    /*
    OFB模式的SM4算法
    也需要初始向量。
    加密第一个分组时,先对初始向量进行加密,得到的中间结果再与第一个明文分组进行异或得到第一个密文分组;加密后面的分组时,把前一个中间结果(前一个分组的向量的密文)作为向量先加密,得到的中间结果再与当前明文分组进行异或得到密文分组。
    解密第一个分组时,先对初始向量进行加密运算(注意用的是加密算法),得到的中间结果再与第一个密文分组进行异或得到明文分组;解密后面的分组时,把上一个中间结果(前一个分组的向量的密文,因为用的依然是加密算法)当作向量进行加密运算(注意用的是加密算法),得到的中间结果再与本次的密文分组进行异或得到本次的明文分组。
    in:明文或者密文
    out:存储明文或者密文,要求out有足够的空间,且长度不低于in的长度
    lenght:in的长度
    key:16字节长度的秘钥
    ivec:初始向量,16字节
    */
    void sm4Ofb(std::vector<unsigned char>& in, std::vector<unsigned char>& out, const size_t lenght, std::vector<unsigned char>& key, std::vector<unsigned char>& ivec);

    //ecb加解密检查
    int sm4ecbcheck();
    //cbc加解密检查
    int sm4cbccheck();
    //cfb加解密检查
    int sm4cfbcheck();
    //ofb加解密检查
    int sm4ofbcheck();
};
View Code

sm4.cpp

#include "sm4.h"
void sm4::sm4Ecb(std::vector<unsigned char> &in, std::vector<unsigned char> &out, const size_t lenght, std::vector<unsigned char> &key, const bool type){
    size_t len = lenght;
    //判断参数是否为空,以及判断长度是否为16的倍数
    if (in.size() == 0 || out.size() == 0 || key.size() == 0 || lenght % SM4_BLOCK_SIZE != 0) {
        return;
    }
    std::vector<unsigned char>::iterator in_iterator = in.begin();
    std::vector<unsigned char>::iterator out_iterator = out.begin();
    while (len >= SM4_BLOCK_SIZE) {
        //SM4加解密的分组大小为128Bit,故对消息进行加解密时,若消息长度过长,则需要进行循环分组加解密。
        if (type== SM4_ENCRYPT) {
            //加密
            this->SM4_Encrypt(key.begin(), in_iterator, out_iterator);
        }
        else {
            this->SM4_Decrypt(key.begin(), in_iterator, out_iterator);
        }
        len -= SM4_BLOCK_SIZE;                //没处理完一个分组,长度就要减去16
        in_iterator += SM4_BLOCK_SIZE;        //原文数据迭代器偏移16字节,即16个char,指向新的未处理的数据
        out_iterator += SM4_BLOCK_SIZE;        //结果迭代器也要偏移16字节,即16个char,指向新的未占用的空间
    }
}
void sm4::sm4Cbc(std::vector<unsigned char>& in, std::vector<unsigned char>& out, const size_t lenght, std::vector<unsigned char>& key, std::vector<unsigned char>& ivec, const bool type) {
    /*
    * 这个算法支持in和out指向同一个缓冲区(称为原地加解密),根据CBC模式的原理,加密时不必区分in和out是否相同,而解密时需要区分。
    */
    size_t len = lenght;
    std::vector<unsigned char> temp(SM4_BLOCK_SIZE, 0);
    std::vector<unsigned char>::iterator iv_iterator = ivec.begin();
    std::vector<unsigned char> iv_temp(SM4_BLOCK_SIZE, 0);
    //判断参数是否为空,以及判断长度是否为16的倍数
    if (in.size() == 0 || out.size() == 0 || key.size() == 0 || ivec.size() == 0 || lenght % SM4_BLOCK_SIZE != 0) {
        return;
    }
    if (type == SM4_ENCRYPT) {
        //加密
        std::vector<unsigned char>::iterator in_iterator = in.begin();
        std::vector<unsigned char>::iterator out_iterator = out.begin();
        while (len >= SM4_BLOCK_SIZE) {
            /*
            * 加密时,第一个明文块和初始向量iv进行异或后,再用key进行加密;
            * 以后每个明文块与前一个分组结果(密文)块进行异或后,再用key进行加密
            * 前一个分组结果(密文)块当做本次iv
            */
            for (int i{}; i < SM4_BLOCK_SIZE; ++i) {
                out_iterator[i] = in_iterator[i] ^ iv_iterator[i];
            }
            //用key进行加密
            this->SM4_Encrypt(key.begin(), out_iterator, out_iterator);
            iv_iterator = out_iterator;            //保存当前结果,以便下一次循环中和明文进行异或运算
            len -= SM4_BLOCK_SIZE;                //减去已完成的字节数
            in_iterator += SM4_BLOCK_SIZE;        //偏移明文数据的迭代器,指向未加密的数据开头
            out_iterator += SM4_BLOCK_SIZE;        //偏移密文数据的迭代器,指向未放置数据的内存
        }
    }
    else {
        //解密
        std::vector<unsigned char>::iterator in_iterator = in.begin();
        std::vector<unsigned char>::iterator out_iterator = out.begin();
        //不同的vector的迭代器不能相互比较,哪怕vector的类型、大小等一样,只要迭代器的来源不属于同一个vector,那么就不能比较。
        //if (in_iterator != out_iterator) {
        if (in.data() != out.data()) {
            //in和out属于不同的缓冲区
            while (len >= SM4_BLOCK_SIZE) {
                //循环分组处理
                this->SM4_Decrypt(key.begin(), in_iterator, out_iterator);
                for (int i{}; i < SM4_BLOCK_SIZE; ++i) {
                    out_iterator[i] = out_iterator[i] ^ iv_iterator[i];
                }
                iv_iterator = in_iterator;
                len -= SM4_BLOCK_SIZE;                //减去已完成的字节数
                in_iterator+= SM4_BLOCK_SIZE;        //偏移密文数据迭代器,指向还没解密的数据开头
                out_iterator += SM4_BLOCK_SIZE;;    //偏移结果数据指针,指向未放置数据的内存
            }
        }
        else {
            //in和out属于相同的缓冲区
            iv_temp.insert(iv_temp.end(), ivec.begin(), ivec.begin() + SM4_BLOCK_SIZE);
            while (len >= SM4_BLOCK_SIZE) {
                //暂存本次分组密文,因为in要存放结果明文
                temp.insert(temp.end(), in.begin(), in.begin() + SM4_BLOCK_SIZE);
                this->SM4_Encrypt(key.begin(), in_iterator, out_iterator);
                for (int i{}; i < SM4_BLOCK_SIZE; ++i) {
                    out_iterator[i] = out_iterator[i] ^ iv_temp[i];
                }
                iv_temp.clear();
                iv_temp.insert(iv_temp.end(), temp.begin(), temp.begin() + SM4_BLOCK_SIZE);
                len -= SM4_BLOCK_SIZE;                //减去已完成的字节数
                in_iterator += SM4_BLOCK_SIZE;        //偏移密文数据迭代器,指向还没解密的数据开头
                out_iterator += SM4_BLOCK_SIZE;;    //偏移结果数据指针,指向未放置数据的内存
            }
        }
    }
}
void sm4::sm4Cfb(std::vector<unsigned char>& in, std::vector<unsigned char>& out, const size_t lenght, std::vector<unsigned char>& key, std::vector<unsigned char>& ivec, const bool type) {
    //CFB模式和CBC类似,也需要IV

    rsize_t len = lenght;
    unsigned char ch{};
    std::vector<unsigned char> iv;
    //判断参数是否为空,以及判断长度是否为16的倍数
    if (in.size() == 0 || out.size() == 0 || key.size() == 0 || ivec.size() == 0 || lenght % SM4_BLOCK_SIZE != 0) {
        return;
    }
    iv.insert(iv.begin(), ivec.begin(), ivec.begin() + SM4_BLOCK_SIZE);
    std::vector<unsigned char>::iterator in_iterator = in.begin();
    std::vector<unsigned char>::iterator out_iterator = out.begin();
    if (type == SM4_ENCRYPT) {
        //加密
        std::vector<unsigned char>::iterator iv_iterator = iv.begin();
        int i{};
        while (len--)
        {
            if (!i) {
                //第一次循环才进入这里
                this->SM4_Encrypt(key.begin(), iv_iterator, iv_iterator);
            }
            iv[i] = *(out_iterator++) = *(in_iterator++) ^ iv[i];
            i = (i + 1) % SM4_BLOCK_SIZE;
            //上面两行代码就很精妙,实现了iv始终在0~SM4_BLOCK_SIZE之间
        }
    }
    else {
        //解密
        //解密也是使用的SM4_Encrypt
        std::vector<unsigned char>::iterator iv_iterator = iv.begin();
        int i{};
        while (len--)
        {
            if (!i) {
                this->SM4_Encrypt(key.begin(), iv_iterator, iv_iterator);
            }
            ch = *in_iterator;
            *(out_iterator++) = *(in_iterator++) ^ iv[i];
            //上面这句代码应该可以换成*(++out_iterator) = *(++in_iterator) ^ iv[i];
            iv[i]=ch;
            i = (i + 1) % SM4_BLOCK_SIZE;
            //上面两行代码就很精妙,实现了iv始终在0~SM4_BLOCK_SIZE之间
        }
    }
}
void sm4::sm4Ofb(std::vector<unsigned char>& in, std::vector<unsigned char>& out, const size_t lenght, std::vector<unsigned char>& key, std::vector<unsigned char>& ivec) {
    size_t len = lenght;
    std::vector<unsigned char> iv;
    //判断参数是否为空,以及判断长度是否为16的倍数
    if (in.size() == 0 || out.size() == 0 || key.size() == 0 || ivec.size() == 0 || lenght % SM4_BLOCK_SIZE != 0) {
        return;
    }
    iv.insert(iv.begin(), ivec.begin(), ivec.begin() + SM4_BLOCK_SIZE);
    std::vector<unsigned char>::iterator in_iterator = in.begin();
    std::vector<unsigned char>::iterator out_iterator = out.begin();
    std::vector<unsigned char>::iterator iv_iterator = iv.begin();

    //OFB模式的加密和解密是一致的
    int i{};
    while (--len)
    {
        if (!i) {
            this->SM4_Encrypt(key.begin(), iv_iterator, iv_iterator);
        }
        *(++out_iterator) = *(++in_iterator) ^ iv[i];
        i = (i + 1) % SM4_BLOCK_SIZE;
    }

}
int sm4::sm4ecbcheck(){
    int i, len, ret = 0;
    std::vector<unsigned char> key{ 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10 };
    std::vector<unsigned char> plain{ 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10 };
    std::vector<unsigned char> cipher{ 0x68,0x1e,0xdf,0x34,0xd2,0x06,0x96,0x5e,0x86,0xb3,0xe9,0x4f,0x53,0x6e,0x42,0x46 };
    std::vector<unsigned char> En_output;
    std::vector<unsigned char> De_output;
    std::vector<unsigned char> in;
    std::vector<unsigned char> out;
    std::vector<unsigned char> chk;

    En_output.resize(16);    //需要提前准备好充足的空间
    this->sm4Ecb(plain, En_output, 16, key, SM4_ENCRYPT);

    //比较两个缓冲区的值是否一致
    if (std::equal(cipher.begin(), cipher.end(), En_output.begin())) {
        std::cout << "ecb enc(len=16) memcmp ok\n";
    }
    else {
        std::cout << "ecb enc(len=16) memcmp failed\n";
        std::cout << "En_output:\n";
        std::copy(En_output.begin(), En_output.end(), std::ostream_iterator<unsigned>(std::cout, ","));
        std::cout << "cipher:\n";
        std::copy(cipher.begin(), cipher.end(), std::ostream_iterator<unsigned>(std::cout, ","));
        std::cout << "\n";
    }
    ////比较两个缓冲区的值是否一致
    //if (memcmp(En_output.data(), cipher.data(), cipher.size())) {
    //    puts("ecb enc(len=16) memcmp failed");
    //}
    //else puts("ecb enc(len=16) memcmp ok");

    De_output.resize(SM4_BLOCK_SIZE);    ////需要提前准备好充足的空间
    this->sm4Ecb(cipher, De_output, SM4_BLOCK_SIZE, key, SM4_DECRYPT);
    //比较两个缓冲区的值是否一致
    if (std::equal(plain.begin(), plain.end(), De_output.begin())) {
        std::cout << "ecb dec(len=16) memcmp ok\n";
    }
    else {
        std::cout << "ecb dec(len=16) memcmp failed\n";
        std::cout << "En_output:\n";
        std::copy(De_output.begin(), De_output.end(), std::ostream_iterator<unsigned>(std::cout, ","));
        std::cout << "cipher:\n";
        std::copy(cipher.begin(), cipher.end(), std::ostream_iterator<unsigned>(std::cout, ","));
        std::cout << "\n";
    }

    //if (memcmp(De_output.data(), plain.data(), SM4_BLOCK_SIZE)) puts("ecb dec(len=16) memcmp failed");
    //else puts("ecb dec(len=16) memcmp ok");

    len = 32;
    for (i = 0; i < 8; i++)
    {
        //memset(in, i, len);
        in.insert(in.end(), len, i);
        out.resize(in.size());    //这里是默认了为16的倍数
        this->sm4Ecb(in, out, len, key, SM4_ENCRYPT);    //加密
        chk.resize(in.size());    //这里是默认了为16的倍数
        this->sm4Ecb(out, chk, len, key, SM4_DECRYPT);    //解密
        
        if (std::equal(in.begin(), in.end(), chk.begin())) {
            std::cout << "ecb enc(len=" << len << ") memcmp ok\n";
        }
        else {
            std::cout << "ecb enc(len=" << len << ") memcmp failed\n";
        }
        //if (memcmp(in.data(), chk.data(), len))  printf("ecb enc/dec(len=%d) memcmp failed\n", len);
        //else printf("ecb enc/dec(len=%d) memcmp ok\n", len);
        len = 2 * len;
        in.clear();
    }
    return 0;
}


int sm4::sm4cbccheck()
{
    int i, len, ret = 0;
    std::vector<unsigned char> key { 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10 };//密钥
    std::vector<unsigned char> iv { 0xeb,0xee,0xc5,0x68,0x58,0xe6,0x04,0xd8,0x32,0x7b,0x9b,0x3c,0x10,0xc9,0x0c,0xa7 }; //初始化向量
    std::vector<unsigned char> plain { 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10,0x29,0xbe,0xe1,0xd6,0x52,0x49,0xf1,0xe9,0xb3,0xdb,0x87,0x3e,0x24,0x0d,0x06,0x47 }; //明文
    std::vector<unsigned char> cipher { 0x3f,0x1e,0x73,0xc3,0xdf,0xd5,0xa1,0x32,0x88,0x2f,0xe6,0x9d,0x99,0x6c,0xde,0x93,0x54,0x99,0x09,0x5d,0xde,0x68,0x99,0x5b,0x4d,0x70,0xf2,0x30,0x9f,0x2e,0xf1,0xb7 }; //密文
    std::vector<unsigned char> En_output;
    std::vector<unsigned char> De_output;
    std::vector<unsigned char> in;
    std::vector<unsigned char> out;
    std::vector<unsigned char> chk;

    En_output.resize(plain.size());
    //sizeof是输出的字节数,对于这里其实就是长度
    this->sm4Cbc(plain, En_output, plain.size(), key, iv, SM4_ENCRYPT);    //加密
    //比较是否相等
    if (std::equal(cipher.begin(), cipher.end(), En_output.begin())) {
        std::cout << "cbc enc(len=16) memcmp ok\n";
    }
    else {
        std::cout << "cbc enc(len=16) memcmp failed\n";
        std::cout << "En_output:\n";
        std::copy(En_output.begin(), En_output.end(), std::ostream_iterator<unsigned>(std::cout, ","));
        std::cout << "cipher:\n";
        std::copy(cipher.begin(), cipher.end(), std::ostream_iterator<unsigned>(std::cout, ","));
        std::cout << "\n";
    }
    //if (memcmp(En_output, cipher, 16)) puts("cbc enc(len=32) memcmp failed");
    //else puts("cbc enc(len=32) memcmp ok");
    De_output.resize(cipher.size());
    this->sm4Cbc(cipher, De_output, cipher.size(), key, iv, SM4_DECRYPT);
    //比较是否相等
    if (std::equal(plain.begin(), plain.end(), De_output.begin())) {
        std::cout << "cbc dec(len=16) memcmp ok\n";
    }
    else {
        std::cout << "cbc dec(len=16) memcmp failed\n";
        std::cout << "En_output:\n";
        std::copy(De_output.begin(), De_output.end(), std::ostream_iterator<unsigned>(std::cout, ","));
        std::cout << "cipher:\n";
        std::copy(plain.begin(), plain.end(), std::ostream_iterator<unsigned>(std::cout, ","));
        std::cout << "\n";
    }

    /*if (memcmp(De_output, plain, SM4_BLOCK_SIZE)) puts("cbc dec(len=32) memcmp failed");
    else puts("cbc dec(len=32) memcmp ok");*/


    len = 32;
    for (i = 0; i < 8; i++)
    {
        //memset(in, i, len);
        in.resize(len, i);
        out.resize(len);
        this->sm4Cbc(in, out, len, key, iv, SM4_ENCRYPT);
        chk.resize(len);
        this->sm4Cbc(out, chk, len, key, iv, SM4_DECRYPT);
        //比较是否相等
        if (std::equal(in.begin(), in.end(), chk.begin())) {
            std::cout << "cbc enc/dec(len=" << len << ") memcmp ok\n";
        }
        else {
            std::cout << "cbc enc/dec(len=" << len << ") memcmp failed\n";
            std::cout << "En_output:\n";
            std::copy(in.begin(), in.end(), std::ostream_iterator<unsigned>(std::cout, ","));
            std::cout << "cipher:\n";
            std::copy(chk.begin(), chk.end(), std::ostream_iterator<unsigned>(std::cout, ","));
        }
        //if (memcmp(in, chk, len))  printf("cbc enc/dec(len=%d) memcmp failed\n", len);
        //else printf("cbc enc/dec(len=%d) memcmp ok\n", len);
        len = 2 * len;
    }
    return 0;
}

int sm4::sm4cfbcheck()
{
    int i, len, ret = 0;
    std::vector<unsigned char> key{ 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10 };//密钥
    std::vector<unsigned char> iv{ 0xeb,0xee,0xc5,0x68,0x58,0xe6,0x04,0xd8,0x32,0x7b,0x9b,0x3c,0x10,0xc9,0x0c,0xa7 }; //初始化向量
    std::vector<unsigned char> in;
    std::vector<unsigned char> out;
    std::vector<unsigned char> chk;
    len = 16;
    for (i = 0; i < 9; i++)
    {
        in.resize(len, i);
        out.resize(len);
        chk.resize(len);
        this->sm4Cfb(in, out, len, key, iv, SM4_ENCRYPT);
        this->sm4Cfb(out, chk, len, key, iv, SM4_DECRYPT);
        //比较是否相等
        if (std::equal(in.begin(), in.end(), chk.begin())) {
            std::cout << "cfb enc/dec(len=" << len << ") memcmp ok\n";
        }
        else {
            std::cout << "\ncfb enc/dec(len=" << len << ") memcmp failed";
            std::cout << "\nin:";
            std::copy(in.begin(), in.end(), std::ostream_iterator<unsigned>(std::cout, ","));
            std::cout << "\nout:";
            std::copy(out.begin(), out.end(), std::ostream_iterator<unsigned>(std::cout, ","));
            std::cout << "\nchk:";
            std::copy(chk.begin(), chk.end(), std::ostream_iterator<unsigned>(std::cout, ","));
            break;
        }
        /*if (memcmp(in, chk, len))  printf("cfb enc/dec(len=%d) memcmp failed\n", len);
        else printf("cfb enc/dec(len=%d) memcmp ok\n", len);*/
        len = 2 * len;
    }
    return 0;
}

int sm4::sm4ofbcheck()
{
    int i, len, ret = 0;
    std::vector<unsigned char> key{ 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10 };//密钥
    std::vector<unsigned char> iv{ 0xeb,0xee,0xc5,0x68,0x58,0xe6,0x04,0xd8,0x32,0x7b,0x9b,0x3c,0x10,0xc9,0x0c,0xa7 }; //初始化向量
    std::vector<unsigned char> in;
    std::vector<unsigned char> out;
    std::vector<unsigned char> chk;
    len = 16;
    for (i = 0; i < 9; i++)
    {
        out.resize(len);
        chk.resize(len);
        in.resize(len, i);
        this->sm4Ofb(in, out, len, key, iv);
        this->sm4Ofb(out, chk, len, key, iv);
        //比较是否相等
        if (std::equal(in.begin(), in.end(), chk.begin())) {
            std::cout << "ofb enc/dec(len=" << len << ") memcmp ok\n";
        }
        else {
            std::cout << "\nofb enc/dec(len=" << len << ") memcmp failed";
            std::cout << "\nin:";
            std::copy(in.begin(), in.end(), std::ostream_iterator<unsigned>(std::cout, ","));
            std::cout << "\nout:";
            std::copy(out.begin(), out.end(), std::ostream_iterator<unsigned>(std::cout, ","));
            std::cout << "\nchk:";
            std::copy(chk.begin(), chk.end(), std::ostream_iterator<unsigned>(std::cout, ","));
            break;
        }
        /*if (memcmp(in, chk, len))  printf("ofb enc/dec(len=%d) memcmp failed\n", len);
        else printf("ofb enc/dec(len=%d) memcmp ok\n", len);*/
        len = 2 * len;
    }
    return 0;
}
View Code

实现SM4-ECB、CBC、CFB、OFB算法(大数据版).cpp

// 实现SM4-ECB、CBC、CFB、OFB算法(大数据版).cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include "sm4.h"

int main()
{
    sm4 s;
    s.sm4ofbcheck();
}

// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单

// 入门使用技巧: 
//   1. 使用解决方案资源管理器窗口添加/管理文件
//   2. 使用团队资源管理器窗口连接到源代码管理
//   3. 使用输出窗口查看生成输出和其他消息
//   4. 使用错误列表窗口查看错误
//   5. 转到“项目”>“添加新项”以创建新的代码文件,或转到“项目”>“添加现有项”以将现有代码文件添加到项目
//   6. 将来,若要再次打开此项目,请转到“文件”>“打开”>“项目”并选择 .sln 文件
View Code

 

标签:OFB,CBC,ECB,iterator,SM4,len,std,vector,out
来源: https://www.cnblogs.com/love-DanDan/p/16691875.html