프로그래밍/블록체인

[해석서]Bitcoin: A Peer-to-Peer Electronic Cash System - 2. 거래(1/2)

산을좋아한라쯔 2018. 1. 31. 13:45
반응형

 

2. 거래

우리는 전자 코인을 디지털 서명의 체인으로 정의한다. 각각의 전자 코인 소유자는, 이전(以前) 거래의 해시와 받을 이의 공개키(public key)에 대해 디지털 서명하고 이 서명값을 코인의 끝에 붙여서, 다른 이에게 코인을 넘긴다. 받는 이는 서명에 대한 검증을 통해 해당 체인의 소유권을 확인할 수 있다.

 

 

 

 

 

이 부분을 이해하기 위해서는 '해시'와 '서명/검증' 기술에 대해 알아야합니다.

 

해시

해시(Hash)는 암호학에서 쓰이는 함수의 하나로, 어떤 데이터덩어리를 약속된 크기의 데이터로 변환합니다. 

예를 들어 A라는 10KBytes 크기의 파일이 있을 때, 이 파일 전체를 해시함수로 변환하면 256비트(=32바이트) 혹은 512비트 등의 약속된 크기의 데이터로 바꿀 수가 있습니다. 압축 비슷한거라 생각할 수 있는데, 압축과는 많이 다릅니다. 압축과 다른 해시함수의 특이한 성질은 다음과 같습니다.

 

  - 큰 크기의 데이터를 일정한 크기의 작은 데이터(32바이트 등)로 변환할 뿐 아니라, 10바이트의 작은 데이터도 32바이트로 크게 만듦

  - A라는 데이터를 해시함수 이용해서 B로 만드는 것은 쉽게 되나(수 마이크로 초에 수행가능 = 1초에 50만회 수행),

    B라는 데이터가 주어졌을 때, 이것이 A라는 것으로부터 나왔다는 것을 알아내긴 불가능에 가깝게 어려움
    --> 이러한 성질을 '일방향성'이라하고, 이런 함수를 '일방향 함수'라 함

      (256비트의 해시함수의 경우, B라는 데이터로부터 A를 유추해내려면, 2^256 횟수만큼 시도해봐야함.

       이 횟수를 시도하는데는 컴퓨터 이용해서 10^63년 정도가 걸림. 즉 불가능)

  - A를 B로 해시변환했을 때, A의 값에서 한 비트만 변동이 있어도, B의 값은 알아볼 수 없을 정도로 거의 모든 비트가 바뀜

위 성질 중 2번째와 3번째가 중요한 성질인데, 2번째인 일방향성이 뭔지 알려면 자연현상을 가지고 이해하면 쉽습니다.

예를 들어, 쌀 알갱이 수 백개를 가지고 방바닥에다 어떤 글자 모양이되도록 만드는 것은 어렵고 시간이 걸리는 일인데, 그렇게 만들어진 글자를 흐트려버리는 일은 매우 쉽습니다. 일방향적 성질을 가지고 있는거죠. 한쪽방향으로의 진행은 어렵고, 반대방향은 쉬운.

수학식에서도 일방향성을 가지는 예가 많는데, 예를 들어 함수 y=x3+x2+x+1 이라할 때 1)x의 값을 알 때 y의 값은 매우 쉽게 계산이 되는데, 2)반대로, y의 값을 알 때 그 x의 값을 알아내는 것은 매우 어렵습니다. (해시함수가 이런 3차 함수라는 얘기는 아닙니다. 일방향성 예를 든것일 뿐)  

 

해시함수도, 입력값을 알 때 그 해시값은 쉽게 구할 수 있으나, 해시값을 알고 있다고 해서 그 입력값은 알아내기 힘듭니다.

다시말해, B = hash(A)라할 때, A를 가지고 B를 계산해내는 것은 쉽게되나, B가 주어졌을 때 A를 유추해내는 것은 매우 힙듭니다. 

(A를 B로 해시변환한다는 것을 B = hash(A) 라고 표현합니다.)

 

일상생활에서 해시함수가 사용되는 대표적인 예는 비밀번호가 저장될 때입니다. 우리가 웹사이트에 로그인할 때 사용하는 비밀번호는, 등록시점에 사용자가 비밀번호를 치면, 그 비밀번호가 해시변환되서 서버의 데이터베이스에 저장됩니다. 

그런 상태에서, 사용자가 로그인하려할 때 비밀번호를 치면, 사용자가 입력한 비밀번호가 해시로 변환되서 서버로 전송되고, 서버에 저장된 해시값과 보내진 해시값이 같은 지 비교해서 같으면 로그인이 성공되는 것이고, 실패하면 로그인이 안됩니다. 

이 과정을 그림으로 표현하면 아래와 같습니다.                   

 

 

 

이렇게 비밀번호를 그대로 서버 데이터베이스에 저장하지 않고, 해시로 변환해서 사용하는 이유는, 비밀번호 자체가 네트웍으로 전송되지 않게 하고, 데이터베이스에도 비밀번호가 그대로 저장되지 않게 하기 위함입니다.

"happypassword"라고 저장되어 있는 것보다, "2omGA28HUSDjXXWKA9UZK4xsMuwv" 이렇게 저장되어 있는 것이 사람이 한 눈에 알아봐서 기억하기 쉽지 않기때문이고, 만약 서버 데이터베이스 관리자가 그 해시값을 본 다하더라도, 그 해시값으로부터 원래의 비밀번호를 알아내지 못하게학기 위함입니다.   

 

비트코인 시스템에서 해시는 여러 용도로 사용됩니다. 

거래에서 사용자의 공개키(공개키가 무엇인지는 아래 전자서명 부분에서 다룹니다.)를 가지고 그 사용자의 '주소'를 만들 때 사용되고, 거래들을 모아서 블록으로 만들때도 사용됩니다. 또한 비트코인에서 아주 중요한 개념중의 하나인 PoW(Proof of Work)의 근간을 이루는 기술도 해시함수입니다. (PoW에 대해서는 논문에 다시 나오니, 그 때 설명하겠습니다.)

 

해시함수는 꽤 많은 종류가 있는데, 비트코인에서는 sha256과 RIPEMD라는 해시함수가 사용됩니다. (sha256은 보통 "샤 이오육"이라고 읽음)

  •   sha256: 전 세계적으로 가장 널리 쓰인다고 생각되는 유명한 해시함수로, 입력값이 무엇이든 256비트(=32바이트)의 값을 만들어 냄
  •   RIPDMD160 : 160비트 출력값을 내는 해시함수. sha256은 미 정부기관인 NSA에 의해 만들졌고, 이것은 민간에서 만들어짐   

디지털 서명/검증

디지털 서명은, 사람들이 자신이 작성한 것임을 증명할 때 실제 필기구로 싸인(sign)을 하듯이, 디지털데이터를 이용해서, 자신이 직접 만들었다는 것이 암호학적으로 증명될 수 있게하는 데이터입니다. 그 디지털데이터를 만드는 것을 서명(sing)이라하고, 그 사람이 만들었다는 것을 확인하는 작업을 검증(verify)이라합니다.

서명/검증을 이해하기 위해서는 암호학에서 얘기하는 개인키(Private Key), 공개키(Public Key)에 대해서 알아야합니다.

개인키든 공개키든 일종의 긴 숫자로, 비트코인에서 개인키는 32바이트(=256비트) 길이이고, 공개키는 64바이트(512비트) 입니다.

 

  - 개인키: 그 사람만이 비밀스럽게 가지고 있어야하는 암호화 키. 서명 하는데 사용

  - 공개키: 다른 사람이 알 수 있도록 공개되어도 되고, 개인키로 서명된 값을 검증 하는데 사용

즉, 이렇게 암기하면 됩니다.

"인키는 에 사용"  "개키는 에 사용"  ==> 개서 공검

 

현재 전 세계적으로 가장 널리 쓰이는 디지털 서명 알고리즘은 RSA와 ECDSA 알고리즘이고, 비트코인에서는 ECDSA알고리즘이 사용됩니다.

(우리나라에서 금융거래 등에 온 국민이 쓰고있는 공개키인증서는 RSA알고리즘을 사용)

 

ECDSA는 타원곡선암호(ECC)를 이용한 서명알고리즘인데, 그 동작 원리까지 알 필요는 없고, 비트코인에서 꼭 알아야할 사항은 다음과 같습니다.

  - 개인키(PrK):  비트코인 프로그램에서 생성할 수 있는 256비트 난수로, 이게 없으면 코인을 찾을 수 없음. 비밀스럽게 잘 보관해야함 

 

  - 공개키(PuK):  개인키로 부터 뽑아낼 수 있고, 공개되어도 상관없음. 위 개인키 정보를 가지고 생성 

                         PuK = f(PrK) : 어떤 함수 f를 통해서 PuK가 PrK로부터 생성된다는 표현임

 

  - 주소 (Addr): 공개키를 sha256으로 해시변환하고, 이값을 다시 RIPEMD160 해시함수로 변환한 값. 즉, 공개키를 두번 해시해서 생성 

                      Addr = RIPEMD160(sha256(PuK))

 

  - 개인키로 어떤 값을 서명한 것은, 공개키로 검증 가능함. 즉, 공개키로 검증이 되었다는 것은, 개인키로 서명을 했다는 것이어서, 

    그 개인키를 가진 소유가자 서명했다는 증거가 됨.  S = sign(PrK, M) : 어떤 값 M을 PrK를 이용해서 sign한 값이 S라는 표현

  - 공개키를 알았다고 해서, 그로부터 개인키를 알아낼 수 없다는 것은 암호학적으로 증명된 사실. 즉, 개인키 알아낼 수 없음

 

개인키로 서명(sign)한 것을, 공개키로 검증(verify)를 하는 일반적인 방법을 도식화해보면 아래와 같습니다.

 

 

 

tx는 거래내역을 의미하고, 해시함수에 의해 해시값으로 나온것이 H(tx)입니다. 이 해시값을 개인키 PrK로 서명한 것이 sig. 일반적으로, 원래의 값인 tx를 이용해서 바로 서명하지 않고, tx에 대해 해시값을 계산 후, 그 해시값을 서명합니다.

이 서명값을 검증하기 위해서는, 원래의 tx값과 서명값, 그리고 공개키 PuK가 필요합니다. 절차는, tx에 대한 해시값 H(tx)를 구하고, 공개키 PuK를 이용해서 sig에 대해 검증을 합니다.

 

실제 비트코인에서, 개인키와 공개키 그리고 주소가 생성되는 모습은 다음과 같습니다.

먼저 256비트의 난수를 만들어서 그것을 개인키로 삼습니다.

공개키는 위에서 구한 개인키로부터 만들어 낼 수 있습니다. 그리고, 그 사람을 대표하는 '주소'는 공개키에 대해 해시값을 계산 후 Base 58이라는 인코딩방법을 이용해서 표현됩니다. Base 58은 숫자+알파벳으로 수를 표현하는 방법으로 16진수로 수를 표현하는 방법보다 사람이 읽기 편합니다. 

 

 

 

-계속-

 

[전체 목차]

1. 서론  
2. 거래(1/2)  
2. 거래 (2/2)
3. 타임스탬프 서버 
4. 작업 증명 
5. 네트워크 
6. 인센티브 
7. 디스크공간 회수 
8. 지불 입증 간소화 
9. 금액의 결합과 분할 
반응형