【问题标题】:RSA mpz_powm() in for-loop: seg faultfor循环中的RSA mpz_powm():段错误
【发布时间】:2013-11-22 05:16:17
【问题描述】:

这是previous question 的后续问题(现在实际问题不同了):

int main() 
{
    mpz_t p, q, n, phi_n, e, d; 
    mpz_inits(p, q, n, phi_n, e, d, NULL);

    generate_pq(p,q);
    compute_n(n,p,q);

    compute_phiN(phi_n,p,q);
    mpz_clear(p,q,NULL);

    select_e(e,phi_n);

    compute_d(d,e,phi_n);
    mpz_clear(phi_n);

    mpz_t* m;
    int size=0;
    store_m(m,size);

    mpz_t* c;
    encrypt(c,m,size,e,n);
    return 0;
}

以下是相关功能:

void store_m(mpz_t m[], int& size) 
{ /* m = original message */
    printf("\nMessage: ");
    char* buffer = new char[128];
    cin.getline(buffer,128);
    size = strlen(buffer); //size = buffer
    m = new mpz_t[size];
    for(int i=0; i<size; i++) {
        mpz_init(m[i]);
        mpz_set_ui(m[i],(int)buffer[i]);
    }
    delete buffer;
}

void encrypt(mpz_t*& c, mpz_t m[], const int size, 
                 const mpz_t e, const mpz_t n)
{ /* c = cipher */
    cout << "1" << endl;
    c = new mpz_t[size];
    cout << "2" << endl;
    for(int i=0; i<size; i++) {
        cout << "3" << endl;
        mpz_init(c[i]);
        cout << "4" << endl;
        mpz_powm(c[i],m[i],e,n);
        cout << "5" << endl;
        mpz_clear(m[i]);
        cout << "6" << endl;
    } /* c = m^e(mod n) */
    cout << "7" << endl;
}

当我执行时,程序进入 encrypt() 但在第 4 个 cout 出现段错误。

【问题讨论】:

  • 你能显示mpz_init吗?
  • 你指的是哪一个?
  • 没关系,这似乎不是问题。看我的回答。

标签: c++ segmentation-fault rsa gmp


【解决方案1】:

请记住,C++ 是按值传递的,除非您明确表示您使用 &amp; 运算符通过引用传递。在store_m() 中,您在函数内部分配和分配给m。这行不通,因为您按值传递 m。因此,main() 函数永远不会看到分配给m,因为store_m() 只有m 的本地副本。因此,您将一个未初始化的变量传递给encrypt()。要么在main() 中分配m,要么像这样声明store_m()

void store_m( mpt_t*&amp; m, int&amp; size);

顺便说一句:你没有在第 4 个cout 出现段错误。当encrypt() 函数准备调用mpz_powm() 时,您正在发生段错误。实际的崩溃是取消引用 m[i](因为 m 是未初始化的)。

【讨论】:

  • 不工作。我初始化的每个mpz_t* 现在都是通过引用传递的。 GMP 文档说 mpz_t 是“有效地”通过引用传递的,所以我不认为这是必要的。
  • “通过 ref 有效传递”表示各种 mpz_* 例程可以修改传入的对象。您仍然必须确保 main() 中的 m 在 store_m() 调用之后被分配和分配,以便 encrypt() 函数可以使用它。发布您修改后的代码。
  • 要修复您的代码,请将 m 中的 store_m() 设为局部变量而不是参数,并使用 return m;。然后在main()m = store_m( size );。你会看到解决了这个问题。这比通过参数初始化m 更容易。
  • 请务必记住delete mencrypt() 之后。在这个小程序中,您不需要这样做,因为程序在main() 返回时停止,但这是一件可怕的事情。最好养成自己打扫卫生的习惯。
  • 由于我在传递参数时遇到了所有麻烦,我只是删除了store_m()encrypt() 并将它们的定义放在main() 中。编译运行没问题。感谢您的所有帮助和信息!!!
猜你喜欢
  • 2016-07-27
  • 1970-01-01
  • 2013-08-21
  • 1970-01-01
  • 2017-09-13
  • 2016-06-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多