예제 #1
0
파일: 10104.c 프로젝트: DavidToca/acm
int egcd(int a, int b, int *x, int *y)
{
	int x1, y1, d;

	if (a < b)
		return egcd(b, a, y, x);

	if (b < 0) {
		d = egcd(a, -b, x, y);
		(*y) *= -1;
		return d;
	}

	if (b == 0) {
		*x = 1;
		*y = 0;
		return a;
	}

	d = egcd(b, a % b, &x1, &y1);
	*x = y1;
	*y = x1 - (a / b) * y1;

	return d;
}
예제 #2
0
int inverse( int n )
{
    int     x, y;

    egcd( n, 1410000017, &x, &y );
    return x;
}
예제 #3
0
Triple< Int > ldioph( Int a, Int b, Int c )
{
    Triple< Int > t = egcd( a, b );
    if( c % t.d ) return Triple< Int >( 0, 0, 0 );
    t.x *= c / t.d; t.y *= c / t.d;
    return t;
}
예제 #4
0
파일: diofanto.cpp 프로젝트: marinvhs/SMAS
int invmod( int a, int n )
{
    Triple t = egcd( a, n );
    if( t.d > 1 ) return 0;
    int r = t.x % n;
    return( r < 0 ? r + n : r );
}
예제 #5
0
	static void moveBezout(int a,int b, int c, int &x, int &y, int pos = 1){
		int gc = egcd(a,b);
		b /= gc;
		a /= gc;
		x += b * pos;
		y -= a * pos;
	}
예제 #6
0
파일: 10090.c 프로젝트: DavidToca/acm
int main()
{
	llong d, t;

	while (scanf("%lld", &n) == 1 && n > 0) {
		scanf("%lld %lld %lld %lld", &c1, &n1, &c2, &n2);

		egcd(n1, n2, &x0, &y0, &d);
		if ((n % d) != 0) {
			printf("failed\n");
			continue;
		}

		n1 /= d;
		n2 /= d;
		n /= d;
		x0 *= n;
		y0 *= n;

		rz = -1;
		for (t = -x0 / n2, d = -2; d <= 2; d++)
			check(t + d);

		for (t = y0 / n1, d = -2; d <= 2; d++)
			check(t + d);

		if (rz <= 0)
			printf("failed\n");
		else
			printf("%lld %lld\n", rx, ry);
	}

	return 0;
}
예제 #7
0
파일: egcd.cpp 프로젝트: neil1422/functions
Triple ldioph( ll a, ll b, ll c )
{
	Triple t = egcd( a, b );
	if( c % t.d ) return Triple( 0, 0, 0 );
	t.x *= c / t.d; t.y *= c / t.d;
	return t;
}
예제 #8
0
/* ax+by=gcd(a,b) */
int egcd(int a,int b,int& x,int& y)
{
	if(!b){x=1;y=0;return a;}
	int d=egcd(b,a%b,y,x);
	y-=a/b*x;
	return d;
}
예제 #9
0
Int inverse( Int a, Int n )
{
    Triple< Int > t = egcd( a, n );
    if( t.d > Int( 1 ) ) return Int( 0 );
    Int r = t.x % n;
    return( r < Int( 0 ) ? r + n : r );
}
예제 #10
0
파일: 10090.c 프로젝트: DavidToca/acm
void egcd(llong a, llong b, llong *x, llong *y, llong *d)
{
	if (a < 0) {
		egcd(-a, b, x, y, d);
		*x = -(*x);
	} else if (b < 0) {
		egcd(a, -b, x, y, d);
		*y = -(*y);
	} else if (b == 0) {
		*x = 1;
		*y = 0;
		*d = a;
	} else {
		egcd(b, a % b, y, x, d);
		*y -= (a / b) * (*x);
	}
}
예제 #11
0
	static bool solveDiophantine(int a, int b, int c, int &x, int &y) {
		int gc = egcd(a,b,x,y);
		if(c % gc != 0)return false;
		int d = c / gc;
		x *= d;
		y *= d;
		return true;
	}
int64 egcd (int64 a, int64 b, int64 &x, int64 &y) {
	int64 x_p = 0, y_p = 1, d = b;
	if (a) {
        d = egcd (b % a, a, x_p, y_p);
        x = y_p - (b / a) * (y = x_p);
	}
	return d;
}
예제 #13
0
파일: gcd.cpp 프로젝트: 0xCAB/ulib
int main()
{
	assert(7 == gcd(21, 14));
	assert(7 == gcd(14, 21));

	long x, y;
	egcd(3, 2, &x, &y);
	assert(x == 1 && y == -1);
	egcd(2, 3, &x, &y);
	assert(x == -1 && y == 1);

	assert(3 == invert(8, 3));

	printf("passed\n");

	return 0;
}
void modular_linear_equation_solver (int64 a, int64 b, int64 n) {
  int64 x, y;
  solutions.clear ();
  int64 d = egcd (a, n, x, y);
  if (!(b % d)) {
    x = mod (x * (b / d), n);
    for (int64 i = 0; i < d; ++i) solutions.push_back (mod (x + i * (n / d), n));
  }
}
예제 #15
0
int egcd(int a, int b, int& x, int& y) {
    if (b == 0) { x = 1; y = 0; return a; }
    else {
        int d = egcd(b, a % b, x, y);
        x -= a / b * y;
        swap(x, y);
        return d;
    }
}
예제 #16
0
int lmes() {
    int i, tm=1, mf, y, ret=0, m;
    for (i=0; i<nn; i++) tm *= n[i];
        for (i=0; i<nn; i++) {
            m = tm/n[i];
            egcd(m, n[i], &mf, &y);
            ret += (a[i]*m*(mf%n[i]))%tm;
        }
    return (ret+tm)%tm;
}
예제 #17
0
/* Computes a st. a * b = 1 mod m */
unsigned long invert(unsigned long m, unsigned long b)
{
	long s, t;

	egcd(m, b, &t, &s);

	if (s < 0)
		return m + s;
	return s;
}
예제 #18
0
int keyGen(int pub)
{
    int test=private-(pub*3);
    p=nth_prime(test/4,test/5);
    q=nth_prime(test/5,test/3);
    e=expGen(p,q);
    d=egcd(e,(p-1)*(q-1));
    n=p*q;
    printf("Public key %d , test %d, P: %d, Q: %d, E: %d, D: %d, n: %d \n",pub,test,p,q,e,d,n);
}
예제 #19
0
int egcd(int a, int b, int *x, int *y) {
    int d;
    if (b == 0) {
        *x = 1; *y = 0;
        return a;
    } else {
        d = egcd(b, a%b, y, x);
        *y -= a/b*(*x);
        return d;
    }
}
예제 #20
0
파일: 10104.c 프로젝트: DavidToca/acm
int main()
{
	int a, b, d, x, y;

	while (scanf("%d %d", &a, &b) == 2) {
		d = egcd(a, b, &x, &y);
		printf("%d %d %d\n", x, y, d);
	}

	return 0;
}
예제 #21
0
vector< Int > msolve( Int a, Int b, Int n )
{
    if( n < 0 ) n = -n;
    Triple< Int > t = egcd( a, n );
    vector< Int > r;
    if( b % t.d ) return r;
    Int x = ( b / t.d * t.x ) % n;
    if( x < Int( 0 ) ) x += n;
    for( Int i = 0; i < t.d; i++ )
        r.push_back( ( x + i * n / t.d ) % n );
    return r;
}
예제 #22
0
파일: MIOJO.cpp 프로젝트: marinvhs/SMAS
int main(void){
	int a, b, c, s, w;
	scanf("%d%d%d",&c,&a,&b);
	Triple t;
	if(a < b) a ^= b ^= a ^= b;
	t = egcd(a,b);
	t.x *= c/t.d; t.y *= c/t.d;
	s = a / t.d; w = b / t.d;
	//printf("x = %+d + %d * n\ny = %+d - %d * n\n",t.x,w,t.y,s);
	int res = min(FUUUUUUUCK(t.x,w,a),FUUUUUUUCK(t.y,s,b));
	printf("%d\n",res);
	return 0;
}
예제 #23
0
파일: BN.cpp 프로젝트: ramyaraju/kg
__int64 invmod(__int64 a, __int64 n)
{
	__int64 gc,x,y;
	if(a<0) a+=n;
	if(a>n){
		x = a;
		a = n;
		n = x;
	}
	gc = egcd(a,n,x,y);
	if(gc==1) {
		if(x<0) x += n;
		return x;
	}
	return -1;
}
예제 #24
0
int main()
{  /*  factoring program using Brents method */
    long k,r,i,m,iter;
    big x,y,z,n,q,ys,c3;
    miracl *mip=mirsys(50,0);
    x=mirvar(mip,0);
    y=mirvar(mip,0);
    ys=mirvar(mip,0);
    z=mirvar(mip,0);
    n=mirvar(mip,0);
    q=mirvar(mip,0);
    c3=mirvar(mip,3);
    printf("input number to be factored\n");
    cinnum(mip,n,stdin);
    if (isprime(mip,n))
    {
        printf("this number is prime!\n");
        return 0;
    }
    m=10L;
    r=1L;
    iter=0L;
    do
    {
        printf("iterations=%5ld",iter);
        convert(mip,1,q);
        do
        {
            copy(y,x);
            for (i=1L;i<=r;i++)
                mad(mip,y,y,c3,n,n,y);
            k=0;
            do
            {
                iter++;
                if (iter%10==0) printf("\b\b\b\b\b%5ld",iter);
                fflush(stdout);  
                copy(y,ys);
                for (i=1L;i<=mr_min(m,r-k);i++)
                {
                    mad(mip,y,y,c3,n,n,y);
                    subtract(mip,y,x,z);
                    mad(mip,z,q,q,n,n,q);
                }
                egcd(mip,q,n,z);
                k+=m;
            } while (k<r && size(z)==1);
            r*=2;
        } while (size(z)==1);
        if (compare(z,n)==0) do 
        { /* back-track */
            mad(mip,ys,ys,c3,n,n,ys);
            subtract(mip,ys,x,z);
        } while (egcd(mip,z,n,z)==1);
        if (!isprime(mip,z))
             printf("\ncomposite factor ");
        else printf("\nprime factor     ");
        cotnum(mip,z,stdout);
        if (compare(z,n)==0) return 0;
        divide(mip,n,z,n);
        divide(mip,y,n,n);
    } while (!isprime(mip,n));
    printf("prime factor     ");
    cotnum(mip,n,stdout);
    return 0;
}
예제 #25
0
int main(void){
	while(scanf("%d%d",&A,&B)!=EOF)
		if(A>=B) t = egcd(A,B),printf("%d %d %d\n",t.x,t.y,t.d);
		else t = egcd(B,A),printf("%d %d %d\n",t.y,t.x,t.d);
	return 0;
}
예제 #26
0
Triple egcd( int a, int b ){
    if(!b) return Triple(a, 1, 0);
    Triple q = egcd(b, a%b);
    return Triple(q.d, q.y, q.x-a/b*q.y);
}
pair<ll,ll> linear_congruence(ll a, ll b, ll n) {
  ll x, y, d = egcd(smod(a,n), n, x, y);
  if ((b = smod(b,n)) % d != 0) return ii(0,0);
  return make_pair(smod(b / d * x, n),n/d); }
예제 #28
0
파일: brent.c 프로젝트: asgene/sm2
int main()
{  /*  factoring program using Brents method */
    long k,r,i,m,iter;
    big x,y,z,n,q,ys,c3;
#ifndef MR_STATIC
    miracl *mip=mirsys(16,0);         /* if allocating from the heap, specify size of bigs here */        
    char *mem=memalloc(7);            /* allocate and clear memory from the heap for 7 bigs     */
#else
    miracl *mip=mirsys(MR_STATIC,0);  /* If allocating from the stack, size of bigs is pre-defined */
    char mem[MR_BIG_RESERVE(7)];      /* reserve space on the stack for 7 bigs ...  */
    memset(mem,0,MR_BIG_RESERVE(7));  /* ... and clear this memory */
#endif

    x=mirvar_mem(mem,0);              /* 7 bigs have index from 0-6  */
    y=mirvar_mem(mem,1);
    ys=mirvar_mem(mem,2);
    z=mirvar_mem(mem,3);
    n=mirvar_mem(mem,4);
    q=mirvar_mem(mem,5);
    c3=mirvar_mem(mem,6);
    convert(3,c3);

    printf("input number to be factored\n");
    cinnum(n,stdin);
    if (isprime(n))
    {
        printf("this number is prime!\n");
        return 0;
    }
    m=10L;
    r=1L;
    iter=0L;
    do
    {
        printf("iterations=%5ld",iter);
        convert(1,q);
        do
        {
            copy(y,x);
            for (i=1L;i<=r;i++)
                mad(y,y,c3,n,n,y);
            k=0;
            do
            {
                iter++;
                if (iter%10==0) printf("\b\b\b\b\b%5ld",iter);
                fflush(stdout);  
                copy(y,ys);
                for (i=1L;i<=mr_min(m,r-k);i++)
                {
                    mad(y,y,c3,n,n,y);
                    subtract(y,x,z);
                    mad(z,q,q,n,n,q);
                }
                egcd(q,n,z);
                k+=m;
            } while (k<r && size(z)==1);
            r*=2;
        } while (size(z)==1);
        if (compare(z,n)==0) do 
        { /* back-track */
            mad(ys,ys,c3,n,n,ys);
            subtract(ys,x,z);
        } while (egcd(z,n,z)==1);
        if (!isprime(z))
             printf("\ncomposite factor ");
        else printf("\nprime factor     ");
        cotnum(z,stdout);
        if (compare(z,n)==0) return 0;
        divide(n,z,n);
        divide(y,n,n);
    } while (!isprime(n));
    printf("prime factor     ");
    cotnum(n,stdout);
#ifndef MR_STATIC
    memkill(mem,7);                  /* delete all 7 bigs */
#else
    memset(mem,0,MR_BIG_RESERVE(7)); /* clear memory used for bigs */
#endif
    return 0;
}
예제 #29
0
int main()
{  /*  factoring program using Lenstras Elliptic Curve method */
    int phase,m,k,nc,iv,pos,btch,u,v;
    long i,p,pa,interval;
    big q,x,z,a,x1,z1,x2,z2,xt,zt,n,fvw;
    static big fu[1+MULT/2];
    static BOOL cp[1+MULT/2];
    mip=mirsys(30,0);
    q=mirvar(0);
    x=mirvar(0);
    z=mirvar(0);
    a=mirvar(0);
    x1=mirvar(0);
    z1=mirvar(0);
    x2=mirvar(0);
    z2=mirvar(0);
    n=mirvar(0);
    t=mirvar(0);
    s1=mirvar(0);
    d1=mirvar(0);
    s2=mirvar(0);
    d2=mirvar(0);
    ak=mirvar(0);
    xt=mirvar(0);
    zt=mirvar(0);
    fvw=mirvar(0);
    w=mirvar(0);
    gprime(LIMIT1);
    for (m=1;m<=MULT/2;m+=2)
        if (igcd(MULT,m)==1)
        {
            fu[m]=mirvar(0);
            cp[m]=TRUE;
        }
        else cp[m]=FALSE;
    printf("input number to be factored\n");
    cinnum(n,stdin);

    if (isprime(n))
    {
        printf("this number is prime!\n");
        return 0;
    }
    prepare_monty(n);
    for (nc=1,k=6;k<100;k++)
    { /* try a new curve */
                             /* generating an elliptic curve */
        u=k*k-5;
        v=4*k;
        convert(u,x);  nres(x,x);
        convert(v,z);  nres(z,z);
        nres_modsub(z,x,a);   /* a=v-u */

        copy(x,t);
        nres_modmult(x,x,x);
        nres_modmult(x,t,x);  /* x=u^3 */

        copy(z,t);
        nres_modmult(z,z,z);
        nres_modmult(z,t,z);  /* z=v^3 */

        copy(a,t);
        nres_modmult(t,t,t);
        nres_modmult(t,a,t);  /* t=(v-u)^3 */

        convert(3*u,a); nres(a,a);
        convert(v,ak);  nres(ak,ak);
        nres_modadd(a,ak,a);
        nres_modmult(t,a,t);  /* t=(v-u)^3.(3u+v) */

        convert(u,a);  nres(a,a);
        copy(a,ak);
        nres_modmult(a,a,a);
        nres_modmult(a,ak,a);   /* a=u^3 */
        convert(v,ak); nres(ak,ak);
        nres_modmult(a,ak,a);   /* a=u^3.v */
        nres_premult(a,16,a);
        nres_moddiv(t,a,ak);     /* ak=(v-u)^3.(3u+v)/16u^3v */

        nc++;

        phase=1;
        p=0;
        i=0;
        btch=50;
        printf("phase 1 - trying all primes less than %d\n",LIMIT1);
        printf("prime= %8ld",p);
        forever
        { /* main loop */
            if (phase==1)
            {
                p=mip->PRIMES[i];
                if (mip->PRIMES[i+1]==0)
                { /* now change gear */
                    phase=2;
                    printf("\nphase 2 - trying last prime less than %ld\n",
                            LIMIT2);
                    printf("prime= %8ld",p);
                    copy(x,xt);
                    copy(z,zt);
                    nres_modadd(x,z,s2);
                    nres_modsub(x,z,d2);                    /*   P = (s2,d2) */
                    duplication(s2,d2,x,z);
                    nres_modadd(x,z,s1);
                    nres_modsub(x,z,d1);                    /* 2.P = (s1,d1) */

                    nres_moddiv(x1,z1,fu[1]);               /* fu[1] = x1/z1 */
                    
                    addition(x1,z1,s1,d1,s2,d2,x2,z2); /* 3.P = (x2,z2) */
                    for (m=5;m<=MULT/2;m+=2)
                    { /* calculate m.P = (x,z) and store fu[m] = x/z */
                        nres_modadd(x2,z2,s2);
                        nres_modsub(x2,z2,d2);
                        addition(x1,z1,s2,d2,s1,d1,x,z);
                        copy(x2,x1);
                        copy(z2,z1);
                        copy(x,x2);
                        copy(z,z2);
                        if (!cp[m]) continue;
                        copy(z2,fu[m]);
                        nres_moddiv(x2,fu[m],fu[m]);
                    }
                    ellipse(xt,zt,MULT,x,z,x2,z2);
                    nres_modadd(x,z,xt);
                    nres_modsub(x,z,zt);              /* MULT.P = (xt,zt) */
                    iv=(int)(p/MULT);
                    if (p%MULT>MULT/2) iv++;
                    interval=(long)iv*MULT; 
                    p=interval+1;
                    ellipse(x,z,iv,x1,z1,x2,z2); /* (x1,z1) = iv.MULT.P */
                    nres_moddiv(x1,z1,fvw);                /* fvw = x1/z1 */
                    nres_modsub(fvw,fu[p%MULT],q);
                    marks(interval);
                    btch*=100;
                    i++;
                    continue;
                }
                pa=p;
                while ((LIMIT1/p) > pa) pa*=p;
                ellipse(x,z,(int)pa,x1,z1,x2,z2);
                copy(x1,x);
                copy(z1,z);
                copy(z,q);
            }
            else
            { /* phase 2 - looking for last large prime factor of (p+1+d) */
                p+=2;
                pos=(int)(p%MULT);
                if (pos>MULT/2)
                { /* increment giant step */
                    iv++;
                    interval=(long)iv*MULT;
                    p=interval+1;
                    marks(interval);
                    pos=1;
                    nres_moddiv(x2,z2,fvw);
                    nres_modadd(x2,z2,s2);
                    nres_modsub(x2,z2,d2);
                    addition(x1,z1,s2,d2,xt,zt,x,z);
                    copy(x2,x1);
                    copy(z2,z1);
                    copy(x,x2);
                    copy(z,z2);
                }
                if (!cp[pos]) continue;

        /* if neither interval +/- pos is prime, don't bother */
                if (!plus[pos] && !minus[pos]) continue;
                nres_modsub(fvw,fu[pos],t);
                nres_modmult(q,t,q);
            }
            if (i++%btch==0)
            { /* try for a solution */
                printf("\b\b\b\b\b\b\b\b%8ld",p);
                fflush(stdout);
                egcd(q,n,t);
                if (size(t)==1)
                {
                    if (p>LIMIT2) break;
                    else continue;
                }
                if (compare(t,n)==0)
                {
                    printf("\ndegenerate case");
                    break;
                }
                printf("\nfactors are\n");
                if (isprime(t)) printf("prime factor     ");
                else            printf("composite factor ");
                cotnum(t,stdout);
                divide(n,t,n);
                if (isprime(n)) printf("prime factor     ");
                else            printf("composite factor ");
                cotnum(n,stdout);
                return 0;
            }
        }
        if (nc>NCURVES) break;
        printf("\ntrying a different curve %d\n",nc);
    } 
    printf("\nfailed to factor\n");
    return 0;
}
예제 #30
0
파일: pk-demo.c 프로젝트: asgene/sm2
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;
}