/* Implementacija DSA algoritma za digitalan potpis * * (c) Dalibor Dukic duke@x.pbf.hr * Sat Oct 23 13:36:41 CEST 2004 */ #include #include #include #include #include #include #include #include #include "Header/sha1.h" #include "Header/dsa.h" #define SEED_LENGTH 160 #define SEED_LENGTH2 32 #define MASK 0x1 #define SUCCESS 1 #define FAIL 0 #define DEBUG /* deklaracija funkcija */ void DSAKeyGeneration(); void DSASignMessage(const char* ); int DSAVerifySignature(const char* ); void DSAInit(); void DSAClear(); void merror(char* , int ); void HASH(mpz_t* ,const char* ); struct dsa_struct{ mpz_t h; }; struct DSAPubKey_t{ mpz_t p; mpz_t q; mpz_t g; mpz_t y; }DSAPubKey; struct DSAPrivKey_t{ mpz_t x; }DSAPrivKey; struct DSASignature_t{ mpz_t r; mpz_t s; }DSASignature; struct dsa_struct dsa_ctx; gmp_randstate_t state_g; int main(int argc, char* argv[]){ /* inicijaliziraj seed() */ gmp_randinit_lc_2exp_size(state_g, 128); gmp_randseed_ui(state_g, time(NULL) + getpid()); DSAInit(); DSAKeyGeneration(); DSASignMessage(argv[1]); if(DSAVerifySignature(argv[1])) fprintf(stdout," v = r POTPIS JE PRIHVACEN!\n"); else fprintf(stdout," v != r POTPIS NIJE PRIHVACEN!\n"); DSAClear(); return 0; } void DSAInit(){ mpz_init(dsa_ctx.h); /* inicijalizacija javnog kljuca */ mpz_init(DSAPubKey.p); mpz_init(DSAPubKey.q); mpz_init(DSAPubKey.g); mpz_init(DSAPubKey.y); /* inicijalizacija privatnog kljuca */ mpz_init(DSAPrivKey.x); mpz_set_str(dsa_ctx.h , "0x2",0 ); mpz_set_str(DSAPubKey.p , "0x8df2a494 492276aa 3d25759b b06869cb eac0d83afb8d0cf7cbb8324f0d7882e5d0762fc5b7210eafc2e9adac32ab7aac49693dfbf83724c2ec0736ee31c80291" ,0 ); mpz_set_str(DSAPubKey.q , "0xc773218c 737ec8ee 993b4f2d ed30f48e dace915f",0 ); } void DSAClear(){ gmp_randclear(state_g); mpz_clear(dsa_ctx.h); /* housekeeping */ /* javnog kljuca */ mpz_clear(DSAPubKey.p); mpz_clear(DSAPubKey.q); mpz_clear(DSAPubKey.g); mpz_clear(DSAPubKey.y); /* inicijalizacija privatnog kljuca */ mpz_clear(DSAPrivKey.x); } void DSAKeyGeneration(){ fprintf(stdout, "DSA Key Generation\n"); /* g=h^[(p-1)/q]%p */ do{ mpz_sub_ui(DSAPubKey.g, DSAPubKey.p, 1); mpz_divexact(DSAPubKey.g, DSAPubKey.g, DSAPubKey.q); mpz_powm(DSAPubKey.g, dsa_ctx.h, DSAPubKey.g, DSAPubKey.p); mpz_mod(DSAPubKey.g, DSAPubKey.g, DSAPubKey.p); }while(mpz_cmp_d(DSAPubKey.g, 0)==0); /* select random integer x [1, g-1]*/ do{ mpz_urandomm(DSAPrivKey.x, state_g, DSAPubKey.g); }while(mpz_cmp_d(DSAPrivKey.x, 0)==0); /* y=g^x % p */ mpz_powm(DSAPubKey.y, DSAPubKey.g, DSAPrivKey.x, DSAPubKey.p ); gmp_printf(" x -> %Zx\n", DSAPrivKey.x); gmp_printf(" g -> %Zx\n", DSAPubKey.g); gmp_printf(" y -> %Zx\n", DSAPubKey.y); } void DSASignMessage(const char* fname){ fprintf(stdout, "DSA Sign Message\n"); mpz_t MessageDigest; mpz_t temp; mpz_init(MessageDigest); mpz_init(temp); mpz_t k, k_1; mpz_init(k); mpz_init(k_1); /* select random integer k [1, q-1] */ do{ mpz_urandomm(k, state_g, DSAPubKey.q); }while(mpz_cmp_d(k, 0)==0); /* r=(g^k%p)%q */ mpz_powm(temp, DSAPubKey.g, k, DSAPubKey.p); mpz_mod(DSASignature.r, temp, DSAPubKey.q); /* compute k^-1%q */ mpz_invert(k_1, k, DSAPubKey.q); /* s=(k_1(SHA-1(M)+xr))%q */ HASH(&MessageDigest, fname); mpz_mul(temp, DSAPrivKey.x, DSASignature.r); mpz_add(temp, MessageDigest, temp); mpz_mul(temp, k_1, temp); mpz_mod(DSASignature.s, temp, DSAPubKey.q); mpz_clear(k); mpz_clear(k_1); mpz_clear(temp); mpz_clear(MessageDigest); gmp_printf(" r -> %Zx\n", DSASignature.r); gmp_printf(" s -> %Zx\n", DSASignature.s); } int DSAVerifySignature(const char* fname){ fprintf(stdout, "DSA Verify Signature\n"); mpz_t u1; mpz_t u2; mpz_t temp; mpz_t a,b,v,w; mpz_init(u1); mpz_init(u2); mpz_init(a); mpz_init(b); mpz_init(v); mpz_init(temp); mpz_init(w); mpz_t MessageDigest; mpz_init(MessageDigest); /* To verify the signature, Bob first checks to see that * 0 < r < q and 0 < s < q; if either condition is violated the signature * shall be rejected! */ if(mpz_cmp(DSASignature.r, DSAPubKey.q) >= 0) return FAIL; if(mpz_cmp(DSASignature.s, DSAPubKey.q) >= 0) return FAIL; /* w=s^-1%q */ mpz_invert(w, DSASignature.s, DSAPubKey.q); /* u1=((SHA-1(m))w)%q */ HASH(&MessageDigest, fname); mpz_mul(temp, MessageDigest, w); mpz_mod(u1, temp, DSAPubKey.q); /* u2=((r')w)%q */ mpz_mul(temp, DSASignature.r, w ); mpz_mod(u2, temp, DSAPubKey.q); /* v=((g^u1)(y^u2)%p)%q*/ /* (g^u1)%p */ mpz_powm(a, DSAPubKey.g, u1, DSAPubKey.p); /* (y^u2)%p */ mpz_powm(b, DSAPubKey.y, u2, DSAPubKey.p); /* v=(ab)%q */ mpz_mul(temp, a, b); mpz_mod(temp, temp, DSAPubKey.p); mpz_mod(v, temp, DSAPubKey.q); gmp_printf(" w -> %Zx\n", w); gmp_printf(" u1 -> %Zx\n", u1); gmp_printf(" u2 -> %Zx\n", u2); gmp_printf(" v -> %Zx\n", v); if(mpz_cmp(v, DSASignature.r)==0) return TRUE; return FAIL; } void HASH(mpz_t *bighash,const char* fname){ SHA_CTX sha1_ctx; u_int8_t buff[BUFFER_LENGTH]; u_int32_t hash[5]; u_int32_t c; u_int8_t temp; int i; int flag=FALSE; FILE* fp; char string[160+1]; if((fp=fopen( fname,"rb"))==NULL) merror("sha-1 ->", __LINE__); memset(&buff,'\0',BUFFER_LENGTH ); sha1_init(&sha1_ctx); c=getc(fp); do{ for(i=0,temp=0;i