마스터링 이더리움 4일차

쌍제이(JJVoiture)·2022년 1월 4일
0
post-custom-banner

공개키 생성

K = k * G
곱셈은 G를 k번 더하는 연산으로 생각할 것...

이더리움에서는 16진수 문자 130개(65바이트)의 sirialization으로 표시되는 공개키를 볼 수 있다.

EC 공개키 접두어

0X00: 무한대를 가리킨다. 바이트 수는 1
0x04: 압축되지 않은 지점. 바이트 수는 65
0x02: 짝수 y의 압축된 점. 바이트 수는 33
0x03: 홀수 y의 압축된 점. 바이트 수는 33

serialization은 공개키의 x와 y 좌표를 연결한다.

04 + x 좌표(32 bytes / 64(16진수)) + y 좌표(32 bytes / 64(16진수))

secp256k1 타원 곡선 라이브러리 목록

  • OpenSSL
  • libsecp256k1: C언어로 구현, OpenSSl을 대체하기 위해 작성됨.

암호화 해시 함수

이더리움 공개키를 주소로 변환하는 작업에서 해시 함수가 기여하는 바가 있고, 디지털 지문을 만드는 데에 사용할 수 있다.

암호 해시 함수는 임의 크기의 데이터를 고정 크기의 비트 열로 매핑하는 단방향 해시 함수이다.
즉 결과값 해시를 알고 있을 때 입력 데이터를 다시 작성하는 것이 계산적으로 불가능함을 의미한다.

주요 속성

  • 결정론: 주어진 입력 메시지는 항상 동일한 해시 결과를 생성한다.
  • 검증성: 메시지의 해시 계산은 효율적이다.
  • 비상관성: 메시지에 대한 작은 변화는 해시 출력을 너무 광범위하게 변경해야 해서 원본 메시지의 해시와 상관 관계가 없다.
  • 비가역성: 해시로부터 메시지를 계산하는 것은 불가능하다. brute force search를 해서 찾는 것과 다를 바가 없다.
  • 충돌 방지: 같은 해시 결과를 생성하는 2개의 서로 다른 메시지를 계산하는 것은 불가능하다.

응용 가능한 분야

  • 데이터 핑거프린팅
  • 메시지 무결성
  • 작업 증명
  • 인증
  • 의사 난수 생성기
  • 메시지 커밋
  • 고유 식별자

Keccak-256

vs SHA-3
NIST에서 수정한 SHA-3의 경우 미국 국가안보국의 영향을 받아 난수 생성기에 백도어를 배치했다는 것이 내부 고발로 드러나게 되어 Keccak 알고리즘이 쓰이고 있다.

이더리움 주소

  • 개인키 k로부터 구한 공개키 K를 Keccak-256을 사용하여 공개키의 해시를 계산한다.
  • 마지막 20바이트만 유지한다.
  • 이더리움 주소가 접두어 0x로 표시되어 다음과 같이 16진수로 인코딩된다.

클라이언트 주소 상호교환 프로토콜(Intere exchange Client Address Protocol)

국제 은행 계좌 번호(IBAN)화 부분적으로 호환되는 인코딩 방식.
IBAN과 호환 가능한 '직접' 인코딩, 기본, 간접 인코딩 등의 구조가 있다.

대문자로 16진수 인코딩된 체크섬 EIP-55

  • ICAP와 ENS의 늦은 개발 때문에, EIP-55로 다른 표준이 제안되었다.

  • EIP-55는 16진수 주소 중 일부를 대문자화하여 구버전과 호환되는 이더리움 주소 체크섬을 제공한다.

  • 이더리움 주소는 대소문자 구분없이 사용할 수 있다는 점을 이용한 아이디어이다.

일반 이더리움 주소

0x001d3f1ef827552ae1114027bd3ecf1f086ba0f9

EIP-55 적용한 주소

0x001d3F1ef827552Ae1114027BD3ECF1f086bA0F9

두 주소의 차이점은 중간 중간 대문자로 변경된 영문자가 보인다는 것이다.
해당 16진수의 해시값이 0x8이상인 경우에 알파벳을 대문자로 만든다.

5장: 지갑

지갑: 사용자의 키를 보관하고 관리하기 위해 사용되는 시스템.

지갑을 설계할 때 중요한 고려 사항은 편의성과 프라이버시 사이의 균형을 맞추는 것.

많이 하는 오해!!!
보통 이더리움 지갑이 이더 혹은 토큰을 보유한다고 생각하지만 지갑은 키만 보유하고 있다.
이더 혹은 토큰은 블록체인에 기록된다.

기존 은행은 은행만이 계좌에 있는 돈을 볼 수 있고 트랜잭션 진행을 위해 자금을 옮기고 싶다면 은행만 납득시키면 된다.
그러나 블록페인 플랫폼에서는 모든 사람이 계좌의 잔액을 볼 수 있고 주인을 알지 못하지만 트랜잭션 진행을 위해 자금을 옮기고 싶어한다는 것을 모든 사람에게 납득시켜야 한다.

지갑의 형태

비결정적 지갑

: 무작위적으로 키를 추출.
모든 트랜잭션마다 새로운 주소를 사용하게 됨...
--> 편의성 면에서 매우 불편하다

그럼에도 불구하고 많은 이더리움 클라이언트는 보안 강화를 위해 암호문으로 암호화된 단일 개인키가 들어 있는 JSON 인코딩 파일인 keystore 파일을 사용한다.

{
    "version": 3,
    "id": "4c07993f-ded2-405a-b83d-3b627eebe5cd",
    "address": "e449efddf8c9b174bbd40a0e0e1902d6eee72068",
    "crypto": {
        "cipher": "aes-128-ctr",
        "cipherparams": {
          "iv": "7d416faf14c88bb124486f6cd851fa88"
        },
        "ciphertext":"e99f6d0e37f33124ee3020fad01363d9d7500efce
                      913aede8a8119229b7a5f2e",        
        "kdf": "scrypt",
        "kdfparams": {
            "dklen": 32,
            "salt": "c47f395c9031233453168f01b5a9999a06ec97c829
                     a395ecd16e1ad37102ec7f",
            "n": 8192,
            "r": 8,
            "p": 1
        },
        "mac": "82078437ee94331c69125eef4001ff4b78b481e909a6
                2a9ac25aa916237b70be"
    }
}

결정적 지갑

: 모든 키가 시드라는 단일 마스터 키로부터 파생된다.
모든 파생된 키는 시드로 복구할 수 있다.

HD 지갑(BIP-32/BIP-44)

HD(hierarchical deterministic) 지갑은 트리 구조로 파생된 키를 가지고 있다.

장점

  • 하위 branch 들마다 다른 역할로 사용 가능하고, 이를 통한 구조적 의미를 표현하는 것도 가능하다.
  • 개인키에 접속하지 않고 공개키 시퀀스를 만들 수 있다.

mnemonic code(BIP-39)

개인키를 인코딩하려면 단어 시퀀스를 사용하는 방법이 있다.
16진수 시퀀스를 기록할 때는 오류가 발생할 확률이 매우 높으나 단어 목록은 오류 업시 고쳐 쓰고, 종이에 기록하고, 읽고, 안전하게 내보내고, 개인키들을 다른 지갑으로 가져오는 가장 쉬운 방법이다.

mnemonic code 단어는 시드로 사용되는 난수를 인코딩하는 단어 시퀀스이다.

brainwallet은 사용자가 고른 단어로 구성되지만, 니모닉 단어는 무작위로 생성된다.

니모닉 코드(1~6)와 시드 생성(7~9)


1. 128~256비트의 무작위 암호화 시퀀스 S를 생성한다.
2. S를 SHA-256으로 해싱한 값을 32비트로 나눈 처음 길이를 체크섬으로 생성한다.
3. 무작위 시퀀스 S의 끝에 체크섬을 추가한다.
4. 시퀀스와 체크섬을 연결한 것을 11비트 단위로 나눈다.
5. 각각의 11비트 값을 사전에 정의된 2,048 단어 사전과 매핑한다.
6. 단어의 시퀀스로부터 순서를 유지하면서 니모닉 코드를 생성한다.

엔트로피는 키 스트레칭 함수 PBKDF2를 사용하여 더 긴 시드를 파생하는 데 사용된다.
이 함수에는 니모닉과 솔트라는 2가지 파라미터가 있다.
솔트의 목적은 무차별 대입 공격을 가능하게 하는 조회 테이블 생성을 어렵게 하는 것이다.


7. PBKDF2 키 스트레칭 함수의 첫 번째 파라미터는 6단계에서 생성된 니모닉이다.
8. PBKDF2 키 스트레칭 함수의 2 번째 파라미터는 salt이다. salt는 문자열 상수 "mnemonic"과 선택적으로 사용자가 지정한 암호문을 연결하여 구성한다.
9. PBKDF2는 최종 출력으로 512비트 값을 만드는 HMAC-SHA512 알고리즘으로, 2048 해시 라운드를 사용하여 니모닉과 솔트 파라미터를 확장하며, 이 결과로 나온 512비트 값이 시드이다.

HD 지갑(BIP-32)과 경로(BIP-43/44)

확장된 공개키와 개인키

키를 확장하는 것은 키 자체를 가져와서 특수 chain code를 추가하는 것.

키가 개인키이면 접두어 xprv로 구분되는 확장된 개인키가 되고,
확장된 공개키의 경우에는 xpub이라는 접두어로 구분된다.

확장된 부모 키는 적절한 연산을 사용하여 자식 키를 파생시킬 수 있다.

HD 지갑은 child 공개키를 파생하는 방법이 2가지가 있는데, 하나는 자식 개인키로부터, 다른 하나는 부모 공개키로부터 파생하는 방법이다.
위 방법은 xpub이 chain code를 포함하므로 하위 개인키가 알려져 있거나 유출되었을 경우에 모든 child 개인키가 노출될 위험이 있고, 부모 chain code 와 자식 개인키로부터 부모 개인키를 추론할 수 있다는 문제점이 있다.

위 문제에 대응하기 위해 HD 지갑은 강화 파생이라고 하는 대체 가능 파생 함수를 사용한다.
이 함수는 자식 chain code를 파생하기 위해 부모 공개키 대신 개인키를 사용한다. 이는 부모 공개키와 자식 chain code 간의 연결을 끊는다.

인덱스 번호

관리를 위해 인덱스 번호를 이용.
0x0 ~ 0x7FFFFFFF(0 ~ 2^31 - 1)은 일반 파생,
0x80000000 ~ 0xFFFFFFFF(2^31 ~ 2^32 - 1)까지는 강화 파생을 위해 사용.

HD 지갑 키 식별자

m: 마스터 키에서 파생된 개인키
M: 마스터 키에서 파생된 공개키

ex) m/1/0: 두번째 자식의 1번째 개인키

HD 지갑 트리 구조

m / purppose' / coin_type' / account' / change / address_index

change에서 HD 지갑에는 2개의 하위 트리가 존재하는데,하나는 입금 주소 작성용이고, 다른 하나는 잔액 주소 작성용이다. 이더리움은 비트코인에 있는 잔액 주소가 필요하지 않지만 BIP-44는 원래 비트코인을 위해 제작된 것이다.

profile
안녕하세요. 중구난방 개발자 쌍제이입니다.
post-custom-banner

0개의 댓글