‘Mastering Bitcoin 2nd’ 세미나 5, 4장. Keys, Addresses
이번 장에서 책 읽기를 포기할 수 있습니다. 세미나에 참석하면 좋은 점이 이런 장을 만나도 포기하지 않고 다음으로 넘어갈 수 있다는 것이지요. 다시 말하지만 포기하지 않는 것이 중요합니다.
이번 장에서 가장 이해하기 어려운 부분은 타원곡선 암호화 관련 부분입니다. 저자는 타원곡선 암호화에 대해서 너무 깊이 들어가지 않으면서 관련 부분을 설명하려고 합니다. 타원곡선 암호화를 어느 정도 수준에서 다루려고 해도 추가적으로 몇 장은 필요할테니까요. 관련해서 좀 더 깊이 있는 내용을 알고 싶으시면 Programming Bitcoin(번역서: 밑바닥부터 시작하는 비트코인) 읽기를 추천합니다.
Chapter 4. Keys, Addresses
아래 인용한 본문 내용을 강조한 부분에 주의를 기울이면서 여러 번 읽어봅니다.
Cryptography can also be used to prove knowledge of a secret without revealing that secret (digital signature), or prove the authenticity of data (digital fingerprint – called a bitcoin address).
In this chapter we will introduce some of the cryptography used in bitcoin to control ownership of funds.
비트코인에서 암호화는 비트코인에 대한 소유권 문제를 다루기 위해 사용됩니다.
Introduction
Ownership of bitcoin is established through digital keys, bitcoin addresses, and digital signatures.
비트코인에 대한 소유권은 디지털 키, 비트코인 주소, 디지털 서명으로 성립됩니다.
Keys come in pairs consisting of a private (secret) key and a public key. Think of the public key as similar to a bank account number and the private key as similar to the secret PIN, or signature on a check, that provides control over the account.
키는 개인키와 공개키 쌍으로 이뤄집니다. 개인키는 비밀키라고도 합니다. 이름 그대로 비밀스럽게 자신만 알고 있어야 합니다.
Keys enable many of the interesting properties of bitcoin, including decentralized trust and control, ownership attestation, and the cryptographic-proof security model.
비트코인 시스템은 탈중앙화된 환경에서 소유권 문제를 다루어야 합니다.
Most bitcoin transactions requires a valid digital signature to be included in the blockchain, which can only be generated with a secret key. The digital signature used to spend funds is also referred to as a witness, a term used in cryptography. The witness data in a bitcoin transaction testifies to the true ownership of the funds being spent.
누가 어떤 비트코인을 소유하고 있다는 것은 트랜잭션의 출력으로 작성됩니다. 트랜잭션 출력으로 작성된 비트코인에 대해 ‘소유권 있음’을 증명하려면 키(개인키)가 있어야 합니다. 소유권 증명을 위해 개인키를 직접 사용하게 되면 개인키가 노출되기 때문에, 개인키로 서명된 ‘서명’을 가지고 소유권을 증명합니다. 비트코인에 있어 암호화는 디지털 서명 만을 위해 사용합니다. 메시지를 암호화하거나 복호화하지는 않습니다.
사용자가 비트코인을 사용하려면 자신의 주소를 수신자로 하는 트랜잭션 출력(여러 출력들이 여러 트랜잭션들에 작성되어 있을 수 있음)이 있어야 합니다. 사용자는 자신의 주소를 수신자로 하는 트랜잭션의 출력을 입력으로 하는 새로운 트랜잭션을 작성합니다. 해당 트랜잭션 출력에 대한 소유권 있음을 증명하기 위해 개인키로 서명한 ‘서명’을 입력 내용으로 작성합니다. 사용자는 새로 작성된 트랜잭션을 비트코인 네트워큰에 전송합니다. 이런 과정은 일반적으로 지갑에 의해 수행됩니다.
비트코인 네트워크 참여자들은 서명을 가지고, 정말로 해당 사용자가 비트코인에 대한 소유권이 있는지를 검증합니다.
Public Key Cryptography and Cryptocurrency
In bitcoin, we use public key cryptography to create a key pair that controls access to bitcoin. The public key is used to receive funds, and the private key is used to sign transactions to spend the funds.
비트코인은 공개키 암호화 방식을 사용합니다. 이번 절의 내용은 암호화에 관한 지식을 요구합니다. 저자의 설명만 가지고 이해하기가 쉽지 않습니다. 세부적인 내용을 이해하기 보다 ‘이건 이렇다’ 정도로 정리해 나가는 것이 정신 건강에 좋을 것 같습니다. 세부적인 내용은 Programming Bitcoin을 참고합니다.
Private and Public Keys
공개키 암호화는 서로 다른 두 개의 키를 사용하는 비대칭 암호화를 사용합니다. 같은 키로 암호화하고 복호화하면 대칭 암호화라고 합니다.
그림 1을 보고 개인키, 공개키, 주소 사이의 관계를 설명합니다. 개인키를 가지고 공개키를 생성하고, 공개키를 가지고 주소를 생성합니다. 이들 생성 함수는 일방향(one-way)입니다. 공개키를 안다고 개인키를 알아낼 수 없으며, 주소를 안다고 공개키를 알 수 없습니다. 개인키에서 공개키를 생성하는데에는 타원곡선 암호화가 사용되고, 공개키에서 주소를 생성하는데에는 해시 함수가 사용됩니다.
앞에서도 이야기 했지만 다시 한 번 강조하면, 비트코인은 소유권 증명에 공개키 암호화를 사용합니다. 더 정확히는 공개키 방식의 타원곡선 디지털 서명을 사용합니다. 개인키를 사용해서 디지털 서명을 생성하고, 공개키를 사용해서 서명이 유효한지를 검증합니다.
비트코인에서 암호화나 복호화를 위해 공개키 암호화를 사용하지는 않는다는 점은 비트코인을 학습하는 입장에서 매우 중요한 사실입니다. 암호와나 복호화에 대해 학습해 두면 여러모로 도움이 될 것입니다. 하지만 비트코인을 학습하는데 주안점을 둔다면 디지털 서명에 대한 부분만 제대로 학습 하시면 됩니다.
Private Keys
개인키는 1에서 n-1 사이의 암호학적으로 안전한 방법으로 생성되는 랜덤수 입니다. n은 1.158 * 1077 로 2256 보다 약간 작은 수 입니다.
다음과 같은 방법으로 비트코인 코어에서 키를 생성할 수 있습니다. getnewaddress 명령은 개인키는 숨기고 공개키로 부터 생성된 주소만 출력합니다. 개인키를 출력하고자 한다면 dumpprivatekey 명령을 사용합니다.
- bitcoin-cli getnewaddress
- bitcoin-cli dumpprivkey <주소>
개인키와 공개키는 256비트로 표현되는 숫자라는 점을 다시 한 번 기억해 둡니다. 비트코인 코어가 출력하는 개인키는 WIF(Wallet Import Format)라 불리는 체크섬을 사용하는 Base58로 인코딩된 것입니다.
Public Keys
공개키를 생성하는데 타원곡선이 사용됩니다. 본문 내용으로 타원곡선 암호화에 대해 다 이해하려고 하면 주화입마에 빠질 수 있습니다. 여기에서는 책에서 언급하는 내용들에 대해 정리하는 수준으로 넘어갑니다. 아래 요약한 내용 정도를 확인하고 넘어갑니다. 가벼운 마음으로 ‘그렇다는 구나’라고 읽어 나가시면 됩니다.
- 공개키 암호화에서는 공개키를 생성하기 위해 타원곡선 암호화를 사용합니다.
- 비트코인에서 사용하는 타원곡선은 secp256k1 표준에 정의되어 있습니다. 그림 2와 같은 형태입니다.
- y2 = (x3 + 7) over (Fp)
- over (Fp)는 위수 p를 갖는 유한체 상의 점들로 타원곡선이 이루어져야 하고, 유한체에 정의된 방식으로 연산이 되어야 함을 의미합니다. 식에 있는 제곱이나 세제곱이나 덧셈이 유한체에 정의된 방식으로 계산되어야 합니다.
- p 값은 표준에 정의되어 있습니다.
- p = 2256 – 232 – 29 – 28 – 27 – 26 – 24 – 1
- 그림 3은 위수 p가 17인 유한체 상의 타원곡선을 만족하는 점 들을 표시한 것입니다. 타원곡선에 x값을 넣고 y값을 구해서 좌표에 점을 찍으면 그림 3처럼 됩니다.
- y2 = (x3 + 7) over (Fp)
- 타원곡선은 좀 더 정확히는 유한체 상의 타원곡선을 사용합니다. 좀 더 정확히는 유한군 상의 타원곡선을 사용합니다. 좀 더 정확히는 유한 순환군 상의 타원곡선을 사용합니다.
- 공개키는 유한군 상의 타원곡선 위에 있는 한 점(개인키) k에 생성원 G를 타원곡선 곱 연산을 해서 구합니다.
- K = k * G
- 좀 더 정확히 말하면 k는 개인키는 아닙니다. 여기에서는 그렇다는 정도만 확인하고 넘어갑니다.
- G는 타원곡선 상의 한 점(x, y)으로 표준에 정의되어 있습니다.
- 타원곡선 곱 연산은 일반적인 연산에서와 마찬가지로 덧셈의 반복입니다. k * G는 G를 k번 더한 것이 됩니다.
- 타원곡선의 덧셈에서 같은 점을 더하는 방법은 타원곡선과 해당 점의 접선을 구하고, 접선을 연장했을 때 만나는 점에 대칭되는 점을 구해서 구합니다.
- 그림 4에서 G를 두 번 더한 것은 타원곡선과 G의 접선을 연장했을 때 타원곡선과 만나는 또 다른 점 -2G를 구하고, -2G에 대칭되는 점 2G를 구하면 됩니다. 같은 방식으로 4G, 8G를 구해갈 수 있습니다. – 기호는 대칭되다는 점을 표현하기 위한 것이라고 생각하면 됩니다.
- 타원곡선 덧셈은 서로 다른 두 점에 대해서도 구할 수 있기 때문에 G와 2G를 더해 3G를 구할 수도 있습니다. 서로 다른 두 점인 경우는 두 점을 잇는 직선을 그리고, 이 직선이 타원곡선과 만나는 또 다른 점을 구하고 그 점과 대칭되는 점을 구하면 됩니다.
- 공개키는 타원곡선 상의 점(x, y)입니다.
- K = k * G
- 유한체 상의 타원곡선에서 덧셈이 가능하려면 항등원과 역원의 개념이 있어야 합니다. 예제 1에서 0이 나왔는데 이러한 경우에 이것을 무한원점이라고 합니다. 덧셈의 항등원에 해당합니다. 사실 0으로 표현한 것일 뿐 실제적으로 0은 아닙니다. G의 덧셈에서 – 부호를 사용했는데 이것은 실제적으로는 역원에 대한 표현입니다.
Bitcoin Addresses
공개키는 타원곡선 상의 점으로 매우 큰 x, y로 되어 있습니다. 비트코인을 전송하려면 수신자를 명시해야 하는데 공개키를 사용해서 수신자를 표현하는 것은 쉬운 일이 아닙니다. 좀 더 단순한 방법으로 공개키보다는 단순한 계정이란 개념의 주소를 등장시킨 것입니다.
그림 5는 공개키에서 주소를 생성하는 절차를 설명합니다.
공개키를 두 개의 해시 함수를 사용해서 공개키 해시 값을 생성합니다. SHA256 함수와 RIPEMD160 함수를 사용합니다. 이 두 해시함수를 연속적으로 적용하는 함수를 HASH160이라고 합니다. RIPEMD160은 160비트를 사용하기 때문에 공개키 해시 값은 20바이트가 됩니다.
이렇게 생성된 공개키 해시 값을 Base58Check으로 인코딩 함수를 사용해서 주소를 생성합니다. 주소는 Base58로 인코딩된 공개키 해시 값입니다.
그림 6은 Base58Check 인코딩 절차를 설명합니다.
Base58Check은 공개키 해시 값에 1바이트 버전 접두어를 추가하고, 여기에 SHA256 함수를 연속 두 번 적용해서 구한 해시 값의 첫 4바이트를 체크섬으로 더합니다. 결과는 ‘버전 접두어(1바이트) + 공개키 해시 값(20바이트) + 체크섬(4바이트)’가 됩니다. 여기에 Base58 인코딩을 적용하면 주소가 생성됩니다.
표1은 비트코인에 사용되는 다양한 버전 번호와 어떤 버전을 사용했을 때 어떤 결과가 나오는지를 비교 설명하고 있습니다. 비트코인 주소의 첫 글자가 다른 이유는 다른 버전 번호를 사용하고 있기 때문입니다. 여기에서는 어떤 경우에 어떤 버전을 사용하고 있고 그 결과에 따라 주소의 첫 글자라 이렇게 되는 구나 정도만 짚고 넘어갑니다.
Key Formats
Private key formats
개인키는 256비트 수 입니다. 32바이트이니 16진수로 표현하면 64자리가 됩니다.
WIF는 서로 다른 지갑들 사이에 개인키를 내보내고 가져오기 할 수 있도록 하기 위한 포맷입니다. 표2의 WIF-compressed는 개인키 포맷이지만 압축하는 것은 개인키가 아니라 공개키입니다. WIF-compressed는 WIF와 구분하기 위해 공개키 해시 값 뒤에 0x01을 추가합니다. WIF-compressed는 버전번호 1바이트, 32바이트 해시 값, WIF-compressed 구분 1바이트, 채크섬 4바이트로 작성됩니다. 이 값을 Base58Check로 인코딩 하면 K나 L로 시작됩니다.
Public key formats
Public keys are also presented in different ways, usually as either compressed or uncompressed public keys.
공개키는 타원곡선 상의 점으로 x좌표와 y좌표로 이루어집니다. 비압축 방식은 단순히 x와 y 값을 연결한 것이고, 비 압축 방식은 x값만 주고, y 값을 계산을 통해 구하는 방식입니다.
비트코인에서 사용하는 타원곡선은 x축에 대해서 대칭을 이루기 때문에 하나의 x 값에 대해서 두 개의 y 값을 갖습니다. 두 y 값은 하나는 짝수이고 하나는 홀수입니다. x 값을 주고 y값이 홀수인지 짝수인지 홀수인지만 알려 주면 y값을 계산해서 구할 수 있습니다.
비압축 방식을 사용하는 경우 접두어로 04를 사용하고, 압축인 경우 y값이 짝수인 경우는 02를, 홀수인경우는 03을 사용합니다.
그림 7은 이러한 내용을 설명하고 있습니다.
Advanced Keys and Addresses
Pay-to-Script Hash (P2SH) and Multisig Addresses
다중서명은 이름 그대로 여러 명이 서명을 가지고 소유권 증명을 하는 방법입니다. 보통의 경우에는 한 계정 주소로 비트코인을 전송하기 때문에 수신자 주소 만을 알면 됩니다. 하지만 다중 서명의 경우는 다수의 계정 주소와 소유권 증명을 유효한 것으로 인정할 수 있는 조건 등이 명시되어야 합니다. 비트코인에서는 이를 스크립트로 작성하고, 이 스크립트에 대해 주소를 생성하고, 이 주소를 수신자로 사용할 수 있게 함으로 다중서명을 처리합니다. 이러한 방식을 ‘스크립트에 대해 지불한다’는 의미 그대로 Pay-to-Script Hash(P2SH)라고 합니다.
Vanity Addresses
Vanity addresses are valid bitcoin addresses that contain human-readable messages.
사람이 읽을 수 있는 메시지를 포함하는 주소입니다. 이런 주소를 만들려면 수많은 시행착오를 해야 합니다. 재미 있는 내용이지만 별로 중요하진 않습니다.
Paper Wallets
Paper wallets are bitcoin private keys printed on paper. Paper wallets are a very effective way to create backups or offline bitcoin storage, also known as “cold storage.” As a “cold storage” mechanism, if the paper wallet keys are generated offline and never stored on a computer system. Paper wallets can be generated easily using a tool such as the client-side JavaScript generator at bitaddress.org. A more sophisticated paper wallet storage system uses BIP-38 encrypted private keys.
비트코인은 돈처럼 취급됩니다. 비트코인을 많이 가지고 있는 사람 입장에서 키 관리는 매우 중요합니다. 종이 지갑은 좀 원시적인 것 같지만 온라인으로 해킹이 빈번히 일어나는 오늘날 환경에서 보면 매우 보안이 뛰어난 방법입니다. 암호화된 개인키를 인터넷이 연결되지 않은 상태에서 여러 장 생성하고 출력해서 여러 안전한 곳에 분산해서 보관해둡니다.