GMP的mpz_init_set_str导致重新分配错误

时间:2019-06-16 22:45:49

标签: c gmp

我正在使用gmp进行项目以实现基本的DH交换。此交换有两个主要功能,一个是从私有密钥创建一个公共密钥,另一个是通过私有密钥和公共密钥生成共享密钥。

在第一个函数中,我对gmp lib的调用按预期工作。在第二个函数中,我的mpz_init_set_str调用要么导致段错误,要么中止并显示消息

realloc():旧大小无效 中止(核心已弃用)

malloc.c:2868:mremap_chunk:断言`(((size + offset)&(GLRO(dl_pagesize)-1))== 0'失败。

导致此问题的行在第一个函数中被逐字使用,我无法弄清楚是什么原因造成的。

下面是一个示例程序,该示例程序在我的计算机上运行时演示了该问题。 我正在使用gcc(Ubuntu 7.4.0-1ubuntu1〜18.04.1)7.4.0。和libgmp10版本2:6.​​1.2 + dfsg-2

#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "gmp.h"
#include "time.h"

#define SECRET_KEY_SIZE             64
#define PRIVATE_KEY_SIZE            512

#define DH_KEY_EXCHANGE_P "96C99B60C4F823707B47A848472345230C5B25103DC37412A701833E8FF5C567A53A41D0B37B10F0060D50F4131C57CF1FD11B6A6CB958F36B1E7D878A4C4BC7"
#define DH_KEY_EXCHANGE_G "2C900DF142E2B839E521725585A92DC0C45D6702A48004A917F74B73DB26391F20AEAE4C6797DD5ABFF0BFCAECB29554248233B5E6682CE1C73DD2148DED76C3"

#define BASE_HEX            16
#define BASE_RADIX          32

char intToCharBase32(int input)
{
    char ret = 0;
    if(input <= 9)
    {
        ret = '0' + input;
    }
    else if(input < 32)
    {
        ret = (input - 10) + 'A';
    }
    return ret;
}

void generateRandomKey(char *random_number_buffer, int len)
{
    short int n;
    srand(time(0));
    for(int i=0; i<len; i++)
    {
        n = rand() % BASE_RADIX;
        random_number_buffer[i] = intToCharBase32(n);
    }
    random_number_buffer[len] = '\0';
}

void calculateDHPublicKey(char *public_key, char *private_key)
{
    mpz_t p;
    mpz_t g;
    mpz_t b;
    mpz_t B;

    mpz_init (B);
    mpz_init_set_str (p, DH_KEY_EXCHANGE_P, BASE_HEX);
    mpz_init_set_str (g, DH_KEY_EXCHANGE_G, BASE_HEX);
    mpz_init_set_str (b, private_key, BASE_RADIX);

    mpz_powm (B, g, b, p);

    mpz_get_str(public_key, BASE_RADIX, B);

    mpz_clear (p);
    mpz_clear (g);
    mpz_clear (b);
    mpz_clear (B);
}

void calculateDHSharedSecret(unsigned char *dh_key_buffer, char *own_private_key, char *other_public_key)
{
    mpz_t p;
    mpz_t b;
    mpz_t A;
    mpz_t SS;

    mpz_init (SS);
    mpz_init_set_str (p, DH_KEY_EXCHANGE_P, BASE_HEX); // <--This line crashes
    mpz_init_set_str (b, own_private_key, BASE_RADIX);
    mpz_init_set_str (A, other_public_key, BASE_RADIX);

    mpz_powm (SS, A, b, p);

    size_t size = 0;

    //todo: move this to the right place (add leading zeros as needed);
    mpz_export(dh_key_buffer, &size, 1, -1, 0, 0, SS);

    mpz_clear (p);
    mpz_clear (b);
    mpz_clear (A);
    mpz_clear (SS);
}

int main (){

    char* private_key = malloc(sizeof(char) * (PRIVATE_KEY_SIZE / BASE_RADIX + 2));
    generateRandomKey(private_key, PRIVATE_KEY_SIZE / BASE_RADIX);
    fprintf(stderr, "Private Key: %s\n", private_key);

    //step 2: generate public key
    char* public_key = malloc(sizeof(char) * (2048 / BASE_RADIX + 1));
    calculateDHPublicKey(public_key, private_key);

    //step 3: share the public key
    fprintf(stderr, "Public Key: %s\n", public_key);

    //step 4: Calculate shared secret
    unsigned char* sharedSecret = malloc(sizeof(unsigned char) * SECRET_KEY_SIZE);
    memset(sharedSecret, 0, SECRET_KEY_SIZE);

    char* other_pk = "1";
    //for debugging just use 1 as the other side of dh handshake
    calculateDHSharedSecret(sharedSecret, private_key, other_pk);

    //step 5: release resources
    free(private_key);
    free(public_key);
    return 0;
}

我尝试使用mpz_init,然后使用mpz_set_str而不是mpz_init_set_str,并且该功能仍然中止。

我能够使用mpz_init2并提供初始大小作为解决方法,但是在我的项目后面,我将不知道所需的大小,因此希望避免将其确定为额外的步骤。

(我很清楚,生成随机密钥的方法要好得多,并且rand()在密码上是不安全的,但是该项目将用于演示此问题以及其他常见的安全问题)< / p>

0 个答案:

没有答案