Exemple #1
0
/* Blinds the c, by computing c *= r^e (mod n), for a random r. Also
   returns the inverse (ri), for use by rsa_unblind. */
void
_rsa_blind (const struct rsa_public_key *pub,
	    void *random_ctx, nettle_random_func *random,
	    mpz_t c, mpz_t ri)
{
  mpz_t r;

  mpz_init(r);

  /* c = c*(r^e)
   * ri = r^(-1)
   */
  do 
    {
      nettle_mpz_random(r, random_ctx, random, pub->n);
      /* invert r */
    }
  while (!mpz_invert (ri, r, pub->n));

  /* c = c*(r^e) mod n */
  mpz_powm_sec(r, r, pub->e, pub->n);
  mpz_mul(c, c, r);
  mpz_fdiv_r(c, c, pub->n);

  mpz_clear(r);
}
Exemple #2
0
void bg_decrypt_block(bg_prikey key, FILE *in, FILE *out, mp_size_t len) {
	mpz_t y, xqmp, xpmq, pp, qq, negone;
	unsigned long int l;
	bbs_state *bbs;

	mpz_init(y);
	mpz_init(xqmp);
	mpz_init(xpmq);
	mpz_init(pp);
	mpz_init(qq);
	mpz_init_set_si(negone, -1);
	bbs = init_bbs(negone, key.n);
	bbs_gen(bbs, NULL, 8*len, 0);
	bbs_iter(bbs);
	bbs_close(bbs);
	l = bbs->len;
	mpz_inp_raw(y, in);

	mpz_add_ui(pp, key.p, 1);
	mpz_tdiv_q_ui(pp, pp, 4);
	mpz_pow_ui(pp, pp, l);
	mpz_powm_sec(pp, y, pp, key.p);

	mpz_add_ui(qq, key.q, 1);
	mpz_tdiv_q_ui(qq, qq, 4);
	mpz_pow_ui(qq, qq, l);
	mpz_powm_sec(qq, y, qq, key.q);

	mpz_mul(xqmp, key.q, pp);
	mpz_powm(pp, key.q, negone, key.p);
	mpz_mul(xqmp, xqmp, pp);

	mpz_mul(xpmq, key.p, qq);
	mpz_powm(qq, key.p, negone, key.q);
	mpz_mul(xpmq, xpmq, qq);

	mpz_add(y, xqmp, xpmq);
	mpz_mod(y, y, key.n);

	bbs = init_bbs(y, key.n);
	while(len && !feof(in)) len -= bg_xor(bbs, in, out, len);
	bbs_close(bbs);
}
Exemple #3
0
/**
 * \fn void dechiffrement(const char* nom_fichier, mpz_t d, mpz_t n, unsigned int blocs)
 * \brief déchiffrement d'un fichier binaire avec la clé privée
 * \param nom_fichier le nom du fichier à déchiffrer
 * \param d premier nombre de la clé
 * \param n second nombre de la clé
 * \param blocs taille des blocs
 * */
void dechiffrement(const char* nom_fichier, mpz_t d, mpz_t n, unsigned int blocs)
{
    FILE *fchiffre, *fclair;
    unsigned char *buffer, *buffer2;
    char nom_fichier_dechiffrer[100];
    mpz_t temp,temp2;
    int taille;
    clock_t s1,s2;

    mpz_init(temp);
    mpz_init(temp2);
	
    strcpy(nom_fichier_dechiffrer,nom_fichier);
    strcat(nom_fichier_dechiffrer,".decrypt");

    fchiffre = fopen(nom_fichier,"rb"); // ouverture fichier chiffré
	
    if (fchiffre != NULL)
    {
	s1 = clock();
	fclair = fopen(nom_fichier_dechiffrer,"wb+");
	
	buffer = (unsigned char*)calloc((blocs+1), sizeof(unsigned char));
	buffer2 = (unsigned char*)calloc((blocs), sizeof(unsigned char));
		
	fread(&taille,sizeof(int),1,fchiffre); //lecture de la taille du fichier 
		
	while(fread(buffer,sizeof(unsigned char), blocs+1, fchiffre) > 0)
	{	
	    conversion10(temp,buffer,blocs+1); // conversion base 10
	    mpz_powm_sec(temp2,temp,d,n); // déchiffrement
	    conversion256(buffer2,temp2,blocs); // convertion base 256
	    	    	
	    if (taille < blocs && taille > 0)	
		decalage(buffer2, &blocs); // suppression des caractères inutiles
			
	    fwrite(buffer2,sizeof(unsigned char),blocs,fclair); // écriture dans le fichier clair
	    taille-=blocs;
	    mpz_init(temp);
	}
	
	free(buffer);
	free(buffer2);
	fclose(fclair);
	fclose(fchiffre);
	s2 = clock();
	printf ("=> Déchiffrement effectué avec succés (%.2fs) dans %s\n", (float)(s2-s1)/CLOCKS_PER_SEC,nom_fichier_dechiffrer);
    }
	
    else
	printf("Fichier %s introuvable !\n", nom_fichier);
	
    mpz_clear(temp);
    mpz_clear(temp2);
}
Exemple #4
0
int main(int argc, char **argv){
	mpz_t prime;
	mpz_init(prime);
	mpz_set_str(prime, "ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca237327ffffffffffffffff", 16);
	
	mpz_t base;
	mpz_init(base);
	mpz_set_ui(base, 2);
	
	mpz_t exp;
	mpz_init(exp);
	mpz_set_str(exp, "16ffd3bddcd2076e9130eed97d6eb59dc4463f3d751ba7e953399e4ea9ada84a3714619b038d63761bcfa786cb0c1124ecdccdb4fd417f25b1458f5acd2d9088c1b5e4661139c8382e3b52841d3dd3f81855f0dbb0705a05304705a69709922e26c80042513c7cbfdbf6c3dbdb11c6f8d45a5d30dd5320a40d935d2cadb3ff2202719ce9fc197dacfee65f2ed5cb7147ee49a2aad18404cf16c9584ba56eef71ba085ad9cd9c61ff0f8dafa43f54e07b2c346389eebdc359afafd3e27d4d6a48",  16);
	
	mpz_t ans;
	mpz_init(ans);
	mpz_powm_sec(ans, base, exp, prime);
	
	gmp_printf("modexp(%#Zx, %#Zx, %#Zx) == %#Zx\n", base, exp, prime, 	ans);
	return 0;
}
int dh(unsigned char * k, int knum,unsigned char * n, int nnum, int s){

	if(VISIBLE){
		printf("\n\n****** Diffie-Hellman begin ******\n\n");
	}

	int i,j=0,itemp;	
	mpz_t p,g,a,A,B,S;
	char buf[BUF_SIZE],*string_A,*string_p, *string_g, *tempkey;
	unsigned long int rand;
	size_t count;
	unsigned int temp;
	FILE *fp;

	mpz_init(a);
	mpz_init(A);
	mpz_init(B);
	mpz_init(S);

	// Setts g and p according to RFC 3526 1536 bits. http://tools.ietf.org/html/rfc3526 
	mpz_init_set_str(g,"2",10);
	mpz_init_set_str(p,"FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 \
      29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD \
      EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245 \
      E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED \
      EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D \
      C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F \
      83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D \
      670C354E 4ABC9804 F1746C08 CA237327 FFFFFFFF FFFFFFFF", 16);
	
	if(VISIBLE){
		printf("\np:\n");
		mpz_out_str(NULL,10,p);
		printf("\n\ng:\n");
		mpz_out_str(NULL,10,g);
		printf("\n");
	}

	//Randomizar a ( Bättre seed nu )
	gmp_randstate_t state;
	gmp_randinit_mt(state);	// Initializerar state random måstes för att urandomm ska funka

	fp = fopen("/dev/urandom", "r");
	fread(&rand, 8, 1, fp);
	fclose(fp);
	
	gmp_randseed_ui(state,rand);	

	mpz_urandomm(a,state,p);	// Ger a random värde mellan 0 <= a <= p-1

	if(VISIBLE){
		printf("\na:\n");
		mpz_out_str(NULL,10,a);
		printf("\n");
	}

	// ^Frågan är om urandom skall användas för att generara hela A??????

	mpz_powm_sec(A,g,a,p);	// g^a mod p = A

	if(VISIBLE){
		printf("\nA:\n");
		mpz_out_str(NULL,10,A);
		printf("\n");
	}

	string_p = (char *)mpz_export (NULL,&count,1,1,0,0, p); // Antal bytes i word är 1

	// Sätter första meddelandet till standard: (bokstav(1 byte(char)),storlek(4 byte(unsigned int)),content und so weiter...)


	i=0;
	buf[i++] = 'p';
	memcpy(&buf[i],(char *)&count,sizeof(unsigned int));		//Detta för att hålla någon slags struktur
	i = i+sizeof(unsigned int);

	itemp = i;
	for(;i<count+itemp;i++){
		buf[i]=string_p[i-itemp];
	}

	string_g = (char *)mpz_export(NULL,&count,1,1,0,0,g);

	buf[i++] = 'g';
	memcpy(&buf[i],(char *)&count,sizeof(unsigned int));
	i = i+sizeof(unsigned int);
	itemp = i;

	for(;i<count+itemp;i++){
		buf[i]=string_g[i-itemp];
	}
	
	string_A = (char *)mpz_export(NULL,&count,1,1,0,0,A);

	buf[i++] = 'A';
	memcpy(&buf[i],(char *)&count,sizeof(unsigned int));
	i = i+sizeof(unsigned int);
	itemp = i;
	for(;i<count+itemp;i++){
		buf[i]=string_A[i-itemp];
	}

	if(write(s,buf,sizeof(buf))==-1){
		return 0;		//Diffie-hellman fail
	}

	read(s,buf,BUF_SIZE);		//Read answer from server _!check!_

	if(buf[j]=='B'){
		j++;
		memcpy(&temp,(unsigned int *)&buf[j],sizeof(unsigned int));
		j+=4;
		mpz_import(B,temp,1,1,0,0,&buf[j]);
		mpz_powm_sec(S,B,a,p);							// B^a mod p = S
	}

	if(VISIBLE){
		printf("\nS:\n");
		mpz_out_str(NULL,10,S);
		printf("\n");	
	}	

	tempkey = (char *)mpz_export(NULL,&count,1,1,0,0,S);		//Fyllar sedan nyckeln med detta för det är mer random

	// Fyller riktig nyckel och nonce

	for(i=0;i<knum;i++){
		k[i] = tempkey[i];
	}
	itemp = i;
	for(;i<nnum+itemp;i++){
		n[i-itemp] = tempkey[i];
	}

	if(VISIBLE){
		printf("\n\n****** Diffie-Hellman end ******\n\n");
	}

	return 1;

}
Exemple #6
0
void dhe_compute_shared_secret(mpz_t shared_secret, mpz_t secret_key, mpz_t other_party_secret, mpz_t prime) {
  mpz_powm_sec(shared_secret, other_party_secret, secret_key, prime);
}
Exemple #7
0
void dhe_compute_party_secret(mpz_t party_secret, mpz_t secret_key, mpz_t generator, mpz_t prime) {
  mpz_powm_sec(party_secret, generator, secret_key, prime);
}
int main()
{
    unsigned int i,j,a,*SV;
    unsigned char logpi;
    int k,S,r,s1,s2,s,NS,logm,ptr,threshold,epri;
    long M,la,lptr;

    qsieve=gmpinit(-36,0);

    if(initv()<0) return 0;

    hmod=2*mlf+1;
    mpz_set_si(TA, hmod);
    while(!mpz_probab_prime_p(TA, qsieve->NTRY)) mpz_sub_ui(TA, TA, 2); //TT=不大于TT的素数
    hmod=qsieve_getsize(TA);
    hmod2=hmod-2;
    for(k=0;k<hmod;k++) hash[k]=(-1);

    M=50*(long)mm;
    NS=(int)(M/SSIZE);
    if(M%SSIZE!=0) NS++;
    M=SSIZE*(long)NS; // M为不小于50*mm的SSIZE的倍数中最小的 from 以上四行
    logm=0;
    la=M;
    while((la/=2)>0) logm++; // 以2为底
    rp[0]=logp[0]=0;
    for(k=1;k<=mm;k++) //求k*N在每个素数下的二次剩余解,与每个素数的ln(pi)
    {
        r=mpz_tdiv_q_ui(TA, D, epr[k]);
        rp[k]=qsieve_sqrmp(r,epr[k]);
        logp[k]=0;
        r=epr[k];
        while((r/=2)>0) logp[k]++;
    }

    r=mpz_tdiv_q_ui(TA, D, 8);
    if(r==5) logp[1]++;
    if(r==1) logp[1]+=2;

    threshold=logm+mpz_sizeinbase(R, 2)-2*logp[mm];

    jj=0;
    nlp=0;
    mpz_mul_si(DG, D, 2);
    mpz_root(DG, DG, 2);

    mpz_set_si(TA, M);
    qsieve_divide(DG,TA,DG);
    mpz_root(DG, DG, 2);
    if(mpz_tdiv_q_ui(TA, DG, 2)==0) mpz_add_ui(DG, DG, 1);
    if(mpz_tdiv_q_ui(TA, DG, 4)==1) mpz_add_ui(DG, DG, 2); // 令DG等于大于等于DG的数中模4余3的最小的数
    printf("  0%");

    while(1) //不断尝试新的多项式,可以并行计算
    {
        r=qsieve->NTRY;
        qsieve->NTRY=1;
        do
        {
            do {
               mpz_add_ui(DG, DG, 4);
            } while(!(mpz_probab_prime_p(DG, qsieve->NTRY) ? TRUE : FALSE));
            mpz_sub_ui(TA, DG, 1);
            mpz_tdiv_q_ui(TA, TA, 2);
            mpz_powm_sec(TA, D, TA, DG);
        } while(qsieve_getsize(TA)!=1); //直到DD是二次剩余
        qsieve->NTRY=r;
        mpz_add_ui(TA, DG, 1);
        mpz_tdiv_q_ui(TA, TA, 4);
        mpz_powm_sec(B, D, TA, DG);
        mpz_neg(TA, D);
        qsieve_muladddiv(B,B,TA,DG,TA,TA);
        mpz_neg(TA, TA);

        mpz_mul_si(A, B, 2);
        qsieve_extgcd(A,DG,A,A,A);
        qsieve_muladddiv(A,TA,TA,DG,DG,A);
        mpz_mul(TA, A, DG);
        mpz_add(B, B, TA);
        mpz_mul(A, DG, DG);
        qsieve_extgcd(DG,D,IG,IG,IG);
        
        r1[0]=r2[0]=0;
        for(k=1;k<=mm;k++) //s1和s2是两个解
        {
            s=mpz_tdiv_q_ui(TA, B, epr[k]);
            r=mpz_tdiv_q_ui(TA, A, epr[k]);
            r=qsieve_getinvers(r,epr[k]);

            s1=(epr[k]-s+rp[k]);
            s2=(epr[k]-s+epr[k]-rp[k]);
            if(s1 > s2)
            {
                int t = s1;
                s1 = s2;
                s2 = t;
            }
            r1[k]=(int)((((long long)s1)*((long long)r)) % ((long long)epr[k]));
            r2[k]=(int)((((long long)s2)*((long long)r)) % ((long long)epr[k]));
        }
        
        for(ptr=(-NS);ptr<NS;ptr++)
        {
            la=(long)ptr*SSIZE;
            SV=(unsigned int *)sieve;
            for(i=0; i<SSIZE/sizeof(int); i++) *SV++=0;
            for(k=1; k<=mm; k++)
            {
                epri=epr[k];
                logpi=logp[k];
                r=(int)(la%epri);
                s1=(r1[k]-r)%epri;
                if(s1<0) s1+=epri;
                s2=(r2[k]-r)%epri;
                if(s2<0) s2+=epri;

			/* 这部分是筛法的主要部分,数组下标表示多项式P(x)的参数x 
				s1与s2是两个P(x)=0(mod p)的解 */
                for(j=s1;j<SSIZE;j+=epri) sieve[j]+=logpi;
                if(s1==s2) continue;
                for(j=s2;j<SSIZE;j+=epri) sieve[j]+=logpi;
            }

            for(a=0;a<SSIZE;a++) //找那些没有被筛掉的数
            {
                if(sieve[a]<threshold) continue;
                lptr=la+a;
                mpz_set_si(TA, lptr);
                S=0;
                mpz_mul(TA, A, TA);
                mpz_add(TA, TA, B);
                qsieve_muladddiv(TA,IG,TA,D,D,P);
                if(qsieve_getsize(P)<0) mpz_add(P, P, D);
                qsieve_muladddiv(P,P,P,D,D,V);
                mpz_abs(TA, TA);
                if(qsieve_compare(TA,R)<0) S=1;
                if(S==1) mpz_sub(V, D, V);
                if(V!=TA) mpz_set(TA, V);
                e[0]=S;
                for(k=1;k<=mm;k++) e[k]=0;
                if(!factored(lptr,TA)) continue;
                if(gotcha())
                {
                    mpz_gcd(P, TA, N);
                    qsieve_getsize(P);
                    printf("\b\b\b\b100%\nFactors are\n");
                    qsieve_outnum(P,stdout);
                    qsieve_divide(N,P,N);
                    qsieve_outnum(N,stdout);
                    return 0;
                }
            }
        }
    }
    return 0;
}
char gotcha(void)  // 进gotcha前提一定是factored返回true了
{
    int r,j,i,k,n,rb,had,hp;
    unsigned int t;
    char found;
    found=TRUE;
    if(partial) // 检查部分分解
    {
        had=lp%hmod;
        while(1) // 哈希大素数
        {
            hp=hash[had];
            if(hp<0)
            {
                found=FALSE;
                break;
            }
            if(pr[hp]==lp) break;
            had=(had+(hmod2-lp%hmod2))%hmod;
        }
        if(!found && nlp>=mlf) return FALSE;
    }
    if(P!=X) mpz_set(X, P);
    mpz_set_si(Y, 1);
    for(k=1;k<=mm;k++) // 把Y乘出来
    {
        if(e[k]<2) continue;
        r=e[k]/2; // 开个根
        e[k]%=2; // 弄成0和1用来解异或方程组
        mpz_ui_pow_ui(TA, epr[k], r);
        mpz_mul(Y, TA, Y); //Y=Y*epr[k]^r
    }

    if(partial)
    {
        if(!found)
        {
            hash[had]=nlp;
            pr[nlp]=lp;
            if(X!=z[nlp]) mpz_set(z[nlp], X);
            if(Y!=w[nlp]) mpz_set(w[nlp], Y);
            for(n=0,rb=0,j=0;j<=mm;j++)
            {
                G[nlp][n]|=((e[j]&1)<<rb); //压位
                if(++rb==nbts) n++,rb=0; // 压32位
            }
            nlp++;
        }
        if(found)
        {
            qsieve_muladddiv(X,z[hp],X,N,N,X);
            qsieve_muladddiv(Y,w[hp],Y,N,N,Y);
            for(n=0,rb=0,j=0;j<=mm;j++)
            {
                t=(G[hp][n]>>rb);
                e[j]+=(t&1);
                if(e[j]==2)
                {
                    mpz_mul_si(Y, Y, epr[j]);
                    qsieve_divide(Y,N,N); // Y%=N
                    e[j]=0;
                }
                if(++rb==nbts) n++,rb=0;
            }
            mpz_mul_si(Y, Y, lp);
            qsieve_divide(Y,N,N);// Y%=N
        }
    }
    if(found)
    {
        for(k=mm;k>=0;k--)
        {
            if(e[k]%2==0) continue;
            if(b[k]<0)
            {
                found=FALSE;
                break;
            }
            i=b[k];
            qsieve_muladddiv(X,x[i],X,N,N,X);
            qsieve_muladddiv(Y,y[i],Y,N,N,Y);
            for(n=0,rb=0,j=0;j<=mm;j++) //高斯消元
            {
                t=(EE[i][n]>>rb);
                e[j]+=(t&1);
                if(++rb==nbts) n++,rb=0;
            }
        }
        for(j=0;j<=mm;j++) // 更新Y
        {
            if(e[j]<2) continue;
            mpz_set_si(TA, epr[j]);
            mpz_set_si(TB, e[j]/2);
            mpz_powm_sec(TA, TA, TB, N);
            qsieve_muladddiv(Y,TA,Y,N,N,Y);
        }
        if(!found) //把结果扔进EE,X,Y继续用
        {
            b[k]=jj;
            if(X!=x[jj]) mpz_set(x[jj], X);
            if(Y!=y[jj]) mpz_set(y[jj], Y);
            for(n=0,rb=0,j=0;j<=mm;j++)
            {
                EE[jj][n]|=((e[j]&1)<<rb);
                if(++rb==nbts) n++,rb=0;
            }
            jj++;
            printf("\b\b\b\b%3d%%",100*jj/mm);
            fflush(stdout);
        }
    }

    if(found)
    {
        mpz_add(TA, X, Y);
        if(qsieve_compare(X,Y)==0 || qsieve_compare(TA,N)==0) found=FALSE;
        if(!found)
        {
            printf("\b\b\b\b%3d%%",100*jj/mm);
            fflush(stdout);
        }
    }
    return found;
}