본문 바로가기
Sejong University/Public-key cryptography

Extended GCP in public key crypto

by reindeer002 2022. 4. 23.
728x90
#유클리드 알고리즘
def gcd(a, b):
    if b == 0: #만약 b가 0이라면 a가 gcd
        return a
    else: #b가 0이 아니라면 정수배 선형결합을 한 값을 주고 재귀
        return gcd(b, a%b)

#확장 유클리드 알고리즘
def extended_gcd(a, b):
    r0, r1 = a, b #초기 r0, r1값 초기화
    x0, y0 = 1, 0 #초기 x0, y0값 초기화
    x1, y1 = 0, 1 #초기 x1, y1값 초기화
    gcd_value = gcd(a, b) #gcd값을 추출
    while gcd_value != r1: #r1이 gcd에 도달할 때까지
        x0, y0, x1, y1 = x1, y1, x0-(r0//r1)*x1, y0-(r0//r1)*y1
        #확장 유클리드 알고리즘에 의한 다음 x, y값 초기화
        r0, r1 = r1, r0%r1
        #다음 q값(r0//r1)을 얻기 위한 초기화
        #print('{} = {}*{} + {}*{}'.format(r1, a, x1, b, y1))
        #계산이 올바르게 수행되는지 확인하기 위한 출력
    return x1, y1 #x, y값 반환

#결과가 올바르게 나왔는지 확인하는 함수
def verify(x, y, d, a, b):
    if d == a*x + b*y: #올바르게 구했다면 Correct 출력
        print("Correct")
    else: #올바르지 않다면 Wrong 출력
        print("Wrong")

#해를 구하고자 하는 방정식의 출력함수
def printans(a, b, num):
    egcd_x, egcd_y = extended_gcd(a, b) #x, y값 초기화
    print(num+") ({}, {})".format(egcd_x, egcd_y)) #출력
    verify(egcd_x, egcd_y, gcd(a, b), a, b) #올바른지 확인


print("-----answer form: (x, y) => ax + by = d-----")
printans(45, 78, "a")
printans(666, 1428, "b")
printans(1020, 10290, "c")
printans(2 ** 20 + 4, 3 ** 10 + 5, "d")
printans(2 ** 30 + 1, 3 ** 30 + 6, "e")
'''
printans(1180, 482, "test1")
printans(240, 46, "test2")
'''

 

#include <stdio.h>
#include <openssl/bn.h>

void printBN(char *msg, BIGNUM * a)
{
        char * number_str = BN_bn2dec(a);
        printf("%s %s\n", msg, number_str);
        OPENSSL_free(number_str);
}

BIGNUM *XEuclid(BIGNUM *x, BIGNUM *y, const BIGNUM *a, const BIGNUM *b)
{
	BN_CTX *ctx = BN_CTX_new();
  	BIGNUM *r = BN_new();
  	BIGNUM *a_copy = BN_new();
  	BIGNUM *b_copy = BN_new();
  	BN_copy(a_copy, a);
  	BN_copy(b_copy, b);
  	while (!BN_is_zero(b_copy))
  	{
		if(!BN_mod(r,a_copy,b_copy,ctx))
			return NULL;
		BN_copy(a_copy,b_copy);
		BN_copy(b_copy,r);
  	}
  	BN_copy(r,a_copy);
  	BN_free(a_copy); BN_free(b_copy);

  	BIGNUM *x0 = BN_new(); BIGNUM *x1 = BN_new(); BIGNUM *x_copy = BN_new();
  	BIGNUM *y0 = BN_new(); BIGNUM *y1 = BN_new(); BIGNUM *y_copy = BN_new();
  	BIGNUM *r0 = BN_new(); BIGNUM *r1 = BN_new(); BIGNUM *r_copy = BN_new();
  	BIGNUM *tx = BN_new(); BIGNUM *ty = BN_new();
  	BIGNUM *dv = BN_new(); BIGNUM *rem = BN_new();
  	BN_dec2bn(&x0, "1"); BN_dec2bn(&y0, "0"); 
	BN_dec2bn(&x1, "0"); BN_dec2bn(&y1, "1");
	BN_copy(r0, a); BN_copy(r1, b);
	while(BN_cmp(r, r1))
	{
		BN_copy(tx, x1); BN_copy(ty, y1);
		if(!BN_div(dv, rem, r0, r1, ctx))
			return NULL;
		if(!BN_mul(x_copy, dv, x1, ctx))
			return NULL;
		BN_sub(x1, x0, x_copy);
		if(!BN_mul(y_copy, dv, y1, ctx))
			return NULL;
		BN_sub(y1, y0, y_copy);
		BN_copy(x0, tx); BN_copy(y0, ty);
		BN_copy(r_copy, r1);
		if(!BN_mod(r1, r0, r1, ctx))
			return NULL;
		BN_copy(r0, r_copy);
	}
	BN_copy(x, x1);
	BN_copy(y, y1);
	if(ctx != NULL)
  		BN_CTX_free(ctx);
  	BN_free(x0); BN_free(x1); BN_free(x_copy);
  	BN_free(y0); BN_free(y1); BN_free(y_copy);
  	BN_free(r0); BN_free(r1); BN_free(r_copy);
  	BN_free(tx); BN_free(ty); BN_free(dv); BN_free(rem);
	return r;
}

int main (int argc, char *argv[])
{
	BIGNUM *a = BN_new();
	BIGNUM *b = BN_new();
	BIGNUM *x = BN_new();
	BIGNUM *y = BN_new();
	BIGNUM *gcd;
	
	if(argc != 3){
		printf("usage: xeuclid num1 num2");
		return -1;
	}

	BN_dec2bn(&a, argv[1]);
	BN_dec2bn(&b, argv[2]);
	
	gcd = XEuclid(x,y,a,b);
	
	printBN("(a,b) = ", gcd);
	printBN("a = ", a);
	printBN("b = ", b);
	printBN("x = ", x);
	printBN("y = ", y);
	printf("%s*(%s) + %s*(%s) = %s\n",BN_bn2dec(a),BN_bn2dec(x),BN_bn2dec(b),BN_bn2dec(y),BN_bn2dec(gcd));

	if(a != NULL) BN_free(a);
	if(b != NULL) BN_free(b);
	if(x != NULL) BN_free(x);
	if(y != NULL) BN_free(y);
	if(gcd != NULL) BN_free(gcd);
	return 0;
}
728x90

'Sejong University > Public-key cryptography' 카테고리의 다른 글

DH Key Agreement  (0) 2022.04.24
Hashed-RSA  (0) 2022.04.24
RSA crypto with miller_rabin and non-miller_rabin  (0) 2022.04.23
Prime with Miller Rabin test  (0) 2022.04.23
Modular exponentiation and CRT  (0) 2022.04.23

댓글