对于GC项目中IDA实验的部分修正

针对Qian在GC项目中指出IDA实验中disperse步骤效率低下的问题,文章探讨了对IDA实现的修正需求。由于原始实现比对称加密更慢,作者计划改进以提高ida disperse的速度,使其与其他高效实现保持一致。同时,作者批评了CSDN博客编辑器的功能不足,导致编辑困难。
摘要由CSDN通过智能技术生成

1月22日,Qian提出了对于IDA实验中的时间结果不太好的问题,希望可以对IDA的实现进行改进。主要问题是IDA disperse部分速度似乎比较慢,要比一般的对称加密还要慢一些,而其他相关工作中IDA的效率似乎要高不少,所以有必要重新修正一下IDA部分的相关实现。

(我不得不再次表示CSDN博客编辑系统太垃圾了,连一些基本的撤销、redo等功能都不支持,导致在格式上编辑博文十分不方便!!!)

首先,需要回顾越三个月前的实验过程(这时,更加发现以后必须要在项目实现的过程中好好的做好记录,做好相关代码、文档的管理)。找到原来的相关代码:

timetest.cc:


//g++ -std=c++0x -c timetest.cc -o timetest.o -lcryptopp
//g++ -std=c++0x timetest.o ida_rel.o  -o crytimetest -lcryptopp
#include<sys/time.h>
#include<iostream>
#include  <unistd.h>
#include  <sys/types.h>       /* basic system data types */
//#include  <sys/socket.h>      /* basic socket definitions */
//#include  <netinet/in.h>      /* sockaddr_in{} and other Internet defns */
//#include  <arpa/inet.h>       /* inet(3) functions */
#include <netdb.h> /*gethostbyname function */
//#include <iostream>
#include <cstdlib>
//#include <errno.h>
#include <stdio.h>
//#include <cstring>
//#include <sstream>
#include <time.h>
//#include <vector>
//#include <pthread.h>
#include<fstream>
//#include "trans_rel.h"
#include "ida_rel.h"
using namespace CryptoPP;
using namespace std;

int main( )
{
    struct timeval tv1;
    struct timeval tv2;
	AutoSeededRandomPool prng;
	string IDAin;
    string IDAkey("key_en");
	byte key[AES::DEFAULT_KEYLENGTH];
	cout<<"AES key length:"<<AES::DEFAULT_KEYLENGTH<<endl;	
    prng.GenerateBlock(key, sizeof(key));
	string cipher, keyencoded, recovered;
	keyencoded.clear();
	StringSource(key, sizeof(key), true,
	    new HexEncoder(
			new StringSink(keyencoded)
		) // HexEncoder
	); // StringSource
	cout << "The initial genetate AES key(hex): " << keyencoded << endl;
	ofstream fkey(IDAkey.data());
   	fkey<< keyencoded;
   	fkey.close();
    ofstream timef("crytime",ofstream::app);
    try{// encrypt the file it will respond.
        gettimeofday(&tv1,NULL);
	    ECB_Mode< AES >::Encryption e;
        e.SetKey(key, sizeof(key));
        AESEncryptFile("Cfile","cipherM",e);
        gettimeofday(&tv2,NULL);
        IDAin = "cipherM";
        timef<<"AES Encryption "<<1000000*(tv2.tv_sec-tv1.tv_sec)+tv2.tv_usec-tv1.tv_usec<<endl;
		
        cout<<"k:"<<4<<"n:"<<6<<endl;
        InformationDisperseFile(4, 6, IDAin.data());
        gettimeofday(&tv1,NULL);
        timef<<"IDA disperse "<<1000000*(tv1.tv_sec-tv2.tv_sec)+tv1.tv_usec-tv2.tv_usec<<endl;
    }
    catch( const CryptoPP::Exception & e){
        cerr << e.what() << endl;
        exit(1);
    }
	
    vector< const char *> v_keys;
    v_keys.clear();
    v_keys.push_back("cipherM.000");
    v_keys.push_back("cipherM.001");
    v_keys.push_back("cipherM.002");
    v_keys.push_back("cipherM.003");
    gettimeofday(&tv1,NULL);
    InformationRecoverFile(4, "cipherM_idarecv",v_keys);
    gettimeofday(&tv2,NULL);
    timef<<"IDA recovery "<<1000000*(tv2.tv_sec-tv1.tv_sec)+tv2.tv_usec-tv1.tv_usec<<endl;
    ECB_Mode< AES >::Decryption d;
    d.SetKey(key,sizeof(key));
				// The StreamTransformationFilter removes
                // //  padding as required.
	AESDecryptFile("cipherM_idarecv","file_aesde",d);
    gettimeofday(&tv1,NULL);
    timef<<"AES decryption "<<1000000*(tv1.tv_sec-tv2.tv_sec)+tv1.tv_usec-tv2.tv_usec<<endl;
    
    getchar();
    return 0;
}
其中 cyrpto_rel.cpp为
#include"crypto_rel.h"
using namespace std;
using namespace CryptoPP;
void HexEncode(const char *in, const char *out)//Hex编码
{
	FileSource(in, true, new HexEncoder(new FileSink(out)));
}

void HexDecode(const char *in, const char *out)//HEX解码
{
	FileSource(in, true, new HexDecoder(new FileSink(out)));
}
//****************************************
void AESEncryptFile(const char *in, const char *out, CryptoPP::ECB_Mode< AES >::Encryption ee)//加密文件

{
	
       FileSource  f(in, true, new StreamTransformationFilter(ee, new FileSink(out)));

}

void AESDecryptFile(const char *in, const char *out, CryptoPP::ECB_Mode< AES >::Decryption dd)//解密文件

{

       FileSource 

  f(in, true, new StreamTransformationFilter(dd, new FileSink(out)));      

}
//*****************************************
void InformationDisperseFile(int threshold, int nShares, const char *filename)// IDA算法加密分配文件
{
	assert(nShares<=1000);

	ChannelSwitch *channelSwitch;
	FileSource source(filename, false, new InformationDispersal(threshold, nShares, channelSwitch = new ChannelSwitch));

	vector_member_ptrs<FileSink> fileSinks(nShares);
	string channel;
	for (int i=0; i<nShares; i++)
	{
		char extension[5] = ".000";
		extension[1]='0'+byte(i/100);
		extension[2]='0'+byte((i/10)%10);
		extension[3]='0'+byte(i%10);
		fileSinks[i].reset(new FileSink((string(filename)+extension).c_str()));

		channel = WordToString<word32>(i);
		fileSinks[i]->Put((byte *)channel.data(), 4);
		channelSwitch->AddRoute(channel, *fileSinks[i], DEFAULT_CHANNEL);
	}

	source.PumpAll();
}

void InformationRecoverFile(int threshold, const char *outFilename, char *const *inFilenames)//IDA算法解密恢复文件(使用文件名)
{
	assert(threshold<=1000);

	InformationRecovery recovery(threshold, new FileSink(outFilename));

	vector_member_ptrs<FileSource> fileSources(threshold);
	SecByteBlock channel(4);
	int i;
	for (i=0; i<threshold; i++)
	{
		fileSources[i].reset(new FileSource(inFilenames[i], false));
		fileSources[i]->Pump(4);
		fileSources[i]->Get(channel, 4);
		fileSources[i]->Attach(new ChannelSwitch(recovery, string((char *)channel.begin(), 4)));
	}

	while (fileSources[0]->Pump(256))
		for (i=1; i<threshold; i++)
			fileSources[i]->Pump(256);

	for (i=0; i<threshold; i++)
		fileSources[i]->PumpAll();
}

void InformationRecoverFile(int threshold, const char *outFilename, const std::vector<const char * > &vectorinfile)//IDA算法解密恢复文件(使用存储文件名的vector)
{
	assert(threshold<=1000);

	InformationRecovery recovery(threshold, new FileSink(outFilename));

	vector_member_ptrs<FileSource> fileSources(threshold);
	SecByteBlock channel(4);
	int i;
	for (i=0; i<threshold; i++)
	{
		fileSources[i].reset(new FileSource(vectorinfile[i], false));
		fileSources[i]->Pump(4);
		fileSources[i]->Get(channel, 4);
		fileSources[i]->Attach(new ChannelSwitch(recovery, string((char *)channel.begin(), 4)));
	}

	while (fileSources[0]->Pump(256))
		for (i=1; i<threshold; i++)
			fileSources[i]->Pump(256);

	for (i=0; i<threshold; i++)
		fileSources[i]->PumpAll();
}

void GenerateRSAKey(unsigned int keyLength, const char *privFilename, const char *pubFilename, const char *seed)
{
	RandomPool randPool;
	randPool.IncorporateEntropy((byte *)seed, strlen(seed));

	RSAES_OAEP_SHA_Decryptor priv(randPool, keyLength);
	HexEncoder privFile(new FileSink(privFilename));
	priv.DEREncode(privFile);
	privFile.MessageEnd();

	RSAES_OAEP_SHA_Encryptor pub(priv);
	HexEncoder pubFile(new FileSink(pubFilename));
	pub.DEREncode(pubFile);
	pubFile.MessageEnd();
}

string RSAEncryptString(const char *pubFilename, const char *seed, const char *message)
{
	FileSource pubFile(pubFilename, true, new HexDecoder);
	RSAES_OAEP_SHA_Encryptor pub(pubFile);

	RandomPool randPool;
	randPool.IncorporateEntropy((byte *)seed, strlen(seed));

	string result;
	StringSource(message, true, new PK_EncryptorFilter(randPool, pub, new HexEncoder(new StringSink(result))));
	return result;
}

string RSADecryptString(const char *privFilename, const char *ciphertext)
{
	FileSource privFile(privFilename, true, new HexDecoder);
	RSAES_OAEP_SHA_Decryptor priv(privFile);

	string result;
	StringSource(ciphertext, true, new HexDecoder(new PK_DecryptorFilter(GlobalRNG(), priv, new StringSink(result))));
	return result;
}


仔细看了一下原先实现IDA的相关代码和crypto++库中相关的源代码(如http://www.cryptopp.com/docs/ref/ida_8cpp_source.html)后,发现这一问题可能与我们之前对算法的实现以及测量方法有关。

在我们之前的代码中,对于IDA、RSA、AES这些算法的函数实现都是以文件为输入输出的。如对于IDA coding,我们实现的函数中输入为一个文件,输出为n个编码后文件(我们的实验中常用参数n=6,k=4时)。采用这样的实现主要是因为crypto++对此有很好的函数API,实现起来比较容易。而且其他部分的代码以文件为接口时可以较好的模块化,方便对于实验中各种大小文件数据的内部存储。

这可能就是导致了“看起来” IDA没有symmetric encryption效率高的原因。因为,运行中发现IDA splitting(coding)过程本身的computation overheads并不高,但随之需要将大的运算结果保存到六个文件中,这个I/O overheads是相对很高的,所以显得整体效率不好。
例如某一次运行相关代码片段得到各部分时间overheads数据为(针对100k大小的原始文件):
AES Encryption函数 : 542 um
IDA coding本身:39 um
IDA 函数(输入输出皆为文件形式): 19177 um
IDA recovery函数:  6464 um
AES decryption函数: 321 um
可见,IDA coding本身的overheads并不算高。
这一可能性在您给我的第一篇论文中也有一定的支持:“It is worth noting that the computational overheads of reasure codes is neglible compared to the overheads of reading, writing or sending data.” (第二页最后一段)。
不过感觉这样修改后还是不对,因为



如果我们看一下crypto++中关于Source的说明,当为false时,只相当于把各个过滤器像水管一样拼接起来了,还没有真正的水(数据)流到里面去,只有到最后pumpAll()时,才真正拧开水龙头,放入数据!随意按上述代码中的方式加以测量还是不对的。。。。




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值