// Generate an RSA public/private key pair suitable for a software "CD key" #include #include #include void print_decoder_key(const char *name, mpz_t value, int size) { int i; mpz_t v; mpz_init_set(v, value); printf(" "); for(i=0;i\nGenerate a public-private key pair with nbits bits.\nAs a general guideline, there are five bits for every character in the \"CD key\" code.\n", argv[0]); return 0; } int nbits = atoi(argv[1]); gmp_randinit_mt(rs); // generate random primes p and q mpz_init(p); mpz_init(q); randomprime(p, rs, nbits/2); gmp_printf("p: %Zd\n", p); randomprime(q, rs, nbits - mpz_sizeinbase(p, 2)); gmp_printf("q: %Zd\n", q); // generate n = pq mpz_init(n); mpz_mul(n, p, q); // generate totient mpz_init(t1); mpz_init(t2); mpz_init(tot); mpz_sub_ui(t1, p, 1); mpz_sub_ui(t2, q, 1); mpz_mul(tot, t1, t2); // gmp_printf("tot: %Zd\n", tot); // generate encryption and decryption exponents mpz_init(e); mpz_init(d); do { mpz_urandomm(e, rs, tot); mpz_invert(d, e, tot); } while(mpz_sgn(d) != 1); gmp_printf("n: %Zd\n", n); gmp_printf("e: %Zd\n", e); gmp_printf("d: %Zd\n", d); printf("encoder keys:\n"); gmp_printf(" mpz_t n,e;\n mpz_init_set_str(n, \"%Zd\", 10); /* %d bits */\n", n, mpz_sizeinbase(n, 2)); gmp_printf(" mpz_init_set_str(e, \"%Zd\", 10);\n", e); { int size = 1+(mpz_sizeinbase(n, 2)/32); printf("decoder keys:\n"); printf(" ubint<%d> n,d;\n", size); print_decoder_key("n", n, size); print_decoder_key("d", d, size); } return 0; }