[Bitcoin] - ch3. 키와 주소

‍허진·2023년 3월 1일
0

Blockchain

목록 보기
3/19
post-thumbnail

본 글은 '비트코인, 공개 블록체인 프로그래밍(Andreas M. Antonopoulos 저, 최은실, 김도훈, 송주한 옮김, 2018)'을 바탕으로 작성되었습니다.

비트코인은 암호학(cryptography)을 기반으로 한다. 암호학을 통해서 비밀을 공개하지 않고도 비밀에 대한 정보를 입증할 수 있고(디지털 서명, 영지식 인증) 데이터의 진위 여부를 입증할 수도 있다(디지털 지문). 이와 같이 암호학을 이용해 증명하는 방식은 비트코인에 중요한 수학적 도구이며 비트코인 어플리케이션에서 광범위하게 사용된다.

반어적으로 암호화(encryption)는 비트코인에 있어 중요하지 않다고 할 수 있다. 왜냐하면 비트코인의 커뮤니케이션 및 거래 데이터들은 암호화되어 있지 않고 자금을 보호하기 위한 용도로 암호화할 필요도 없기 때문이다.

> 들어가며

디지털 키, 비트코인 주소, 디지털 서명 등을 통해 비트코인의 소유권이 성립된다.

  • 디지털 키 : 네트워크 상에 저장되어 있지 않고 사용자가 간단한 데이터 베이스인 지갑 속에 저장한다. 키는 분산화된 신뢰 및 관리, 소유권 입증, 암호증명(cryptographic-proof) 보안 모델 등을 가능하게 한다. 공개키와 개인키 한 쌍으로 구성된다.
  • 디지털 서명 : 비밀 키만 보유하고 있으면 생성할 수 있다. 금액을 소비하기 위해 사용되는 디지털 서명은 암호학 용어로 증인(witness)이라고도 한다. 비트코인 거래 내의 증인 데이터는 소비되는 자금의 실제 소유권을 증명한다.
  • 비트코인 주소 : 비트코인 거래에서 수취인의 공개키가 바로 비트코인 주소라고 불린다. 대부분의 비트코인 주소는 공개키로부터 생성되며 공개키에 대응한다. 비트코인 주소는 수표처럼 돈의 수취와 관련된 정보를 요약해서 보여 줌으로써 비트코인 거래 시 송금처를 마음대로 지정할 수 있다.

> 공개키의 암호학과 암호화폐

대칭키 암호학이 입증을 위해서 1대1로 각각 다른 키를 교환해야 했던 번거로움이 있었다면, 공개키 암호학은 공개키를 공개하면 개인키를 알고 있는 사람이라면 누구나 입증이 가능하다는 성질 때문에 1대 다수로 입증이 가능하다는 장점을 지녔다. 대표적인 공개키 암호학으로는 RSA 암호, Elgamal 암호, 타원곡선 암호 등이 있다.

공개키 암호학에 쓰이는 수학 함수들은 불가역성을 보인다. 즉, 한 방향으로 계산하는 것은 쉽지만 반대 방향으로 계산하는 것은 실행 불가능하다. 이러한 수학 함수들을 바탕으로 하고 있는 암호학은 디지털 비밀번호와 위조가 불가능한 디지털 서명을 가능하게 한다. 비트코인은 암호학을 기반으로 타원곡선 곱셈 함수를 사용한다.

> 개인키와 공개키

비트코인 지갑에는 쌍으로 구성된 키가 여러 개 들어있고, 각각의 쌍은 개인키와 공개키로 구성되어 있다. 개인키(k)는 숫자로 구성되어 있으며 대개 무작위로 숫자를 추출한다. 일방 암호함수인 타원곡선 곱셈함수를 이용해서 개인키로부터 공개키(K)를 생성한다. 그리고 일방 암호해시함수를 이용해서 공개키(K)로부터 비트코인 주소(A)를 생성한다. (소문자 k와 대문자 K에 유의)

[그림 - 키와 주소 생성 과정]

> 개인키

개인키는 무작위로 추출한 숫자로 구성되어 있다. 거래에서 사용되는 돈의 소유권을 증명하게 되면 비트코인을 소비할 수 있게 되는데, 이때 서명을 하기 위해 개인키를 사용한다. 개인키는 절대 제 3자에게 공개해서는 안된다.

키를 생성하는 과정 중 가장 첫 단계이자 중요한 단계는 보안이 철저한 엔트로피소스, 즉 무작위성을 찾는 일이다. 비트코인 소프트웨어는 기본적인 운영체제의 난수생성기(random number generator)를 이용해서 256비트의 엔트로피(무작위성)을 만들어낸다.

좀 더 정확하게 설명하자면, 개인키는 1에서 n-1 사이의 어떠한 숫자로도 구성될 수 있다. 여기에서 n은 비트코인에 사용된 타원곡선의 위수(order)라고 정의된 상수(n=1.158 * 10^77, 2^256보다 약간 작은 값)다.

프로그래밍 용어로 설명하면 암호학적으로 안전한 엔트로피소스를 통해 수집된 무작위 비트 문자열 중에서 크기가 큰 것들을 SHA256 해시 알고리즘에 집어넣으면 편리하게 256비트의 숫자를 생성할 수 있다. 결과값이 n-1보다 작으면 알맞은 개인키가 생성됐다고 보면 된다.

> 공개키

공개키는 타원곡선 곱셈 함수를 이용해서 개인키로부터 계산되며, 그 과정을 거꾸로 진행할 수는 없다. 즉 K= k * G라는 식에서 k는 개인키, G는 생성 포인트라는 이름의 상수이며 K는 계산 결과로 나온 공개키다. '이산로그(discrete logarithm) 찾기'로도 알려져 있는 역계산법은 K값을 안다는 가정 하에 k값을 계산하는 과정인데, 가능한 k값을 모두 대입해 보는 것만큼 어렵다.

개인키로부터 공개키를 생성하는 방법을 알아보기 전에 타원곡선 암호학에 대해 알아보자.

> 타원곡선 암호학

타원곡선 암호학과 관련된 내용은 다음의 블로그를 참고하도록 하자.
https://www.crocus.co.kr/1226

> 공개키 생성하기

무작위로 생성된 K라는 개인키에, 곡선 위에서 미리 정해진 값인 생성 포인트 G를 곱해서 곡선상의 다른 곳에 위치한 포인트를 얻는다. 바로 이 포인트가 공개키인 K가 된다. 생성 포인트는 secp256k1의 일부로 명시되어 있고 비트코인의 모든 키에 대해 동일한 값을 가진다. k와 K값의 관계는 고정되어 있지만, k값에서 K값 쪽으로 한 방향으로만 계산할 수 있다. 그래서 비트코인 주소(K값에서 파생)는 누구와도 공유할 수 있지만 사용자의 개인키(k)는 공유하지 않는다.

공개키 K는 포인트 K = (x, y)로 정의된다.
정수 좌표인 한 점의 곱셈 함수를 가시화하기 위해서 실수 체계에서 사용하는 더 간단한 타원곡선을 사용하게 될 것이다. 우리의 목적은 생성 포인트 G에 대해 여러 개의 kG를 찾는 것이다. G를 곡선에 대입한 후 계속해서 k번 더하는 과정은 동일하다. 곡선상 점을 대입시켜 해당 포인트에 대한 접선을 그려서 곡선과의 교차점을 찾고 x축에 대칭시킨다.
다음 그림은 곡선상에서 기하학적인 방법을 통해 G, 2G, 4G를 구하는 과정이다.

[그림 - 타원곡선 암호학 : 곡선상에 있는 포인트 G와 정수 k의 곱을 가시화한 그림]

> 비트코인 주소

비트코인 주소는 숫자와 문자로 구성된 문자열로, 자신에게 돈을 전송하고자 하는 누구와도 공유할 수 있다. 비트코인 주소는 개인키 및 공개키 쌍을 보유한 소유주를 나타낼 수 있고, 'Pay-to-Script-Hash(P2SH)'에서 다루게 될 지불 스크립트 등 여러 다른 대상을 나타낼 수 도 있다.

비트코인 주소를 공개키로부터 생성할 때는 일방 암호화 해싱을 사용한다. 주로 사용하는 해시 알고리즘으로는 'SHA256'과 'RACE Integrity Primitives Evaluation Message Digest(RIPEMD)'이 있다. 공개기 K를 가지고 SHA256 해시를 산출한 후 그 결과값의 RIPEMD160 해시를 산출하면 160비트(20바이트) 크기의 숫자가 생성된다.

A = RIPEMD160(SHA256(K))

A가 바로 계산의 결과값으로 나온 비트코인 주소이다.

비트코인 주소는 Base58Check로 인코딩된다. Base58Check 인코딩은 58개의 문자와 검사합(checksum)을 이용해서 사람이 읽을 수 있는 문자로 바꾸어 주고 비슷한 모양의 문자를 쓰지 않음으로써 혼란을 방지하며 거래의 표기나 항목에 대한 에러가 발생하지 않도록 해준다.
Base58Check에 대한 추가적인 설명은 다음을 참고하자.
http://wiki.hash.kr/index.php/%EB%B2%A0%EC%9D%B4%EC%8A%A458

[그림 - 공개키가 비트코인 주소로 전환되는 과정]

> 압축 공개키

비트코인에서 대부분의 거래에는 비트코인 소유주의 자격을 검증하고 비트코인을 소비하는 데 필요한 공개키가 포함되어 있는데, 각각의 공개키는 520비트(접두부 + x + y)의 공간이 필요하다. 블록당 수백 개의 거래가 증가하면, 즉 매일 수만 개의 거래가 생겨나면 블록체인에 어마어마한 크기의 데이터가 합쳐지게 된다.

그런데 공개키는 타원곡선상의 한 점(x,y)이다. 그러므로 x좌표만 알면 방정식 y^2 mod p = (x^3 + 7) mod p를 풀어서 y좌표를 계산할 수 있다. 이러한 방식 때문에 공개키의 x좌표만 저장함으로써 필요한 공간을 50%로 줄일 수 있다.

이렇게 공개키를 압축하여 비트코인 주소를 생성하면 비압축된 공개키로 만든 비트코인 주소와 다르게 된다. 하지만 두 비트코인 주소 모두 유효하며 개인키로 서명을 할 수도 있다.

> 압축 개인키

먼저 바로잡자면, 압축 개인키라고 해서 기존의 개인키에서 압축된 것은 아니다. 오히려 압축 개인키는 비압축 개인키보다 1바이트가 더 길다.

그렇다면 왜 압축 개인키라고 부르는 것일까? 압축 개인키의 의미는 사실 '압축 공개키만의 생성 출처가 돼야 하는 개인키'를 의미한다. 자동으로 비압축 개인키는 '비압축 공개키만의 생성 출처가 돼야 하는 개인키'를 의미한다. 이렇게 구분한 이유는 하나의 공개키에서 다른 두 비트코인 주소가 생성되어서 혼란을 야기하는 문제를 해결하기 위해, '압축 개인키 -> 압축 공개키 -> 압축 비트코인 주소'와 '비압축 개인키 -> 비압축 공개키 -> 비압축 비트코인 주소'로 구분하기 위해서이다. 이를 통해 데이터를 불러온 지갑은 이전 지갑에서 생성된 개인키와 새로운 지갑에서 생성된 개인키를 구분할 수 있고, 비압축 공개키나 압축 공개키 각각에 대응하는 비트코인 주소가 들어 있는 거래를 위해 블록체인을 검색할 수 있다.

> 암호화된 개인키(BIP-38)

BIP-38은 개인키를 안전하게 백업 매체에 저장하고 지갑 간 전송을 시행하며 노출될 수 있는 어떠한 조건에서도 비밀이 유지될 수 있도록 하기 위해서 패스페레이즈를 이용해 개인키를 암호화하고 Base58Check로 개인키를 인코딩하는 데 필요한 공동 표준을 제안한다. NIST(미 국립표준기술원)에서 개발한 고급암호표준(AES)을 암호 표준으로 이용한다.

BIP-38 암호화 키가 가장 흔하게 사용되는 경우는 개인키를 한 장의 종이로 백업하는 데 사용할 수 있는 종이지갑에서다. 사용자들이 복잡한 패스페이즈를 선택하는 한 BIP-38 암호화 개인키가 담긴 종이지갑은 매우 안전하며 오프라인에 비트코인을 저장하는 장소('cold storage'로 알려져 있음)를 만드는 데 가장 좋은 방법이다.

종이지갑은 비트코인 개인키를 종이에 인쇄해 놓은 것으로, bitaddress.org에 있는 클라이언트 사이드 자바스크립트 생성기 등의 도구를 사용해서 쉽게 생성할 수 있다. 이 웹페이지에는 인터넷과의 접속이 완전히 끊긴 상태에서도 키와 종이지갑을 생성하는 데 필요한 코드가 전부 다 들어 있다. 따라서 오프라인 상태로 이 코드들을 이용해서 키와 종이지갑을 생성한다면 어떠한 온라인 체제에 저장되지 않고 종이 위에만 존재하는 안전한 종이지갑을 생성할 수 있다.

[그림 - 종이지갑 예시]

profile
매일 공부하기 목표 👨‍💻 

0개의 댓글