using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Windows.Forms;namespace ElGamalProgram
{
class ElGamal
{
private const int MAXINT64LEN = sizeof(Int64);//用来作为读取的单位长度
private const string tempPrePadding = "_elgpad";//用来生成paded文件的文件名
private const string tempPreTransforming = "_elgtrans";//用来生成transformed文件的文件名
private const int BITSLEN = 60;//密钥的长度
private RandomPrimeGenerator r = new RandomPrimeGenerator();//用来生成随机数,及进行其他运算 private Int64 p; //大素数
private Int64 a; //生成元
private Int64 sk; //私钥
private Int64 pk; //公钥 public ElGamal(Int64 p, Int64 sk)
{
this.p = p;
this.sk = sk;
} public void init4Encode(Int64 a)
{
this.a = a;
this.pk = r.modPower(a, sk, p);
} //将输入的文件进行变换之后,再加密,输出到输出文件中
public void Encode(string inputFile, string outputFile)
{
string path = Path.GetDirectoryName(inputFile);
string name = Path.GetFileName(inputFile);
string transformedFile = path + "\\"+tempPreTransforming + name;
prepare4Encoding(inputFile, transformedFile, p);
ElGamalEncode(transformedFile, outputFile);
File.Delete(transformedFile);
}
//将输入的文件进行变换之后,再解密,输出到输出文件中
public void Decode(string inputFile, string outputFile)
{
string path = Path.GetDirectoryName(inputFile);
string name = Path.GetFileName(inputFile);
string decodedFile = path +"\\"+ tempPrePadding+name;
ElGamalDecode(inputFile, decodedFile);
postDecoding(decodedFile, outputFile, p);
File.Delete(decodedFile);
}
//对于已经经过变换之后的文件,直接进行加密
private void ElGamalEncode(string inputFile, string outputFile)
{
FileStream finput = openFile(inputFile);
if (finput == null)
return;
FileStream foutput = createFile(outputFile);
if (foutput == null)
return;
Int64 m;
while ((m = inputInt64(finput)) != -1)
{
Int64 k = r.nextInt64(0, p - 1);
Int64 y1 = r.modPower(a, k, p);
byte[] temp = BitConverter.GetBytes(y1);
foutput.Write(temp, 0, MAXINT64LEN);
Int64 pk1 = r.modPower(pk, k, p);
Int64 y2 = r.multiplyMod(m, pk1, p);
foutput.Write(BitConverter.GetBytes(y2), 0, MAXINT64LEN);
}
finput.Close();
foutput.Close();
}
//将变换之后的文件进行直接解密
private void ElGamalDecode(string inputFile, string outputFile)
{
FileStream finput = openFile(inputFile);
if (finput == null)
return;
FileStream foutput = createFile(outputFile);
if (foutput == null)
return;
Int64 y1;
while ((y1 = inputInt64(finput)) != -1)
{
Int64 y2 = inputInt64(finput);
Int64 t = r.modPower(y1, sk, p);
t = r.reverse(t, p);
Int64 m = r.multiplyMod(y2, t, p);
foutput.Write(BitConverter.GetBytes(m), 0, MAXINT64LEN);
}
finput.Close();
foutput.Close();
} //将二进制串进行加密,结果存放在output1和output2中
public void ElGamalEncodeBits(Int64 input, out Int64 output1, out Int64 output2)
{
Int64 k = r.nextInt64(0, p - 1);
output1 = r.modPower(a, k, p);
Int64 pk1 = r.modPower(pk, k, p);
output2 = r.multiplyMod(input, pk1, p);
}
//将二进制串进行解密,结果存放在input中
public void ElGamalDecodeBits(out Int64 input, Int64 output1, Int64 output2)
{
Int64 t = r.modPower(output1, sk, p);
t = r.reverse(t, p);
input = r.multiplyMod(output2, t, p);
}
//从文件流finput中读入一个Int64型数据
private Int64 inputInt64(FileStream finput)
{
byte[] temp = new byte[MAXINT64LEN];
int count = finput.Read(temp, 0, MAXINT64LEN);
if (count == 0)
return -1;
Int64 result = BitConverter.ToInt64(temp, 0);
return result;
}
//为加密做准备
private void prepare4Encoding(string inputFile, string transformedFile, Int64 p0)
{
FileStream finput = openFile(inputFile);
if (finput == null)
return;
string path = Path.GetDirectoryName(inputFile);
string name = Path.GetFileName(inputFile);
string paddedFile = path + "\\"+tempPrePadding + name;
FileStream fPadded = createFile(paddedFile);
if (fPadded == null)
return;
FileStream fTransformed = createFile(transformedFile);
if (fTransformed == null)
return;
padding_Transform(finput, fPadded, fTransformed, p0);
File.Delete(paddedFile);
}
//在解密完成之后,进行变换
private void postDecoding(string decodedFile, string depaddedFile, Int64 p0)
{
FileStream fDecoded = openFile(decodedFile);
if (fDecoded == null)
return;
string path = Path.GetDirectoryName(decodedFile);
string name = Path.GetFileName(decodedFile);
string detransformedFile = path + "\\"+tempPreTransforming + name;
FileStream fDetransformed = createFile(detransformedFile);
if (fDetransformed == null)
return;
FileStream fDepadded = createFile(depaddedFile);
if (fDepadded == null)
return;
detransform_Depadding(fDecoded, fDetransformed, fDepadded, p0);
File.Delete(detransformedFile);
}
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Windows.Forms;namespace ElGamalProgram
{
class ElGamal
{
private const int MAXINT64LEN = sizeof(Int64);//用来作为读取的单位长度
private const string tempPrePadding = "_elgpad";//用来生成paded文件的文件名
private const string tempPreTransforming = "_elgtrans";//用来生成transformed文件的文件名
private const int BITSLEN = 60;//密钥的长度
private RandomPrimeGenerator r = new RandomPrimeGenerator();//用来生成随机数,及进行其他运算 private Int64 p; //大素数
private Int64 a; //生成元
private Int64 sk; //私钥
private Int64 pk; //公钥 public ElGamal(Int64 p, Int64 sk)
{
this.p = p;
this.sk = sk;
} public void init4Encode(Int64 a)
{
this.a = a;
this.pk = r.modPower(a, sk, p);
} //将输入的文件进行变换之后,再加密,输出到输出文件中
public void Encode(string inputFile, string outputFile)
{
string path = Path.GetDirectoryName(inputFile);
string name = Path.GetFileName(inputFile);
string transformedFile = path + "\\"+tempPreTransforming + name;
prepare4Encoding(inputFile, transformedFile, p);
ElGamalEncode(transformedFile, outputFile);
File.Delete(transformedFile);
}
//将输入的文件进行变换之后,再解密,输出到输出文件中
public void Decode(string inputFile, string outputFile)
{
string path = Path.GetDirectoryName(inputFile);
string name = Path.GetFileName(inputFile);
string decodedFile = path +"\\"+ tempPrePadding+name;
ElGamalDecode(inputFile, decodedFile);
postDecoding(decodedFile, outputFile, p);
File.Delete(decodedFile);
}
//对于已经经过变换之后的文件,直接进行加密
private void ElGamalEncode(string inputFile, string outputFile)
{
FileStream finput = openFile(inputFile);
if (finput == null)
return;
FileStream foutput = createFile(outputFile);
if (foutput == null)
return;
Int64 m;
while ((m = inputInt64(finput)) != -1)
{
Int64 k = r.nextInt64(0, p - 1);
Int64 y1 = r.modPower(a, k, p);
byte[] temp = BitConverter.GetBytes(y1);
foutput.Write(temp, 0, MAXINT64LEN);
Int64 pk1 = r.modPower(pk, k, p);
Int64 y2 = r.multiplyMod(m, pk1, p);
foutput.Write(BitConverter.GetBytes(y2), 0, MAXINT64LEN);
}
finput.Close();
foutput.Close();
}
//将变换之后的文件进行直接解密
private void ElGamalDecode(string inputFile, string outputFile)
{
FileStream finput = openFile(inputFile);
if (finput == null)
return;
FileStream foutput = createFile(outputFile);
if (foutput == null)
return;
Int64 y1;
while ((y1 = inputInt64(finput)) != -1)
{
Int64 y2 = inputInt64(finput);
Int64 t = r.modPower(y1, sk, p);
t = r.reverse(t, p);
Int64 m = r.multiplyMod(y2, t, p);
foutput.Write(BitConverter.GetBytes(m), 0, MAXINT64LEN);
}
finput.Close();
foutput.Close();
} //将二进制串进行加密,结果存放在output1和output2中
public void ElGamalEncodeBits(Int64 input, out Int64 output1, out Int64 output2)
{
Int64 k = r.nextInt64(0, p - 1);
output1 = r.modPower(a, k, p);
Int64 pk1 = r.modPower(pk, k, p);
output2 = r.multiplyMod(input, pk1, p);
}
//将二进制串进行解密,结果存放在input中
public void ElGamalDecodeBits(out Int64 input, Int64 output1, Int64 output2)
{
Int64 t = r.modPower(output1, sk, p);
t = r.reverse(t, p);
input = r.multiplyMod(output2, t, p);
}
//从文件流finput中读入一个Int64型数据
private Int64 inputInt64(FileStream finput)
{
byte[] temp = new byte[MAXINT64LEN];
int count = finput.Read(temp, 0, MAXINT64LEN);
if (count == 0)
return -1;
Int64 result = BitConverter.ToInt64(temp, 0);
return result;
}
//为加密做准备
private void prepare4Encoding(string inputFile, string transformedFile, Int64 p0)
{
FileStream finput = openFile(inputFile);
if (finput == null)
return;
string path = Path.GetDirectoryName(inputFile);
string name = Path.GetFileName(inputFile);
string paddedFile = path + "\\"+tempPrePadding + name;
FileStream fPadded = createFile(paddedFile);
if (fPadded == null)
return;
FileStream fTransformed = createFile(transformedFile);
if (fTransformed == null)
return;
padding_Transform(finput, fPadded, fTransformed, p0);
File.Delete(paddedFile);
}
//在解密完成之后,进行变换
private void postDecoding(string decodedFile, string depaddedFile, Int64 p0)
{
FileStream fDecoded = openFile(decodedFile);
if (fDecoded == null)
return;
string path = Path.GetDirectoryName(decodedFile);
string name = Path.GetFileName(decodedFile);
string detransformedFile = path + "\\"+tempPreTransforming + name;
FileStream fDetransformed = createFile(detransformedFile);
if (fDetransformed == null)
return;
FileStream fDepadded = createFile(depaddedFile);
if (fDepadded == null)
return;
detransform_Depadding(fDecoded, fDetransformed, fDepadded, p0);
File.Delete(detransformedFile);
}
//辅助函数
private FileStream openFile(string fileName)
{
FileStream file = new FileStream(fileName, FileMode.Open);
if (!file.CanRead)
{
string complain = "不能打开文件" + file + "!";
errorComplain(complain);
file.Close();
return null;
}
return file;
}
//辅助函数
private FileStream createFile(string fileName)
{
FileStream file = new FileStream(fileName, FileMode.Create);
if (!file.CanWrite)
{
string complain = "不能创建文件" + file + "!";
errorComplain(complain);
file.Close();
return null;
}
return file;
}
//辅助函数
private void errorComplain(string complain)
{
MessageBox.Show(complain, "Error");
}
//进行padding的变换
private void padding_Transform(FileStream finput, FileStream fPadded, FileStream fTransformed, Int64 p0)
{
finput.CopyTo(fPadded);
encodePadding(fPadded);
fPadded.Seek(0, SeekOrigin.Begin);
encodeTransform(fPadded, fTransformed, p0); finput.Close();
fPadded.Close();
fTransformed.Close();
}
//逆变换
private void detransform_Depadding(FileStream fDecoded, FileStream fDetransformed, FileStream fDepadded, Int64 p0)
{
decodeDeTransform(fDecoded, fDetransformed, p0);
fDetransformed.Seek(0, SeekOrigin.Begin);
decodeDePadding(fDetransformed, fDepadded, p0); fDecoded.Close();
fDetransformed.Close();
fDepadded.Close();
}
//padding
private void encodePadding(FileStream foutput)
{
Int64 size = foutput.Length;
Int64 residue;
residue = size % MAXINT64LEN;
residue = MAXINT64LEN - residue;
for (Int64 i = 0; i < residue; i++)
foutput.WriteByte(0);
byte[] temp = BitConverter.GetBytes(size);
foutput.Write(temp, 0, MAXINT64LEN);
} private void encodeTransform(FileStream fPadded, FileStream fTransformed, Int64 p0)
{
UInt64 p = (UInt64)p0;
byte[] tempForInputM = new byte[MAXINT64LEN];
byte[] tempForOutputM;
while (fPadded.Read(tempForInputM, 0, MAXINT64LEN) != 0)
{
UInt64 m = BitConverter.ToUInt64(tempForInputM, 0);
tempForOutputM = BitConverter.GetBytes(m / p + 1);
fTransformed.Write(tempForOutputM, 0, MAXINT64LEN);
tempForOutputM = BitConverter.GetBytes(m % p + 1);
fTransformed.Write(tempForOutputM, 0, MAXINT64LEN);
}
}
private void decodeDeTransform(FileStream fDecoded, FileStream fDetransformed, Int64 p0)
{
UInt64 p = (UInt64)p0;
byte[] tempForOutputM = new byte[MAXINT64LEN];
while (fDecoded.Read(tempForOutputM, 0, MAXINT64LEN) != 0)
{
UInt64 m1 = BitConverter.ToUInt64(tempForOutputM, 0);
fDecoded.Read(tempForOutputM, 0, MAXINT64LEN);
UInt64 m2 = BitConverter.ToUInt64(tempForOutputM, 0);
m1 -= 1;
m2 -= 1;
UInt64 m = m1 * p + m2;
fDetransformed.Write(BitConverter.GetBytes(m), 0, MAXINT64LEN);
}
}
private void decodeDePadding(FileStream fDetransformed, FileStream fDepadded, Int64 p0)
{
UInt64 p = (UInt64)p0;
byte[] tempForOutputM1 = new byte[MAXINT64LEN];
byte[] tempForOutputM2 = new byte[MAXINT64LEN];
Int64 size = fDetransformed.Length;
while (fDetransformed.Read(tempForOutputM1, 0, MAXINT64LEN) != 0)
{
//如果是倒数第二个字符
if (fDetransformed.Position == size - 1 * MAXINT64LEN)
{
UInt64 padding = BitConverter.ToUInt64(tempForOutputM1, 0);
fDetransformed.Read(tempForOutputM2, 0, MAXINT64LEN);
UInt64 fileLen = BitConverter.ToUInt64(tempForOutputM2, 0);
UInt64 residue = fileLen % MAXINT64LEN;
for (UInt64 i = 0; i < residue; i++)
fDepadded.WriteByte(tempForOutputM1[i]);
return;
}
else
{
fDepadded.Write(tempForOutputM1, 0, MAXINT64LEN);
}
} }
/*static void Main(string[] args)
{
RandomPrimeGenerator r = new RandomPrimeGenerator();
Int64 p = r.RandomSafePrime(60);
Int64 a = r.generator(p);
Int64 k = r.nextInt64(0, p-1);
Int64 sk = r.nextInt64(1, p - 1);
ElGamal e = new ElGamal(p, sk);
Int64 output1 = 0, output2 = 0;
e.ElGamalEncodeBits(1243424,out output1,out output2);
Console.WriteLine(output1);
Console.WriteLine(output2);
}*/
}
}
http://download.csdn.net/detail/shjh369/3204008