Browse Source

Base58 인코딩 쓰는중

iwanhae 3 years ago
parent
commit
4866f5f7ec
5 changed files with 40 additions and 4 deletions
  1. 1 1
      1_시작하는글.md
  2. 5 1
      2_비트코인에대한얘기.md
  3. 34 2
      4_지갑과_비트코인_주소.md
  4. BIN
      img/4_1.gif
  5. BIN
      img/4_3.jpg

+ 1 - 1
1_시작하는글.md

@@ -2,7 +2,7 @@
 
  컴퓨터업계에 관련되있는 사람들은 한번쯤은 비트코인에 대해서 들어보았을 것이다. 이는 필자도 예외가 아니며 필자가 처음 비트코인에 대해 들어본것은 2011년 겨울, 금융학을 공부하는 캐나다인이 금융학과 컴퓨터공학의 결합해 만들어진 비트코인에대해 알아볼것을 권유하면서 이다. 다만 당시 비트코인은 매우 초기단계였고 그 명성은 지금과 같지 않아 필자는 단순히 사이버 머니의 아류정도로 생각하고 넘어갔다.
 
- 그렇게 무심코 넘겼던 비트코인을 다시 만나게 된 것은 2013년 겨울 비트코인의 가치가 폭등에 모두가 비트코인에 관심을 가지고 비트코인의 정체에 대해 탐구했을 때 이다. 비록 당시 광풍은 보란듯이 엄청난 폭락과 함께 대부분의 사람들의 기억속에서 사라져갔지만 필자는 비트코인이 도대체 어떤 원리를 가지기에 이렇게 큰 붐을 일으킬 수 있었나? 에대해 탐구해보았고 비트코인 고유기술인 블록체인에 대해 이해했을때 비트코인의 첫인상은 "어쩜 이리 비효율적일수가 있지?" 였다. 이러한 생각이 돌출하게된 가장 큰 이유는 블록체인의 크기가 약 매 10분마다 1MB씩, 한달에 약 4GB씩. 1년에 약 50GB씩 커지기만 하고 줄어들지는 않는다는 구조 때문이었다. 물론 이는 비트코인을 통한 거래내역이 매 10분마다 약 1천건 이상씩 발생때의 상황이며 당시에는 이론에 불과했던 이야기이자만  2016년 이후로는 실제 그러하게 거래가 발생해 2016년 6월 70GB라는 크기였던 블록체인은 2017년 6월 120GB에 다달해 실제 매년 약 50GB씩 커지고 있다. 물론 저장용량 값이 나날히 싸지는 오늘날 이는 큰 문제가 되진 않지만 2013년 당시에는 이론적으로 매년 50GB씩 커지는 크기를 모든 채굴자들이 가지고있어야 한다는 아이디어는 심히 이해하기 힘들었다. 그뿐아니라 채굴을 위해서 연산하는것은 비트코인 그 자체를 제외하고는 완전히 쓸모가 없고, 거래가 성사되기까지 수십분의 시간이 걸린다는 아이디어도 그당시 이해하기 힘들었다. (이 모든것은 신뢰기관 하나만 존재하면 엄청나게 쉽고 효율적이게 해결 가능한 사항들이다.)
+ 그렇게 무심코 넘겼던 비트코인을 다시 만나게 된 것은 2013년 겨울 비트코인의 가치가 폭등에 모두가 비트코인에 관심을 가지고 비트코인의 정체에 대해 탐구했을 때 이다. 비록 당시 광풍은 보란듯이 엄청난 폭락과 함께 대부분의 사람들의 기억속에서 사라질때쯤 필자는 비트코인이 도대체 어떤 원리를 가지기에 이렇게 큰 붐을 일으킬 수 있었나? 에대해 탐구해보았고 비트코인 고유기술인 블록체인에 대해 이해했을때 비트코인의 첫인상은 "어쩜 이리 비효율적일수가 있지?" 였다. 이러한 생각이 돌출하게된 가장 큰 이유는 블록체인의 크기가 약 매 10분마다 1MB씩, 한달에 약 4GB씩. 1년에 약 50GB씩 커지기만 하고 줄어들지는 않는다는 구조 때문이었다. 물론 이는 비트코인을 통한 거래내역이 매 10분마다 약 1천건 이상씩 발생때의 상황이며 당시에는 이론에 불과했던 이야기이자만  2016년 이후로는 실제 그러하게 거래가 발생해 2016년 6월 70GB라는 크기였던 블록체인은 2017년 6월 120GB에 다달해 실제 매년 약 50GB씩 커지고 있다. 물론 저장용량 값이 나날히 싸지는 오늘날 이는 큰 문제가 되진 않지만 2013년 당시에는 이론적으로 매년 50GB씩 커지는 크기를 모든 채굴자들이 가지고있어야 한다는 아이디어는 심히 이해하기 힘들었다. 그뿐아니라 채굴을 위해서 연산하는것은 비트코인 그 자체를 제외하고는 완전히 쓸모가 없고, 거래가 성사되기까지 수십분의 시간이 걸린다는 아이디어도 단지 신뢰기관 (혹은 중앙기관) 하나의 존재만으로도 손쉽게 해결할 수 있으므로 그당시 이해하기 힘들었다. 
 
  하지만 이러한 생각도 비트코인의 탄생목적이 "완전하게 분산적인 구조를 취해 그 어떤 중앙기관의 존재없이 화폐시스템을 구현하는것" 이었다는것을 깨달았을때 완전히 뒤바뀌게 되었다. 중앙기관의 존재는 위에서 언급한 모든 문제를 해결하기 무지 쉬워지지만, 그와함께 한가지 큰 문제가 딸려오게 되는데 그것은 바로 중앙기관이 부정을 일으키면 아무도 적발하지 못하고 아무도 정정하지 못한다는 것이다. 이러한 중앙기관 부정의 위협으로부터 벗어나기위한 시스템이 바로 비트코인인 것을 깨달았을때 처음 생각하게 된것은 "정녕 비트코인이 최선의 방법인가?" 였고 그렇게 몇날몇일을 고민한 결과 최종적으로 깨닫게 된것은 "앞으로 혁신적인 방법이 생길지는 몰라도 지금으로서는 비트코인만큼 완벽한 분산체계는 없다."라는 것이였다.
 

+ 5 - 1
2_비트코인에대한얘기.md

@@ -54,4 +54,8 @@
 
 ### 지갑
 
- 비트코인에서는 보안을 위해 한번 사용한 비트코인 주소는 버릴것을 권장한다. 다만 그러면 내가 지금 가지고 있는 비트코인을 알아보기위해 여태껏 사용해온 비트코인 주소와 비트코인 주소의 소유주임을 증명해줄 비밀키를 모두 기록해둬야한다. 이러한 정보들을 관리하는데 **지갑**이라는 소프트웨어가 사용된다.
+ 비트코인에서는 보안을 위해 한번 사용한 비트코인 주소는 버릴것을 권장한다. 다만 그러면 내가 지금 가지고 있는 비트코인을 알아보기위해 여태껏 사용해온 비트코인 주소와 비트코인 주소의 소유주임을 증명해줄 비밀키를 모두 기록해둬야한다. 이러한 정보들을 관리하는데 **지갑**이라는 소프트웨어가 사용된다.
+
+### Bitcoin Core
+
+ 비트코인을 사용할 수 있는법은 다양하다. 스마트폰 앱으로 구현되어 있는 비트코인 지갑을 사용할 수도 있고 웹에 구현되어 있는 비트코인 지갑을 사용할 수도 있으나, 이 모든 지갑 소프트웨어의 원조이자 지금은 레퍼런스처럼 자리잡은 것이 Bitcoin Core이다.  

+ 34 - 2
4_지갑과_비트코인_주소.md

@@ -12,7 +12,13 @@
 
  비대칭 암호화에 대해서 설명할떄 비트코인은 RSA를 사용하지 않고 ECC를 사용한다고 했던부분 기억하는가? ECC란  Elliptic curve cryptography 의 약자로 한국어로는 **"타원곡선 암호"**정도로 번역되는 존재이다. ECC는 그 원리에 대해서만 설명하는 책이 있을정도로 기초적으로 알아야할 지식이 많고 복잡해서 이 책에서 자세히 다루지 않겠지만 추상적으로나마 표현해보자면 RSA가 두 소수의 곱을 통해 암호화된 어떤 값은 두 소수를 모르면 해독하는데 엄청난 시간이 걸린다는 점을 이용했다면 ECC는 아래 그림과 같은 타원곡선 상에서 알려진 어떤 시작점을 기준으로 특별한 규칙에 따라 n번 움직인 점으로 암호화한 값은 정확히 몇 번 움직였는지 모르면 해독하는데 엄청난 시간이 소모된다는 점을 이용한 암호화 방법이다.
 
-![](./img/4_1.png)
+> 공개키와 비밀키에 잠깐 얘기해보자면 ECDSA의 한 표준안인 secp256k1의 경우 $$y^2 = x^3 + 7$$ 라는 함수를 가지는 타원곡선 상에서 `G = 04 79BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9 59F2815B 16F81798 483ADA77 26A3C465 5DA4FBFC 0E1108A8 FD17B448 A6855419 9C47D08F FB10D4B8` 로 표현되는 G를 출발점으로 하는것으로 정해져 있으며 움직인 횟수 n이 그대로 256bits 크기의 `비밀키`, 움직인 결과 나온 타원곡선상의 한 점이 그대로 520bits 크기의 `공개키`가 된다.
+>
+>  다만, 여기서 한가지 짚고 넘어가볼만한 사항이 위에서 엄청나게 긴 16진수 숫자열로 표시된 `G`의 값이 사실을 x좌표와 y좌표를 표시했다는 것이다.  `04`부분은 뒤쪽에 표시되는 내용이 어떤 양식인지를 보여주고, 앞쪽의 `79BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9 59F2815B 16F81798`부분은 좌표평면상의 x좌표, 뒤쪽의 `483ADA77 26A3C465 5DA4FBFC 0E1108A8 FD17B448 A6855419 9C47D08F FB10D4B8`부분은 좌표평면상의 y좌표를 나타낸다. 하지만 조금만 생각해보면 알 수 있다시피 그래프의 형태를 이미 $$y^2 = x^3 + 7$$ 으로 알고 있으므로 우리는 x좌표와 y좌표 모두의 존재를 알 필요없이 x좌표만 알고있으면 나머지 y좌표는 컴퓨터 연산으로 알아낼 수 있고 추가적으로 필요한 정보는 y좌표의 값이 양수(위쪽)이냐 음수(아래쪽)이냐 인 것이다. 그래서 좌표를 표현할때 `압축형`이라는 형태가 존재하는데 앞에 접두부가 y좌표가 양수면 `02`가 되고 음수면 `03`이 되며 그후 x좌표만 추가되어 위에서 밝힌 점 `G`의 좌표의 경우 기본형에서 520bits크기를 점유했었지만 압축형이되면 264bits 크기의 `02 79BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9 59F2815B 16F81798`가 되어 256bits 상당의 공간을 절약할 수 있게된다. 이는 공개키 또한 마찬가지이며 압축된 공개키를 사용하면 트랜젝션의 크기가 32byte=256bits 줄어들어 조금이나마 수수료를 아낄 수 있으니 참고하자. 
+
+
+
+![](./img/4_1.gif)$$y^2 = x^3 + 7$$ 그래프 개형 
 
  비트코인에서 금융권에서 많이 쓰여 이미 안정성이 입증된 RSA를 활용한 전자서명을 사용하지 않고 ECC를 활용한 **ECDSA**를 사용하는 이유는 간단한데, 그것은 바로 RSA보다 더 적은양의 데이터만으로도 RSA보다 뛰어난 안정성을 보장해주기 때문이다.
 
@@ -20,7 +26,33 @@
 
  위 도표를 보면 현재 금융권에서 가장 활발히 쓰고있는 RSA2048의 경우 키 크기로2048bits를 사용하면 해독을 해내는데 초당 백만건씩 비교를 해볼때 약 10^20년정도가 걸리지만 ECC의 경우 단 210bits만을 이용해도 같은 10^20년정도가 걸리게 할 수 있으며 당연하게도 만약 ECC가 2048bits를 사용하면 RSA는 같은 수준의 보안을 유지하기위해서는 훨씬더 많은 bits를 사용하는 키가 필요하게 될것이다.
 
- 현재 비트코인에서 사용하는 ECDSA는 미국립표준기술원(NIST)에서 2000년 중순에 발표한 secp256k1라는 표준을 따른다. 이
+ 현재 비트코인에서 사용하는 ECDSA는 미국립표준기술원(NIST)에서 2000년 중순에 발표한 secp256k1라는 표준을 따른다. 이 표준안에 따라 비트코인에서는 256bits 크기의 비밀키와 512bits 크기의 공개키를 가진다.
+
+### 비트코인 주소의 생성과정
+
+ 공인인증서를 사용하며 나 자신이 비밀키를 사용해 서명을 했을때 금융기관이 정말 본인이 한 서명인지 맞는지 확인하는 법은 신뢰할 수 있는 인증기관에서 보관하고 있는 공개키와 나 자신이 첨부한 공개키가 서로 일치하는지 보는 것이다. 이러한 방법으로 나 자신이 어떤 행동을 했음을 증명할 수 있고, 그에따라 나 자신의 자산을 마음대로 사용할 수 있게된다. 하지만 비트코인은 어떨까? 일단 완벽한 분산화로 인해 인증기관이란 존재도 없을 뿐더러 모든것은 익명으로 진행되어 나 자신임을 증명하는 것도 의미가 없다. 그럼 어떻게 어떤 계좌의 존재가 나 자신이 소유하고 있음을 증명할 수 있을까? 이에대한 해결책으로 비트코인은 비밀키로부터 나온 공개키를 사용해 비트코인 주소로 만들어 버렸다. 이렇게 하므로써 비트코인은 아주 간단한 진리를 만들었는데 그것은 바로 "비밀키를 소유한자가 이 주소의 소유자이다!"라는 것이다.
+
+ 그럼 지금부터 비트코인 주소의 생성과정을 한번 살펴보자. 일단 secp256k1표준에 맞게 비밀키를 생성할 필요가 있다. 방법은 간단하다. 남들이 예측하지 못하게 256개의 0과 1을 적당히 늘어놓으면 된다. 좀 더 쉽게 표현하자면전세계 아무도 예측하지 못할 0 에서 2^256-1 사이의 아무숫자나 하나 고르면 된다. 물론 모든 비트코인 사용자가 같은 방법으로 비밀키를 생성하므로 우연히 같은 비밀키를 가지게 될 확률이 존재는 하지만 이는 1/2^256 이라는 엄청나게 적은 확률로 완벽하게 임의로 비밀키를 골랐다면 겹치는 상황은 거의 불가능에 가깝다는것을 생각해두자.
+
+>  초기 비트코인의 경우 1에서 2^256 사이의 숫자를 고를때 운영체제 자체에서 제공하는 난수발생기를 이용하던가 자신이 직접 아무숫자나 고를 수 도 있었지만 요즘 대부분의 비트코인 특정 규칙에따라 난수를 발생시키는데 이는 지갑파트에서 자세히 다룰것이다.
+
+ 비밀키가 만들어졌으면, 다음으로 필요한 것은 공개키 이다. 공개키를 구하는 과정은 앞쪽에서 ECDSA를 설명하면서 그 과정만을 설명한 책이 있을정도로 분량이 많고 복잡하다면서 건너뛰었다. 사실 이 개념은 필자 본인도 대략적으로 이해만 할뿐 정확히 수학적으로 어떻게 구현되는지는 모르고, 이건 비트코인 개발자들도 마찬가지여서 원조 비트코인 프로그램인 Bitcoin Core도 개발 초기에는 OpenSSL에 구현된 secp256k1을 사용했다. 현재는 OpenSSL 대신 비트코인을 위해 개발된 libsecp256k1을 사용해 ECDSA관련 연산을 행하고 있는데 libsecp256k1 자체가 `sipa`라는 Github유저에 의해 2013년 중순에 개발되기 시작해 2015년 11월에 와서야 완성되고 Bitcoin Core에 통합되었다는 점을 생각해보면 그 복잡도를 상상해 볼 수 있다.
+
+ 이제 이 완성된 공개키를 이용해서 비트코인 주소를 만들어볼 차례이다. 공개키로부터 비트코인 주소를 만드는 과정은 아래와 같은 그림으로 간단히 표현할 수 있다. 
+
+```mermaid
+graph TD
+
+비밀키-->공개키
+공개키-->|RIPEMD160, SHA2|Public_Key_Hash
+Public_Key_Hash-->|Base58Check|비트코인주소
+```
+
+먼저 공개키를 SHA2 해시함수에 넣고 돌려서 256bits크기의 해시값 A를 얻어낸다. 그 후 얻어낸 해시값A를 RIPEMD160이라는 해시함수에 넣고 돌려서 160bits크기의 해시값 B를 얻어낸다. 이 해시값 B는 `Public Key Hash`라 불리며 비트코인 주소 대신에 이 값으로 송금을 할 수도 있다. (거래 생성부분에서 `P2PKH` 참고) 근데  `Public Key Hash`만으로도 거래가 가능하면 왜 비트코인 주소가 따로있는 것일까? 그 이유는 미관에 있다. 공개키를 해시함수를 두번돌려서 나온 160bits크기의 값은 0과 1로만 구성되어있는 2진수 데이터 이고 이를 그나마 보기쉬운 16진수표기법으로 바꾸면 `005F9D6E944D5B968DADE7EFABFA02395A8733F6086E43E710`이런 형태로 나타나는데 미관상 보기 좋지 않을뿐더러 입력하다가 실수하기 좋은 형태이기도 하다. 이렇게 실수하기 좋은 형태를한 2진수 데이터를 사람이 입력할때 실수가 잘 발생하지 않도록 보기좋은 형태로 바꿔주는 것이 바로 Base58 인코딩이다.
+
+![img](./img/4_3.jpg)
+
+이미 잘 알려진 Base64인코딩과 다른점은 글꼴에 따라 혼동하기 쉬운 0(숫자), O(알파벳), l(소문자 L), I(대문자 i), +, / 등의 글자가 빠져 사람이 옮겨적을때 실수할 가능성을 낮춰졌다는 정도이다. 다만 비트코인 주소가 실제 자산이 옮겨가는 주소이고 사소한 실수가 
 
 ## 지갑
 

BIN
img/4_1.gif


BIN
img/4_3.jpg