|

楼主 |
发表于 2022-6-2 12:07:29
|
显示全部楼层
- #pragma once
- #include <vector>
- #include "stdafx.h"
- #include "Key.h"
- #include "StdAfx.h"
- #include "ECC.h"
- #include <math.h>
- #include <sstream>
- #include <stdlib.h>
- #include <string>
- #include <iomanip>
- class ECC
- {
- public:
- ECC(int a,int b,int p);
- virtual ~ECC(void);
- void encrypt(const std::vector<Point> &Pm,Key &key,std::vector<Cipher> &result,int k=-1);
- void decrypt(const std::vector<Cipher>& ciphers,int x,std::vector<Point> &result);
- const std::vector<Generator> getGenerators()const;
- void genKey(Key& result,int gIndex=-1,int x=-1);
- void decodePlainPoints(const std::vector<Point>& Pm,std::string &result);
- void encodePlainText(const char* plainText,std::vector<Point> &result);
- static bool isPrime(int n);
- protected:
- int mA,mB,mP;
- std::vector<Point> mPoints;
- std::vector<Generator> mGenerators;
- Dictionary mDictionary;
- private:
- void getAllPoints();
- void getAllOrders();
- int getOrder(const Point&p);
- int ex_gcd(int a,int b,int& x,int& y);
- int getInverse(int a,int p);
- Point getMultiplePoint(int k,const Point& p);
- Point add(const Point& p1,const Point& p2);
- int mod(int a,int p);
- };
- ECC::ECC(int a = 4, int b = 20, int p = 29)
- {
- this->mA = a;
- this->mB = b;
- this->mP = p;
- this->getAllPoints();
- this->getAllOrders();
- }
- ECC::~ECC(void)
- {
- }
- void ECC::getAllPoints()
- {
- int left, right = 0;
- for (int x = 0; x < mP; x++)
- {
- right = x * x * x + mA * x + mB;
- for (int y = 0; y < mP; y++)
- {
- left = y * y;
- if (mod(left, mP) == mod(right, mP))
- {
- mPoints.push_back(Point(x, y));
- }
- }
- }
- }
- class Key
- {
- public:
- Key(void);
- Key(const Generator& g, int x, const Point& Q);//生成元g,私钥x,公钥Q
- virtual ~Key(void);
- const Point& getPublicKey()const;
- const int getPrivateKey()const;
- const Generator& getGenerator()const;
- protected:
- Generator m_g;//生成元
- Point m_Q;//公钥
- int m_x;//私钥
- };
- void ECC::getAllOrders()
- {
- for (std::vector<Point>::const_iterator it = mPoints.begin(); it != mPoints.end(); it++)
- {
- mGenerators.push_back(Generator(*it, getOrder(*it)));
- }
- }
- int ECC::getOrder(const Point& p)
- {
- int i = 1;
- Point q = add(p, p);
- while (q != p && q.isInfinity() == false)
- {
- i++;
- q = add(p, q);
- }
- return ++i;
- }
- int ECC::ex_gcd(int a, int b, int& x, int& y)
- {
- if (b == 0)
- {
- x = 1;
- y = 0;
- return a;
- }
- int ans = this->ex_gcd(b, a % b, x, y);
- int tmp = x;
- x = y;
- y = tmp - a / b * y;
- return ans;
- }
- int ECC::getInverse(int a, int p)
- {
- int x, y;
- int n = ex_gcd(a, p, x, y);
- if (1 % n != 0) return -1;
- x *= 1 / n;
- p = abs(p);
- int ans = x % p;
- if (ans <= 0) ans += p;
- return ans;
- }
- Point ECC::getMultiplePoint(int k, const Point& p)
- {
- Point q(p);
- for (int i = 1; i < k; i++)
- {
- q = add(p, q);
- }
- return q;
- }
- Point ECC::add(const Point& p, const Point& q)
- {
- int lambda, m, n;
- int x, y;
- if (p.isInfinity())
- {
- return q;
- }
- if (q.isInfinity())
- {
- return p;
- }
- if (p == q)
- {
- m = mod(3 * p.X * p.X + mA, mP);
- n = mod(2 * p.Y, mP);
- }
- else//P≠Q
- {
- m = mod(q.Y - p.Y, mP);
- n = mod(q.X - p.X, mP);
- }
- if (n == 0)
- {
- return Point::Infinity();
- }
- lambda = mod(m * getInverse(n, mP), mP);
- x = mod(lambda * lambda - p.X - q.X, mP);
- y = mod(lambda * (p.X - x) - p.Y, mP);
- return Point(x, y);
- }
- int ECC::mod(int a, int p)
- {
- if (a >= 0)
- {
- return a % p;
- }
- else
- {
- return ((a % p) + p) % p;
- }
- }
- void ECC::encrypt(const std::vector<Point>& Pm, Key& key, std::vector<Cipher>& result, int k)
- {
- bool flag = k <= 1 || k > key.getGenerator().Order;
- for (std::vector<Point>::const_iterator it = Pm.begin(); it != Pm.end(); it++)
- {
- if (flag)
- {
- k = rand() % (key.getGenerator().Order - 1) + 1;
- }
- Point C1 = getMultiplePoint(k, key.getGenerator().Value);
- Point C2 = add(*it, getMultiplePoint(k, key.getPublicKey()));
- result.push_back(Cipher(C1, C2));
- }
- }
- void ECC::encodePlainText(const char* plainText, std::vector<Point>& result)
- {
- mDictionary = Dictionary(plainText);
- while (*plainText != '\0')
- {
- int index = mDictionary.getIndex(*plainText);
- result.push_back(mPoints[index]);
- plainText++;
- }
- }
- void ECC::decodePlainPoints(const std::vector<Point>& Pm, std::string& result)
- {
- std::stringstream ss;
- for (std::vector<Point>::const_iterator it = Pm.begin(); it != Pm.end(); it++)
- {
- for (unsigned int i = 0; i < mPoints.size(); i++)
- {
- if (mPoints[i] == *it)
- {
- unsigned char ch = mDictionary.getChar(i);
- ss << ch;
- break;
- }
- }
- }
- ss >> result;
- }
- void ECC::decrypt(const std::vector<Cipher>& ciphers, int x, std::vector<Point>& result)
- {
- for (std::vector<Cipher>::const_iterator it = ciphers.begin(); it != ciphers.end(); it++)
- {
- Point C1R = Point(it->C1.X, -it->C1.Y);
- Point Pm = add(it->C2, getMultiplePoint(x, C1R));
- result.push_back(Pm);
- }
- }
- bool ECC::isPrime(int n)
- {
- if (n < 2)
- return false;
- if (n == 2 || n == 3)
- return true;
- if (n % 6 != 1 && n % 6 != 5)
- return false;
- float n_sqrt = floor(sqrt((float)n));
- for (int i = 5; i <= n_sqrt; i += 6)
- {
- if (n % i == 0 || n % (i + 2) == 0)
- return false;
- }
- return true;
- }
- //g是生成元,x是私钥
- void ECC::genKey(Key& result, int gIndex, int x)
- {
- int n;
- Generator G;
- if (gIndex < 0 || isPrime(mGenerators[gIndex].Order) == false)
- {
- do
- {
- gIndex = rand() % mGenerators.size();
- n = mGenerators[gIndex].Order;
- } while (isPrime(n) == false);
- }
- else
- {
- n = mGenerators[gIndex].Order;
- }
- G = mGenerators[gIndex];
- if (x >= n || x <= 1)
- {
- x = rand() % (n - 1) + 1;
- }
- Point Q = getMultiplePoint(x, G.Value);
- result = Key(G, x, Q);
- }
- const std::vector<Generator> ECC::getGenerators()const
- {
- return mGenerators;
- }
- Key::Key(const Generator& g, int x, const Point& Q)
- {
- this->m_g = g;
- this->m_Q = Q;
- this->m_x = x;
- }
- Key::Key(void)
- {
- }
- Key::~Key(void)
- {
- }
- const Point& Key::getPublicKey()const
- {
- return m_Q;
- }
- const int Key::getPrivateKey()const
- {
- return m_x;
- }
- const Generator& Key::getGenerator()const
- {
- return m_g;
- }
- using namespace std;
- template <typename T>
- void print(const vector<T>& list)
- {
- for (unsigned int i = 0; i < list.size(); i++)
- {
- if (i % 4 == 0)
- {
- cout << endl;
- }
- cout << setw(3) << setfill(' ') << i << "、" << list[i] << "\t\t";
- }
- cout << endl;
- cout << "-------------------------------------------------------" << endl;
- }
- int main()
- {
- int a, b, p, x, k;
- Key key;
- cout << "椭圆曲线方程为:" << "y^2 = x^3 + ax + b (mod p)" << endl;
- //选取方程参数
- input: cout << "请输入a的值(a是整数,a>0):";
- cin >> a;
- cout << "请输入b的值(b是整数,b>0):";
- cin >> b;
- cout << "请输入p的值(p是大素数,但目前用Int32表示):";
- cin >> p;
- if (ECC::isPrime(p) == false)
- {
- cout << "p不是素数,请重新输入!" << endl;
- goto input;
- }
- if ((4 * (a * a * a) + 27 * (b * b)) % p == 0)
- {//当4a^3+27b^2≠0时,是一条非奇异椭圆曲线,此时可以在E(a,b)定义一个阿贝尔群
- cout << "输入的参数有误,请重新输入!" << endl;
- goto input;
- }
- //初始化椭圆曲线方程
- ECC ecc(a, b, p);
- //获取所有生成元以及对应的阶
- vector<Generator> generators = ecc.getGenerators();
- cout << "下面是生成元及对应的阶数:" << endl;
- print(generators);
- //选择基点G
- cout << "请选择基点G(x,y)的序号:";//G=P
- cin >> k;
- //输入私钥
- cout << "请输入私钥(x<" << generators[k].Order << "):x = ";
- cin >> x;
- //产生公私钥对
- ecc.genKey(key, k, x);
- if (generators[k] != key.getGenerator())
- {
- cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << endl;
- cout << "你选择的生成元为:G = " << generators[k] << endl;
- cout << "该生成元的阶数为:ord(G) = " << generators[k].Order << ",不是素数" << endl;
- cout << "生成元已自动变更为:G = " << key.getGenerator() << endl;
- cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << endl;
- }
- cout << "生成的公钥为:Q = " << key.getPublicKey() << endl;
- cout << "目前的私钥为:x = " << key.getPrivateKey() << endl;
- //输入随机数k
- cout << "请输入k的值来计算 kG,kQ+Pm,输入负数使用随机值(1<k<" << key.getGenerator().Order << "):k = ";
- cin >> k;
- vector<Point> encodedPoints;
- vector<Cipher> cipheredPoints;
- //将明文m编码为椭圆曲线上的点
- ecc.encodePlainText("Hello,我是明文", encodedPoints);
- cout << "编码后的明文点集为:Pme = " << endl;
- print(encodedPoints);
- //加密
- ecc.encrypt(encodedPoints, key, cipheredPoints, k);
- cout << "加密后的密文点集为:Pc = " << endl;
- print(cipheredPoints);
- vector<Point> decryptedPoints;
- string decodedText;
- //解密
- ecc.decrypt(cipheredPoints, key.getPrivateKey(), decryptedPoints);
- cout << "解密后的明文点集为:Pm = " << endl;
- print(decryptedPoints);
- //解码明文点集,得到明文字符串
- ecc.decodePlainPoints(decryptedPoints, decodedText);
- cout << "解码后的字符串明文为:" << endl;
- cout << decodedText << endl;
- system("Pause");
- return 0;
- }
复制代码 |
|