教学服务系统

 找回密码
 立即注册
搜索
查看: 545|回复: 2

信息计算2019级2班9号范承蝶

[复制链接]

9

主题

20

帖子

127

积分

注册会员

Rank: 2

积分
127
发表于 2022-6-1 11:38:39 | 显示全部楼层 |阅读模式
本帖最后由 范承蝶 于 2022-6-1 11:43 编辑

一、RSA加解密和签名:
1、RSA加密介绍:
RSA加密是一种非对称加密。可以在不直接传递密钥的情况下,完成解密。者能够确保信息的安全性,避免了直接传递密钥所造成的被破解的风险。是由一对密钥来进行加解密的过程,分别称之为公钥和私钥。如果用公钥进行加密,则只能通过对应的私钥去解密,如果用私钥进行加密,则只能通过对应的公钥去解密。两者之间有数字相关,该加密发酸的原理就是对一极大整数做因数分解的困难行来保证安全性。通常个人保存私钥,公钥是公开的(可能同时多人持有)。
2、RSA加密和签名的区别:
加密和签名都是为了安全性考虑,但略有不同。常有人问加密和签名使用私钥还是公钥?其实都是对加密和签名的作用有所混淆。简单的说,加密是为了防止信息被泄露,而签名是为了防止信息被篡改。
3、源代码:
(1)RSACode

  1. package test;

  2. import java.io.ByteArrayOutputStream;
  3. import java.security.Key;
  4. import java.security.KeyFactory;
  5. import java.security.KeyPair;
  6. import java.security.KeyPairGenerator;
  7. import java.security.PrivateKey;
  8. import java.security.PublicKey;
  9. import java.security.Signature;
  10. import java.security.interfaces.RSAPrivateKey;
  11. import java.security.interfaces.RSAPublicKey;
  12. import java.security.spec.PKCS8EncodedKeySpec;
  13. import java.security.spec.X509EncodedKeySpec;
  14. import java.util.HashMap;
  15. import java.util.Map;

  16. import javax.crypto.Cipher;

  17. public class RSA {

  18.     /*
  19.      * 加密算法RSA
  20.      */
  21.     public static final String KEY_ALGORITHM = "RSA";

  22.     /**
  23.      * 签名算法
  24.      */
  25.     public static final String SIGNATURE_ALGORITHM = "MD5withRSA";

  26.     /**
  27.      * 获取公钥的key
  28.      */
  29.     private static final String PUBLIC_KEY = "RSAPublicKey";

  30.     /**
  31.      * 获取私钥的key
  32.      */
  33.     private static final String PRIVATE_KEY = "RSAPrivateKey";

  34.     /**
  35.      * RSA最大加密明文大小
  36.      */
  37.     private static final int MAX_ENCRYPT_BLOCK = 117;

  38.     /**
  39.      * RSA最大解密密文大小
  40.      */
  41.     private static final int MAX_DECRYPT_BLOCK = 128;

  42.     //生成密钥对(公钥和私钥)
  43.     public static Map<String, Object> genKeyPair() throws Exception {
  44.         KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
  45.         keyPairGen.initialize(1024);
  46.         KeyPair keyPair = keyPairGen.generateKeyPair();
  47.         RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
  48.         RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
  49.         Map<String, Object> keyMap = new HashMap<String, Object>(2);
  50.         keyMap.put(PUBLIC_KEY, publicKey);
  51.         keyMap.put(PRIVATE_KEY, privateKey);
  52.         return keyMap;
  53.     }

  54.    
  55.     //用私钥对信息生成数字签名
  56.     public static String sign(byte[] data, String privateKey) throws Exception {
  57.         byte[] keyBytes = Base64.decode(privateKey);
  58.         PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
  59.         KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
  60.         PrivateKey privateK = keyFactory.generatePrivate(pkcs8KeySpec);
  61.         Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
  62.         signature.initSign(privateK);
  63.         signature.update(data);
  64.         return Base64.encode(signature.sign());
  65.     }

  66.    
  67.     //校验数字签名
  68.     public static boolean verify(byte[] data, String publicKey, String sign)
  69.             throws Exception {
  70.         byte[] keyBytes = Base64.decode(publicKey);
  71.         X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
  72.         KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
  73.         PublicKey publicK = keyFactory.generatePublic(keySpec);
  74.         Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
  75.         signature.initVerify(publicK);
  76.         signature.update(data);
  77.         return signature.verify(Base64.decode(sign));
  78.     }

  79.     //私钥解密
  80.     public static byte[] decryptByPrivateKey(byte[] encryptedData, String privateKey)
  81.             throws Exception {
  82.         byte[] keyBytes = Base64.decode(privateKey);
  83.         PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
  84.         KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
  85.         Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
  86.         Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
  87.         cipher.init(Cipher.DECRYPT_MODE, privateK);
  88.         int inputLen = encryptedData.length;
  89.         ByteArrayOutputStream out = new ByteArrayOutputStream();
  90.         int offSet = 0;
  91.         byte[] cache;
  92.         int i = 0;
  93.         // 对数据分段解密
  94.         while (inputLen - offSet > 0) {
  95.             if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
  96.                 cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
  97.             } else {
  98.                 cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
  99.             }
  100.             out.write(cache, 0, cache.length);
  101.             i++;
  102.             offSet = i * MAX_DECRYPT_BLOCK;
  103.         }
  104.         byte[] decryptedData = out.toByteArray();
  105.         out.close();
  106.         return decryptedData;
  107.     }

  108.   
  109.     //公钥解密
  110.     public static byte[] decryptByPublicKey(byte[] encryptedData, String publicKey)
  111.             throws Exception {
  112.         byte[] keyBytes = Base64.decode(publicKey);
  113.         X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
  114.         KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
  115.         Key publicK = keyFactory.generatePublic(x509KeySpec);
  116.         Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
  117.         cipher.init(Cipher.DECRYPT_MODE, publicK);
  118.         int inputLen = encryptedData.length;
  119.         ByteArrayOutputStream out = new ByteArrayOutputStream();
  120.         int offSet = 0;
  121.         byte[] cache;
  122.         int i = 0;
  123.         // 对数据分段解密
  124.         while (inputLen - offSet > 0) {
  125.             if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
  126.                 cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
  127.             } else {
  128.                 cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
  129.             }
  130.             out.write(cache, 0, cache.length);
  131.             i++;
  132.             offSet = i * MAX_DECRYPT_BLOCK;
  133.         }
  134.         byte[] decryptedData = out.toByteArray();
  135.         out.close();
  136.         return decryptedData;
  137.     }

  138.    
  139.     //公钥加密
  140.     public static byte[] encryptByPublicKey(byte[] data, String publicKey)
  141.             throws Exception {
  142.         byte[] keyBytes = Base64.decode(publicKey);
  143.         X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
  144.         KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
  145.         Key publicK = keyFactory.generatePublic(x509KeySpec);
  146.         // 对数据加密
  147.         Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
  148.         cipher.init(Cipher.ENCRYPT_MODE, publicK);
  149.         int inputLen = data.length;
  150.         ByteArrayOutputStream out = new ByteArrayOutputStream();
  151.         int offSet = 0;
  152.         byte[] cache;
  153.         int i = 0;
  154.         // 对数据分段加密
  155.         while (inputLen - offSet > 0) {
  156.             if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
  157.                 cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
  158.             } else {
  159.                 cache = cipher.doFinal(data, offSet, inputLen - offSet);
  160.             }
  161.             out.write(cache, 0, cache.length);
  162.             i++;
  163.             offSet = i * MAX_ENCRYPT_BLOCK;
  164.         }
  165.         byte[] encryptedData = out.toByteArray();
  166.         out.close();
  167.         return encryptedData;
  168.     }

  169.    
  170.     //私钥加密
  171.     public static byte[] encryptByPrivateKey(byte[] data, String privateKey)
  172.             throws Exception {
  173.         byte[] keyBytes = Base64.decode(privateKey);
  174.         PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
  175.         KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
  176.         Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
  177.         Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
  178.         cipher.init(Cipher.ENCRYPT_MODE, privateK);
  179.         int inputLen = data.length;
  180.         ByteArrayOutputStream out = new ByteArrayOutputStream();
  181.         int offSet = 0;
  182.         byte[] cache;
  183.         int i = 0;
  184.         // 对数据分段加密
  185.         while (inputLen - offSet > 0) {
  186.             if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
  187.                 cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
  188.             } else {
  189.                 cache = cipher.doFinal(data, offSet, inputLen - offSet);
  190.             }
  191.             out.write(cache, 0, cache.length);
  192.             i++;
  193.             offSet = i * MAX_ENCRYPT_BLOCK;
  194.         }
  195.         byte[] encryptedData = out.toByteArray();
  196.         out.close();
  197.         return encryptedData;
  198.     }

  199.   
  200.     //获取私钥
  201.     public static String getPrivateKey(Map<String, Object> keyMap)
  202.             throws Exception {
  203.         Key key = (Key) keyMap.get(PRIVATE_KEY);
  204.         return Base64.encode(key.getEncoded());
  205.     }

  206.    // 获取公钥
  207.     public static String getPublicKey(Map<String, Object> keyMap)
  208.             throws Exception {
  209.         Key key = (Key) keyMap.get(PUBLIC_KEY);
  210.         return Base64.encode(key.getEncoded());
  211.     }
  212. }
复制代码

回复

使用道具 举报

9

主题

20

帖子

127

积分

注册会员

Rank: 2

积分
127
 楼主| 发表于 2022-6-1 11:42:48 | 显示全部楼层
本帖最后由 范承蝶 于 2022-6-1 11:45 编辑

RSA代码后续以及测试运行截图:
(2)Base64Code
  1. package test;

  2. public class Base64{
  3.   private static char[] Base64Code = {
  4.     'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
  5.     'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
  6.     'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
  7.    'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
  8.     'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
  9.     'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
  10.     '8', '9', '+', '/' };

  11.   private static byte[] Base64Decode = {
  12.     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  13.     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  14.     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  15.     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  16.     -1, -1, -1, 62, -1, 63, -1, 63, 52, 53,
  17.     54, 55, 56, 57, 58, 59, 60, 61, -1, -1,
  18.     -1, 0, -1, -1, -1, 0, 1, 2, 3, 4,
  19.     5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
  20.     15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
  21.     25, -1, -1, -1, -1, -1, -1, 26, 27, 28,
  22.     29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
  23.     39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
  24.     49, 50, 51, -1, -1, -1, -1, -1 };

  25.    public static String encode(byte[] b)
  26.    {
  27.     int code = 0;
  28.     if (b == null)
  29.       return null;
  30.     StringBuffer sb = new StringBuffer((b.length - 1) / 3 << 6);
  31.     for (int i = 0; i < b.length; i++)
  32.      {
  33.       code |= b[i] << 16 - i % 3 * 8 & 255 << 16 - i % 3 * 8;
  34.       if ((i % 3 != 2) && (i != b.length - 1))
  35.          continue;
  36.       sb.append(Base64Code[((code & 0xFC0000) >>> 18)]);
  37.       sb.append(Base64Code[((code & 0x3F000) >>> 12)]);
  38.       sb.append(Base64Code[((code & 0xFC0) >>> 6)]);
  39.       sb.append(Base64Code[(code & 0x3F)]);
  40.       code = 0;
  41.      }

  42.     if (b.length % 3 > 0)
  43.       sb.setCharAt(sb.length() - 1, '=');
  44.     if (b.length % 3 == 1)
  45.       sb.setCharAt(sb.length() - 2, '=');
  46.     return sb.toString();
  47.    }

  48.    public static byte[] decode(String code)
  49.    {
  50.     if (code == null)
  51.       return null;
  52.     int len = code.length();
  53.     if (len % 4 != 0)
  54.       throw new IllegalArgumentException("Base64 string length must be 4*n");
  55.     if (code.length() == 0)
  56.       return new byte[0];
  57.     int pad = 0;
  58.     if (code.charAt(len - 1) == '=')
  59.       pad++;
  60.     if (code.charAt(len - 2) == '=')
  61.       pad++;
  62.     int retLen = len / 4 * 3 - pad;
  63.     byte[] ret = new byte[retLen];
  64.     for (int i = 0; i < len; i += 4)
  65.      {
  66.       int j = i / 4 * 3;
  67.       char ch1 = code.charAt(i);
  68.       char ch2 = code.charAt(i + 1);
  69.       char ch3 = code.charAt(i + 2);
  70.       char ch4 = code.charAt(i + 3);
  71.        int tmp = Base64Decode[ch1] << 18 | Base64Decode[ch2] << 12 | Base64Decode[ch3] << 6 | Base64Decode[ch4];
  72.       ret[j] = (byte)((tmp & 0xFF0000) >> 16);
  73.       if (i < len - 4)
  74.        {
  75.         ret[(j + 1)] = (byte)((tmp & 0xFF00) >> 8);
  76.         ret[(j + 2)] = (byte)(tmp & 0xFF);
  77.        }
  78.        else {
  79.         if (j + 1 < retLen)
  80.           ret[(j + 1)] = (byte)((tmp & 0xFF00) >> 8);
  81.         if (j + 2 < retLen)
  82.           ret[(j + 2)] = (byte)(tmp & 0xFF);
  83.        }
  84.      }
  85.     return ret;
  86.    }
  87. }
复制代码


(3)RSATest
  1. import java.util.Map;

  2. import test.RSA;

  3. public class RSATest {
  4.     static String publicKey;
  5.     static String privateKey;

  6.     static {
  7.         try {
  8.             Map<String, Object> keyMap = RSA.genKeyPair();
  9.             publicKey = RSA.getPublicKey(keyMap);
  10.             privateKey = RSA.getPrivateKey(keyMap);
  11.             System.err.println("公钥: " + publicKey);
  12.             System.err.println("私钥: " + privateKey);
  13.         } catch (Exception e) {
  14.             e.printStackTrace();
  15.         }
  16.     }

  17.     public static void main(String[] args) throws Exception {
  18.         test();
  19.         testSign();
  20.     }

  21.     static void test() throws Exception {
  22.         System.err.println("公钥加密——私钥解密");
  23.         String source = "一边清零,一边拥有";
  24.         System.out.println("加密前文字:" + source);
  25.         byte[] data = source.getBytes();
  26.         //公钥加密
  27.         byte[] encodedData = RSA.encryptByPublicKey(data, publicKey);
  28.         System.out.println("加密后文字:" + new String(encodedData));
  29.         //私钥解密
  30.         byte[] decodedData = RSA.decryptByPrivateKey(encodedData, privateKey);
  31.         String target = new String(decodedData);
  32.         System.out.println("解密后文字: " + target);
  33.     }

  34.     static void testSign() throws Exception {
  35.         System.err.println("私钥加密——公钥解密");
  36.         String source = "一边清零,一边拥有";
  37.         System.out.println("原文字:" + source);
  38.         byte[] data = source.getBytes();
  39.         //私钥加密
  40.         byte[] encodedData = RSA.encryptByPrivateKey(data, privateKey);
  41.         System.out.println("加密后:" + new String(encodedData));
  42.         //公钥解密
  43.         byte[] decodedData = RSA.decryptByPublicKey(encodedData, publicKey);
  44.         String target = new String(decodedData);
  45.         System.out.println("解密后: " + target);

  46.         System.err.println("私钥签名——公钥验证签名");
  47.         String sign = RSA.sign(encodedData, privateKey);
  48.         System.err.println("签名:\r" + sign);
  49.         boolean status = RSA.verify(encodedData, publicKey, sign);
  50.         System.err.println("验证结果:\r" + status);
  51.     }
  52. }
复制代码


4、运行截图:

本帖子中包含更多资源

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

x
回复

使用道具 举报

9

主题

20

帖子

127

积分

注册会员

Rank: 2

积分
127
 楼主| 发表于 2022-6-1 12:09:52 | 显示全部楼层
二、椭圆曲线上公钥密码
1、椭圆加密算法介绍:
椭圆加密算法(ECC)是一种公钥加密体制,最初由Koblitz和Miller两人于1985年提出,其数学基础是利用椭圆曲线上的有理点构成Abel加法群上椭圆离散对数的计算困难性。公钥密码体制根据其所依据的难题一般分为三类:大素数分解问题类、离散对数问题类、椭圆曲线类。有时也把椭圆曲线类归为离散对数类。
2、原理:
(1)计算该椭圆曲线上所有在有限域GF(89)上的点;
(2)实现椭圆曲线上任意一个点P(例如P=(12,5))的倍点运算的递归算法,即计算k*P( k=2,3,…);
(3)利用此递归算法找出椭圆曲线上的所有生成元G以及它们的阶n,即满足n*G=O。
3、源代码:
  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[30]="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[]="yes";
  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. int main()
  43. {       
  44.         get_generetor_class();
  45.         encrypt_ecc();
  46.         decrypt_ecc();
  47.         return 0;
  48. }
  49. //task4:加密
  50. void encrypt_ecc()
  51. {
  52.         int num,i,j;
  53.         int gene_class;
  54.         int num_t;
  55.         int k;
  56.         srand(time(NULL));
  57.         //明文转换过程
  58.         for(i=0;i<strlen(plain);i++)
  59.         {
  60.                 for(j=0;j<26;j++) //for(j=0;j<26;j++)
  61.                 {
  62.                         if(plain[i]==alphabet[j])
  63.                         {
  64.                                 m[i]=j;//将字符串明文换成数字,并存到整型数组m里面
  65.                         }
  66.                 }         
  67.         }
  68.         //选择生成元
  69.         num=rand()%geneLen;
  70.         gene_class=geneSet[num].p_class;
  71.         while(isPrime(gene_class)==-1)//不是素数
  72.         {
  73.                  num=rand()%(geneLen-3)+3;
  74.                  gene_class=geneSet[num].p_class;
  75.         }       
  76.         G=geneSet[num].p;
  77.         nB=rand()%(gene_class-1)+1;//选择私钥
  78.         PB=timesPiont(nB,G);
  79.         printf("\n公钥:\n");
  80.         printf("一边清零,一边拥有");
  81.         printf("\n私钥:\n");
  82.         printf("nB=%d\n",nB);
  83.         //加密
  84.         //
  85.         k=rand()%(gene_class-2)+1;
  86.         P1=timesPiont(k,G);
  87.         //
  88.         num_t=rand()%eccPoint.len; //选择映射点
  89.         Pt=eccPoint.p[num_t];
  90.         P2=timesPiont(k,PB);
  91.         Pm=add_two_points(Pt,P2);
  92.         printf("加密数据:\n");
  93.         printf("kG=(%d,%d),Pt+kPB=(%d,%d),C={",P1.point_x,P1.point_y,Pm.point_x,Pm.point_y);
  94.         for(i=0;i<strlen(plain);i++)
  95.         {
  96.                 C[i]=m[i]*Pt.point_x+Pt.point_y;
  97.                 printf("{%d}",C[i]);
  98.         }       
  99.         printf("}\n");
  100. }
  101. //task5:解密
  102. void decrypt_ecc()
  103. {
  104.         Point temp,temp1;
  105.         int m,i;
  106.         temp=timesPiont(nB,P1);
  107.         temp.point_y=0-temp.point_y;
  108.         temp1=add_two_points(Pm,temp);//求解Pt
  109.         printf("\n解密结果:\n");
  110.         for(i=0;i<strlen(plain);i++)
  111.         {
  112.                 m=(C[i]-temp1.point_y)/temp1.point_x;
  113.                 printf("%c",alphabet[m]);//输出密文
  114.         }
  115.         printf("\n");
  116. }
  117. //判断是否为素数
  118. int isPrime(int n)
  119. {
  120.         int i,k;
  121.     k = sqrt(n);
  122.     for (i = 2; i <= k;i++)
  123.     {
  124.             if (n%i == 0)
  125.                         break;
  126.         }      
  127.     if (i <=k){
  128.             return -1;
  129.         }
  130.     else {
  131.              return 0;
  132.         }
  133. }
  134. //task3:求生成元以及阶
  135. void get_generetor_class()
  136. {       
  137.         int i,j=0;
  138.         int count=1;
  139.         Point p1,p2;
  140.         get_all_points();       
  141.         printf("\n**********************************输出生成元以及阶:*************************************\n");
  142.         for(i=0;i<eccPoint.len;i++)
  143.         {
  144.                 count=1;
  145.                 p1.point_x=p2.point_x=eccPoint.p[i].point_x;
  146.                 p1.point_y=p2.point_y=eccPoint.p[i].point_y;               
  147.                 while(1)
  148.                 {       
  149.                         p2=add_two_points(p1,p2);                                       
  150.                         if(p2.point_x==-1 && p2.point_y==-1)
  151.                         {
  152.                                 break;
  153.                         }
  154.                         count++;
  155.                         if(p2.point_x==p1.point_x)
  156.                         {
  157.                                 break;
  158.                         }                                               
  159.                 }
  160.                 count++;
  161.                 if(count<=eccPoint.len+1)
  162.                 {
  163.                         geneSet[j].p.point_x=p1.point_x;
  164.                         geneSet[j].p.point_y=p1.point_y;
  165.                         geneSet[j].p_class=count;
  166.                         printf("(%d,%d)--->>%d\t",geneSet[j].p.point_x,geneSet[j].p.point_y,geneSet[j].p_class);
  167.                         j++;
  168.                         if(j % 6 ==0){
  169.                                 printf("\n");
  170.                         }
  171.                 }
  172.                 geneLen=j;       
  173.         }
  174. }

  175. //task2:倍点运算的递归算法
  176. Point timesPiont(int k,Point p0)
  177. {
  178.         if(k==1){
  179.                 return p0;
  180.         }                
  181.         else if(k==2){
  182.                 return add_two_points(p0,p0);
  183.         }else{
  184.                 return add_two_points(p0,timesPiont(k-1,p0));
  185.         }
  186. }

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

  308. //取模函数
  309. int mod_p(int s)
  310. {
  311.         int i;        //保存s/p的倍数
  312.         int result;        //模运算的结果
  313.         i = s / p;
  314.         result = s - i * p;
  315.         if (result >= 0)
  316.         {
  317.                 return result;
  318.         }
  319.         else
  320.         {
  321.                 return result + p;
  322.         }
  323. }

  324. //判断平方根是否为整数
  325. int int_sqrt(int s)
  326. {
  327.         int temp;
  328.         temp=(int)sqrt(s);//转为整型
  329.         if(temp*temp==s)
  330.         {
  331.                 return temp;
  332.         }else{
  333.                 return -1;
  334.         }
  335. }
  336. //打印点集
  337. void print()
  338. {
  339.         int i;
  340.         int len=eccPoint.len;
  341.         printf("\n该椭圆曲线上共有%d个点(包含无穷远点)\n",len+1);
  342.         for(i=0;i<len;i++)
  343.         {
  344.                 if(i % 8==0)
  345.                 {
  346.                         printf("\n");
  347.                 }
  348.                 printf("(%2d,%2d)\t",eccPoint.p[i].point_x,eccPoint.p[i].point_y);
  349.         }
  350.         printf("\n");
  351. }
复制代码

4、运行截图:

本帖子中包含更多资源

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

x
回复

使用道具 举报

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

本版积分规则

教学服务系统

GMT+8, 2025-4-30 07:47 , Processed in 0.016639 second(s), 19 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

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