usingSystem;usingSystem.Collections.Generic;usingSystem.Globalization;usingSystem.Linq;usingSystem.Text;usingSystem.Threading.Tasks;namespaceConsoleApplication3{classClass1{pointA=newpoint(11,4);pointB=newpoint(120,41);//公钥publicconstintk=9;publicconstinta=5;publicconstintb=37;publicconstintp=127;publicconstintr=7;publicstructpoint{publicintx;publicinty;publicpoint(intx,inty){this.x=x;this.y=y;}publicpoint(pointp){this.x=p.x;this.y=p.y;}}publicintgetX_1(intx,intmod){intQ,X1,X2,X3,Y1,Y2,Y3,T1,T2,T3;X1=1;X2=0;X3=mod;Y1=0;Y2=1;Y3=(x%mod+mod)%mod;//获得正整数while(Y3!=1){Q=X3/Y3;T1=X1-Q*Y1;T2=X2-Q*Y2;T3=X3-Q*Y3;X1=Y1;X2=Y2;X3=Y3;Y1=T1;Y2=T2;Y3=T3;}returnY2;}//获得其乘法逆元publicpointchen(pointb,intn){pointq=b;n=n-1;for(inti=1;in;i++){q=jia(q,b);}returnq;}publicpointjia(pointpa,pointpb){intk;if(bi(pa,pb))k=((3*pa.x*pa.x+a)*getX_1(2*pa.y,p))%p;//必须使用正整数。这里pa.y的值不能取0.//当取0时,这就不能进行这个计算了,因为pa=-pb了,则,应该进行一个判断。但是,这样的结果是O,是不在椭圆曲线上的,不能进行输出的值。//这里是有一个周期数在,对于容易一个基值的也就是先给出的A来说,它有一个周期n,使nA=O,而这里所有参数的选取值//都小于n,使其不会达到O,保证了不会出错,应该是这样吧。。。elsek=(pb.y-pa.y)*getX_1(pb.x-pa.x,p)%p;pointc=newpoint();c.x=(k*k-pa.x-pb.x)%p;c.y=(k*(pa.x-c.x)-pa.y)%p;c.x=(c.x+p)%p;c.y=(c.y+p)%p;returnc;}publicboolbi(pointpa,pointpb){returnpa.x==pb.x&&pa.y==pb.y;}publicstringDCode(stringinput){stringoutput=;pointM,P1,P2;for(inti=0;iinput.Length;){P1.x=input[i++];P1.y=input[i++];P2.x=input[i++];P2.y=input[i++];Dictionaryint,pointCC=newDictionaryint,point();CC.Add(3,P1);CC.Add(4,P2);M=DCodePoint(CC);output+=(char)M.y;}returnoutput;}publicpointDCodePoint(Dictionaryint,pointt){pointZ=chen(t[3],k);pointm;m.x=t[4].x*getX_1(Z.x,p)%p;m.y=t[4].y*getX_1(Z.y,p)%p;returnm;}publicstringECode(stringinput){//明文的输入是一个string类型,但是单个的操作应该是对单个的字符char转换成的int类型进行计算stringoutput=;pointM;Dictionaryint,pointC=newDictionaryint,point();for(inti=0;iinput.Length;i++){M.x=i;M.y=input[i];C=ECodePoint(M);output+=(char)C[1].x;output+=(char)C[1].y;output+=(char)C[2].x;output+=(char)C[2].y;}returnoutput;}publicDictionaryint,pointECodePoint(pointm){pointc1=newpoint();pointc2=newpoint();c1=chen(A,r);pointY=chen(B,r);c2.x=Y.x*m.x%p;c2.y=Y.y*m.y%p;Dictionaryint,pointEE=newDictionaryint,point();EE.Add(1,c1);EE.Add(2,c2);returnEE;}}classProgram{staticvoidMain(string[]args){Class1EE=newClass1();stringS=;//加密简单,随便输入点东西就可以加密了,但是解密不行啊,随便输入肯定是错误的结果,//程序肯定会出错,所以,只支持对之前加密的结果进行解密。//Console.WriteLine(使用在素域上的曲线y^2=x^3+5*x+37,使用Menezes-Vanstone的算法:);//Console.WriteLine(在素域p=127上,私钥为k=9,公钥A(11,4),B(120,41),对明文字符串直接转换为int进行加密);Console.WriteLine(请输入加密的内容);S=Console.ReadLine();Console.WriteLine(密文如下);S=EE.ECode(S);Console.WriteLine(S);Console.WriteLine(完成);//Console.WriteLine(对之前密文解密,得到明文如下(由于输入密文不正确绝对会使这个程序出错,所以只能解密绝对安全的密文):);S=EE.DCode(S);Console.WriteLine(S);Console.WriteLine(完成);}#regionXMl异常符号解决///summary///把一个字符串中的低序位ASCII字符替换成字符///转换ASCII0-8-�-///转换ASCII11-12--///转换ASCII14-31--////summary///paramname=tmp/param///returns/returnspublicstaticstringReplaceLowOrderASCIICharacters(stringtmp){StringBuilderinfo=newStringBuilder();foreach(charccintmp){intss=(int)cc;if(((ss=0)&&(ss=8))||((ss=11)&&(ss=12))||((ss=14)&&(ss=32)))info.AppendFormat({0:X};,ss);elseinfo.Append(cc);}returninfo.ToString();}///summary///把一个字符串中的下列字符替换成低序位ASCII字符///转换�--ASCII0-8///转换--ASCII11-12///转换--ASCII14-31////summary///paramname=input/param///returns/returnspublicstaticstringGetLowOrderASCIICharacters(stringinput){if(string.IsNullOrEmpty(input))returnstring.Empty;intpos,startIndex=0,len=input.Length;if(len=4)returninput;StringBuilderresult=newStringBuilder();while((pos=input.IndexOf(,startIndex))=0){boolneedReplace=false;stringrOldV=string.Empty,rNewV=string.Empty;intle=(len-pos6)?len-pos:6;intp=input.IndexOf(;,pos,le);if(p=0){rOldV=input.Substring(pos,p-pos+1);//计算对应的低位字符shortss;if(short.TryParse(rOldV.Substring(3,p-pos-3),NumberStyles.AllowHexSpecifier,null,outss)){if(((ss=0)&&(ss=8))||((ss=11)&&(ss=12))||((ss=14)&&(ss=32))){needReplace=true;rNewV=Convert.ToChar(ss).ToString();}}pos=p+1;}elsepos+=le;stringpart=input.Substring(startIndex,pos-startIndex);if(needReplace)result.Append(part.Replace(rOldV,rNewV));elseresult.Append(part);startIndex=pos;}result.Append(input.Substring(startIndex));returnresult.ToString();}#endregion}}