2

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」を呼び出します。各呼び出しの間に妥当な遅延を置いて1回または複数回呼び出すと、正しい結果が生成されますが、ループでその関数を呼び出すと、異なる誤った値が生成されます。

- (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

注:一部の数値は、収まるようにトリミングされています。ここでの提案に従いました。私は何かが足りないのですか?どこかに間違いはありますか?誰でも助けることができますか?

ありがとう

編集:

コードにいくつかの変更を加えましたが、問題はまだ存在します。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));
}

しかし、コードはループ計算で同じ誤った結果を生成します

4

1 に答える 1

3

BN_hex2bn(&big_number、(char *)hex_s); 2番目の引数としてC文字列を想定しています。つまり、文字列のサイズを知る他の方法がないため、「\0」で終了します。

于 2013-03-12T17:52:14.380 に答える