• 611KB weixin_44219914 2020-04-15 12:30:41
• 1.头文件部分#include #include #include 2.判断大数是不是0或1参见《C语言实现...先乘积后取模的函数int big_num_mul_mod(unsigned long *a, unsigned long *b, unsigned long *c, unsigned long *s, int len){unsi...

1.头文件部分
#include
#include
#include
2.判断大数是不是0或1
参见《C语言实现RSA算法》
3.大数加减乘除幂模
参见《C语言实现RSA算法》
4.先乘积后取模的函数
int big_num_mul_mod(unsigned long *a, unsigned long *b, unsigned long *c, unsigned long *s, int len)
{
unsigned long d[2*len];
unsigned long e[2*len];
unsigned long f[2*len];
memset(d, 0x00, sizeof(d));
memset(e, 0x00, sizeof(e));
memset(f, 0x00, sizeof(f));
memcpy(e+len, c, 4*len);
big_num_mul(a, b, d, len);
big_num_mod(d, e, f, 2*len);
memcpy(s, f+len, 4*len);
return 0;
}
5.根据私钥求公钥
int dsa_get_key(unsigned long *p, unsigned long *q, unsigned long *h, unsigned long *g, unsigned long *x, unsigned long *y, int len)
{
unsigned long a[len];
unsigned long b[len];
memset(a, 0x00, sizeof(a));
memset(b, 0x00, sizeof(b));
a[len-1] = 1;
printf("key p: ");
print_num(p, len);
printf("key a: ");
print_num(a, len);
big_num_sub(p, a, b, len);
a[len-1] = 0;
big_num_div(b, q, a, len);
big_num_pow_mod(h, a, p, g, len);
big_num_pow_mod(g, x, p, y, len);
printf("key g: ");
print_num(g, len);
printf("key y: ");
print_num(y, len);
return 0;
}
6.签名函数
int dsa_set_sig(unsigned long *p, unsigned long *q, unsigned long *g, unsigned long *x, unsigned long *k, unsigned long *m, unsigned long *r, unsigned long *s, int len)
{
unsigned long a[len];
unsigned long b[len];
unsigned long c[len];
unsigned long d[len];
unsigned long e[len];
unsigned long f[len];
memset(a, 0x00, sizeof(a));
memset(b, 0x00, sizeof(b));
memset(c, 0x00, sizeof(c));
memset(d, 0x00, sizeof(d));
memset(e, 0x00, sizeof(e));
memset(f, 0x00, sizeof(f));
big_num_pow_mod(g, k, p, a, len);
printf("step 1 end\n");
big_num_mod(a, q, r, len);
printf("step 2 end\n");
big_num_mod_inv(k, q, b, len);
printf("step 3 end\n");
big_num_mul_mod(x, r, q, c, len);
printf("step 4 end\n");
big_num_mod(m, q, d, len);
printf("step 5 end\n");
big_num_add(c, d, e, len);
printf("step 6 end\n");
big_num_mod(e, q, f, len);
printf("step 7 end\n");
big_num_mul_mod(b, f, q, s, len);
printf("step 8 end\n");
printf("key m: ");
print_num(m, len);
printf("key r: ");
print_num(r, len);
printf("key s: ");
print_num(s, len);
return 0;
}
7.签名验证函数
int dsa_verify_sig(unsigned long *p, unsigned long *q, unsigned long *g, unsigned long *y, unsigned long *m, unsigned long *r, unsigned long *s, unsigned long *v, int len)
{
unsigned long a[len];
unsigned long b[len];
unsigned long c[len];
unsigned long d[len];
unsigned long e[len];
unsigned long f[len];
memset(a, 0x00, sizeof(a));
memset(b, 0x00, sizeof(b));
memset(c, 0x00, sizeof(c));
memset(d, 0x00, sizeof(d));
memset(e, 0x00, sizeof(e));
memset(f, 0x00, sizeof(f));
big_num_mod_inv(s, q, a, len);
printf("verify step 3 end\n");
big_num_mul_mod(d, e, p, f, len);
printf("verify step 6 end\n");
big_num_mod(f, q, v, len);
printf("verify step 7 end\n");
return 0;
}
8.主函数部分
int main()
{
unsigned long p[16] = {0x41C416C1, 0x59C0E918, 0xB16668C4, 0x93481D71, 0x1EF64AF5, 0xC9BC2A23, 0x671494D1, 0x9512D773, 0x103C7497, 0xB53ABB51, 0x7CF0EAD2, 0x86F8A8F3, 0x5862D58A, 0x82095489, 0x0A64A7DA, 0xFD3CD307};
unsigned long q[16] = {0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xE342DAC7, 0x8043EFD8, 0x93AA3A8C, 0x43CB20CE, 0x4FFD13FF};
unsigned long h[16] = {0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x1f25dbcb, 0x8cc6d056, 0x9fff2a9c, 0xc4cc8be6, 0xefdba4d1};
//unsigned long g[16] = {0};
unsigned long x[16] = {0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x90f755d3, 0xb2719345, 0x15098119, 0x6ef74fe8, 0x0104f1f2};
//unsigned long y[16] = {0};
unsigned long g[16] = {0x18C0EB49, 0xA18E9A74, 0x4D119F13, 0x08A5AFCF, 0x5152747A, 0x2F9C9144, 0x1ED48DC3, 0xEFB05F2B, 0x194063CE, 0x77602605, 0x88C098CB, 0x13F80BA5, 0x3C3BBB93, 0xC9BA32FA, 0x4C14A3D2, 0xAB1A8623};
unsigned long y[16] = {0x288FA8BB, 0x4F783D45, 0x514E0C7C, 0x13629F03, 0xDDD82F3A, 0xECBE5337, 0xBFF9FF4A, 0x55945ADA, 0xFBF36083, 0xC68436BA, 0x48649C41, 0x31B647FC, 0x815019DB, 0x105A9B85, 0xCB7C670E, 0xA6A0A615};
unsigned long k[16] = {0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x7ce0b2c4, 0x7ec535c0, 0x40a64a18, 0xc5f6f450, 0xf0868e30};
unsigned long u[16] = {0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xac01065b, 0xcf974ba9, 0x86c84f0f, 0x335180e0, 0x9a65e139};
unsigned long v[16] = {0};
unsigned long r[16] = {0};
unsigned long s[16] = {0};
int len = 16;
printf("key p: ");
print_num(p, len);
//dsa_get_key(p, q, h, g, x, y, len);
dsa_set_sig(p, q, g, x, k, u, r, s, len);
dsa_verify_sig(p, q, g, y, u, r, s, v, len);
printf("key m: ");
print_num(u, len);
printf("key r: ");
print_num(r, len);
printf("key s: ");
print_num(s, len);
printf("key v: ");
print_num(v, len);
return 0;
}

展开全文
weixin_39622568 2021-05-20 06:29:15
• ## DSA:用C ++实现标准数据结构和算法-源码 C++

534KB weixin_42136791 2021-04-09 02:12:04
• Digital Signature Algorithm (DSA)是Schnorr和ElGamal签名算法的变种，被美国NIST作为DSS(DigitalSignature Standard)。(文尾梳理了对不同消息M,重用k时候带来的威胁..)算法描述:参数: 全局公钥为 {p, q, g, y} :p ...

Digital Signature Algorithm (DSA)是Schnorr和ElGamal签名算法的变种，被美国NIST作为DSS(DigitalSignature Standard)。
(文尾梳理了对不同消息M,重用k时候带来的威胁..)
算法描述:
参数: 全局公钥为 {p, q, g, y} :
p : L bits长的素数.L是64倍数,范围[512, 1024]
q : p - 1的160bits素因子
g : g = h^((p-1)/q) mod p
其中 h满足h < p - 1, h^((p-1)/q) mod p > 1
x : x < q, x 为私钥
y : y = g^x mod p
签名过程
对于报文m, 挑选秘密随机数k: k ∈ (0, q)
r = ( g^k mod p ) mod q
s = ( k^(-1) (H(m) + xr)) mod q
签名结果即为(m, r, s)
验算过程
w = s^(-1)mod q
a = ( H( m ) * w ) mod q
b = ( r * w ) mod q
v = (( g^a * y^b ) mod p ) mod q
若v = r，则认为签名有效。
可以代入参数理一下验算过程
ga = g (H(m)*w)mod q mod p
yb = gx*r*w mod q mod p
则上两式相乘是在mod p条件下的, 指数是在mod q条件下的,下面省略mod运算符
相乘结果(式一) = g(H(m)*w + x*r*w) = gw*(H(m) + x*r)
因为 H(m) + x * r = k * s = s * k 所以 式一 又等于 g(w*s*k)
又因为 w = s-1mod q 所以上式,再加上完整的mod运算符,即
g(k mod p) mod q, 亦即v.
代码实现
这里只列出签名函数的实现. 依赖的库是 NTL 库. 链接在此 下载后安装方法见
For a detailed guide to installation, please see the appropriate documentation:
* doc/tour-unix.html for unix systems
* doc/tour-win.html for Windows and other systems
一般NTL又需要gmp库, 也有教程,在文档
* tour-gmp.html
列几个这里会经常要查询的链接:
这里我的数据存放:
私钥放在 privateKey.data :
x 988656368...
公钥放在 publicKey.data :
p 344457347...
q 169861902...
...
即,先是一个标识,后是数据,方便代码理解(简书不能折叠显得好冗长..也没太多理解的地方..当作是熟悉一下NTL...)
SHA-3的接口,项目官网上的尝试了很久都失败了..包括make pack等等等等..
最终是改写了一下这里的SHA-3实现, 得到了一个能方便#include后调用返回hash值的函数.
只给出签名函数了,因为简单的计算意义不大,函数在上面链接可查:
void signing(char* fileName) {
string fileDir = "./key/publicKey.data";
fstream pubf(fileDir, ios::in);
/* checkFile是一个简单的封装的检查文件状态的函数*/
if (!checkFile(pubf, fileDir))
return;
fileDir = "./key/privateKey.data";
fstream prif(fileDir, ios::in);
if (!checkFile(prif, fileDir))
return;
pubf.seekg(0);
prif.seekg(0);
char tmp;
pubf >> tmp >> p >> tmp >> q >> tmp >> g >> tmp >> y;
prif >> tmp >> x;
pubf.close();
prif.close();
ZZ k, r, s, hm;
hm = getHash(fileName);
/*k -> (0, q - 1)*/
k = RandomBnd(q - 1) + 1;
r = PowerMod(g, k, p) % q;
s = (InvMod(k, q) * (hm + x * r)) % q;
fileDir = "./signatureResult.data";
fstream resf(fileDir, ios::out);
if (!resf.is_open()) {
cerr << "create ./signatureResult.data failed" << endl;
return;
}
resf << "r " << r << "\n"
<< "s " << s << "\n";
resf.close();
fprintf(stdout,
"----------------------------------------\n"
" digital signature done ! \n"
" in file : ./signatureResult.data \n"
"----------------------------------------\n"
);
}
注意几个地方 :
p是一个大素数,q是p-1的素因子,我选择的方法是: 先得到一个素数q,再去找素数p. 其次我的q并非160bits, 而是比H(m) 和 x,r都大,即满足指数在域内可逆的一个更大的素数.
对于不同消息M1,M2 重用私密随机数k带来的威胁

OTZ
考试的时候没写出来..额..额..额...额! 额..
记录2种解法(我不...只..搬运工):
[1] 解方程法:
对于报文m, 挑选秘密随机数k: k ∈ (0, q)
r = ( gk mod p ) mod q
s = ( k-1(H(m) + xr)) mod q
其中x为私钥. 两个消息M1 M2, 即有
{M1, r, s1}, 其中s1 = k-1(H(M1)+xr) % q
{M2, r, s2}, 其中s2 = k-1(H(M2)+xr) % q 则有
式2 : ks1 = H(M1)+xr % q
式3 : ks2 = H(M2)+xr % q
式2 * s2 = 式3 * s1 = ks1s2
即 s1H(M2) + s1xr = s2H(M1) +s2xr
移项,提取公因式即可有
x = (s2H(M1) - s1H(M2))(s1 - s2)-1r-1 % q
其中s都已知,H(x)可自行hash计算,又因为 q是素数,且s1 != s2, 所以(s1-s2)-1是存在的(域的性质,封闭性).当然,r-1也存在.所以上式右边式子所有元素均已知或者可计算,私钥x将会暴露.
[2] 求k再直接通过s求x痛苦没想出来法
s1 - s2 = k-1(H(M1) - H(M2)) % q
k = (H(M1) - H(M2)) * (s1 - s2)-1
这里得到了k
又由 s1 = ( k-1(H(M1) + xr)) mod q
有式子x = (ks1 - H(M1)) r-1
也可以用s2来得x的表达式
同解法一理,右边各元素均可求/已知,所以私钥x将会暴露.
按理说,到这里就该狼狈溜了..
再贴一个小工具吧,挺方便的.解决命令行的参数交互问题. 省得自己写一堆分支和判断..
相关博客 写得挺通俗易懂
大概用起来会是这样:
int main(int argc, char* argv[]) {
int users_option;
puts("");
if (argc == 1) usage();
while ((users_option = getopt(argc, argv, "s:v:gh")) != -1) {
switch (users_option) {
case 's' :
signing(optarg); break;
case 'v' :
verifying(optarg); break;
case 'g' :
generate_key(); break;
case 'h' :
case '?' :
usage(); break;
}
}
return 0;
}

展开全文
weixin_33894125 2021-05-20 15:10:57
• ## DSA数字签名含C语言实例 c语言

DSA数字签名 1994年12月美国国家标准和技术研究所(NIST，National Institute of Standard and Technology)正式颁布了数字签名标 准DSS(Digital Signature Standard)，它是在ElGamal和Schorr 数字签名方案的基础上...
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("不接受");
}

}

展开全文
mlynb 2020-12-03 20:53:52
• 86KB weixin_38719702 2020-11-30 07:17:49
• 《实验三DSA数字签名算法》... DSA算法原理数字签名是数据在公开行信道传输的安全保障，能够实现数据的公开、公正、不可抵赖等特点的方法，只能公开的密钥、密码签名算法。国际供认的公开密钥签字算法主要有RSA算...

《实验三DSA数字签名算法》由会员分享，可在线阅读，更多相关《实验三DSA数字签名算法(8页珍藏版)》请在人人文库网上搜索。
1、实验三 DSA数字签名算法姓 名： 学 号: 学 院： 信息工程学院 指导老师： 郑明辉 1. DSA算法原理数字签名是数据在公开行信道中传输的安全保障，能够实现数据的公开、公正、不可抵赖等特点的方法，只能公开的密钥、密码签名算法。国际供认的公开密钥签字算法主要有RSA算法、ElGAMAL算法或者其变形的签名算法。DSA(Digite Signature Arithmotic )是Schnore和ElGamal算法的变型。美国国家标准技术研究所(NIST)1994年5月19日公布了数字签名标准的(DSS),标准采用的算法便是DSA，密钥长度为5121024位。密钥长度愈长，签名速度愈慢，制约运。
2、算速度的只要因素是大数的模指数运算。2. DSA签名中的参数参数描述：Digital Signature Algorithm (DSA)是Schnorr和ElGamal签名算法的变种，被美国NIST作为DSS(DigitalSignature Standard)。算法中应用了下述参数： p：L bits长的素数。L是64的倍数，范围是512到1024； q：p - 1的160bits的素因子； g：g = h(p-1)/q) mod p，h满足h 1； x：x #include #include BigInt.h#include sha1.h#include time.hint shas1(c。
3、onst unsigned int x, unsigned char digest20)SHA1_CTX context;unsigned char buffer16384; /,digest20;/FILE *file; SHA1Init(&context);SHA1Update(&context, buffer, 1);SHA1Final(digest, &context);return 0;CBigInt sha(CBigInt y)SHA1_CTX context;CBigInt X;unsigned char buffer16384,digest20;CString str;char。
4、 *t=0123456789ABCDEF;if(y.m_nLength=1)&(y.m_ulValue0=0)str=0;X.Mov(0);return X;str=;int a;char ch=0;str.Insert(0,ch);X.Mov(y);while(X.m_ulValueX.m_nLength-10)a=X.Mod(16);ch=ta;str.Insert(0,ch);X.Mov(X.Div(16);int i=0;while (stri0) i+;for (a=i,i=0;i=0)&(digesti=A)&(digesti=a)&(digesti0)if (y%2=0) q.M。
5、ov(q.Mul(q); y /= 2 ; else p.Mov(p.Mul(q); y -= 1; return p;CBigInt pow3(CBigInt x, CBigInt y, CBigInt m)CBigInt p,t;p.Mov(1);t.Mov(0);while (y.Cmp(t)0)if (y.m_ulValue0&0x1=0) x.Mov(x.Mul(x); x.Mov(x.Mod(m); x.Mov(x.Div(2); else p.Mov(p.Mul(x); p.Mov(p.Mod(m); y.Mov(y.Sub(1); return p;4. 过程及结果截图描述开始运行选择512位密钥长度，点击公开参数，如下图随便选择一个你要签名的文件，然后选择算法点击数字签名然后点击签名验证(注：文档可能无法思考全面，请浏览后下载，供参考。可复制、编制，期待你的好评与关注。

展开全文
weixin_42521856 2021-05-20 15:10:17
• 3.62MB zzjniatnh 2020-10-09 18:33:46
• 124KB weixin_42160376 2021-03-28 15:59:31
• 167KB weixin_42099176 2021-05-07 03:06:31
• ## DSA签名算法的C#实现 c#

4星
32KB davinciyxw 2015-11-06 16:57:08
• ## DSA-源码 C

2KB weixin_42118160 2021-03-05 17:48:41
• weixin_33447647 2021-05-20 15:10:15
• ## c代码-DSA学习中....... 代码

979B weixin_38659248 2021-07-16 13:16:57
• ## 学习dsa-源码 C

2KB weixin_42149145 2021-02-16 21:40:05
• ## dsa程序-源码 C

273KB weixin_42131601 2021-02-11 03:17:35
• ## dsa:使用Golang练习DSA-源码 Go

1.13MB weixin_42121058 2021-03-08 05:51:23
• ## dsa：C ++中的数据结构和算法-源码 Assembly

5.23MB weixin_42129970 2021-02-23 07:08:51
• 79KB weixin_42132056 2021-03-13 21:39:44
• weixin_39779537 2021-01-14 15:39:51
• 30KB weixin_38602982 2021-06-30 17:51:32
• 2KB weixin_42134878 2021-02-23 04:18:58
• ## College-DSA:一所大学|| DSA by Ravi Sir || C语言-源码 C

5KB weixin_42127748 2021-03-13 14:02:26
• ## cdsaext:C DSA扩展-开源 开源软件

5KB weixin_42123191 2021-04-24 22:00:39
• 69KB weixin_42119281 2021-03-19 02:14:58
• ## java中的DSA数据转换 dsa的java实现

weixin_31958413 2021-03-14 03:45:01
• ## dsa_lab_codes-源码 C

1.27MB weixin_42125192 2021-06-02 01:58:25
• 1.87MB weixin_42117116 2021-05-16 17:41:35

...