void pollard(big id,big dl) { int i; long iter; big_chinese bc; big w,Q,R,m,n,q; char stack_mem[mr_big_reserve(6,50)]; memset(stack_mem,0,mr_big_reserve(6,50)); w=mirvar_mem(stack_mem,0); Q=mirvar_mem(stack_mem,1); R=mirvar_mem(stack_mem,2); m=mirvar_mem(stack_mem,3); n=mirvar_mem(stack_mem,4); q=mirvar_mem(stack_mem,5); copy(id,q); crt_init(&bc,np,pp); for (i=0;i<np;i++) { /* accumulate solutions for each pp */ copy(p1,w); divide(w,pp[i],w); powmod(q,w,p,Q); powltr(PROOT,w,p,R); copy(pp[i],order); iter=rho(Q,R,m,n); xgcd(m,order,w,w,w); mad(w,n,n,order,order,rem[i]); printf("%9ld iterations needed\n",iter); } crt(&bc,rem,dl); /* apply chinese remainder thereom */ crt_end(&bc); }
int invmodp(_MIPD_ big x,big y,big z) { #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif int gcd; MR_IN(213); gcd=xgcd(_MIPP_ x,y,z,z,z); MR_OUT return gcd; }
int xgcd(int a, int b, int& x, int &y) { // baseb condition if (b == 0) { x = 1; y = 0; // printf("%d = %d * %d + %d * %d\n", a, a, x, b, y); return a; } // recursion int x1, y1; int gcd = xgcd(b, a%b, x1, y1); x = y1; y = x1 - a/b * y1; // printf("%d = %d * %d + %d * %d\n", gcd, a, x, b, y); return gcd; }
void pollard(big id,big dl) { int i; long iter; big w,Q,R,m,n,q; big_chinese bc; w=mirvar(0); Q=mirvar(0); R=mirvar(0); m=mirvar(0); n=mirvar(0); q=mirvar(0); copy(id,q); crt_init(&bc,np,pp); for (i=0;i<np;i++) { /* accumulate solutions for each pp */ copy(p1,w); divide(w,pp[i],w); powmod(q,w,p,Q); powltr(PROOT,w,p,R); copy(pp[i],order); iter=rho(Q,R,m,n); xgcd(m,order,w,w,w); mad(w,n,n,order,order,rem[i]); printf("%9ld iterations needed\n",iter); } crt(&bc,rem,dl); /* apply chinese remainder thereom */ crt_end(&bc); mirkill(q); mirkill(n); mirkill(m); mirkill(R); mirkill(Q); mirkill(w); }
void zzn2_inv(_MIPD_ zzn2 *w) { #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif if (mr_mip->ERNUM) return; MR_IN(163) nres_modmult(_MIPP_ w->a,w->a,mr_mip->w1); nres_modmult(_MIPP_ w->b,w->b,mr_mip->w2); nres_modadd(_MIPP_ mr_mip->w1,mr_mip->w2,mr_mip->w1); if (mr_mip->qnr==-2) nres_modadd(_MIPP_ mr_mip->w1,mr_mip->w2,mr_mip->w1); redc(_MIPP_ mr_mip->w1,mr_mip->w6); xgcd(_MIPP_ mr_mip->w6,mr_mip->modulus,mr_mip->w6,mr_mip->w6,mr_mip->w6); nres(_MIPP_ mr_mip->w6,mr_mip->w6); nres_modmult(_MIPP_ w->a,mr_mip->w6,w->a); nres_negate(_MIPP_ mr_mip->w6,mr_mip->w6); nres_modmult(_MIPP_ w->b,mr_mip->w6,w->b); MR_OUT }
int main() { FILE *fp; char ifname[50],ofname[50]; big a,b,p,q,x,y,d,r,s,k,hash; epoint *g; long seed; int bits; miracl instance; miracl *mip=&instance; char mem[MR_BIG_RESERVE(11)]; /* reserve space on the stack for 11 bigs */ char mem1[MR_ECP_RESERVE(1)]; /* and one elliptic curve points */ memset(mem,0,MR_BIG_RESERVE(11)); memset(mem1,0,MR_ECP_RESERVE(1)); /* get public data */ #ifndef MR_EDWARDS fp=fopen("common.ecs","rt"); if (fp==NULL) { printf("file common.ecs does not exist\n"); return 0; } fscanf(fp,"%d\n",&bits); #else fp=fopen("edwards.ecs","rt"); if (fp==NULL) { printf("file edwards.ecs does not exist\n"); return 0; } fscanf(fp,"%d\n",&bits); #endif mirsys(mip,bits/4,16); /* Use Hex internally */ a=mirvar_mem(mip,mem,0); b=mirvar_mem(mip,mem,1); p=mirvar_mem(mip,mem,2); q=mirvar_mem(mip,mem,3); x=mirvar_mem(mip,mem,4); y=mirvar_mem(mip,mem,5); d=mirvar_mem(mip,mem,6); r=mirvar_mem(mip,mem,7); s=mirvar_mem(mip,mem,8); k=mirvar_mem(mip,mem,9); hash=mirvar_mem(mip,mem,10); innum(mip,p,fp); /* modulus */ innum(mip,a,fp); /* curve parameters */ innum(mip,b,fp); innum(mip,q,fp); /* order of (x,y) */ innum(mip,x,fp); /* (x,y) point on curve of order q */ innum(mip,y,fp); fclose(fp); /* randomise */ printf("Enter 9 digit random number seed = "); scanf("%ld",&seed); getchar(); irand(mip,seed); ecurve_init(mip,a,b,p,MR_PROJECTIVE); /* initialise curve */ g=epoint_init_mem(mip,mem1,0); epoint_set(mip,x,y,0,g); /* initialise point of order q */ /* calculate r - this can be done offline, and hence amortized to almost nothing */ bigrand(mip,q,k); ecurve_mult(mip,k,g,g); /* see ebrick.c for method to speed this up */ epoint_get(mip,g,r,r); divide(mip,r,q,q); /* get private key of signer */ fp=fopen("private.ecs","rt"); if (fp==NULL) { printf("file private.ecs does not exist\n"); return 0; } innum(mip,d,fp); fclose(fp); /* calculate message digest */ printf("file to be signed = "); gets(ifname); strcpy(ofname,ifname); strip(ofname); strcat(ofname,".ecs"); if ((fp=fopen(ifname,"rb"))==NULL) { printf("Unable to open file %s\n",ifname); return 0; } hashing(mip,fp,hash); fclose(fp); /* calculate s */ xgcd(mip,k,q,k,k,k); mad(mip,d,r,hash,q,q,s); mad(mip,s,k,k,q,q,s); fp=fopen(ofname,"wt"); otnum(mip,r,fp); otnum(mip,s,fp); fclose(fp); memset(mem,0,MR_BIG_RESERVE(11)); memset(mem1,0,MR_ECP_RESERVE(1)); return 0; }
int main() { int i; FILE *fp; big K,rid,id,w,a,b,n,q1; miracl *mip=mirsys(200,256); for (i=0;i<NPRIMES;i++) { pp[i]=mirvar(0); rem[i]=mirvar(0); } w=mirvar(0); n=mirvar(0); a=mirvar(0); b=mirvar(0); p=mirvar(0); p1=mirvar(0); q1=mirvar(0); K=mirvar(0); lim1=mirvar(0); lim2=mirvar(0); id=mirvar(0); rid=mirvar(0); order=mirvar(0); printf("Enter ID= "); innum(rid,stdin); getprime("trap1.dat"); copy(p,n); getprime("trap2.dat"); multiply(n,p,n); printf("\ncomposite =\n"); cotnum(n,stdout); premult(rid,256,id); while (jack(id,n)!=1) { /* bad identity - id=256*rid+i */ printf("No Discrete Log. for this ID -- incrementing\n"); incr(id,1,id); } getprime("trap1.dat"); copy(p1,q1); pollard(id,b); getprime("trap2.dat"); pollard(id,a); xgcd(p1,q1,K,K,K); subtract(b,a,w); mad(w,K,w,q1,q1,w); if(size(w)<0) add_r(w,q1,w); subdiv(w,2,w); multiply(w,p1,w); add_r(w,a,w); fp=fopen("secret.dat","w"); otnum(rid,fp); cotnum(w,fp); cotnum(n,fp); fclose(fp); printf("\nDiscrete log (secret key) \n"); cotnum(w,stdout); powltr(PROOT,w,n,id); subdiv(id,256,id); otstr(id,mip->IOBUFF); printf("Check Identity= %s\n",mip->IOBUFF); return 0; }
/* SM2 signature algorithm */ int SM2_standard_sign(unsigned char *message, int len, unsigned char ZA[], unsigned char rand[], unsigned char d[], unsigned char R[], unsigned char S[]) { unsigned char hash[SM3_len / 8]; int M_len = len + SM3_len / 8; unsigned char *M = NULL; int i; big dA, r, s, e, k, KGx, KGy; big rem, rk, z1, z2; epoint *KG; i = SM2_standard_init(); if (i) return i; //initiate dA = mirvar(0); e = mirvar(0); k = mirvar(0); KGx = mirvar(0); KGy = mirvar(0); r = mirvar(0); s = mirvar(0); rem = mirvar(0); rk = mirvar(0); z1 = mirvar(0); z2 = mirvar(0); bytes_to_big(SM2_NUMWORD, d, dA); //cinstr(dA, d); KG = epoint_init(); //step1, set M = ZA || M M = (char *)malloc(sizeof(char)*(M_len + 1)); memcpy(M, ZA, SM3_len / 8); memcpy(M + SM3_len / 8, message, len); //step2, generate e = H(M) SM3_256(M, M_len, hash); bytes_to_big(SM3_len / 8, hash, e); //step3:generate k bytes_to_big(SM3_len / 8, rand, k); //step4:calculate kG ecurve_mult(k, G, KG); //step5:calculate r epoint_get(KG, KGx, KGy); add(e, KGx, r); divide(r, para_n, rem); //judge r = 0 or n + k = n? add(r, k, rk); if (Test_Zero(r) | Test_n(rk)) return ERR_GENERATE_R; //step6:generate s incr(dA, 1, z1); xgcd(z1, para_n, z1, z1, z1); multiply(r, dA, z2); divide(z2, para_n, rem); subtract(k, z2, z2); add(z2, para_n, z2); multiply(z1, z2, s); divide(s, para_n, rem); //judge s = 0? if (Test_Zero(s)) return ERR_GENERATE_S ; big_to_bytes(SM2_NUMWORD, r, R, TRUE); big_to_bytes(SM2_NUMWORD, s, S, TRUE); free(M); return 0; }
int main() { int ia,ib; time_t seed; epoint *g,*ea,*eb; big a,b,p,q,n,p1,q1,phi,pa,pb,key,e,d,dp,dq,t,m,c,x,y,k,inv; big primes[2],pm[2]; big_chinese ch; miracl *mip; #ifndef MR_NOFULLWIDTH mip=mirsys(500,0); #else mip=mirsys(500,MAXBASE); #endif a=mirvar(0); b=mirvar(0); p=mirvar(0); q=mirvar(0); n=mirvar(0); p1=mirvar(0); q1=mirvar(0); phi=mirvar(0); pa=mirvar(0); pb=mirvar(0); key=mirvar(0); e=mirvar(0); d=mirvar(0); dp=mirvar(0); dq=mirvar(0); t=mirvar(0); m=mirvar(0); c=mirvar(0); pm[0]=mirvar(0); pm[1]=mirvar(0); x=mirvar(0); y=mirvar(0); k=mirvar(0); inv=mirvar(0); time(&seed); irand((unsigned long)seed); /* change parameter for different values */ printf("First Diffie-Hellman Key exchange .... \n"); cinstr(p,primetext); /* offline calculations could be done quicker using Comb method - See brick.c. Note use of "truncated exponent" of 160 bits - could be output of hash function SHA (see mrshs.c) */ printf("\nAlice's offline calculation\n"); bigbits(160,a); /* 3 generates the sub-group of prime order (p-1)/2 */ powltr(3,a,p,pa); printf("Bob's offline calculation\n"); bigbits(160,b); powltr(3,b,p,pb); printf("Alice calculates Key=\n"); powmod(pb,a,p,key); cotnum(key,stdout); printf("Bob calculates Key=\n"); powmod(pa,b,p,key); cotnum(key,stdout); printf("Alice and Bob's keys should be the same!\n"); /* Now Elliptic Curve version of the above. Curve is y^2=x^3+Ax+B mod p, where A=-3, B and p as above "Primitive root" is the point (x,y) above, which is of large prime order q. In this case actually q=FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831 */ printf("\nLets try that again using elliptic curves .... \n"); convert(-3,a); mip->IOBASE=16; cinstr(b,ecb); cinstr(p,ecp); ecurve_init(a,b,p,MR_BEST); /* Use PROJECTIVE if possible, else AFFINE coordinates */ g=epoint_init(); cinstr(x,ecx); cinstr(y,ecy); mip->IOBASE=10; epoint_set(x,y,0,g); ea=epoint_init(); eb=epoint_init(); epoint_copy(g,ea); epoint_copy(g,eb); printf("Alice's offline calculation\n"); bigbits(160,a); ecurve_mult(a,ea,ea); ia=epoint_get(ea,pa,pa); /* <ia,pa> is compressed form of public key */ printf("Bob's offline calculation\n"); bigbits(160,b); ecurve_mult(b,eb,eb); ib=epoint_get(eb,pb,pb); /* <ib,pb> is compressed form of public key */ printf("Alice calculates Key=\n"); epoint_set(pb,pb,ib,eb); /* decompress eb */ ecurve_mult(a,eb,eb); epoint_get(eb,key,key); cotnum(key,stdout); printf("Bob calculates Key=\n"); epoint_set(pa,pa,ia,ea); /* decompress ea */ ecurve_mult(b,ea,ea); epoint_get(ea,key,key); cotnum(key,stdout); printf("Alice and Bob's keys should be the same! (but much smaller)\n"); epoint_free(g); epoint_free(ea); epoint_free(eb); /* El Gamal's Method */ printf("\nTesting El Gamal's public key method\n"); cinstr(p,primetext); bigbits(160,x); /* x<p */ powltr(3,x,p,y); /* y=3^x mod p*/ decr(p,1,p1); mip->IOBASE=128; cinstr(m,text); mip->IOBASE=10; do { bigbits(160,k); } while (egcd(k,p1,t)!=1); powltr(3,k,p,a); /* a=3^k mod p */ powmod(y,k,p,b); mad(b,m,m,p,p,b); /* b=m*y^k mod p */ printf("Ciphertext= \n"); cotnum(a,stdout); cotnum(b,stdout); zero(m); /* proof of pudding... */ subtract(p1,x,t); powmod(a,t,p,m); mad(m,b,b,p,p,m); /* m=b/a^x mod p */ printf("Plaintext= \n"); mip->IOBASE=128; cotnum(m,stdout); mip->IOBASE=10; /* RSA. Generate primes p & q. Use e=65537, and find d=1/e mod (p-1)(q-1) */ printf("\nNow generating 512-bit random primes p and q\n"); do { bigbits(512,p); if (subdivisible(p,2)) incr(p,1,p); while (!isprime(p)) incr(p,2,p); bigbits(512,q); if (subdivisible(q,2)) incr(q,1,q); while (!isprime(q)) incr(q,2,q); multiply(p,q,n); /* n=p.q */ lgconv(65537L,e); decr(p,1,p1); decr(q,1,q1); multiply(p1,q1,phi); /* phi =(p-1)*(q-1) */ } while (xgcd(e,phi,d,d,t)!=1); cotnum(p,stdout); cotnum(q,stdout); printf("n = p.q = \n"); cotnum(n,stdout); /* set up for chinese remainder thereom */ /* primes[0]=p; primes[1]=q; crt_init(&ch,2,primes); */ /* use simple CRT as only two primes */ xgcd(p,q,inv,inv,inv); /* 1/p mod q */ copy(d,dp); copy(d,dq); divide(dp,p1,p1); /* dp=d mod p-1 */ divide(dq,q1,q1); /* dq=d mod q-1 */ mip->IOBASE=128; cinstr(m,text); mip->IOBASE=10; printf("Encrypting test string\n"); powmod(m,e,n,c); printf("Ciphertext= \n"); cotnum(c,stdout); zero(m); printf("Decrypting test string\n"); powmod(c,dp,p,pm[0]); /* get result mod p */ powmod(c,dq,q,pm[1]); /* get result mod q */ subtract(pm[1],pm[0],pm[1]); /* poor man's CRT */ mad(inv,pm[1],inv,q,q,m); multiply(m,p,m); add(m,pm[0],m); /* crt(&ch,pm,m); combine them using CRT */ printf("Plaintext= \n"); mip->IOBASE=128; cotnum(m,stdout); /* crt_end(&ch); */ return 0; }
int main() { FILE *fp; char ifname[13],ofname[13]; big p,q,g,x,r,s,k,hash; long seed; int bits; miracl *mip; /* get public data */ fp=fopen("common.dss","r"); if (fp==NULL) { printf("file common.dss does not exist\n"); return 0; } fscanf(fp,"%d\n",&bits); mip=mirsys(3+bits/MIRACL,0); p=mirvar(0); q=mirvar(0); g=mirvar(0); x=mirvar(0); r=mirvar(0); s=mirvar(0); k=mirvar(0); hash=mirvar(0); mip->IOBASE=16; cinnum(p,fp); cinnum(q,fp); cinnum(g,fp); mip->IOBASE=10; fclose(fp); /* randomise */ printf("Enter 9 digit random number seed = "); scanf("%ld",&seed); getchar(); irand(seed); /* calculate r - this can be done offline, and hence amortized to almost nothing */ bigrand(q,k); powmod(g,k,p,r); /* see brick.c for method to speed this up */ divide(r,q,q); /* get private key of signer */ fp=fopen("private.dss","r"); if (fp==NULL) { printf("file private.dss does not exist\n"); return 0; } cinnum(x,fp); fclose(fp); /* calculate message digest */ printf("file to be signed = "); gets(ifname); strcpy(ofname,ifname); strip(ofname); strcat(ofname,".dss"); if ((fp=fopen(ifname,"rb"))==NULL) { printf("Unable to open file %s\n",ifname); return 0; } hashing(fp,hash); fclose(fp); /* calculate s */ xgcd(k,q,k,k,k); mad(x,r,hash,q,q,s); mad(s,k,k,q,q,s); fp=fopen(ofname,"w"); cotnum(r,fp); cotnum(s,fp); fclose(fp); mirexit(); return 0; }
int main() { const int urfd = open("/dev/urandom", O_RDONLY); mpz_t p, q, n; fprintf(stderr, "Generating group...\n"); init_random_prime(p, urfd, 512, 3); init_random_prime(q, urfd, 512, 7); print(" p:", p); print(" q:", q); mpz_init(n); mpz_mul(n, p, q); print(" n:", n); fprintf(stderr, "Performing extended Euclid...\n"); mpz_t u, v; xgcd(u, v, p, q); mpz_mul(u, u, p); mpz_mul(v, v, q); print (" u:", u); print (" v:", v); fprintf(stderr, "Picking random element...\n"); mpz_t e; random_element(e, urfd, 1024, n); print(" e:", e); fprintf(stderr, "Tweaking...\n"); int a = is_quadratic_residue(e, p); int b = is_quadratic_residue(e, q); fprintf(stderr, " residue state: [%d, %d]\n", a, b); int mul_2 = 0, negate = 0; if (a ^ b) { mul_2 = 1; a ^= 1; } if (!a) { negate = 1; a ^= 1; b ^= 1; } fprintf(stderr, " tweaks: 2:%d -:%d\n", mul_2, negate); if (negate) { mpz_neg(e, e); } if (mul_2) { mpz_mul_ui(e, e, 2); } if (negate || mul_2) mpz_mod(e, e, n); print(" tweaked e:", e); uint8_t root; read(urfd, &root, 1); root &= 3; fprintf(stderr, "Calculating root %d...\n", root); mpz_t pp1over4, qp1over4; mpz_init_set(pp1over4, p); mpz_add_ui(pp1over4, pp1over4, 1); mpz_cdiv_q_2exp(pp1over4, pp1over4, 2); mpz_init_set(qp1over4, q); mpz_add_ui(qp1over4, qp1over4, 1); mpz_cdiv_q_2exp(qp1over4, qp1over4, 2); mpz_t proot, qroot; mpz_init_set(proot, e); mpz_powm(proot, e, pp1over4, p); mpz_init_set(qroot, e); mpz_powm(qroot, e, qp1over4, q); if (root & 1) mpz_neg(proot, proot); if (root & 2) mpz_neg(qroot, qroot); mpz_mul(proot, proot, v); mpz_mul(qroot, qroot, u); mpz_add(proot, proot, qroot); mpz_mod(proot, proot, n); print(" sig:", proot); fprintf(stderr, "Compressing signature...\n"); mpz_t zsig; mpz_t ncopy; mpz_init_set(ncopy, n); signature_compress(zsig, proot, ncopy); print(" zsig:", zsig); mpz_t zsigcopy, t, t2; mpz_init(t); mpz_init(t2); mpz_init(zsigcopy); fprintf(stderr, "Performing 1000000 verifications\n"); const uint64_t start_time = time_now(); unsigned i; for (i = 0; i < 1000000; ++i) { mpz_set(zsigcopy, zsig); mpz_mul(zsigcopy, zsigcopy, zsigcopy); mpz_mul(zsigcopy, zsigcopy, e); mpz_mod(zsigcopy, zsigcopy, n); if (0 == mpz_sgn(zsigcopy)) abort(); mpz_sqrtrem(t, t2, zsigcopy); if (mpz_sgn(t2)) abort(); } const uint64_t end_time = time_now(); fprintf(stderr, "verify time: %f\n", ((double) (end_time - start_time)) / 1000000); return 0; }
int modinv(int a, int M) { int x, y; int gcd = xgcd(a, M, x, y); return x; }
int main() { FILE *fp; int m,a,b,c,cf; miracl *mip; char ifname[13],ofname[13]; big a2,a6,q,x,y,d,r,s,k,hash; epoint *g; long seed; /* get public data */ fp=fopen("common2.ecs","r"); if (fp==NULL) { printf("file common2.ecs does not exist\n"); return 0; } fscanf(fp,"%d\n",&m); mip=mirsys(3+m/MIRACL,0); a2=mirvar(0); a6=mirvar(0); q=mirvar(0); x=mirvar(0); y=mirvar(0); d=mirvar(0); r=mirvar(0); s=mirvar(0); k=mirvar(0); hash=mirvar(0); mip->IOBASE=16; cinnum(a2,fp); /* curve parameters */ cinnum(a6,fp); /* curve parameters */ cinnum(q,fp); /* order of (x,y) */ cinnum(x,fp); /* (x,y) point on curve of order q */ cinnum(y,fp); mip->IOBASE=10; fscanf(fp,"%d\n",&a); fscanf(fp,"%d\n",&b); fscanf(fp,"%d\n",&c); fclose(fp); /* randomise */ printf("Enter 9 digit random number seed = "); scanf("%ld",&seed); getchar(); irand(seed); ecurve2_init(m,a,b,c,a2,a6,FALSE,MR_PROJECTIVE); /* initialise curve */ g=epoint2_init(); epoint2_set(x,y,0,g); /* set point of order q */ /* calculate r - this can be done offline, and hence amortized to almost nothing */ bigrand(q,k); ecurve2_mult(k,g,g); /* see ebrick2.c for method to speed this up */ epoint2_get(g,r,r); divide(r,q,q); /* get private key of signer */ fp=fopen("private.ecs","r"); if (fp==NULL) { printf("file private.ecs does not exist\n"); return 0; } cinnum(d,fp); fclose(fp); /* calculate message digest */ printf("file to be signed = "); gets(ifname); strcpy(ofname,ifname); strip(ofname); strcat(ofname,".ecs"); if ((fp=fopen(ifname,"rb"))==NULL) { printf("Unable to open file %s\n",ifname); return 0; } hashing(fp,hash); fclose(fp); /* calculate s */ xgcd(k,q,k,k,k); mad(d,r,hash,q,q,s); mad(s,k,k,q,q,s); fp=fopen(ofname,"w"); cotnum(r,fp); cotnum(s,fp); fclose(fp); return 0; }