int main() {
    BIGNUM *tmp = NULL;
    BIGNUM *p = NULL, *q = NULL, *N = NULL, *e_value = NULL, *d = NULL;
    BIGNUM *r0=NULL,*r1=NULL,*r2=NULL;

    bn_ctx = BN_CTX_new();
    BN_CTX_init(bn_ctx);
    BN_CTX_start(bn_ctx);

    /* Generate RSA key using safe primes */
    p = BN_CTX_get(bn_ctx);
    BN_generate_prime_ex(p, 1024, 1, NULL, NULL, NULL);
    q = BN_CTX_get(bn_ctx);
    BN_generate_prime_ex(q, 1024, 1, NULL, NULL, NULL);
    N = BN_CTX_get(bn_ctx);
    BN_mul(N, p, q, bn_ctx);
    r0 = BN_CTX_get(bn_ctx);
    r1 = BN_CTX_get(bn_ctx);
    r2 = BN_CTX_get(bn_ctx);
    e_value = BN_new();
    d = BN_CTX_get(bn_ctx);
    BN_set_word(e_value, e);

    /* calculate d */
    BN_sub(r1,p,BN_value_one());    /* p-1 */
    BN_sub(r2,q,BN_value_one());    /* q-1 */
    BN_mul(r0,r1,r2,bn_ctx);   /* (p-1)(q-1) */
    BN_mod_inverse(d,e_value,N,bn_ctx);  /* d */

    Poly *poly = new Poly(threshold-1, N);

    /* Extract secret exponent */
    poly->set_coeff(0, d);

    /* Output modulus and public exponent */
    cout << BN_bn2hex(N) << endl;
    cout << BN_bn2hex(e_value) << endl;

    for (int i=0; i<num_nodes; i++) {
        tmp = poly->eval(i + 1);
        /* Output secret share */
        cout << BN_bn2hex(tmp) << endl;
    }

    delete poly;
    BN_CTX_end(bn_ctx);     
    BN_CTX_free(bn_ctx);
    return 0;
}