관리 메뉴

개발이야기

[블록체인 이론] 비트코인과 이더리움 키, 주소 생성 방법 - 1 본문

블록체인 /블록체인 이론

[블록체인 이론] 비트코인과 이더리움 키, 주소 생성 방법 - 1

안성주지몬 2018. 9. 23. 19:57

이전 포스팅에서 아실 수 있듯이 최근 저는 '마스터링 이더리움'을 정리하고 있는데요. 초안 작성은 모두 끝났고 현재는 초안을 정리하는 중입니다. '마스터링 비트코인' , '마스터링 이더리움'을 정리하다 보니 공통적인 내용이 많았는데요. 

특히 'Key' 부분은 거의 똑같았습니다. '마스터링 비트코인'을 정리하면서 한 번 제대로 이해했던 내용이라 '마스터링 이더리움'을 보면서는 쉽게 쉽게 읽혔던 것 같습니다. 하지만 처음 제가 'Key' 부분을 접했을때는 굉장히 어려운 개념이었습니다. 그래서! 이번 포스팅에서는 저와 같이 'Key' 에 대해서 전반적으로 이해를 못하신 분들을 위해  'Key Overview' 을 포스팅할려고 합니다! 


1. 개인키 & 공개키 


비트코인, 이더리움은 모두 한 쌍의 키를 보유하고 있는데요. 바로 개인키(Private Key)와 공개키(Public Key) 입니다. 각각의 역할과 두 키가 어떻게 생성되는지 알아보도록 하죠 !


[그림 1] 키, 주소 생성 방법 (출처: Mastering Bitcoin Ch04)


키, 주소의 생성 방법은 위 그림에 다 나와있습니다. 지금으로서는 무슨 말일지 모르실겁니다. 하지만 이 포스팅 맨 마지막에서 이 그림을 다시 보시고 고개를 끄덕끄덕 하신다면! 키에 대해서 제대로 이해하시게 된 것입니다 !


- 개인키  


개인키(Private Key)는 계정의 소유권을 증명해주는 키입니다. 비트코인에서는 출금, 입금과 관련된 자금에 대한 소유권을 통제할 수 있게 해주고 이더리움에서는 EOA의 소유권을 설정하게 해줍니다.


비트코인과 이더리움에서 개인키의 역할을 살짝 다르지만 그 둘의 생성되는 원리는 같습니다.


생성 방법


개인키는 256비트의 무작위로 생성된 숫자들로 구성되어 있습니다. 프로그래밍 언어상에서 제공되는 간단한 생성기를 사용하면 안되고 완벽히 예측이 불가능한 도구를 이용하여 숫자를 생성하여야 안전합니다.  개인키는 1 ~ 2^256 -1 범위의 숫자 중 하나입니다. 


보관 방법


개인키는 거래에서 사용되는 자금의 소유권을 증명해주고 자금(비트코인이나 이더)을 보내는데 필요한 서명을 만드는데 사용되므로 자신이 아닌 다른 사람에게 절대 유출되지 않도록 각별한 주의를 해야합니다. 그래서 오프라인상에 따로 백업을 해두어서 유출이 안되게 해야 하고 잊어버리거나 잃어버리지 않게 해야 합니다. 


- 공개키  


개인키는 무작위 숫자로 256비트 범위내에 숫자라는 것이 전부입니다. 문제는 공개키입니다. 공개키를 생성하는 방법이 처음 보시는 분은 까다로울 수 있기 때문에 차근차근 풀어서 설명해보겠습니다. 


공개키 (K)는 K = k * G 라는 수식으로 만들어집니다. 여기서 k는 개인키를 의미하고 G는 'Generator point)로 타원 곡선 위의 임의의 값을 뜻합니다. 


타원 곡선 함수 ? 


ecc-curve

[그림 2]  타원 곡선 함수 (출처: Mastering Bitcoin Ch04)


공개키는 특정한 타원 곡선(secp256k1)과 수학적 상수를 사용하여 만들어집니다.  여기서 수학적 상수는 secp256k1이라는 곡선에서 정의되는 값입니다.



ecc_illustrated

[그림 3] K = k * G 계산 예시 (출처 : Mastering Bitcoin Ch 04)


그렇다면 타원 곡선 함수를 이용하여 k * G를 어떻게 구하는 것일까요? 우선 k * G의 의미를 수학적으로 풀어서 생각해봅시다. 일반적으로 kG라는 것은 G + G + G ... +G , 즉 G를 k번 더한 것(k번 반복한다)을 의미합니다. 이 원리를 타원 곡선 함수에 적용한 것이 위에 그림입니다. 


우선 임의의 점 G 에서 시작합니다. (임의의 점 G는 모든 사용자가 동일합니다). 점 G에서 접선을 긋게 되면 타원 곡선 특성상 점 G와 다른 곡선 상에 접점을 하나 더 만나게 됩니다. 이를 -2G라고 합니다. -2G를 x 축 대칭을 하면 2G가 됩니다. 이 행동을 k(개인키) 만큼 반복하면 kG를 구할 수 있는 것이죠. 정리하면


1) 임의의 점 G에서 접선을 그어 만나는 다른 접점을 찾는다.

2) 찾은 접점을 x축 대칭시킨다.

3) 1),2) 과정을 k번 반복하여 K를 찾는다. 


이렇게 공개키가 생성되게 됩니다 ! 


- 주소 


그렇다면 주소는 어떻게 생성될까요 ? 주소는 공개키에 의해 생성이 됩니다. 

주소는 SHA256과 RIPEMD160(Race Integrity Primitives Evaluation Message Digest) 해시 함수를 사용하여 공개키로부터 생성이되는데요. 

보통 공개키에 SHA256, RIPEMD160을 차례로 적용한 결과 160bits(20Bytes)를 주소로 사용하게 됩니다.

또한 주소는 대부분 Base58Check를 기반으로 암호화 됩니다. 위 과정을 차례로 차근차근 설명해보도록 하겠습니다.


* RIPEMD ? 

RIPEMD란 MD4라는 해시 함수를 기반으로 개발한 암호화 해시 알고리즘입니다. 임의의 길이의 메시지에서 128또는 160비트의 메시지 요약을 생성하며 32비트 연산에 최적화 되어 있습니다. 또한 생성되는 메시지 요약의 길이에 따라서 RIPEMD160을 병렬 연결한 것이 RIPEMD320입니다. 


pubkey_to_address


[그림 4] 공개키에서 주소를 생성하는 방법 (출처 : Mastering Bitcoin Ch04)


위 그림에서 볼 수 있듯이 우선 공개키를 SHA256해시를 사용하여 해시화하고 다시 RIPEMD160을 이용하여 160비트 크기로 해시화 하여 줍니다. 이 Public Key Hash 를 Base58Check Encode하게 됩니다. 


Base58Check Encoding?


[그림 5] Bitcoin's Base58 alphabet (출처 : Mastering Bitcoin Ch04)

Base58은 binary data를 text로 변경해주는 encoding 기법 중 하나입니다. Base64보다 표현할 수 있는 범위가 작지만 Base58을 사용하는 이유는 숫자와 혼동될 수 있는 단어들 예를 들어 O(문자 O는 숫자 0과 헷갈릴 수 있다), I등을 제거하였기 때문입니다. 




Base58CheckEncoding


[그림 6] Base58Check Encoding 과정 (출처: Mastering Bitcoin Ch04)


Base58Check Encoding 과정을 순서대로 살펴보도록 하겠습니다. 먼저 payload(data)에 1byte 크기의 Version Byte라고 불리는 접두사(prefix)를 붙여줍니다. (비트코인의 경우 0x0, 개인키를 인코딩한 것은 0x80 입니다) (1번) 

그리고 sha256 해시 연산을 두 번 해줍니다. 즉 , sha256(sha256(prefix + data)) (2번)

2번의 결과로 32byte (256bits) 크기의 결과값이 생성되면 첫 4bytes가 error-check code 가 됩니다. 이를 checksum이라 부릅니다. 즉, checksum = sha256(sha256(prefix + data))인 것이죠. (3번)

이제 이를 Base58Encode 하게 됩니다. (4번)

 

*Checksum은 전송 및 타이핑 오류를 감지하고 방지하는 데 사용할 수 있습니다. Base58Check 코드가 제공되면 디코딩 소프트웨어는 데이터의 Checksum을 계산하여 코드에 포함 된 Checksum과 비교합니다. 두 개가 다르면 오류가 발생하고 Base58Check 데이터는 유효하지 않게 됩니다. 이렇게 되면 잘못 입력된 비트코인 주소가 지갑 소프트웨어에서 유효한 대상으로 승인이 되지가 않으므로 자금의 손실이 일어나지 않게 됩니다.



네 이상으로 주소의 생성 방법까지 알게 되었습니다. 다시 아래 그림을 보겠습니다. 



privk_to_pubK_to_addressA


[그림 7] 키, 주소 생성 방법 (출처: Mastering Bitcoin Ch04)


처음 이 그림을 봤을때와는 어떠신가요? 그림이 대략적으로 이해되시나요 ? 네! 그렇다면 이제 키, 주소 생성 방법을 이해하고 계신겁니다!

모르시는 부분이나 제가 틀린 부분이 있으면 망설이지 마시고 댓글로 남겨주세요 !

여러분의 피드백이 더욱 좋은 포스팅을 완성시키는데 도움이 됩니다 !!

긴 글 읽어주셔서 감사합니다. 다음 포스팅은 실제 코드상에서 키, 주소를 어떻게 생성하는지 살펴보도록 하겠습니다.



출처 

1. Mastering Bitcoin

https://github.com/AhnSungJoo/bitcoinbook/blob/develop/ch04.asciidoc

2. Mastering Ethereuem

https://github.com/AhnSungJoo/ethereumbook/blob/develop/keys-addresses.asciidoc

Comments