C语言--椭圆曲线加密

C语言椭圆曲线加密算法

椭圆曲线加密算法简易的实现,主要就是针对点对点之间的转换

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <windows.h>

void MultipleP(int P[2], int multiple, int a, int b, int p, int A[2]);
void AddPandQ(int P[2], int Q[2], int a, int b, int p, int P_Q[2]);
int mod_invese(int d, int n);

int main(void)
{
    int a;
    int b;
    int p;
    int x;
    int y;
    int k;
    int i = 0;
    int multiple;
    int feature;
    int P[2], Q[2], P_Q[2], G[2], kPa[2], kG[2];
    double run_time;
    double dqFreq; //计时器频率
    while (1)
    {
        printf("\n请输入所选择的功能:1.求椭圆曲线上的所有点\t2.求点与点的加法运算\t3.求点的倍数运算\t4.加解密运算\t5.退出程序!\nInput the feature you want:");
        scanf("%d", &feature);
        if (feature == 5)
        {
            return 0;
            break;
        }
        printf("\n请输入整数a,b以及素数p:");
        scanf("%d%d%d", &a, &b, &p);
        switch (feature)
        {
        case 1:
            printf("\n则椭圆曲线上的所有整点为:\n");
            for (x = 0; x < p - 1; x++)
            {
                for (y = 0; y < p - 1; y++)
                {
                    for (k = -pow(p, 2); k < pow(p, 2); k++)
                    {
                        if ((pow(x, 3) + a * x + b + k * p) == pow(y, 2))
                        {
                            i++;
                            printf(" [%2d,%2d] ", x, y);
                            printf(" [%2d,%2d] ", x, p - y);
                        }
                    }
                }
            }
            printf("\n总计%d个点\n", 2 * i);
            break;
        case 2:
            printf("\n请输入点P:\n");
            for (k = 0; k < 2; k++)
                scanf("%d", &P[k]);
            printf("\n请输入点Q:\n");
            for (k = 0; k < 2; k++)
                scanf("%d", &Q[k]);
            AddPandQ(P, Q, a, b, p, P_Q);
            printf("\nP + Q = (%2d,%2d)", P_Q[0], P_Q[1]);
            break;
        case 3:
            printf("\n请输入点P:\n");
            for (k = 0; k < 2; k++)
                scanf("%d", &P[k]);
            printf("\n请输入要计算的倍数 multiple = ");
            scanf("%d", &multiple);
            MultipleP(P, multiple, a, b, p, P_Q);
            printf("\n%dP = (%2d,%2d)", multiple, P_Q[0], P_Q[1]);
            break;
        case 4:
            P[0] = 201;
            P[1] = 5;
            G[0] = 0;
            G[1] = 376;
            printf("\n公开参数为:(%2d,%2d)\n", a, b);
            printf("\n生成元为:G=(%2d,%2d)\n", G[0], G[1]);
            printf("\nA的公开钥为:Pa=(%2d,%2d)\n", P[0], P[1]);
            printf("\n请输入要发送的消息:Pm:\n");
            for (k = 0; k < 2; k++)
            {
                scanf("%d", &Q[k]);
            }

            LARGE_INTEGER time_start; //开始时间
            LARGE_INTEGER time_over;  //结束时间
            LARGE_INTEGER f;          //计时器频率
            QueryPerformanceFrequency(&f);
            dqFreq = (double)f.QuadPart;
            QueryPerformanceCounter(&time_start); //计时开始

            multiple = 386; // k=rand()%p;
            MultipleP(G, multiple, a, b, p, kG);
            printf("\n%dG = (%2d,%2d)", multiple, kG[0], kG[1]);
            MultipleP(P, multiple, a, b, p, kPa);
            AddPandQ(Q, kPa, a, b, p, P_Q);
            printf("\nPm+kPa=(%2d,%2d)", P_Q[0], P_Q[1]);
            printf("\n密文为:{(%2d,%2d),(%2d,%2d)}", kG[0], kG[1], P_Q[0], P_Q[1]);

            //计时结束
            QueryPerformanceCounter(&time_over); //计时结束
            run_time = 1000000 * (time_over.QuadPart - time_start.QuadPart) / dqFreq;
            printf("\n总计用时: %.2f us\n", run_time);
            break;
        default:
            printf("\n请输入正确的功能编号!\n");
            break;
        }
    }
}

void MultipleP(int P[2], int multiple, int a, int b, int p, int P_Q[2])
{
    int k, i;
    int Q[2];
    for (i = 0; i < 2; i++)
    {
        Q[i] = P[i];
    }
    for (k = 0; k < multiple - 1; k++)
    {
        AddPandQ(P, Q, a, b, p, P_Q);
        for (i = 0; i < 2; i++)
        {
            Q[i] = P_Q[i];
        }
        // printf("\n%dPa=(%2d, %2d)", k + 2, P_Q[0], P_Q[1]);
    }
}

void AddPandQ(int P[2], int Q[2], int a, int b, int p, int P_Q[2])
{
    int k;
    int lamada_1, lamada_2, lamada;
    if (P[0] == Q[0] && P[1] == Q[1])
    {
        lamada_1 = 3 * P[0] * P[0] + a;
        lamada_2 = 2 * P[1];
    }
    else
    {
        lamada_1 = Q[1] - P[1];
        lamada_2 = Q[0] - P[0];
        // printf("\nlamada_1=%d", lamada_1);
        // printf("\nlamada_2=%d", lamada_2);
    }
    if (lamada_2 != 0)
    {
        if (floor((double)(lamada_1 / lamada_2) + 0.5) != (double)lamada_1 / lamada_2)
        {
            k = mod_invese(lamada_2, p);
            if (lamada_2 < 0)
                lamada = -lamada_1 * k;
            else
                lamada = lamada_1 * k;
            lamada = lamada >= 0 ? lamada % p : lamada % p + p;
            // printf("\nlamada=%d", lamada);
        }
        else
        {
            lamada = lamada_1 / lamada_2 > 0 ? (lamada_1 / lamada_2) % p : (lamada_1 / lamada_2) % p + p;
        }
        P_Q[0] = lamada * lamada - P[0] - Q[0];
        P_Q[0] = P_Q[0] > 0 ? P_Q[0] % p : P_Q[0] % p + p;
        P_Q[1] = lamada * (P[0] - P_Q[0]) - P[1];
        P_Q[1] = P_Q[1] >= 0 ? P_Q[1] % p : P_Q[1] % p + p;
        // printf("\nlamada=%d", lamada);
        // printf("\nP_Q[0]=%d", P_Q[0]);
        // printf("\nP_Q[1]=%d", P_Q[1]);
    }
    else if (lamada_2 == 0)
    {
        P_Q[0] = p;
        P_Q[1] = p;
    }
}

int mod_invese(int d, int n) //求d模n的逆,n 为正整数
{
    int a; //被除数
    int b; //除数
    int q; //商
    int r;
    int u = 0;
    int v = 1;
    int t;
    a = n;
    b = (d >= 0) ? (d % n) : -(d % n); //规定正负数mod(n)都取正;
    while (b != 0)
    {
        q = (int)a / b;
        r = a - b * q;
        a = b;
        b = r;
        t = v;
        v = u - q * v;
        u = t; //把每次没有进行运算的v的值给u
    }          //辗转相除,直到余数b=0,跳出循环
    if (a != 1)
        return 0;
    return ((u < 0) ? u + n : u); //返回的值都是mod(n)后的值,使得最后的值是正数;
}
  • 1
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
椭圆曲线加密是一种公钥加密算法,它基于椭圆曲线上的离散对数问题。下面是一个简单的用c语言实现椭圆曲线加密的示例代码: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <openssl/ec.h> #include <openssl/ecdsa.h> #include <openssl/obj_mac.h> #include <openssl/rand.h> int main() { EC_KEY *key; EC_GROUP *group; EC_POINT *pub_key; unsigned char *msg = "Hello World"; unsigned char hash[SHA256_DIGEST_LENGTH]; unsigned char sig[128]; unsigned int sig_len; // 初始化EC_KEY对象 key = EC_KEY_new_by_curve_name(NID_secp256k1); if (key == NULL) { printf("Error: failed to create EC_KEY object.\n"); return -1; } // 生成密钥对 if (!EC_KEY_generate_key(key)) { printf("Error: failed to generate EC key pair.\n"); return -1; } // 获取椭圆曲线群 group = EC_KEY_get0_group(key); if (group == NULL) { printf("Error: failed to get EC group.\n"); return -1; } // 生成公钥 pub_key = EC_POINT_new(group); if (pub_key == NULL) { printf("Error: failed to create EC_POINT object.\n"); return -1; } if (!EC_POINT_copy(pub_key, EC_KEY_get0_public_key(key))) { printf("Error: failed to copy public key.\n"); return -1; } // 计算消息的哈希值 SHA256(msg, strlen(msg), hash); // 签名 sig_len = sizeof(sig); if (!ECDSA_sign(0, hash, sizeof(hash), sig, &sig_len, key)) { printf("Error: failed to sign message.\n"); return -1; } // 验证签名 if (!ECDSA_verify(0, hash, sizeof(hash), sig, sig_len, pub_key)) { printf("Error: signature verification failed.\n"); return -1; } printf("Signature verified successfully.\n"); // 释放内存 EC_KEY_free(key); EC_POINT_free(pub_key); return 0; } ``` 上面的示例代码使用了OpenSSL库来实现椭圆曲线加密。它生成一个secp256k1曲线的密钥对,对一个字符串消息进行签名,并验证签名的正确性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值