ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

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

2022-09-14 09:31:03  阅读:229  来源: 互联网

标签:OFB CBC ECB iterator SM4 len std vector out


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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有