블록체인 학습을 목적으로 하는 비트코인 백서 번역입니다.
지식이 부족하거나, 애매한 부분은 공식 깃허브에 올라온 국문 번역을 참고합니다. 그럼에도 정확하지 않을 수 있습니다. 비트코인 백서를 처음 접하는 분이라면 가급적 원문(https://bitcoin.org/en/bitcoin-paper) 정독을 추천드립니다.
번역상의 오류나 보완점은 알려주시면 감사한 마음으로 수정하겠습니다.
비트코인 : P2P 전자 화폐 시스템
satoshin@gmx.com
www.bitcoin.org
Ver.1.0, 20180315 Translated by @choigww
INDEX
- Introduction
- Transactions
- Timestamp Server
- Proof-of-Work
- Network
- Incentive
- Reclaiming Disk Space
- Simplified Payment Verification
- Combining and Splitting Value
- Privacy
- Calculations
- Conclusion
Abstract. 완전한 형태로 구현된 P2P 전자 화폐는 금융 기관을 거치지 않는 당사자 간의 온라인 결제를 처리할 수 있다. 전자 서명이 대안이 될 수 있으나, 여전히 신뢰할 수 있는 제 3자가 이중결제를 막아야 한다. 우리는 P2P 네트워크를 이용하여 이중결제를 해결하는 시스템 네트워크를 제안한다. 네트워크는 해시 기반 작업증명(proof-of-work)으로 이어지는 연속적인 데이터 체인에 해싱 처리를 통해 트랜잭션을 타임스탬프로 기록한다. 따라서 이 기록은 동일한 작업증명을 반복하지 않고서는 변경할 수 없다. 가장 긴 체인은 목격된 연속적인 이벤트들을 증명할 뿐 아니라, 이러한 체인이 가장 커다란 CPU 파워로부터 만들어졌음을 증명한다. CPU 파워의 과반(majority)을 점유하는 노드 집단이 네트워크를 공격하지 않는 한, 그들은 가장 긴 체인을 올바른 체인으로 받아들임으로써 공격자를 배제한다. 미니멀한 구조를 갖는 네트워크 내에서 메시지는 best-effort 방식으로 공표된다. 노드는 자유롭게 네트워크를 떠나고 다시 참가할 수 있으며, 노드가 떠나 있는 동안 변경 사항에 대한 증명으로서 가장 긴 작업증명 체인이 채택된다.
1. Introduction
전자상거래는 신뢰할 수 있는 제3자, 금융기관의 전자 결제 처리에 거의 전적으로 의존해 왔다. 대부분의 거래를 처리하는 것이 가능하지만 이러한 신뢰 기반 모델에는 내재적인 취약점이 있다. 금융 기관은 제3자로서 거래 당사자 간 분쟁을 중재해야 하므로, 거래를 원천적으로 되돌릴 수 없도록 하는 것은 불가능하다. 중재 비용은 곧 거래 비용의 증가로 이어지고, 따라서 거래 가능한 최소 거래액이 높아져 소규모 거래가 불가능해진다. 또한 구매하고자 하는 서비스의 내용이 바뀔 수 있고, 결제 내용마저 확신할 수 없는 상황은 그 자체로 커다란 비용이다. 거래 내용이 언제든 뒤바뀔 수 있다는 가능성이 존재하므로, 거래 당사자 간 "신뢰"를 만드는 데 비용이 발생한다. 판매자는 구매자를 경계하며 필요 이상의 정보를 요구한다. 일정 빈도로 사기가 벌어지겠지만 불가피하다. 면대면 실물화폐 거래를 제외한다면, 이러한 비용과 결제 불확실성 때문에 특정한 채널을 거쳐야 하는 그 어떤 거래에서도 신뢰할 수 있는 제3자의 존재는 강제된다.
신뢰할 수 있는 제3자 없이도 상호 직접 거래를 가능하게 만들기 위해서는 신뢰가 아닌 암호화된 증명에 기반한 전자 결제 시스템이 필요하다. 부당이득을 목적으로 거래 내용을 바꾸려면 비현실적인 수준의 컴퓨팅 파워가 필요한 트랜잭션은 판매자를 사기로부터 보호하고, 에스크로 메커니즘을 손쉽게 적용하여 구매자를 보호할 수 있다. 이 백서에서 우리는, 트랜잭션의 시간 순서 기록을 컴퓨터 연산으로 증명하는 P2P 분산 서버를 사용하여 이중결제를 해결하는 시스템을 제안한다. 이 시스템은 공격자 노드보다 정직한 노드가 더 많은 CPU 파워를 점유하는 한 안전하다.
2. Transactions
우리는 전자 화폐를 전자 서명의 체인으로 정의한다. 각 소유자는 다음과 같은 절차를 통하여 화폐를 다음 소유자에게 전송한다.
- 직전 트랜잭션의 해시와 다음 소유자의 퍼블릭 키에 대해, 자신의 프라이빗 키를 이용하여 전자 서명한다
- 전자화폐 끝단에 위 정보를 추가하여 다음 소유자에게 전달한다
- 전자화폐를 받는 사람은 직전 소유자의 서명을 통하여 소유자 변동 히스토리를 확인할 수 있다
문제는 복수의 소유자들 중 누군가가 이중결제를 저지르지 않았다는 것을 확인할 수 없다는 것이다. 일반적으로 이를 위해 신뢰할 수 있는 권위기구 또는 모든 트랜잭션에 대하여 이중결제 사실을 확인하는 화폐발행기구를 도입하게 된다. 트랜잭션이 이루어질 때마다 화폐는 반드시 발행기구로 되돌아가 재발행되며, 발행기구로부터 직접 발행된 화폐는 이중결제가 이루어지지 않은 것으로 신뢰할 수 있다. 이 방법의 문제는 화폐 시스템의 운명이 전면적으로 발행을 관리 감독하는 조직에 달려 있다는 것이다. 현재의 화폐경제가 은행에 달려 있는 것과 같이.
직전 화폐 소유자가 자신을 제외한 어떤 트랜잭션에도 서명하지 않았음을 화폐를 받는 사람이 알 수 있어야 한다. 이를 위해서는 가장 빠른 트랜잭션을 확인하면 된다. 이후 발생한 트랜잭션은 모두 이중결제로 간주할 수 있다. 트랜잭션이 존재하지 않는지를 판단하는 유일한 방법은 모든 트랜잭션의 정보를 갖는 것이다. 화폐발행기구 기반 모델에서 발행기구는 모든 트랜잭션의 정보를 점유한 상태로 어떤 트랜잭션이 가장 먼저 발생했는지 판단한다. 신뢰할 수 있는 제3자 없이 이를 달성하기 위해서는 모든 트랜잭션이 공표되며 [1], 단 하나의 트랜잭션 히스토리를 참가자가 합의할 수 있는 시스템이 필요하다. 화폐를 전달받는 사람은 트랜잭션이 이루어지는 바로 그 시간에 네트워크 참여자 다수가 "네 트랜잭션이 가장 빠른 트랜잭션"이라고 동의한다는 증명이 필요하다.
3. Timestamp Server
우리가 제안하는 솔루션은 타임스탬프 서버로부터 시작한다. 타임스탬프 서버는 데이터 블록의 해시를 받아 시간 정보와 함께 기록하고, 신문이나 유즈넷 포스트 [2-5]와 같이 해시를 공표한다. 데이터는 시간 정보로 해당 시간에 반드시 존재했음이 증명되며, 해시로 변환된다. 각 시간정보는 해시 내부에 직전 시간정보를 포함하며, 결과적으로 각 시간정보가 꼬리에 꼬리를 무는 체인을 형성한다.
4. Proof-of-Work
P2P 기반으로 분산된 타임스탬프 서버를 구현하기 위해서 Adam Back의 Hashcash [6]와 유사한 작업증명 시스템이 필요하다. 작업증명은, 예를 들면 SHA-256 알고리즘에 의해 해시로 변환될 때 해시가 여러 개의 0비트로 시작하는지 해시값을 스캐닝하는 것을 포함한다. 이에 요구되는 평균 작업량은 요구되는 0비트 개수(the number of zero bits required)에 대하여 지수적으로(exponentially) 비례하며 단일 해시의 실행에 의해 식별 가능하다.
블록의 해시에 요구되는 갯수만큼의 0비트(the required zero bits)를 제공하는 값을 찾을 때까지, 블록 내에서 nonce값을 1씩 더함으로써 작업증명을 타임스탬프 네트워크에 구현한다. CPU 파워가 투입된 끝에 작업증명 조건이 충족된 이후부터, 블록은 동일한 CPU 작업량을 수행하지 않고는 변경될 수 없다. 이후 블록이 체인을 이루어 나감에 따라서 하나의 블록을 바꾸기 위한 작업량은 그 블록 뒤에 연결된 모든 블록들의 CPU 작업량을 포함한다.
작업증명은 또한 다수결 의사결정에 있어 대표군 결정에 관한 문제를 해결한다. 만약 다수결이 하나의 IP당 하나의 투표권에 기반한다면 다수의 IP를 확보하는 누군가에 의하여 결과가 왜곡될 수 있다. 작업증명은 본질적으로 하나의 CPU당 하나의 투표권 방식이다. 다수결은 가장 긴 체인에 의해 대변되며, 그 체인은 어마어마한 CPU 파워가 투입된 가장 거대한 작업증명에 해당한다. 만약 다수의 CPU 파워가 정직한 노드 집단에 의해 제어된다면 정직한 체인은 가장 빠르게 몸집을 키우고 다른 경쟁 체인을 압도할 것이다. 이후의 장에서, 계속 블록이 늘어남에 따라 느린 공격자가 가장 긴 체인을 따라잡을 확률이 지수적으로 감소함을 보일 것이다.
5. Network
네트워크는 아래와 같이 돌아간다:
- 신규 트랜잭션이 모든 노드에게 공표된다.
- 각 노드는 신규 트랜잭션의 정보를 local 블록 내에 저장한다.
- 각 노드는 복잡한 작업증명을 풀기 위하여 작업한다.
- 한 노드가 작업증명을 풀면, 해당 local 블록을 모든 노드에게 공표한다.
- 전체 노드는 공표된 블록 내의 모든 트랜잭션이 유효하며 이중결제되지 않은 경우에만 블록을 받아들인다.
- 유효 블록으로 판단한 노드는 해당 블록의 해시를 직전 해시로 지정하고 체인에 다음 블록을 생성하는 것으로 블록을 수용했음을 알린다.
모든 노드는 가장 긴 체인을 올바른 것으로 간주하며 해당 체인을 계속 이어나가게 된다. 만약 두 개의 노드가 동시에 서로 다른 블록을 현재 체인의 바로 다음에 오는 블록이라고 공표할 경우, 노드마다 첫번째 블록을 다르게 판단할 수 있다. 이 경우, 노드들은 그들이 첫번째로 받은 블록으로 체인을 연장하며 (체인 1), 두 번째로 받은 블록으로 연장한 다른 버전의 체인(체인2)을 일단 저장해 둔다. 이러한 일시적 분기상태는 바로 다음 작업증명이 풀리면서 해소된다. 새로운 블록을 체인1, 체인2에 각각 붙였을 때, 체인1이 체인2보다 길어지게 되면, 체인2를 작업했던 노드는 체인1로 갈아탄 뒤 새로운 블록을 연장하게 된다.
6. Incentive
관습적으로 블록의 최초 트랜잭션은 특별한 종류의 트랜잭션으로, 블록 생성자에게 신규 화폐를 지급한다. 이를 통해 노드가 네트워크에 기여하는 것에 대해 인센티브를 부여하며, 화폐를 발행하는 기구가 없으므로 지급된 화폐들을 순환시키는 역할을 수행한다. 신규 화폐가 일정량씩 꾸준히 지급된다는 것은 화폐 채굴자들이 자원을 투입하여 지속적으로 화폐 유통망에 신규 화폐를 공급한다는 의미다. 비트코인의 경우 CPU 가동 시간과 그에 따른 전기 사용료가 자원에 해당한다.
인센티브는 트랜잭션 수수료의 형태로 지급될 수도 있다. 트랜잭션의 산출값이 투입값보다 작은 경우, 그 차이는 트랜잭션 수수료 명목으로 해당 트랜잭션을 보유한 블록에게 인센티브로 지급된다. 사전에 정해진 양의 코인들이 유통되기 시작하면, 인센티브는 트랜잭션 수수료의 형태로 전환되며 인플레이션으로부터 완전하게 자유로울 수 있다.
인센티브는 노드가 정직한 상태를 유지하도록 동기를 부여할 수도 있을 것이다. 공격자가 모든 정직한 노드들의 총합보다 많은 CPU 파워를 확보한 경우, 공격자는 CPU를 사용하여 자신의 지불 기록을 되돌리면서 사기를 치거나, 아니면 새로운 코인을 생성할 수 있다. 다른 노드가 보유한 화폐보다 더 많은 화폐를 얻을 수 있는 규칙 하에서 공격자의 최적선택은 자신의 보유 화폐의 유효성을 속이는 것보다 새로운 화폐를 계속해서 만들어내는 것이 된다.
7. Reclaiming Disk Space
충분한 개수의 블록에 가장 최근의 트랜잭션이 기록되면, 그 이전에 기록된 트랜잭션은 디스크 공간 절약을 위해 삭제될 수 있다. 블록의 해시를 무너뜨리지 않기 위해서, 트랜잭션은 머클 트리 내부에서 루트 해시로 변환된다 [7][2][5]. 오래된 블록은 트리의 가지(branch)를 쳐내는 것으로 디스크 용량을 줄일 수 있다. 내부 해시는 저장될 필요가 없다.
트랜잭션이 기록되지 않은 블록 헤더는 약 80바이트의 용량을 차지한다. 블록이 10분에 하나씩 생성된다고 하면, 80바이트 * 6 * 24 * 365 = 매년 4.2MB가 늘어난다. 2008년도 일반적인 컴퓨터 사양이 2GB RAM이며, 여기에 매년 +1.2GB의 성장을 예측하는 무어의 법칙을 적용하면, 블록 헤더가 메모리에 저장되더라도 용량이 문제가 될 일은 없어 보인다.
8. Simplified Payment Verification
네트워크 노트 전부를 사용하지 않아도 결제를 검증할 수 있다. 사용자는 가장 긴 작업증명 체인에 있는 블록 헤더들을 복사하기만 하면 된다. 체인 블록헤더를 복사하기 위해서는,
- 그가 가장 긴 체인을 가졌다고 확신할 수 있을 때까지 네트워크 노드에 쿼리(query)를 날린다.
- 해당 트랜잭션(결제 검증 대상)과 그 트랜잭션의 시간정보가 기록된 블록을 연결하는 머클 브랜치를 찾는다.
사용자는 원하는 트랜잭션 자체를 확인할 수는 없지만, 그 트랜잭션을 체인 내부 공간에 연결시킴으로써 네트워크 노드가 해당 트랜잭션을 받아들였는지, 그리고 그 이후로 네트워크가 받아들인 블록들이 추가되어 있는지를 확인할 수 있다.
이와 같이, 결제의 검증은 정직한 노드 다수가 네트워크를 지배하는 한 신뢰할 수 있지만, 네트워크 지배권이 공격자에게 넘어가게 된다면 매우 취약해질 수 있다. 네트워크 노드는 스스로 트랜잭션의 유효성을 검사할 수 있지만, 공격자가 네트워크를 계속해서 지배하는 동안 공격자가 생성한 트랜잭션에 의해서 노드 유효성 검사가 왜곡될 수 있다. 이에 대한 대비책 중 하나는, 다른 네트워크 노드가 유효하지 않은 블록을 발견했을 때 그에 대한 알림을 받는 것이다. 예를 들면, 유효하지 않은 블록을 발견한 노드가 네트워크 비일관성을 확정하기 위해 전체 블록과 함께 유효하지 않은 것으로 발견된 트랜잭션을 다운로드 받으라고 다른 노드에게 알림을 보내는 것이다. 그러나 여전히, 결제가 빠른 주기로 이루어지는 비즈니스의 경우 독립된 보안 환경과 빠른 검증을 위해서 그들 자신만의 노드를 운영하고 싶어할 수도 있다.
9. Combining and Splitting Value
금액을 나누거나 합쳐서 화폐를 보내려고 트랜잭션을 매번 쪼개는 것은 매우 번거로운 일이 될 것이다. 이를 위해 트랜잭션은 복수의 인풋과 아웃풋으로 이루어진다. 일반적으로 커다란 직전 트랜잭션을 하나의 인풋으로 받아올 수도 있고, 더 작은 값으로 쪼갠 여러 개의 인풋으로 받아올 수도 있다. 아웃풋의 경우 가능한 경우는 최대 2가지. 하나는 결제를 위한 아웃풋, 그리고 하나는 잔돈을 회수하기 위한 아웃풋이다.
하나 짚고 넘어갈 점. 하나의 트랜잭션이 다른 다수 트랜잭션에 인풋-아웃풋 관계로 의존되고, 다시 그 여러 개의 트랜잭션은 또다른 여러 개의 트랜잭션과 인풋-아웃풋으로 의존되는 fan-out은 문제되지 않는다. 단일 트랜잭션의 히스토리 복사본을 통째로 추출해야만 할 일은 일어나지 않기 때문이다.
10. Privacy
전통적인 은행 모델은 이해관계자와 신뢰할 수 있는 제3자에 대한 정보 접근을 제한함으로써 프라이버시를 지킨다. 모든 트랜잭션을 공표해야 한다는 건 이 자체를 부정하는 것이다. 그러나 "이 곳"의 프라이버시는 "다른 곳"에서의 정보 유통을 막음으로써도 유지될 수 있다. 이는 퍼블릭 키를 익명으로 유지함으로써 가능하다. 모든 사람들은 누군가가 돈 얼마를 누군가에게 보낸다는 것은 볼 수 있지만, 트랜잭션에 관여한 이가 누구인지는 알 수 없다. 이것은 시간과 거래 규모는 공개되지만 거래 당사자는 공개되지 않는 주식거래 정보 공개와도 유사하다.
추가적으로 트랜잭션마다 새로운 키 조합을 사용하여, 특정 키 조합으로 사용자를 특정할 수 없게 할 수도 있다. 하지만 복수의 인풋을 받는 일부 트랜잭션의 경우, 어쩔 수 없이 그 트랜잭션의 모든 인풋은 동일한 사용자의 소유였음을 숨길 수 없다. 이로써 파생되는 리스크는 만약 어떤 사용자의 키가 알려질 경우, 해당 사용자에게 속한 다른 트랜잭션 정보까지 노출될 수 있다는 점이다.
11. Calculations
우리는 공격자가 정직한 체인보다 더 빠르게 대체 체인을 생성한다는 시나리오를 대비하고자 한다. 설령 공격자가 위 시나리오를 성공시킨다 해도, 모든 프로세스를 무시하고 화폐를 만들어낸다거나 하는 수준의 급진적인 변화를 시스템이 허용하지 않는다. 노드는 결제가 유효하지 않은 트랜잭션을 받아들이지 않을 것이고, 정직한 노드는 부정한 트랜잭션이 포함된 블록 자체를 받아들이지 않을 것이다. 공격자는 오로지 그가 사용한 화폐를 되돌려받기 위해서 그 자신의 트랜잭션을 하나씩 바꿔볼 수 있을 뿐이다.
정직한 체인과 공격자 체인 간의 경쟁은 Binomial Random Walk, 무작위 행보으로 특징지을 수 있다.
- 성공 이벤트 = 정직한 체인이 1블록 연장되어 +1만큼 앞서는 것, "increase lead by +1"
- 실패 이벤트 = 공격자 체인이 1블록 연장되어 격차가 -1만큼 줄어드는 것, reduce the gap by -1
공격자 체인이 정직한 체인보다 짧은 상황에서, 정직한 체인을 따라잡을 확률은 Gambler's Ruin problem, 도박꾼의 파산 문제과 유사하다. 무제한의 신용/돈/자원을 가진 도박꾼이 지고 있는 상황에서 추격하여 반반을 달성하기 위해 유한수의 게임을 실시한다. 우리는 도박꾼이 반반까지 따라잡을 확률, 즉 공격자 체인이 정직한 체인을 따라잡을 확률을 아래와 같이 계산할 수 있다.
p > q라고 가정할 때 확률은 공격자가 따라잡아야 하는 블록 개수에 비례하여 지수적으로 하락한다. 따라서 공격자가 초반부에 요행으로 따라붙지 못한다면 그 이후 기하급수적으로 성공 확률이 감소하게 된다.
우리는 이제 신규 트랜잭션을 보내는 쪽(sender)이 트랜잭션의 내용을 변경할 수 없음을 확신할 때까지 받는 쪽(recipient)이 얼마나 기다려야 하는지를 고려해야 한다. 보내는 쪽이 자신의 지불 사실을 속여 거래를 한 뒤 이후에 지불 내용을 번복하는 공격자라고 가정해 보자. 지불 내용이 번복되면 받는 쪽은 알람을 받겠지만, 되돌리기엔 너무 늦은 시점일 것이다.
받는 쪽은 새로운 키 조합을 생성하여, 전자 서명이 완료됨과 동시에 보내는 쪽에 퍼블릭 키를 전달한다. 이렇게 하면 보내는 쪽이 미리 준비해 둔 가짜 블록 체인으로 작업증명을 시도하다가 운좋게 정직한 체인을 크게 앞서게 된 시점에 거래를 실행하는 것을 막을 수 있다.
받는 쪽은 트랜잭션이 한 블록에 추가 완료될 때까지 기다리고, z개의 블록이 그 뒤로 따라붙는다. 받는 쪽은 공격자가 시도한 작업량은 알 수 없다. 그러나 정직한 체인이 블록 1개당 평균적인 기대 시간을 갖는다는 것을 생각했을 때, 공격자의 잠재적인 작업 진행은 평균 기대 시간에 대해 푸아송 분포, Poisson distribution를 따를 것이다:
공격자가 "지금" 따라잡을 가능성을 구하기 위해, [공격자의 작업량 각각에 대한 포아송 밀도] * [해당 시점에서 공격자가 따라잡을 확률]을 계산한다.
분포의 무한한 꼬리 부분을 더하지 않기 위해 식을 다듬으면,
이를 C로 작성하면,
아래 결과로부터 확률값이 z에 비례하여 지수적으로 감소함을 볼 수 있다.
P가 0.1% 미만인 경우에 대해 풀어보면,
12. Conclusion
여기까지 신뢰에 기반하지 않는 전자상거래를 위한 시스템을 제안해 보았다. 우리는 소유증명에 탁월하지만 이중결제 방지에는 불완전한, 전자서명 기반 화폐 프레임워크로부터 시작했다. 이중결제 문제의 해결을 위해 우리는 작업증명(PoW)을 사용하는 P2P 네트워크를 제안했다. 이를 통해 정직한 노드가 네트워크 총 CPU 파워의 과반을 넘는 한, 공격자가 내용을 변경하는 것이 매우 빠르게 어려워지는 트랜잭션의 공개 히스토리를 네트워크에 기록할 수 있다. 이러한 네트워크의 견고함은 바로 구조화되지 않은 단순성에서 비롯한다. 노드는 서로 거의 협력하지 않고 한꺼번에 작동한다. 메시지가 도달할 장소를 특정할 필요 없이 best effort 기반으로 전송되기만 하면 되므로, 노드를 식별할 필요가 없다. 노드는 원할 때 네트워크를 떠났다가 다시 들어올 수 있으며, 돌아올 때는 체인 변경분에 대한 증명으로 작업증명 체인을 인정한다. 노드의 합의는 각 노드의 CPU 파워 기반으로 이루어진다. 노드는 유효 블록을 현재 체인에 붙임으로써 블록의 유효성을 승인하고, 유효하지 않은 블록은 거부한다. 이러한 합의 메커니즘 위에 여러가지 필요한 규칙과 인센티브가 만들어진다.
References
- [1] W. Dai, "b-money," http://www.weidai.com/bmoney.txt, 1998.
- [2] H. Massias, X.S. Avila, and J.-J. Quisquater, "Design of a secure timestamping service with minimal
trust requirements," In 20th Symposium on Information Theory in the Benelux, May 1999. - [3] S. Haber, W.S. Stornetta, "How to time-stamp a digital document," In Journal of Cryptology, vol 3, no
2, pages 99-111, 1991. - [4] D. Bayer, S. Haber, W.S. Stornetta, "Improving the efficiency and reliability of digital time-stamping,"
In Sequences II: Methods in Communication, Security and Computer Science, pages 329-334, 1993. - [5] S. Haber, W.S. Stornetta, "Secure names for bit-strings," In Proceedings of the 4th ACM Conference
on Computer and Communications Security, pages 28-35, April 1997. - [6] A. Back, "Hashcash - a denial of service counter-measure,"
http://www.hashcash.org/papers/hashcash.pdf, 2002. - [7] R.C. Merkle, "Protocols for public key cryptosystems," In Proc. 1980 Symposium on Security and
Privacy, IEEE Computer Society, pages 122-133, April 1980. - [8] W. Feller, "An introduction to probability theory and its applications," 1957.