BIGNUM计算循环中的奇怪行为

时间:2013-03-11 16:34:02

标签: ios openssl

我正在尝试实现一个基本例程来对BIGNUM执行一些计算,我发现了一个奇怪的行为。功能如下

unsigned char *char_array_as_hex(unsigned char *chr_a, int len)
{
    unsigned char *chr_s = (unsigned char *)malloc(len * 2);
    char buffer[5];

    for (int i = 0; i < len; i++)
    {
        sprintf(buffer, "%02X", chr_a[i]);
        chr_s[(2 * i) + 0] = buffer[0];
        chr_s[(2 * i) + 1] = buffer[1];
    }

    return chr_s;
}

char *big_number_as_decimal_from_hex_array(unsigned char *chr_a, int len, BN_CTX *bn_ctx)
{
    unsigned char *hex_s = char_array_as_hex(chr_a, len);
    BIGNUM *big_number = BN_CTX_get(bn_ctx);
    BN_hex2bn(&big_number, (char *)hex_s);
    char *big_number_as_decimal = BN_bn2dec(big_number);

    free(hex_s);
    BN_free(big_number);

    return big_number_as_decimal;
}

void test_compute_prime256v1()
{
    BN_CTX *bn_ctx = BN_CTX_new();
    BN_CTX_start(bn_ctx);

    unsigned char seed_a[20] = {
        0xC4,0x9D,0x36,0x08,0x86,0xE7,0x04,0x93,0x6A,0x66,  /* seed */
        0x78,0xE1,0x13,0x9D,0x26,0xB7,0x81,0x9F,0x7E,0x90
    };
    printf("s = %s\n", big_number_as_decimal_from_hex_array(seed_a, 20, bn_ctx));

    unsigned char p_a[32] = {
        0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x01,0x00,0x00,  /* p */
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
        0xFF,0xFF
    };
    printf("p = %s\n", big_number_as_decimal_from_hex_array(p_a, 32, bn_ctx));

    BN_CTX_end(bn_ctx);
    BN_CTX_free(bn_ctx);
}

然后我在Objective-C方法中调用“test_compute_prime256v1”。如果我在每次调用之间以合理的延迟调用一次或多次它会产生正确的结果,但是当我在循环中调用该函数时会产生不同的错误值

- (IBAction)btnOK_Clicked:(id)sender
{
    for (int i = 1; i < 10; i++)
    {
        printf("i = %d\n", i);
        test_compute_prime256v1();
    }   
}

,示例输出

i = 1
s = 1122468115042657169822351801880191947498376363664
p = 115792089210356248762697446949407573530086143415290314195533631308867097853951
i = 2
s = 1122468115042657169822351801880191947498376363664
p = 966134380529368896499052403318808180610643774633026536153469502543482958881555881553276...
i = 3
s = 1122468115042657169822351801880191947498376363664
p = 115792089210356248762697446949407573530086143415290314195533631308867097853951

注意:修剪了一些数字以适应。我遵循了here中的建议。 我错过了什么吗?某处有错误吗? 有人可以帮忙吗?

由于

编辑:

我对代码进行了一些修改,但问题仍然存在。我更改了big_number_as_decimal_from_hex_array如下

char *big_number_as_decimal_from_hex_array_ex(unsigned char *chr_a, int len)
{
    BN_CTX *bn_ctx = BN_CTX_new();
    BN_CTX_start(bn_ctx);
    unsigned char *hex_s = char_array_as_hex(chr_a, len);
    BIGNUM *big_number = BN_CTX_get(bn_ctx);
    BN_hex2bn(&big_number, (char *)hex_s);
    char *big_number_as_decimal = BN_bn2dec(big_number);

    free(hex_s);
    BN_free(big_number);
    BN_CTX_end(bn_ctx);
    BN_CTX_free(bn_ctx);

    return big_number_as_decimal;
}

以及

char *big_number_as_decimal_from_hex_array_ex_2(unsigned char *chr_a, int len)
{
    BN_CTX *bn_ctx = BN_CTX_new();
    unsigned char *hex_s = char_array_as_hex(chr_a, len);
    BIGNUM *big_number = BN_CTX_get(bn_ctx);
    BN_hex2bn(&big_number, (char *)hex_s);
    char *big_number_as_decimal = BN_bn2dec(big_number);

    free(hex_s);
    BN_free(big_number);
    BN_CTX_free(bn_ctx);

    return big_number_as_decimal;
}

我将test_compute_prime256v1修改为

void test_compute_prime256v1_ex()
{
    unsigned char seed_a[20] = {...};
    printf("s = %s\n", big_number_as_decimal_from_hex_array_ex(seed_a, 20));
    unsigned char p_a[32] = {...};
    printf("p = %s\n", big_number_as_decimal_from_hex_array_ex(p_a, 32));
        // or
    unsigned char seed_a[20] = {...};
    printf("s = %s\n", big_number_as_decimal_from_hex_array_ex_2(seed_a, 20));
    unsigned char p_a[32] = {...};
    printf("p = %s\n", big_number_as_decimal_from_hex_array_ex_2(p_a, 32));
}

但代码在循环计算中产生相同的错误结果

1 个答案:

答案 0 :(得分:3)

BN_hex2bn(&amp; big_number,(char *)hex_s);期望一个C字符串作为第二个参数,即'\ 0'终止一个,因为它没有其他方法来知道你的字符串的大小。