教学服务系统

 找回密码
 立即注册
搜索
查看: 612|回复: 4

信息计算2019级2班10号蔡冉平

[复制链接]

8

主题

24

帖子

116

积分

注册会员

Rank: 2

积分
116
发表于 2022-6-2 13:48:29 | 显示全部楼层 |阅读模式
本帖最后由 信计2班蔡冉平 于 2022-6-2 14:17 编辑

RSA加密、解密及签名

       RSA密码体制是一种公钥密码体制,公钥公开,私钥保密,它的加密解密算法是公开的。 由公钥加密的内容可以并且只能由私钥进行解密,并且由私钥加密的内容可以并且只能由公钥进行解密。也就是说,RSA的这一对公钥、私钥都可以用来加密和解密,并且一方加密的内容可以由并且只能由对方进行解密。                                                                                                                                                 加密,是指对某个内容加密,加密后的内容还可以通过解密进行还原。 例如对信件进行加密,加密后的内容在网络上进行传输,接收者在收到后,通过解密可以还原信件的真实内容。          
        RSA的加密过程如下:
  (1)A生成一对密钥(公钥和私钥),私钥不公开,A自己保留。公钥为公开的,任何人可以获取。
  (2)A传递自己的公钥给B,B用A的公钥对消息进行加密。
  (3)A接收到B加密的消息,利用A自己的私钥对消息进行解密。
       签名,就是在信息的后面再加上一段内容,可以证明信息没有被修改过。一般是对信息做一个hash计算得到一个hash值,注意,这个过程是不可逆的,也就是说无法通过hash值得出原来的信息内容。在把信息发送出去时,把这个hash值加密后做为一个签名和信息一起发出去。 接收方在收到信息后,会重新计算信息的hash值,并和信息所附带的hash值(解密后)进行对比,如果一致,就说明信息的内容没有被修改过,因为这里hash计算可以保证不同的内容一定会得到不同的hash值,所以只要内容一被修改,根据信息内容计算的hash值就会变化。                                                                                                         
       RSA签名的过程如下:
  (1)A生成一对密钥(公钥和私钥),私钥不公开,A自己保留。公钥为公开的,任何人可以获取。
  (2)A用自己的私钥对消息加签,形成签名,并将加签的消息和消息本身一起传递给B。
  (3)B收到消息后,在获取A的公钥进行验签,如果验签出来的内容与消息本身一致,证明消息是A回复的。





回复

使用道具 举报

8

主题

24

帖子

116

积分

注册会员

Rank: 2

积分
116
 楼主| 发表于 2022-6-2 14:11:33 | 显示全部楼层
本帖最后由 信计2班蔡冉平 于 2022-6-2 14:13 编辑
  1. package mm;

  2. import java.io.ByteArrayInputStream;
  3. import java.io.ByteArrayOutputStream;
  4. import java.io.InputStream;
  5. import java.security.Key;
  6. import java.security.KeyFactory;
  7. import java.security.KeyPair;
  8. import java.security.KeyPairGenerator;
  9. import java.security.PrivateKey;
  10. import java.security.PublicKey;
  11. import java.security.interfaces.RSAPrivateKey;
  12. import java.security.interfaces.RSAPublicKey;
  13. import java.security.spec.PKCS8EncodedKeySpec;
  14. import java.security.spec.X509EncodedKeySpec;
  15. import java.util.Base64;
  16. import javax.crypto.Cipher;

  17. public class mmRSA{
  18.         public static final String  SIGN_ALGORITHMS = "SHA1WithRSA";
  19.     public static final String KEY_ALGORITHM = "RSA";
  20.     private static final int MAX_ENCRYPT_BLOCK = 117;
  21.     private static final int MAX_DECRYPT_BLOCK = 128;
  22.         
  23.         /**
  24.         * RSA签名
  25.         * content 待签名数据
  26.         * privateKey 商户私钥
  27.         * input_charset 编码格式
  28.         */
  29.         public static String sign(String content, String privateKey, String input_charset){
  30.         try {
  31.                 PKCS8EncodedKeySpec priPKCS8         = new PKCS8EncodedKeySpec(Base64_.decode(privateKey) );
  32.                 KeyFactory keyf                                 = KeyFactory.getInstance(KEY_ALGORITHM);
  33.                 PrivateKey priKey                                 = keyf.generatePrivate(priPKCS8);
  34.             java.security.Signature signature = java.security.Signature.getInstance(SIGN_ALGORITHMS);
  35.             signature.initSign(priKey);
  36.             signature.update(content.getBytes(input_charset));
  37.             byte[] signed = signature.sign();
  38.             return Base64_.encode(signed);
  39.         }catch (Exception e) {
  40.                 e.printStackTrace();
  41.         }
  42.         return null;
  43.     }
  44.         
  45.         /**
  46.         * RSA验签名检查
  47.         *content 待签名数据
  48.         * sign 签名值
  49.         *ali_public_key 支付宝公钥
  50.         * input_charset 编码格式
  51.         */
  52.         public static boolean verify(String content, String sign, String ali_public_key, String input_charset){
  53.                 try {
  54.                         KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
  55.                 byte[] encodedKey = Base64_.decode(ali_public_key);
  56.                 PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
  57.                         java.security.Signature signature = java.security.Signature.getInstance(SIGN_ALGORITHMS);
  58.                         signature.initVerify(pubKey);
  59.                         signature.update(content.getBytes(input_charset) );
  60.                         boolean bverify = signature.verify( Base64_.decode(sign) );
  61.                         return bverify;
  62.                 } catch (Exception e) {
  63.                         e.printStackTrace();
  64.                 }
  65.                 return false;
  66.         }
  67.         
  68.         /**
  69.         * 私钥解密
  70.         * content 密文
  71.         * private_key 商户私钥
  72.         * input_charset 编码格式
  73.         */
  74.         public static String decrypt(String content, String private_key, String input_charset) throws Exception {
  75.         PrivateKey prikey = getPrivateKey(private_key);
  76.         Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
  77.         cipher.init(Cipher.DECRYPT_MODE, prikey);
  78.         InputStream ins = new ByteArrayInputStream(Base64_.decode(content));
  79.         ByteArrayOutputStream writer = new ByteArrayOutputStream();
  80.         byte[] buf = new byte[128];
  81.         int bufl;
  82.         while ((bufl = ins.read(buf)) != -1) {
  83.             byte[] block = null;
  84.             if (buf.length == bufl) {
  85.                 block = buf;
  86.             } else {
  87.                 block = new byte[bufl];
  88.                 for (int i = 0; i < bufl; i++) {
  89.                     block[i] = buf[i];
  90.                 }
  91.             }
  92.             writer.write(cipher.doFinal(block));
  93.         }
  94.         return new String(writer.toByteArray(), input_charset);
  95.     }
  96.         
  97.         /**
  98.      * 公钥加密
  99.      * data 源数据
  100.      * publicKey 公钥(BASE64编码)
  101.      */
  102.     public static byte[] encryptByPublicKey(byte[] data, String publicKey) throws Exception {
  103.         byte[] keyBytes = Base64_.decode(publicKey);
  104.         X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
  105.         KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
  106.         Key publicK = keyFactory.generatePublic(x509KeySpec);
  107.         // 对数据加密
  108.         Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
  109.         cipher.init(Cipher.ENCRYPT_MODE, publicK);
  110.         int inputLen = data.length;
  111.         ByteArrayOutputStream out = new ByteArrayOutputStream();
  112.         int offSet = 0;
  113.         byte[] cache;
  114.         int i = 0;
  115.         // 对数据分段加密
  116.         while (inputLen - offSet > 0) {
  117.             if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
  118.                 cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
  119.             } else {
  120.                 cache = cipher.doFinal(data, offSet, inputLen - offSet);
  121.             }
  122.             out.write(cache, 0, cache.length);
  123.             i++;
  124.             offSet = i * MAX_ENCRYPT_BLOCK;
  125.         }
  126.         byte[] encryptedData = out.toByteArray();
  127.         out.close();
  128.         return encryptedData;
  129.     }
  130.    
  131.     public static String encryptByPublicKeyToStr(byte[] data, String publicKey) throws Exception {
  132.             byte[] bytes = encryptByPublicKey(data, publicKey);
  133.             String result = Base64_.encode(bytes);
  134.             return result;
  135.     }
  136.         
  137.         /**
  138.         * 得到私钥
  139.         * key 密钥字符串(经过base64编码)
  140.         * Exception
  141.         */
  142.         public static PrivateKey getPrivateKey(String key) throws Exception {
  143.                 byte[] keyBytes;
  144.                 keyBytes = Base64_.decode(key);
  145.                 PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
  146.                 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
  147.                 PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
  148.                 return privateKey;
  149.         }
  150.         
  151.         public static class Base64_ {
  152.                 private static final Base64.Decoder decoder = Base64.getDecoder();
  153.                 private static final Base64.Encoder encoder = Base64.getEncoder();
  154.                 public static byte[] decode(String key) {
  155.                         if (key == null) { return null;}
  156.                         byte[] decode = decoder.decode(key);
  157.                         return decode;
  158.                 }
  159.                 public static String encode(byte[] content) {
  160.                         if (content == null) {return null;}
  161.                         String encode = encoder.encodeToString(content);
  162.                         return encode;
  163.                 }
  164.         }
  165.         

  166.         public static void main(String args[]) throws Exception{
  167.         KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
  168.         keyPairGen.initialize(1024);
  169.         KeyPair keyPair = keyPairGen.generateKeyPair();
  170.         RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
  171.         RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
  172.         String pubKey = Base64_.encode(publicKey.getEncoded()); //公钥
  173.         String priKey = Base64_.encode(privateKey.getEncoded()); //私钥
  174.         System.out.println("公钥为:"+pubKey);
  175.         System.out.println("私钥为:"+priKey);
  176.         
  177. //公钥加密,私钥解密!
  178.         
  179.         String sourceStr = "treat the world well";
  180.         byte[] ens = mmRSA.encryptByPublicKey(sourceStr.getBytes(),pubKey);
  181.         String encodes = Base64_.encode(ens);
  182.         System.out.println("加密后密文:"+ encodes);
  183.         String res2 = mmRSA.decrypt(encodes, priKey, "UTF-8");
  184.         System.out.println("解密后密文:"+res2);
  185.         
  186. //签名验证,私钥签名,公钥验证是否正确!
  187.         
  188.         String source = "id=shoig&name=shoer&age=23dnjlegj;reg";
  189.         String sign = mmRSA.sign(source, priKey, "UTF-8");      
  190.         System.out.println("签名是:"+sign);
  191.         
  192. // 公钥验证签名是否正确.
  193. // 具体流程是,请求参数+sign发送给公钥方,然后公钥方过滤掉sign,用公钥验证其他参数是否通过。
  194.         boolean result = mmRSA.verify(source, sign, pubKey, "UTF-8");      
  195.         System.out.println("签名验证结果:"+result);
  196.         
  197.         }
  198. }
复制代码

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

8

主题

24

帖子

116

积分

注册会员

Rank: 2

积分
116
 楼主| 发表于 2022-6-2 21:18:41 | 显示全部楼层
本帖最后由 信计2班蔡冉平 于 2022-6-2 21:40 编辑

ECC/椭圆曲线加密算法

RSA的解决分解整数问题需要亚指数时间复杂度的算法,而目前已知计算椭圆曲线离散对数问题(ECDLP)的最好方法都需要全指数时间复杂度。这意味着在椭圆曲线系统中我们只需要使用相对于RSA 短得多的密钥就可以达到与其相同的安全强度。

        椭圆曲线加密算法于1985年提出,由于自身优点,它一出现便受到关注,现在密码学界普遍认为它将替代RSA加密算法成为通用的公钥加密算法。ECC是基于椭圆曲线数学理论实现的一种非对称加密算法。相比RSA,ECC优势是可以使用更短的密钥,来实现与RSA相当或更高的安全。椭圆曲线加密系统是迄今为止每比特具有最高安全强度的加密系统,它被认为最有希望成为下一代通用的公钥加密系统。

        ECC算法中的关键变量

    (1)基点:基点G,G为椭圆曲线Ep(a,b)上的点
    (2)阶:如果椭圆曲线上一点P,存在最小的正整数n使得数乘n P = O ∞ ,则将n称为P的阶,若n不存在,则P是无限阶的.
    (3)公钥K:则给定私钥k和基点G,根据加法法则,计算K很容易但反过来,给定K和G,求k就非常困难。因为实际使用中的ECC原则上把p取得相当大,n也相当大,要把n个解点逐一算出来列成上表是不可能的。
       下面是利用椭圆曲线进行加密通信的过程:
       1、用户A选定一条椭圆曲线Ep(a,b),并取椭圆曲线上一点,作为基点G。
       2、用户A选择一个私有密钥k,并生成公开密钥K=kG。
       3、用户A将Ep(a,b)和点K,G传给用户B。
       4、用户B接到信息后 ,将待传输的明文编码到Ep(a,b)上一点M(编码方法很多,这里不作讨论),并产生一个随机整数r(r<n)。
       5、用户B计算点C 1=M+rK和C 2=rG。
       6、用户B将C 1 、 C 2 传给用户A。
       7、用户A接到信息后,计算C 1 − k C 2结果就是点M。再对点M进行解码就可以得到明文。
      因为C 1−k C 2 = M+rK−k(rG)=M+rkG−krG=M
      代码会用到两个结构体,一个结构体用来装在有限域上的椭圆,里面的变量有他们的阶,x,y,序号,还有另外的一个结构体数组,这是来装这些点对应的mP的坐标,这里的m从-1到阶 没有 0 ,这个数组的下标就是m ,m为0 对应-P,这样将他的所有mP 保存起来,用于计算阶,以及后面的加密需要用到mp 。
       选择一个椭圆上的点作为基点,然后选择一个私钥,私钥k小于这个基点的阶n,生成公开密钥K=kG。这里选择基点是靠输入基点的序号,根据序号找到基点,在调取基点结构体中的数组,找到下标为k的数组,里面的坐标就是kG,因为计算了阶,所以已经有kG的值了。




回复

使用道具 举报

8

主题

24

帖子

116

积分

注册会员

Rank: 2

积分
116
 楼主| 发表于 2022-6-2 21:40:50 | 显示全部楼层
  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<string.h>
  4. #include<math.h>
  5. #include<time.h>
  6. #define MAX 100

  7. typedef struct point{
  8.         int point_x;
  9.         int point_y;
  10. }Point;
  11. typedef struct ecc{
  12.         struct point p[MAX];
  13.         int len;
  14. }ECCPoint;
  15. typedef struct generator{
  16.         Point p;
  17.         int p_class;
  18. }GENE_SET;

  19. void get_all_points();
  20. int int_sqrt(int s);
  21. Point timesPiont(int k,Point p);
  22. Point add_two_points(Point p1,Point p2);
  23. int inverse(int n,int b);
  24. void get_generetor_class();
  25. void encrypt_ecc();
  26. void decrypt_ecc();
  27. int mod_p(int s);
  28. void print();
  29. int isPrime(int n);

  30. char alphabet[26]="abcdefghijklmnopqrstuvwxyz";
  31. int a=-1,b=0,p=89;//椭圆曲线为E89(-1,0): y2=x3-x (mod 89)
  32. ECCPoint eccPoint;
  33. GENE_SET geneSet[MAX];
  34. int geneLen;
  35. char plain[]="plaintext";
  36. int m[MAX];
  37. int cipher[MAX];
  38. int nB;//私钥
  39. Point P1,P2,Pt,G,PB;
  40. Point Pm;
  41. int C[MAX];


  42. //task4:加密
  43. void encrypt_ecc()
  44. {
  45.         int num,i,j;
  46.         int gene_class;
  47.         int num_t;
  48.         int k;
  49.         srand(time(NULL));
  50.         printf("\n\n\n明文为:\n");
  51.         for(i=0;i<strlen(plain);i++)
  52.       printf("%c",plain[i]);       
  53.         for(i=0;i<strlen(plain);i++)//明文转换
  54.         {
  55.                 for(j=0;j<26;j++)
  56.                 {
  57.                         if(plain[i]==alphabet[j])
  58.                         {
  59.                                 m[i]=j;//将字符串明文换成数字,并存到整型数组m里面
  60.                         }
  61.                 }         
  62.         }         //选择生成元
  63.         num=rand()%geneLen;
  64.         gene_class=geneSet[num].p_class;
  65.         while(isPrime(gene_class)==-1)//不是素数
  66.         {
  67.                  num=rand()%(geneLen-3)+3;
  68.                  gene_class=geneSet[num].p_class;
  69.         }       
  70.         G=geneSet[num].p;
  71.         nB=rand()%(gene_class-1)+1;//选择私钥
  72.         PB=timesPiont(nB,G);
  73.         printf("\n\n公钥:");
  74.         printf("{y^2=x^3%d*x+%d,%d,(%d,%d),(%d,%d)}\n",a,b,gene_class,G.point_x,G.point_y,PB.point_x,PB.point_y);
  75.         printf("私钥:");
  76.         printf("nB=%d\n",nB);
  77.         k=rand()%(gene_class-2)+1;
  78.         P1=timesPiont(k,G);
  79.         num_t=rand()%eccPoint.len; //选择映射点
  80.         Pt=eccPoint.p[num_t];
  81.         P2=timesPiont(k,PB);
  82.         Pm=add_two_points(Pt,P2);
  83.         printf("加密数据:\n");
  84.         printf("kG=(%d,%d),Pt+kPB=(%d,%d),C={",P1.point_x,P1.point_y,Pm.point_x,Pm.point_y);
  85.         for(i=0;i<strlen(plain);i++)
  86.         {
  87.                 C[i]=m[i]*Pt.point_x+Pt.point_y;//选择映射点
  88.                 printf("{%d}",C[i]);
  89.         }       
  90.         printf("}\n\n");
  91. }
  92. //task5:解密
  93. void decrypt_ecc()
  94. {
  95.         Point temp,temp1;
  96.         int m,i;
  97.         temp=timesPiont(nB,P1);
  98.         temp.point_y=0-temp.point_y;
  99.         temp1=add_two_points(Pm,temp);//求解Pt
  100.         printf("\n解密:\n");
  101.         for(i=0;i<strlen(plain);i++)
  102.         {
  103.                 m=(C[i]-temp1.point_y)/temp1.point_x;
  104.                 printf("%c",alphabet[m]);//输出密文
  105.         }
  106.         printf("\n\n\n");
  107. }
  108. //判断是否为素数
  109. int isPrime(int n)
  110. {
  111.         int i,k;
  112.     k = sqrt(n);
  113.     for (i = 2; i <= k;i++)
  114.     {
  115.             if (n%i == 0)
  116.                         break;
  117.         }      
  118.     if (i <=k){
  119.             return -1;
  120.         }
  121.     else {
  122.              return 0;
  123.         }
  124. }
  125. //task3:求生成元以及阶
  126. void get_generetor_class()
  127. {       
  128.         int i,j=0;
  129.         int count=1;
  130.         Point p1,p2;
  131.         get_all_points();       
  132.         printf("\n**********************************输出生成元以及阶:*************************************\n");
  133.         for(i=0;i<eccPoint.len;i++)
  134.         {
  135.                 count=1;
  136.                 p1.point_x=p2.point_x=eccPoint.p[i].point_x;
  137.                 p1.point_y=p2.point_y=eccPoint.p[i].point_y;               
  138.                 while(1)
  139.                 {       
  140.                         p2=add_two_points(p1,p2);                                       
  141.                         if(p2.point_x==-1 && p2.point_y==-1)
  142.                         {
  143.                                 break;
  144.                         }
  145.                         count++;
  146.                         if(p2.point_x==p1.point_x)
  147.                         {
  148.                                 break;
  149.                         }                                               
  150.                 }
  151.                 count++;
  152.                 if(count<=eccPoint.len+1)
  153.                 {
  154.                         geneSet[j].p.point_x=p1.point_x;
  155.                         geneSet[j].p.point_y=p1.point_y;
  156.                         geneSet[j].p_class=count;
  157.                         printf("(%d,%d)--->>%d\t",geneSet[j].p.point_x,geneSet[j].p.point_y,geneSet[j].p_class);
  158.                         j++;
  159.                         if(j % 6 ==0){
  160.                                 printf("\n");
  161.                         }
  162.                 }
  163.                 geneLen=j;       
  164.         }
  165. }

  166. //task2:倍点运算的递归算法
  167. Point timesPiont(int k,Point p0)
  168. {
  169.         if(k==1){
  170.                 return p0;
  171.         }                
  172.         else if(k==2){
  173.                 return add_two_points(p0,p0);
  174.         }else{
  175.                 return add_two_points(p0,timesPiont(k-1,p0));
  176.         }
  177. }

  178. //两点的加法运算
  179. Point add_two_points(Point p1,Point p2)
  180. {
  181.         long t;
  182.         int x1=p1.point_x;
  183.         int y1=p1.point_y;
  184.         int x2=p2.point_x;
  185.         int y2=p2.point_y;
  186.         int tx,ty;
  187.         int x3,y3;
  188.         int flag=0;
  189.         if((x2==x1)&& (y2==y1) )
  190.         {
  191.        
  192.                 if(y1==0)       
  193.                 {
  194.                         flag=1;
  195.                 }else{
  196.                         t=(3*x1*x1+a)*inverse(p,2*y1) % p;
  197.                 }
  198.         }else{
  199.                 ty=y2-y1;       
  200.                 tx=x2-x1;
  201.                 while(ty<0)
  202.                 {
  203.                         ty+=p;
  204.                 }
  205.                 while(tx<0)
  206.                 {
  207.                         tx+=p;
  208.                 }
  209.                 if(tx==0 && ty !=0)
  210.                 {
  211.                         flag=1;
  212.                 }else{
  213.                         t=ty*inverse(p,tx) % p;
  214.                 }
  215.         }
  216.         if(flag==1)
  217.         {
  218.                 p2.point_x=-1;
  219.                 p2.point_y=-1;
  220.         }else{
  221.                 x3=(t*t-x1-x2) % p;
  222.                 y3=(t*(x1-x3)-y1) % p;
  223.                 while(x3<0)        //使结果在有限域GF(P)上
  224.                 {
  225.                         x3+=p;
  226.                 }
  227.                 while(y3<0)
  228.                 {
  229.                         y3+=p;
  230.                 }
  231.                 p2.point_x=x3;
  232.                 p2.point_y=y3;
  233.         }       
  234.         return p2;
  235. }
  236. int inverse(int n,int b) //求b关于n的逆元
  237. {
  238.         int q,r,r1=n,r2=b,t,t1=0,t2=1,i=1;
  239.         while(r2>0)
  240.         {
  241.                 q=r1/r2;
  242.                 r=r1%r2;
  243.                 r1=r2;
  244.                 r2=r;
  245.                 t=t1-q*t2;
  246.                 t1=t2;
  247.                 t2=t;
  248.         }
  249.         if(t1>=0)
  250.                 return t1%n;
  251.         else{  
  252.                 while((t1+i*n)<0)
  253.                         i++;
  254.                 return t1+i*n;
  255.         }
  256. }
  257. void get_all_points()//求出椭圆曲线上所有点
  258. {
  259.         int i=0;
  260.         int j=0;
  261.         int s,y=0;
  262.         int n=0,q=0;
  263.         int modsqrt=0;
  264.         int flag=0;
  265.         if (4 * a * a * a + 27 * b * b != 0)
  266.         {
  267.                 for(i=0;i<=p-1;i++)
  268.                 {
  269.                         flag=0;
  270.                         n=1;
  271.                         y=0;
  272.                         s= i * i * i + a * i + b;
  273.                         while(s<0)
  274.                         {
  275.                                 s+=p;
  276.                         }
  277.                         s=mod_p(s);
  278.                         modsqrt=int_sqrt(s);
  279.                         if(modsqrt!=-1)
  280.                         {
  281.                                 flag=1;
  282.                                 y=modsqrt;
  283.                         }else{
  284.                                 while(n<=p-1)
  285.                                 {
  286.                                         q=s+n*p;
  287.                                         modsqrt=int_sqrt(q);
  288.                                         if(modsqrt!=-1)
  289.                                         {
  290.                                                 y=modsqrt;
  291.                                                 flag=1;
  292.                                                 break;
  293.                                         }
  294.                                                 flag=0;
  295.                                                 n++;
  296.                                 }
  297.                         }
  298.                         if(flag==1)
  299.                         {
  300.                                 eccPoint.p[j].point_x=i;
  301.                                 eccPoint.p[j].point_y=y;
  302.                                 j++;
  303.                                 if(y!=0)
  304.                                 {
  305.                                         eccPoint.p[j].point_x=i;
  306.                                         eccPoint.p[j].point_y=(p-y) % p;
  307.                                         j++;
  308.                                 }                               
  309.                         }
  310.                 }
  311.                 eccPoint.len=j;//点集个数
  312.                 print(); //打印点集
  313.         }       
  314. }

  315. int mod_p(int s)//取模函数
  316. {
  317.         int i;        //保存s/p的倍数
  318.         int result;        //模运算的结果
  319.         i = s / p;
  320.         result = s - i * p;
  321.         if (result >= 0)
  322.         {
  323.                 return result;
  324.         }
  325.         else
  326.         {
  327.                 return result + p;
  328.         }
  329. }

  330. int int_sqrt(int s)//判断平方根是否为整数
  331. {
  332.         int temp;
  333.         temp=(int)sqrt(s);//转为整型
  334.         if(temp*temp==s)
  335.         {
  336.                 return temp;
  337.         }else{
  338.                 return -1;
  339.         }
  340. }

  341. void print() //打印点集
  342. {
  343.         int i;
  344.         int len=eccPoint.len;
  345.         printf("\n该椭圆曲线上共有%d个点(包括无穷远点)\n",len+1);
  346.         for(i=0;i<len;i++)
  347.         {
  348.                 if(i % 8==0)
  349.                 {
  350.                         printf("\n");
  351.                 }
  352.                 printf("(%2d,%2d)\t",eccPoint.p[i].point_x,eccPoint.p[i].point_y);
  353.         }
  354.         printf("\n");
  355. }

  356. int main()
  357. {                
  358.         get_generetor_class();
  359.         encrypt_ecc();
  360.         decrypt_ecc();
  361.         return 0;
  362. }
复制代码

回复

使用道具 举报

8

主题

24

帖子

116

积分

注册会员

Rank: 2

积分
116
 楼主| 发表于 2022-6-2 21:42:34 | 显示全部楼层
运行结果为:

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

教学服务系统

GMT+8, 2025-4-30 01:32 , Processed in 0.017311 second(s), 19 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表