Ch 4. Cryptography
업데이트:
Public Key Cryptography에 대해서 설명한다.
Key and Addresses
- 두 가지 유형의 이더리움 계정
- Externally Owned Account (EOA)
- Contract
- Private Key, Ethereum Address, Digitial signature
- 위의 3가지를 이용해 이더 소유권 확립
- 계정 주소는 개인키에서 파생
- 개인키는 account라 불리는 단일 이더리움 주소 결정
- Public Key: 계좌번호 / Private Key: PIN 번호
- 계좌번호는 식별, PIN 번호는 제어
Public Key Cryptography and Cryptocurrency
- 암호화는 소인수 분해 (prime factorization)에 기반
- 8,018,009라는 두 소수의 결과를 제시했을 떄, 두 소수를 찾는것은 소수를 곱하는 것 보다 어려움
- Trapdoor function: 단, 한쪽의 수라도 알면 쉽게 계산할 수 있음
- 더 발전된 암호화는 타원 곡선 암호화 (elliptic curve cryptography)를 이용
- 소수로 나눈 나머지를 곱하는 것은 간단
- 역함수는 사실상 불가능
- 개인키는 digital signature를 만드는데 필요한 고유한 정보의 접근을 제어
- Digital signature는 소유자 또는 컨트랙트 사용자 인증
Private Key
- 개인키는 자금의 소유권을 증명함으로써 Ether를 소비하는데 필요한 서명을 만드는데 사용
- 개인키를 공개하는것은 모든 권한을 제 3자에게 넘기는 것
Generating a Private Key from a Random Number
- 이더리움 개인키는 1에서 2^256 사이의 숫자를 선택
- 현재로서 하나의 개인키를 무작위로 선택했을 떄 그것의 값을 추측할 수 있는 방법은 없음
Public Key
- $K$를 구하기 위해서 $G$와 $k$를 연산하는 것은 쉬움
- $K$와 $G$를 안다고 $k$를 구하기는 어려움
\(K=k*G\)
- $K$ : public key
- $k$ : private key
- $G$ : Generator point
- $*$ : special elliptic curve “multiplication” operator
- 이것이 one-way methematical function
Elliptical Curve Cryptography Explained
-
이더리움은 미국 표준기술연구소(National Institute of Standards and Technology, NIST)에서 제정한
secp256k1
표준에 따라 특정 타원 곡선과 수학 상수 집합을 사용 secp256k1
\(y^2 = (x^3+7) \; \text{over} \; (\mathbb{F}_p)\) or: \(y^2 \; \text{mod} \; p=(x^3+7) \; \text{mod} \; p\)- $\text{mod} \; p$ : 소수 $p$로 나눈 나머지
- $\mathbb{F}_p$: 유한한 소수 $p$의 범위로 한정 지어줌
- 그래서 curve가 무한하지 않고 유한함
-
$y^2$을 소수 $p$로 나눴을 때의 나머지와 $x^3+7$을 소수 $p$로 나눴을 떄의 나머지가 동일한 경우 point Q가 된다.
- point가 eliptic curve 위에 있는 점임을 python으로 검증
C:\Users\user>python Python 3.10.10 (tags/v3.10.10:aad5f6a, Feb 7 2023, 17:20:36) [MSC v.1929 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> p = 115792089237316195423570985008687907853269984665640564039457584007908834671663 >>> x = 49790390825249384486033144355916864607616083520101638681403973749255924539515 >>> y = 59574132161899900045862086493921015780032175291755807399284007721050341297360 >>> (x ** 3 + 7 - y**2) % p 0
Elliptic Curve Arithmetic Operations
- 타원 곡선에서의 연산은 정수 산술과 흡사
+
연산자를 정의 가능- 덧셈을 특이하게 정의함
-
타원 점의 집합 G는 아래의 조건을 만족 1) G에 속한 임의점 P, Q에 대해서 P+Q 또한 G에 속한다 2) (P+Q)+R=P+(Q+R) 3) ideal point 0이 있으며, P+0=0+P=P 4) Q가 P의 역원이면 P+Q=0 5) P+Q=Q+P
- 앞서 덧셈이 정의 되었는데, 덧셈을 확장하여 곱셈을 정의 가능
- G의 원소 P에 대해 k가 정수이면 k*P = P+P+P+…+P (k번 반복)
Generating a Public Key
\(K=k*G\)
- $K$ : public key
- $k$ : private key (Random generation)
- $G$ : Generator point
- Generator point는
secp256k1
표준의 일부로 지정 - 모든 이더리움 사용자에 대해 G는 항상 동일
- Generator point는
- $*$ : special elliptic curve “multiplication” operator
Example of Public Key Generation
- Public key를 다음과 같이 생성한다.
K = f8f8a2f43c8376ccb0871305060d7b27b0554d2cc72bccf41b2705608452f315 * G
- 이때 K는 다음과 같은 점으로 정의
K=(x,y) x = 6e145ccef1033dea239875dd00dfb4fee6e3348b84985c92f103444683bae07b y = 83b5c38e5e2b0c8529d7fa3f64d46daa1ece2d9ac14cab9477d042c84c32ccd0
- 이더리움에서는 130개의 serialization으로 공개키가 표시 |Prefix |Meaning|Length(byte counting prefix) | |——-|——————-|——————————-| |0x00 |무한대 |1 | |0x04 |압축되지 않은 지점 |65 | |0x02 |짝수 y의 압축된 점 |33 | |0x03 |짝수 x의 압축된 점 |33 |
- 이더리움은 압축되지 않은 공개키만을 사용
- 관련된 유일한 접두어는 04
- Serialization은 공개키의 x와 y좌표를 연결
04 + x좌표(32바이트/64(16진수)) + y좌표(32바이트/64(16진수))
- 계산된 공개키는 다음과 같음
04 + 6e145ccef1033dea239875dd00dfb4fee6e3348b84985c92f103444683bae07b + 83b5c38e5e2b0c8529d7fa3f64d46daa1ece2d9ac14cab9477d042c84c32ccd0
Elliptic Curve Libraries
암호화폐 관련 프로젝트에 사용되는 secp256k1
elliptic curve를 구현한 라이브러리들
- OpenSSL
secp256k1
의 전체 구현을 포함한 포괄적인 암호학적 기반요소 제공
- libsecp256k1
- Bitcoin Core에서 제작
- Elliptical Curve 및 기타 암호화 기초 요소를 C언어로 구현
- OpenSSL 대체를 위해 완전히 새로 작성
Cryptographic Hash Functions
- Hash function: 임의 크기의 데이터를 고정된 크기의 데이터로 매핑하는 데 사용할 수 있는 모든 함수
- 함수에 대한 입력(pre-image, message, input data)를 모두 hash로 매핑
- 암호 hash function은 단방향 해시 함수
- 사실상 일치하는 해시를 찾기는 불가능
- 해시 함수가 좋을 수록 해시 충돌이 덜 발생
- 특징
- Determinism: 항상 동일한 해시 결과 생성
- Verifiability: 메시지의 해시 계산은 효율적
- Noncorrelation: 원본 메시지와 관계성이 없다
- Irreversibility: 역으로 메시지를 계산해내는 것은 불가능
- Collision protection: 사실상 같은 해시를 생성하는 2개의 메시지를 계산하는 것은 불가능
Ethereum’s Cryptographic Hash Function: Keccak-256
Keccak-256
: 국립 과학 기술 연구소(National Institute of Science and Technology)에서 개최한 SHA-3 암호화 해시 함수 경쟁 대회(SHA-3 Cryptographic Hash Function Competition)의 후보로 설계Keccak
은 우승한 알고리즘으로, FIPS202로 표준화 됨- 표준화 과정에서 난수 생성기 표준을 의도적으로 약화시켜 표준 난수 생성기에 백도어를 효과적으로 배치했다는 내부 고발
- Ethereum은 원래
Keccak
을 채택
Which Hash Function Am I Using?
- 주어진 입력에 대해 예상되는 결과인 test vector를 이용
- 가장 일반적으로는 empty input을 넣어서 확인 ``` Keccak256(“”) = c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470
SHA3(“”) = a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a ```
- Keccak-256과 표준 SHA-3 사이에서 해시 함수 차이로 인한 혼란이 있기 때문에 모든 opcode 및 라이브러리 sha3 인스턴스를 모두 keccak256으로 개명하기 위한 노력이 진행중이다. (ERC59)
Ethereum Addresses
-
이더리움 주소는
Keccak-256
단방향 해시 함수를 사용하는 공개키/컨트랙트에서 파생한 고유 식별자이다. - 이전 예제는 개인키 k로 시작해서 공개키 K를 만듬
k = f8f8a2f43c8376ccb0871305060d7b27b0554d2cc72bccf41b2705608452f315 K = k * Gz K = 6e145ccef1033dea239875dd00dfb4fee6e3348b84985c92f103444683bae07b83b5c38e5e...
- Keccak-256을 이용해 공개키의 해시를 계산
Keccak256(K) = 2a5bc342ed616b5ba5732269001d3f1ef827552ae1114027bd3ecf1f086ba0f9
- 이더리움의 최하위 20바이트를 유지한다
001d3f1ef827552ae1114027bd3ecf1f086ba0f9
- 종종 이더리움 주소가 접두어 0x로 표시
0x001d3f1ef827552ae1114027bd3ecf1f086ba0f9
Ethereum Address Format
- 공개키 해시의 마지막 20비트에서 파생된 식별자
- 체크섬이 없는 원시 16진수
- 이더리움의 주소가 결국 상위 계층에서 추상화에 숨겨짐
- 필요하다면 상위 계층에 checksum 추가
- 상위 계층이 너무 천천히 개발되어 초반의 생태계에 많은 문제점을 자아냄
Inter Exchange Cilent Address Protocol
- 클라이언트 주소 상호교환 프로토콜(Inter exchange Client Address Protocol, ICAP)
- 국제 은행 계좌 번호(International Bank Account Number, IBAN) 인코딩과 부분적으로 호환되는 이더리움 주소 인코딩
- 이더리움 주소에 대해 다목적의 체크섬 가능
- 상호운용 가능한 인코딩 제공
- IBAN
- 중앙 집중적
- 은행 계좌 번호 식별을 위한 국제 표준
- 국가코드/체크섬/은행 계좌 식별자 를 포함하는 34개의 문자열
- ICAP
- 이더리움을 나타내는 비표준 국가 코드 XE 도임
- 두 문자 체크섬/계정 식별자의 세가지 가능한 변형 도입
Direct
- 이더리움 주소의 최하위 비트 155개를 나타내는 최대 30자의 영숫자로 구성된 빅엔디안(big-endian) base36 정수
- 장점: 필드 길이와 체크섬 측면에서 IBAN과 호환
- 예: XE60HAMICDXSV5QXVJA7TJW47Q9CHWKJD (33자 길이)
Basic
- 직접 인코딩과 동일하지만 길이는 31자
- 이더리움 주소를 인코딩할 수 있지만 IBAN 필드 유효성 검사와 호환 X
- 예: XE18CHDJBPLTBCJ03FE9O2NS0BPOJVQCU2P (35자 길이)
Indirect
- 이름 레지스트리 공급자를 통해 이더리움 주소로 확인되는 식별자를 인코딩
- 자산 식별자(asset identifier, 예: ETH), 이름 서비스(예: XREG) 및 사람이 읽을 수 있는 9자의 이름(예: KITTYCATS)으로 구성된 16개의 영숫자 사용
- 예: XE##ETHXREGKITTYCATS (20자 길이)
- ##은 checksum
Hex Encoding with Checksum in Capitalization (EIP-55)
ICAP와 네임 서비스의 느린 배포 때문에 EIP-55에서 표준을 제안했다.
- 16진수 주소의 대문자를 수정하여 이전 버전과 호환되는 체크섬 제공
- 이더리움 주소는 대소문자를 구분하지 않는다.
- 모든 지갑은 해석의 차이 없이 대/소문자로 표현된 이더리움 주소를 수용
- EIP-55 체크섬을 지원하는 지갑은 99.986%의 정확도로 오류 감지
# EIP-55 적용 전
0x001d3f1ef827552ae1114027bd3ecf1f086ba0f9
# EIP-55 적용 후
0x001d3F1ef827552Ae1114027BD3ECF1f086bA0F9
- 16진수 인코딩 알파벳의 일부 알파벳(A~F) 문자는 대문자
- 그 밖의 문자는 소문자
EIP-55 구현
- 0x 접두어 없이 소문자 주소 해시 처리
Keccak256("001d3f1ef827552ae1114027bd3ecf1f086ba0f9") = 23a69c1653e4ebbb619b0b2cb8a9bad49892a8b9695d9a19d8f673ca991deae1
- 해시의 해당 16진수가 0x8 이상인 경우, 각 알파벳 문자를 대문자로 변환
# 변환 전 Address: 001d3f1ef827552ae1114027bd3ecf1f086ba0f9 Hash : 23a69c1653e4ebbb619b0b2cb8a9bad49892a8b9... # 변환 후 Address: 001d3F1ef827552Ae1114027BD3ECF1f086bA0F9 Hash : 23a69c1653e4ebbb619b0b2cb8a9bad49892a8b9...
EIP-55로 인코딩 된 주소의 오류 감지
- 다음은 EIP-55로 인코딩된 이더리움 주소이다.
0x001d3F1ef827552Ae1114027BD3ECF1f086bA0F9
- 주소를 읽는데 있어서 마지막 F를 E로 잘못 읽었다 가정한다.
0x001d3F1ef827552Ae1114027BD3ECF1f086bA0E9
- 주소의 유효성 검사를 위해 소문자로 변환하고 checksum hash를 계산
Keccak256("001d3f1ef827552ae1114027bd3ecf1f086ba0e9") = 5429b5d9460122fb4b11af9cb88b7bb76d8928862e0a57d46dd18dd8e08a6927
- 주소와 hash를 비교한다.
001d3F1ef827552Ae1114027BD3ECF1f086bA0E9 5429b5d9460122fb4b11af9cb88b7bb76d892886...
- 입력한 주소의 대문자 사용이 계산된 checksum과 일치하지 않음으로 오류가 발생했다.
댓글남기기