DSA数字签名
1994年12月美国国家标准和技术研究所(NIST,National
Institute of Standard and Technology)正式颁布了数字签名标
准DSS(Digital Signature Standard),它是在ElGamal和Schorr
数字签名方案的基础上设计的。DSS最初建议使用p为512比
特的素数,q为160比特的素数,后来在众多的批评下,NIST
将DSS的密钥p从原来的512比特增加到介于512比特到1024比
特之间。当p选为512比特的素数时,ElGamal签名的长度为
1024比特,而DSS中通过160比特的素数q可将签名的长度降
低为320比特,这就大大地减少了存储空间和传输带宽。由于
DSS具有较大的兼容性和适用性,因此DSS将得到广泛的应用。
数字签名标准DSS中的算法常称为DSA(Digital Signature
Algorithm)。
DSA数字签名算法(初始化)
DSA数字签名算法(签名)
DSA数字签名算法(验证)
DSA数字签名算法(正确性)
DSA数字签名算法(举例)
C语言实例
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
int xy[22];
int myPow(int a, int b, int m) {
int res = 1;
a %= m;
while (b != 0) {
if ((b & 1) == 1)
res = (res * a) % m;
a = (a * a) % m;
b >>= 1;
}
return res;
}
int calculate(int h,int p,int q){
int a = (p-1)/q;
int k=1;
for(int i = 0;i<a;i++){
k=k*h;
}
return k%p;
}
int calculate1(int g,int x,int p){
int k=1;
for(int i = 0;i<x;i++){
k=k*g;
}
return k%p;
}
// 求 a mod b 的逆元
void exGcd(int a, int b) {
if (b == 0) {
xy[0] = 1;
xy[1] = 0;
} else {
exGcd(b, a % b);
int x = xy[0];
xy[0] = xy[1];
xy[1] = x - (a / b) * xy[1];
}
}
main()
{
int p,q,g,x,y,s,k,m,w,u1,u2,v,h,r;
//初始化
printf("请输入大素数 p和q ,且满足(p-1)能够被q整除");
scanf("%d%d",&p,&q);//素数p和q
srand(time(NULL)); //随机数种子
h=12;//rand()%p-1+2 ;//随机数
g=calculate(h,p,q);
x=10;//rand()%p-1+2 ;//私钥
y=calculate1(g,x,p);//计算公钥
printf("公钥是(%d,%d,%d,%d)\n",p,q,g,y);
printf("私钥为%d\n",x);
//签名过程
k=9;//rand()%p-1+2 ;//随机数k
r=calculate1(g,k,p)%q;
exGcd(k, q);
k = xy[0];
if(k < 0) k += (p-1);
m=13;
s=(m+x*r)*k%q;
printf("签名为(%d,%d)\n",r,s);
//验证
exGcd(s,q);
w =xy[0];
if(w < 0) w += (q);
u1=(m*w)%q;
u2=r*w%q;
v=myPow(g, u1, p)*myPow(y, u2, p)%p%q;
printf("(w,u1,u2,v)=(%d,%d,%d,%d)\n",w,u1,u2,v);
if(v==r){
printf("接受");
}else{
printf("不接受");
}
}