elgamal签名算法c语言,elgamal数字签名方案

Elgamal算法由T.E1Gamal在1985年发表的一篇论文中提出,是Rabin体制的一种变型。其修正形式已被美国国家标准技术研究所作为数字签名标准(DS),其核心就是著名是数字签名方法(DSA)。与RSA密码体系既可以用于公钥加密又可以用于数字签名等计划。E1gamal数字签名计划是专门为数字签名的意图而规划的。后来有很多变型的Elgamal签名计划被提出。在1989年,Schnorr提出了一种可看做是Eigamal数字签名计划的变型的一种签名计划,其签名的长度被大大地缩短了。数字签名办法(DSA)是E1Gamal数字签名计划的另外一种变型,它吸收了Schnorr签名计划的一些思维。

Elgamal数字签名算法的理论基础是求解离散对数的困难性。基于离散对数问题的数字签名体制是数字签名体制中最为常用的一类,其中包括 Elgamal签字体制、DSA签字体制、 Okamoto签字体制等。

Elgamal数字签名方案可分为初始化进程(设置体系参数,发生密钥)、签名进程和验证进程三个部分。

1)初始化过程—设置系统参数,产生密钥

p、q为两个大素数,可使Z*q中求解离散对数为困难问题。用户A秘密密钥x∈Z*q;

用户A的公开密钥为y=gx mod p 。

2)签名过程

对于待签名的消息m,用户A执行以下步骤:

(1)计算m的散列值H(m)。

(2)选择随机数k:k∈RZ*p,计算r=gk(mod p)

其中, k∈RZ*q表示k是以Z*p中随机选取的, Z*p=Zp-{0}

(3)计算s=(H(m)-xr)k-1-(mod p-1)。(r,S)即为产生的数字签名。

3)验证过程

接收方在收到消息m和数字签名(r,s)后,先计算H(m)并按下式验证:

Ver(y,(r,s),H(m))=True台→yrrs=gH(m)(mod p)

正确性可由下式证明:

yrrs =grxgks=grx+H(m)-rx=gH(m)(mod p)

4)安全性

该方案的安全性基于求离散对数的困难性。所谓离散对数,就是给定正整数x、y、n求出正整数k(如果存在的话),使y=xk(mod n)。就目前而言,人们还没有找到计算离散对数的快速算法(所谓快速算法,是指其计算复杂性在多项式范围内的算法,即O(logn)k,其中k为常数)。

该计划的安全性根据求离散对数的困难性。所谓离散对数,就是给定正整数x、y、n求出正整数k(如果存在的话),使y=xk(mod n)。就现在而言,人们还没有找到核算离散对数的快速算法(所谓快速算法,是指其核算复杂性在多项式范围内的算法,即O(logn)k,其间k为常数)。

5)应用

此体制专门设计作为签名使用ANSIX9.30-199X已将Eigamal签字体制作为签名标准算法。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是 C 语言实现的 ElGamal 签名算法代码: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include <openssl/bn.h> // 生成公钥和私钥 void generate_keys(BIGNUM *p, BIGNUM *g, BIGNUM *x, BIGNUM *y) { BIGNUM *one = BN_new(); BN_one(one); // 生成私钥 BN_rand_range(x, p); // 生成公钥 BN_mod_exp(y, g, x, p, NULL); BN_free(one); } // 签名 void sign(unsigned char *m, int m_len, BIGNUM *p, BIGNUM *g, BIGNUM *x, BIGNUM *r, BIGNUM *s) { BIGNUM *k = BN_new(); BIGNUM *m_int = BN_new(); BN_bin2bn(m, m_len, m_int); // 生成 k BN_rand_range(k, p); // 计算 r = g^k mod p BN_mod_exp(r, g, k, p, NULL); // 计算 s = (m - x*r) * k^-1 mod (p-1) BIGNUM *temp1 = BN_new(); BIGNUM *temp2 = BN_new(); BN_mod_mul(temp1, x, r, p, NULL); BN_mod_sub(temp2, m_int, temp1, p, NULL); BN_mod_inverse(temp1, k, p-1, NULL); BN_mod_mul(s, temp2, temp1, p-1, NULL); BN_free(k); BN_free(m_int); BN_free(temp1); BN_free(temp2); } // 验证签名 int verify(unsigned char *m, int m_len, BIGNUM *p, BIGNUM *g, BIGNUM *y, BIGNUM *r, BIGNUM *s) { int valid = 0; BIGNUM *v1 = BN_new(); BIGNUM *v2 = BN_new(); BIGNUM *m_int = BN_new(); BN_bin2bn(m, m_len, m_int); // 计算 v1 = g^m mod p BN_mod_exp(v1, g, m_int, p, NULL); // 计算 v2 = (y^r * r^s) mod p BIGNUM *temp1 = BN_new(); BIGNUM *temp2 = BN_new(); BN_mod_exp(temp1, y, r, p, NULL); BN_mod_exp(temp2, r, s, p, NULL); BN_mod_mul(temp1, temp1, temp2, p, NULL); // 验证 v1 == v2 valid = BN_cmp(v1, temp1) == 0; BN_free(v1); BN_free(v2); BN_free(m_int); BN_free(temp1); BN_free(temp2); return valid; } // 示例 int main() { // 初始化 OpenSSL 大数库 BN_CTX *ctx = BN_CTX_new(); BIGNUM *p = BN_new(); BIGNUM *g = BN_new(); BIGNUM *x = BN_new(); BIGNUM *y = BN_new(); BIGNUM *r = BN_new(); BIGNUM *s = BN_new(); BN_hex2bn(&p, "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" "E485B576625E7EC6F44C42E9A63A3620FFFFFFFFFFFFFFFF"); BN_set_word(g, 2); unsigned char message[] = "Hello, world!"; int message_len = strlen((char*)message); generate_keys(p, g, x, y); sign(message, message_len, p, g, x, r, s); printf("Signature: (r="); BN_print_fp(stdout, r); printf(", s="); BN_print_fp(stdout, s); printf(")\n"); if (verify(message, message_len, p, g, y, r, s)) { printf("Signature is valid.\n"); } else { printf("Signature is invalid.\n"); } // 释放资源 BN_free(p); BN_free(g); BN_free(x); BN_free(y); BN_free(r); BN_free(s); BN_CTX_free(ctx); return 0; } ``` 在示例中,我们使用了 OpenSSL 的大数库来进行精确计算,使用了一个 1024 位的质数 `p`,基于 `g=2` 的 ElGamal 签名算法进行了签名,并验证了签名的有效性。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值