赞
踩
- #ifndef POPERATION_H
- #define POPERATION_H
-
- // 定义点的结构
- typedef struct {
- long long x;
- long long y;
- } Point;
-
- // 定义椭圆曲线的结构
- typedef struct {
- long long a, b; // 曲线参数 y^2 = x^3 + ax + b
- long long p; // 有限域的素数
- } EllipticCurve;
-
- // 模逆运算的函数声明
- long long mod_inverse(long long a, long long m);
-
- // 点加运算的函数声明
- Point point_add(Point P, Point Q, EllipticCurve ec);
-
- // 点乘运算的函数声明
- Point point_multiply(long long scalar, Point P, EllipticCurve ec);
-
- #endif // POPERATION_H
- #ifndef ECDSA_H
- #define ECDSA_H
-
- #include "POperation.h" // 包含 EllipticCurve 和 Point 结构的定义
-
- // ECDSA签名函数声明
- void ecdsa_sign(char* message, long long d, EllipticCurve ec, Point G, long long n, long long* r, long long* s);
-
- // ECDSA验证函数声明
- int ecdsa_verify(char* message, Point Q, EllipticCurve ec, Point G, long long n, long long r, long long s);
-
- // 简单哈希函数声明
- long long simple_hash(char* message);
-
- #endif // ECDSA_H
- #ifndef ELGAMAL_H
- #define ELGAMAL_H
-
- #include <gmpxx.h>
- #include <vector>
- #include <iostream>
-
- // 检测原根
- bool is_primitive_root(const mpz_class& g, const mpz_class& p);
-
- // 生成大质数和其原根
- void generate_prime_and_primitive_root(mpz_class& p, mpz_class& g);
-
- // 生成公钥和私钥
- void generate_keys(mpz_class& p, mpz_class& g, mpz_class& y, mpz_class& x);
-
- // 加密
- void encrypt(const mpz_class& p, const mpz_class& g, const mpz_class& y, const mpz_class& m, mpz_class& c1, mpz_class& c2);
-
- // 解密
- void decrypt(const mpz_class& p, const mpz_class& x, const mpz_class& c1, const mpz_class& c2, mpz_class& m);
-
- #endif // ELGAMAL_H
- #pragma once
- #ifndef SM2_H
- #define SM2_H
-
- #include <openssl/evp.h>
- #include <openssl/ec.h>
- #include <openssl/pem.h>
- #include <openssl/err.h>
- #include <iostream>
- #include <cstring>
-
- // 错误处理函数
- void handleOpenSSLErrors();
-
- // 生成SM2密钥对
- EVP_PKEY* generateSM2KeyPair();
-
- // SM2签名
- bool sm2Sign(EVP_PKEY* pkey, const unsigned char* data, size_t dataLen, unsigned char** sig, size_t* sigLen);
-
- #endif // SM2_H
- #include <stdio.h>
- #include <stdlib.h>
- #include "POperation.h"
-
- //typedef struct {
- // long long x;
- // long long y;
- //} Point;
- //
- //typedef struct {
- // long long a, b; // 曲线参数 y^2 = x^3 + ax + b
- // long long p; // 有限域的素数
- //} EllipticCurve;
-
- // 模逆运算
- long long mod_inverse(long long a, long long m) {
- long long m0 = m, t, q;
- long long x0 = 0, x1 = 1;
-
- if (m == 1) {
- return 0;
- }
-
- while (a > 1) {
- q = a / m;
- t = m;
- m = a % m, a = t;
- t = x0;
- x0 = x1 - q * x0;
- x1 = t;
- }
-
- if (x1 < 0) {
- x1 += m0;
- }
-
- return x1;
- }
-
- // 点加运算
- Point point_add(Point P, Point Q, EllipticCurve ec) {
- Point R;
-
- if (P.x == Q.x && P.y == Q.y) { // 点倍运算
- if (P.y == 0) {
- R.x = 0;
- R.y = 0;
- return R;
- }
-
- long long s = (3 * P.x * P.x + ec.a) * mod_inverse(2 * P.y, ec.p) % ec.p;
- R.x = (s * s - 2 * P.x) % ec.p;
- R.y = (s * (P.x - R.x) - P.y) % ec.p;
- }
- else { // 一般点加运算
- if (P.x == Q.x) {
- R.x = 0;
- R.y = 0;
- return R;
- }
-
- long long s = (Q.y - P.y) * mod_inverse(Q.x - P.x, ec.p) % ec.p;
- R.x = (s * s - P.x - Q.x) % ec.p;
- R.y = (s * (P.x - R.x) - P.y) % ec.p;
- }
-
- R.x = (R.x + ec.p) % ec.p;
- R.y = (R.y + ec.p) % ec.p;
- return R;
- }
-
- // 点乘运算
- Point point_multiply(long long scalar, Point P, EllipticCurve ec) {
- Point result = { 0, 0 }; // 无穷远点
- Point temp = P;
-
- while (scalar != 0) {
- if (scalar % 2 != 0) {
- if (result.x == 0 && result.y == 0) {
- result = temp;
- }
- else {
- result = point_add(result, temp, ec);
- }
- }
-
- temp = point_add(temp, temp, ec);
- scalar /= 2;
- }
-
- return result;
- }
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include "POperation.h" // 假设之前定义的椭圆曲线结构和函数在这个头文件中
- #include "ECDSA.h"
-
- // 简单的哈希函数(仅用于示例)
- long long simple_hash(char* message) {
- long long hash = 0;
- while (*message) {
- hash = (hash * 31 + *message) % LONG_MAX;
- message++;
- }
- return hash;
- }
-
- void ecdsa_sign(char* message, long long d, EllipticCurve ec, Point G, long long n, long long* r, long long* s) {
- long long z = simple_hash(message); // 获取消息的哈希值
-
- long long k, x1, y1;
- do {
- k = rand() % (n - 1) + 1; // 随机数 k
- Point kG = point_multiply(k, G, ec); // 计算 k * G
- x1 = kG.x; y1 = kG.y;
-
- *r = x1 % n;
- } while (*r == 0);
-
- long long k_inv = mod_inverse(k, n);
- *s = (k_inv * (z + *r * d)) % n;
-
- if (*s == 0) {
- ecdsa_sign(message, d, ec, G, n, r, s); // 如果 s 为 0,则重新签名
- }
- }
-
-
- int ecdsa_verify(char* message, Point Q, EllipticCurve ec, Point G, long long n, long long r, long long s) {
- if (r <= 0 || r >= n || s <= 0 || s >= n) {
- return 0; // 验证 r 和 s 是否在合法范围内
- }
-
- long long z = simple_hash(message); // 获取消息的哈希值
-
- long long w = mod_inverse(s, n);
- long long u1 = (z * w) % n;
- long long u2 = (r * w) % n;
-
- Point u1G = point_multiply(u1, G, ec);
- Point u2Q = point_multiply(u2, Q, ec);
- Point P = point_add(u1G, u2Q, ec);
-
- if (P.x == LONG_MAX && P.y == LONG_MAX) {
- return 0; // 如果 P 是无穷远点
- }
-
- return (P.x % n == r); // 验证 r 是否等于 P.x mod n
- }
-
-
-
-
-
- #include <gmpxx.h>
- #include <cstdlib>
- #include <ctime>
- #include <vector>
- #include <iostream>
- #include "ElGamal.h"
-
- using namespace std;
-
- // 检测原根
- bool is_primitive_root(const mpz_class& g, const mpz_class& p) {
- vector<mpz_class> factors;
- mpz_class phi = p - 1;
- mpz_class n = phi;
-
- // 计算p - 1的所有质因数
- for (mpz_class i = 2; i * i <= n; ++i) {
- if (n % i == 0) {
- factors.push_back(i);
- while (n % i == 0)
- n /= i;
- }
- }
- if (n > 1)
- factors.push_back(n);
-
- for (mpz_class factor : factors) {
- mpz_class res;
- mpz_powm(res.get_mpz_t(), g.get_mpz_t(), mpz_class(phi / factor).get_mpz_t(), p.get_mpz_t());
- if (res == 1)
- return false;
- }
- return true;
- }
-
-
-
- // 生成大质数和其原根
- void generate_prime_and_primitive_root(mpz_class& p, mpz_class& g) {
- // 生成大质数
- gmp_randclass rr(gmp_randinit_default);
- rr.seed(time(NULL));
- p = rr.get_z_bits(512);
- mpz_nextprime(p.get_mpz_t(), p.get_mpz_t());
-
- // 寻找原根
- g = 2;
- while (!is_primitive_root(g, p))
- g += 1;
- }
-
- // 生成公钥和私钥
- void generate_keys(mpz_class& p, mpz_class& g, mpz_class& y, mpz_class& x) {
- // 随机生成大质数p和其原根g
- // 由于寻找原根的效率问题,这里简化为固定的质数和原根
- p = 23; // 实际应用中应该是大质数
- g = 5; // 实际应用中应该是p的原根
-
- // 随机选择私钥x
- x = rand() % (p - 2) + 1;
-
- // 计算公钥y
- mpz_powm(y.get_mpz_t(), g.get_mpz_t(), x.get_mpz_t(), p.get_mpz_t());
- }
-
- // 加密
- void encrypt(const mpz_class& p, const mpz_class& g, const mpz_class& y, const mpz_class& m, mpz_class& c1, mpz_class& c2) {
- mpz_class k = rand() % (p - 1) + 1; // 随机选择k
- mpz_class s;
-
- // 计算c1
- mpz_powm(c1.get_mpz_t(), g.get_mpz_t(), k.get_mpz_t(), p.get_mpz_t());
- // 计算s (共享密钥)
- mpz_powm(s.get_mpz_t(), y.get_mpz_t(), k.get_mpz_t(), p.get_mpz_t());
- // 计算c2
- c2 = (m * s) % p;
- }
-
- // 解密
- void decrypt(const mpz_class& p, const mpz_class& x, const mpz_class& c1, const mpz_class& c2, mpz_class& m) {
- mpz_class s, s_inv;
-
- // 计算s (共享密钥)
- mpz_powm(s.get_mpz_t(), c1.get_mpz_t(), x.get_mpz_t(), p.get_mpz_t());
- // 计算s的逆
- mpz_invert(s_inv.get_mpz_t(), s.get_mpz_t(), p.get_mpz_t());
- // 解密消息
- m = (c2 * s_inv) % p;
- }
- #include "openssl/evp.h"
- #include "openssl/ec.h"
- #include "openssl/pem.h"
-
- #include <iostream>
- #include <cstring>
- #include "SM2.h"
-
-
- // 错误处理
- void handleOpenSSLErrors() {
- ERR_print_errors_fp(stderr);
- abort
- ();
- }
-
- // 生成SM2密钥对
- EVP_PKEY* generateSM2KeyPair() {
- EVP_PKEY_CTX* pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, nullptr);
- EVP_PKEY* pkey = nullptr;
- if (EVP_PKEY_keygen_init(pctx) <= 0) {
- handleOpenSSLErrors();
- }
-
- if (EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, NID_sm2) <= 0) {
- handleOpenSSLErrors();
- }
-
- if (EVP_PKEY_keygen(pctx, &pkey) <= 0) {
- handleOpenSSLErrors();
- }
-
- EVP_PKEY_CTX_free(pctx);
- return pkey;
- }
-
- // SM2签名
- bool sm2Sign(EVP_PKEY* pkey, const unsigned char* data, size_t dataLen, unsigned char** sig, size_t* sigLen) {
- EVP_MD_CTX* mdctx = EVP_MD_CTX_new();
- EVP_PKEY_CTX* pctx = nullptr;
- bool result = false;
- if (EVP_DigestSignInit(mdctx, &pctx, EVP_sm3(), nullptr, pkey) <= 0) {
- handleOpenSSLErrors();
- }
-
- if (EVP_DigestSign(mdctx, nullptr, sigLen, data, dataLen) <= 0) {
- handleOpenSSLErrors();
- }
-
- *sig = (unsigned char*)OPENSSL_malloc(*sigLen);
- if (EVP_DigestSign(mdctx, *sig, sigLen, data, dataLen) <= 0) {
- handleOpenSSLErrors();
- }
- else {
- result = true;
- }
-
- EVP_MD_CTX_free(mdctx);
- return result;
- }
- main.c
- //#include "ecc.h"
- //#include <stdio.h>
- //
- //int main() {
- // EllipticCurve ec = {/* 初始化曲线参数 */ };
- // Point p = {/* 初始化点 */ };
- //
- // // 测试点乘
- // Point result = point_multiply(2, p, ec);
- // printf("Result of Point Multiply: (%lld, %lld)\n", result.x, result.y);
- //
- // // 测试ECDSA签名和验证
- //
- // return 0;
- //}
-
- #include<cstdio>
- #include <gmp.h>
- #include <time.h>
- //#include "openssl/ec.h"
- //#include "openssl/evp.h"
-
- #include "POperation.h"
- #include "SM2.h"
- #include "ECDSA.h"
- #include "ElGamal.h"
-
- #define P "23"
- #define G "5"
-
-
- int main() {
- 示例:定义椭圆曲线参数和点
- //EllipticCurve ec = { 1, 6, 11 }; // 曲线 y² = x³ + x + 6 (mod 11)
- //Point P = { 2, 4 }; // 初始点
- 执行点乘运算
- //Point Q = point_multiply(3, P, ec);
- //printf("3P = (%lld, %lld)\n", Q.x, Q.y);
-
- 执行点加运算
- //Point R = point_add(P, Q, ec);
- //printf("P + 3P = (%lld, %lld)\n", R.x, R.y);
-
-
-
- //auto key = EC_KEY_new_by_curve_name(NID_secp256k1);
- //EC_KEY_generate_key(key);
-
- //unsigned char* pub_key = nullptr;
-
- //auto size = i2o_ECPublicKey(key, &pub_key);
- //for (int i = 0; i < size; ++i) {
- // std::printf("%02x", pub_key[i]);
- //}
-
- // EC_KEY_free(key);
-
-
-
-
-
-
-
-
-
- ECDSA sign and verify
- // // 定义椭圆曲线参数(简化版secp256k1)
- //EllipticCurve ec = { 0, 7, 17 }; // y^2 = x^3 + 7 (mod 17)
- //Point G = { 1, 1 }; // 基点G
- //long long n = 19; // 基点的阶
-
- 定义私钥(随机选取,但必须小于n)
- //long long d = 13; // 私钥
-
- 计算公钥
- //Point Q = point_multiply(d, G, ec);
-
- 要签名的消息
- //char message[] = "Hello, ECDSA!";
-
- 签名
- //long long r, s;
- //ecdsa_sign(message, d, ec, G, n, &r, &s);
- //printf("Signature:\n");
- //printf("r: %lld\n", r);
- //printf("s: %lld\n", s);
-
- 验证
- //int valid = ecdsa_verify(message, Q, ec, G, n, r, s);
- //if (valid) {
- // printf("Signature is valid.\n");
- //}
- //else {
- // printf("Signature is invalid.\n");
- //}
-
-
-
- SM2加密和签名
- //OpenSSL_add_all_algorithms();
- //ERR_load_crypto_strings();
- 生成密钥对
- //EVP_PKEY* pkey = generateSM2KeyPair();
-
- 要签名的数据
- //const char* data = "Hello, SM2!";
- //unsigned char* sig = nullptr;
- //size_t sigLen = 0;
-
- 签名
- //if (sm2Sign(pkey, (const unsigned char*)data, strlen(data), &sig, &sigLen)) {
- // std::cout << "Signature successful!" << std::endl;
- //}
- //else {
- // std::cout << "Signature failed!" << std::endl;
- //}
-
- 清理
- //OPENSSL_free(sig);
- //EVP_PKEY_free(pkey);
- //EVP_cleanup();
- //ERR_free_strings();
-
-
-
-
- //ElGamal测试
- mpz_t p, g, x, y, m, c1, c2, decrypted_m;
- mpz_inits(p, g, x, y, m, c1, c2, decrypted_m, NULL);
-
- // 设置p和g
- mpz_set_str(p, P, 10);
- mpz_set_str(g, G, 10);
-
- // 生成密钥
- generate_keys(p, g, x, y);
- gmp_printf("Public Key (y): %Zd\n", y);
- gmp_printf("Private Key (x): %Zd\n", x);
-
- // 设置消息m
- mpz_set_ui(m, 13); // 设置一个示例消息
-
- // 加密消息
- encrypt(p, g, y, m, c1, c2);
- gmp_printf("Encrypted Message (c1, c2): (%Zd, %Zd)\n", c1, c2);
-
- // 解密消息
- decrypt(p, x, c1, c2, decrypted_m);
- gmp_printf("Decrypted Message: %Zd\n", decrypted_m);
-
- mpz_clears(p, g, x, y, m, c1, c2, decrypted_m, NULL);
-
-
- return 0;
- }
-
-
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。