2013-03-11 2 views
2

J'essaye d'implémenter une routine de base pour effectuer un calcul sur BIGNUM (s) et j'ai trouvé un comportement étrange. Les fonctions sont les suivantes dans une méthode Objective-CBIGNUM comportement étrange dans une boucle de calcul

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; 
} 

et

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; 
} 

et

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); 
} 

j'appelle "test_compute_prime256v1". Si je l'appelle une ou plusieurs fois avec un délai raisonnable entre chaque appel, il produit un résultat correct mais, quand je l'appelle cette fonction dans une boucle il produit différentes valeurs incorrectes

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

et une sortie de l'échantillon était

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

Note: certains nombres sont ajustés pour s'adapter. J'ai suivi la suggestion dans here. Ai-je raté quelque chose? Y a-t-il une erreur quelque part? Quelqu'un peut-il aider?

Merci

: ÉDITÉ

quelques modifications que je fait au code, mais le problème existe toujours. J'ai changé big_number_as_decimal_from_hex_array comme suit

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; 
} 

et aussi

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; 
} 

Je modifié le test_compute_prime256v1 comme

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)); 
} 

mais le code produit le même résultat erroné dans un calcul en boucle

+0

J'ai testé votre code sous linux gcc 64bits et n'a obtenu aucun résultat bizarre. Je n'ai pas utilisé de gui mais le code n'est pas appelé dans un rappel guidé par un gui. –

+0

deviner rapidement serait de réinitialiser le contexte entre le calcul s et p ou pour obtenir deux bignumbers à distance puisque http://www.openssl.org/docs/crypto/BN_CTX_start.html affirme que tous les appels BN_CTX_get() doivent être faits avant d'appeler toutes les autres fonctions qui utilisent le ctx comme argument. –

+0

J'ai modifié le code pour refléter votre suggestion mais le résultat reste le même. Il produit un résultat incorrect dans un calcul en boucle. Je l'ai testé sur un simulateur iOS 6.0 (iPhone 5.0) sous mac-os-x lion 64bit. – anonim

Répondre

3

BN_hex2bn (& big_number, (char *) il x_s); attend une chaîne C comme deuxième argument, c'est-à-dire un '\ 0' terminé car il n'a pas d'autre moyen de connaître la taille de votre chaîne.

+0

Merci, la documentation Open SSL est trop pauvre et en tant que novice j'ai fait une telle erreur. Merci encore – anonim