Network/OpenSSL

[OpenSSL] BigInteger 빅 넘버 라이브러리

crypsec 2023. 11. 7. 22:54
반응형

"빅 넘버" 또는 "빅넘", BigInteger은 일반적인 정수 데이터 타입의 범위를 넘어선 매우 큰 정수를 의미합니다. 예를 들어, 수백 자리 이상의 정수를 다루는 경우에 필요합니다. 대부분의 프로그래밍 언어는 일반적으로 제공하는 정수 타입의 범위를 초과하는 큰 정수를 다루기 어렵기 때문에, 이런 경우에는 빅 넘버 (Big number) 라이브러리를 사용합니다.

 

예를 들어, C언어에서는 GMP, OpenSSL 라이브러리와 같은 빅 넘버 라이브러리를 사용하여 큰 정수를 다룰 수 있습니다. 마찬가지로 JAVA에도 BigInteger 라이브러리가 있습니다. Python에서는 내장된 빅 넘버 지원이 있어 별도의 라이브러리 없이도 큰 정수를 다룰 수 있습니다. 다만 이 또한 한계가 있기 때문에 저 같은 경우 Python에서 따로 SageMath을 이용합니다.


사용 방법은 아래 URL에서 확인 가능합니다. 하지만 그럼에도 처음 사용할 때는 엄청 헤매게 됩니다. 제가 그랬습니다😢
https://gmplib.org/

https://www.openssl.org/docs/manpages.html

https://www.sagemath.org/


따라서 OpenSSL을 사용하여 빅 넘버(큰 정수)를 다루는 방법을 설명해 드리겠습니다. 아래는 OpenSSL을 사용하여 빅 넘버를 생성하고 연산하는 간단한 예제 코드입니다.

빅 넘버 생성하기

#include <openssl/bn.h>

int main() {
    
    BIGNUM *a = BN_new();
    BIGNUM *b = BN_new();
    BIGNUM *result = BN_new();

    BN_set_word(a, 123);  // a = 123, BN_dec2bn(&a , "123"); 이런 방법도 있다.
    BN_set_word(b, 456);  // b = 456, BN_dec2bn(&b , "456");
    
    printf("a = %s\n",BN_bn2dec(a));
    printf("b = %s\n",BN_bn2dec(b));
    BN_add(result, a, b);  // result = a + b

    char *result_str = BN_bn2dec(result);  // 결과를 문자열로 변환
    printf("Result: %s\n", result_str);

    // 메모리 해제
    BN_free(a);
    BN_free(b);
    BN_free(result);
    OPENSSL_free(result_str);

    return 0;
}

빅 넘버의 덧셈과 뺄셈

#include <openssl/bn.h>

int main() {

    BIGNUM *a = BN_new();
    BIGNUM *b = BN_new();
    BIGNUM *result = BN_new();

    BN_set_word(a, 789);
    BN_set_word(b, 123);

    BN_add(result, a, b);  // result = a + b
    printf("Addition: %s\n", BN_bn2dec(result));

    BN_sub(result, a, b);  // result = a - b
    printf("Subtraction: %s\n", BN_bn2dec(result));

    // 메모리 해제
    BN_free(a);
    BN_free(b);
    BN_free(result);

    return 0;
}

빅 넘버의 곱셈과 나눗셈

#include <openssl/bn.h>

int main() {

    BIGNUM *a = BN_new();
    BIGNUM *b = BN_new();
    BIGNUM *result = BN_new();
    BIGNUM *rem = BN_new();

    BN_set_word(a, 123);
    BN_set_word(b, 372);
    BN_CTX *ctx = BN_CTX_new();

    BN_mul(result, a, b, ctx);  // result = a * b
    printf("곱셈 결과: %s\n", BN_bn2dec(result));

    BN_div(result, rem, b, a, BN_CTX_new()/*또는 ctx 사용가능*/);  // result = a / b
    printf("몫: %s\n", BN_bn2dec(result));
    printf("나머지: %s\n", BN_bn2dec(rem));

    // 메모리 해제
    BN_free(a);
    BN_free(b);
    BN_free(result);
    BN_free(rem);
    BN_CTX_free(ctx);

    return 0;
}

 

이 코드들은 OpenSSL의 BIGNUM 구조체와 관련 함수들을 사용하여 빅 넘버를 다루는 간단한 예제입니다. 각각의 예제에서 빅 넘버를 생성하고 연산한 후에는 반드시 메모리를 해제해야 합니다.

 

필요한 경우 OpenSSL 라이브러리의 문서를 참조하여 더 자세한 정보를 얻을 수 있습니다. 예제에서 보셨다시피 빅넘버 관련 기능은 대부분 bn으로 시작합니다. 또한 매우 큰 의사 소수나 난수 등을 생성하는 기능을 하는 함수도 있습니다.

 

이는 공식 문서를 찾아보는 습관을 들여야 합니다. 이런 정보를 정리해 두는 곳은 제 경험상 없어서 검색해도 잘 안 뜨는 경우가 많고 잘못된 정보도 많습니다.

반응형