상세 컨텐츠

본문 제목

[Mastering the Lightning Network] 10 - Onion Routing

IT.About/라이트닝 네트워크

by zNine 2022. 4. 21. 11:35

본문

728x90
반응형

  • 마지막 10장에서는 라이트닝 네트워크의 Onion 라우팅 매커니즘에 대해 설명한다.
  • Onion 라우팅
    • 해군 연구원들이 통신 보안 프로토콜로 발명, 모든 사람이 인터넷을 익명으로 사용할 있도록 하며,
    • Tor에서 가장 많이 사용됨.
    • 메시지 발신자가 의도한 수신자에게 가장 안쪽 레이어가 전달될 때까지 중간 노드에 의해 "벗겨지는" 연속된 중첩 암호화 레이어를 구축하는 암호화된 통신 방식.
    • 양파 껍질처럼 번에 한층씩 벗겨지는 계층화된 암호화.
    • 중간의 노드는 레이어만 "벗길" 있고 통신 경로상 다음 전달할 곳을 볼수 있음.
    • 발신자 외에는 통신 경로, 목적지, 길이를 없고, 중개자는 이전/다음 홉만 알고 있음.
    • 라이트닝 네트워크에서는 2009년에 Sphinx 기반의 Onion 라우팅 프로토콜을 사용. (BOLT #4 정의)
 

GitHub - lightning/bolts: BOLT: Basis of Lightning Technology (Lightning Network Specifications)

BOLT: Basis of Lightning Technology (Lightning Network Specifications) - GitHub - lightning/bolts: BOLT: Basis of Lightning Technology (Lightning Network Specifications)

github.com

 

  • Onion 라우팅의 실사용 예
    • Alice Dina에게 비밀 편지를 밀봉된 봉투에 넣어 전달한다고 가정,
    • 봉투는 암호화 계층을 나타내며, 지정된 수신자만 봉투를 열고 내용을 읽을 있다.
    • 경로 선택
      • 라이트닝에서 경로는 보내는 사람이 선택.
      • Alice Bob Chan 거쳐 Dina에게 전달되는 경로를 선택
    • 레이어 만들기
      • A D에게 비밀 편지를 쓰고, 봉투안에 편지를 봉해 바깥쪽에 "To Dina"라고 표기.
      • 봉투는 D만이 봉투를 열어 편지를 읽을 있도록 D 공개키로 암호화.
      • D에게 전달될 봉투는 C 전달해주어야 하므로,
      • C에게 보내는 봉투안에 D 봉투를 넣고, (C "To Dina" 있음) C 볼수 있도록 C 공개키로 암호화.
      • 또, C 봉투는 B 전달해주어야 하므로,
      • B에게 보내는 봉투안에 C 봉투를 넣고, B 봉투안의 "To Chan" 있도록 B 공개키로 암호화.
      • 봉투안의 내부를 들여다 보면,
    • 레이어 필링(벗기기)
      • A "To Bob" 적힌 B 공개키로 암호화된 봉투를 B에게 전달.
      • B 전달자가 A라는 것은 알지만, 발신자인지 전달자인지는 모르며,
      • 봉투를 열어 "To Chan" 적힌 봉투를 찾고, C에게 전달…
      • 최종적으로 D C에게 봉투를 받고, 열어 안의 편지를 발견.

 

  • HTLC의 Onion 라우팅
    • A 모든 중개 노드에게 경로의 다음 노드로 설정할 HTLC 알려준다.
    • 발신자 A 원본 노드(origin node), 수신자 D 최종 노드(final node), 중개자 B C (hop) 이라 .
    • 모든 홉은 다음 홉으로 나가는 HTLC 설정해야하며, A 홉에 전달한 정보를 페이로드 또는 데이터 라고 .
    • A에서 D 라우팅되는 메세지를 양파(Onion)라고 하며, 홉에 암호화면 페이로드 혹은 데이터로 구성 된다.
    • A 데이터로 양파를 구성하고, 홉에 최종 노드에 지불을 보내기위해 outgoing HTLC 구성하는 방법을 알려야 .
    • Alice 경로 선택
      • 채널에 대한 공지와 업데이트를 통해 A B, C, D 간의 채널에 대한 다음 정보를 알고 있음.
      • 경로를 구성할 채널을 참고하는데 사용할 있는 채널의 short_channel_id
      • HTLC 만료 시간에 추가할 있는 cltv_expiry_delta(timelock delta)
      • 라우팅 요금을 계산하는데 사용할 있는 free_base_msat fee_proportional_millionths
    • Alice 페이로드 구성
      • 홉에 전달되는 정보에 사용할 있는 가지 형식이 있음.
        • hop data - 레거시 고정-길이 형식
        • hop payload - 유연한 TLV(Type-Length-Value) 형식
      • Dina 최종 노드 페이로드
        • A D에게 전달할 페이로드를 가장 먼저 구성하며,
        • 최종 노드(수신자)이므로, outgoing HTLC 구성하지 않음.
        • D 페이로드는 Dina for Alice에서 생성한 인보이스의 정보와 일치해야하며, TLV형식의 다음 필드를 포함.
          • amt_to_forward
            • 지불 금액, 여러 페이로드로 지불된 경우 총액보다 작고, 그렇지 않을 경우 total_msat 일치해야 .
          • outgoing_cltv_value
            • 지불 만료시간 잠금, 인보이스내 min_final_cltv_expiry 값으로 설정.
          • payment_secret
            • 인보이스에 전달된 256-bit 비밀 .
          • total_msat
            • 인보이스와 일치하는 총액.
        • A D에게서 받은 인보이스에는 금액이 50,000sat, D min_final_cltv_expiry 18블록( 3시간)으로 지정 .
        • A 결제를 시도할 비트코인 블록체인의 높이가 700,000블록이었다고 가정하면,
        • A outgoing_cltv_value 최소 700,018 설정해야 .
        • D 대한 페이로드를 다음과 같이 구성하고, 이를 TLV 형식으로 직렬화 한다
          • amt_to_forward : 50,000,000
            outgoing_cltv_value: 700,018
            payment_secret: fb53d94b7b65580f75b98f10...03521bdab6d519143cd521d1b3826
            total_msat: 50,000,000
      • Chan 페이로드
        • C 대한 페이로드를 구성하고, 이것으로 D 대한 HTLC 설정하는 방법을 알려준다.
          • short_channel_id: 010002010a42be
            amt_to_forward: 50,000,000
            outgoing_cltv_value: 700,018
      • Bob 페이로드
        • short_channel_id: 000004040a61f0
          amt_to_forward: 50,100,000
          outgoing_cltv_value: 700,038
        • 라우팅 수수료에 대한 100sat, 20블록의 타임록 델타를 반영.
    • Onion 레이어 포장하기 (Wrapping the Onion Layers)
      • https://github.com/lightningnetwork/lightning-rfc/blob/master/04-onion-routing.md#packet-construction 자세히 설명되어 있다.
      • 고정 길이 Onion (Fixed-Length Onions)
        • Onion 패킷의 길이를 모든 단계에서 동일하게 유지하므로써 노드가 경로의 길이나 경로의 위치를 알지 못하게 하는데 사용.
        • Onion 페이로드는 1,300 바이트이며, 홉의 페이로드는 65바이트 이하(65보다 작으면 65 맞게 채워짐).
        • 따라서 최대 라우팅 경로는 20홉이며, 모든 홉은 20개의 자신이 첫번째 홉으로 착각하게 패킷 부분이 채워짐.
        • Onion 크기는 1,366 바이트이며, 아래와 같이 구성
          • 1 byte - 버전 바이트
          • 33 bytes - 압축된 공개 세션 (A 센셔 키이며, 이것으로 A 신원을 숨기면서 홉당 shared secret 생성 할수 있음)
          • 1,300 bytes - 실제 페이로드
          • 32 bytes - HMAC 무결성 체크섬
      • 포장하기 (Outlined)
        • 홉에 대해 A에서 동일한 프로세스를 반복.
        • 별로 공유 비밀과 rho, mu pad 키를 생성.
        • 1,300 바이트의 필러를 생성하고, 1,300바이트의 어니언 페이로드 필드를 필러로 채움.
        • 페이로드에 대한 HMAC 계산(최종 노드의 경우 0)
        • 페이로드의 길이 + HMAC + 길이 자체를 저장할 공간의 길이를 계산.
        • 페이로드의 길이 만큼 Onion 페이로드를 오른쪽으로 shift. 오른쪽 필러가 삭제되어 왼쪽에 페이로드를 위한 공간이 생긴다.
        • 페이로드 필드의 앞쪽에 페이로드의 길이 + 페이로드 + HMAC insert.
        • rho 키를 사용해 1,300 바이트의 일회용 패드를 생성.
        • rho키에서 생성된 바이트를 XOR하여 전체 Onion 페이로드를 난독화.
        • mu키를 사용해 Onion 페이로드의 HMAC 계산.
        • 세션 공개 키를 추가.(홉이 공유 비밀을 계산할 있도록)
        • 버전 번호를 추가
        • 공유 비밀과 이전 홉의 공개키를 해시하여 파생된 값을 사용해 세션 키를 re-blind.
      • Dina 페이로드 래핑
        • 1,300바이트의 필드인 고정 길이 Onion 페이로드로 시작.
        • pad 키에서 생성된 pseudo 랜덤 바이트 스트림 "filler" 페이로드를 채움.
        • 랜덤 바이트 스트림 생성은 ChaCha20 알고리즘을 암호화 pseudo 난숙 생성기(CSPRNG) 사용.
        • D 페이로드를 왼쪽에 삽입, 오른쪽 오버플로되는 것은 버림.
        • D 읽을 있도록 전체 페이로드를 난독화.
        • 난독화를 위해 rho (D 알고 있는) 사용해 바이트 스트림을 생성, 페이로드 비트와 바이트 스트림을 XOR.
        •  XOR 두번 적용 원래대로 복구(ex: XOR(a,b), b) = a)
        • mu 키를 초기화 키로 사용하는 D 페이로드에 대한 해시 기반 메시지 인증 코드(HMAC) 계산하고, D 페이로드에 추가.
        • HMAC 보안 체크섬 역할 D 페이로드의 무결성을 확인하는데 도움.
      • Chan 페이로드 래핑
        • D 위해 생성된 1,300 바이트의 Onion 페이로드로 시작.
      • Bob 페이로드 래핑
      • 마지막 Onion 패킷
        • B에게 보낼 준비 완료.
        • Onion 페이로드에 대한 HMAC 계산하여 B 확인할 있는 체크섬 암호화 방식을 보호.
        • shared secret, rho, mu, pad 키를 생성하기 위해 홉에서 사용할 33바이트 공개 센셔 키를 추가.
        • 끝으로 버전 번호(현재 0) 앞에 추가
    • Onion 패킷 보내기
      • 패킷이 전달되는 방식과 HTLC 경로를 따라 배포되는 방식을 살펴본다.
      • updateadd_htlc 메시지
        • Onion 패킷을 update_add_htlc 메세지의 일부로 전송
        • [channel_id:channel_id]
          [u64:id]
          [u64:amount_msat]
          [sha256:payment_hash]
          [u32:cltv_expiry]
          [1366*byte:onion_routing_packet]
      • Alice Bob에게 Onion 보냄
        • channel_id - A B 채널ID
        • ID - 채널에 있는 HTLC ID,  0 ~
        • amount_msat - 밀리 사토시, 50,200
        • payment_hash - 지불 해시
        • cltv_expiry - HTLC 만료 시간 잠금, 700,058
        • onion_routing_packet - 모든 홉의 페이로드로 구성된 Onion packet from Alice
      • Bob Onion 패킷 확인
        • B HTLC 커밋 TX 추가하고, A 채널 상태를 업데이트.
        • Onion 다음과 같이 벗긴다.
          • 패킷에서 세션 키를 가져와 A-B 공유 비밀을 도출.
          • 공유 비밀에서 mu키를 생성해, 이것으로 HMAC 체크섬 확인.
        • HMAC 확인했으므로 패킷내에서 1,300바이트 페이로드의 래핑 해제를 시작할 있음.
        • 목표는 B 자신의 페이로드를 검색하고, 나머지 패킷을 다음 홉으로 전달하는
      • Bob Filler 생성
        • A 약간 다른 방식으로 필러를 생성하지만 동일한 규칙을 따름.
        • Onion 페이로드를 1,300바이트 추가로 확장하고 0으로 값을 채움. (2,600바이트가 )
      • Bob 페이로드 난독화
        • A-B 공유 키에서 rho 생성. 이것을 ChaCha20 알고리즘을 사용해 2,600바이트를 생성하는데 사용.
        • XOR 연산,
          • 이때 페이로드 1,300바이트에 대해서는 A 적용한 동일한 작업이므로, XOR 의해 난독화가 해제되고,
          • 0으로 채운 1,300바이트는 임의의 필러 데이터로 바뀜.
      • Bob 다음 홉을 위한 외부 HMAC 추출
        • 내부 HMAC 홉에 포함되고, 이는 다음 홉의 외부 HMAC .
        • B 내부 HMAC 추출하고, C 자신의 암호화된 패킷의 HMAC 확인할 있도록 난독 해제된 패킷에 추가할 것이지 때문에 따로 보관한다.
      • Bob 자신의 페이로드를 제거하고, Onion Left-Shifts
        • B 제거된 페이로드 만큼 추간 필러(1,300바이트) 채워지는 .
      • Bob 새로운 Onion 패킷 구성
        • 페이로드를 Onion 패킷에 복사하고, C 대한 외부 HMAC 추가하고, 세션 키를 re-randomize하고, 버전 바이트를 추가한다.
        • 세션 키를 무작위화하기위해 B 노드 공개 키와 파생된 공유 비밀을 사용해 홉에 대한 블라이드 요소를 계산.
          • b_bob = SHA-256(P_bob || shared_secret_bob)
        • 세션 키와 블라이드 팩터를 사용해 EC 곱셈을 수행, 세션 키를 무작위화.
          • session_key_chan = session_key_bob * b_bob
        • C 의해 처리 session_key_chan 공개 키는 onion 패킷 앞에 추가된다.
      • Bob HTLC 세부정보를 확인
        • B 페이로드에는 C 위한 HTLC 만드는데 필요한 지침이 포함.
        • short_channel_id, amt_to_forward, cltv_expiry 검색,
        • short_channel_id 가진 채널이 있는지 확인하고, C와의 채널이 있다는 확인.
        • 나가는 금액(50,100) 들어오는 금액(50,200)보다 적으므로 수수료가 충족되는지 확인.
        • 나가는 cltv_expiry 들어오는 cltv_expiry보다 작은지확인하여, 위반이 있는 경우 B에게들어오는 HTLC 요청할 있는 충분한 시간을 제공.
      • Bob Chan에게 update_add_htlc 보냄
        • C에게 보낼 HTLC 구성
          • channel_id
          • id
          • amount_msat - 50,100
          • payment_hash
          • cltv_expiry - 700,038
          • onion_routing_packet
      • Chan Onion 전달
        • B 똑같은 과정을 반복
        • update_add_htlc 수신, HTLC 요청을 처리하여 Commit TX 추가.
        • Alice-Chan 공유 키와 mu 하위 생성.
        • 패킷 HMAC 확인하고, 다음 1,300바이트 페이로드 추출.
        • 페이로드를 1,300바이트 추가 확장하고, 0으로 채움.
        • rho 생성하여 2,600 바이트 생성
        • XOR하여 1,300바이트 어니언 페이로드에 대한 난독화를 해제하고, 추가 1,300바이트를 난독화하여 필로러 바꿈.
        • 페이로드에서 내부 HMAC 추출, 이는 D 외부 HMAC .
        • C 페이로드를 제거하고, 페이로드를 왼쪽으로 이동.
        • Onion 페이로드를 사용해 D 대한 패킷을 구성.
        • D 대한 update_add_htlc 메세지를 작성하고, Onion 패킷을 삽입.
        • update_add_htlc D에게 보냄.
        • C B D 대해 이전 홉에서 했던 것과 같이 세션 키를 re-randomize.
      • Dina 최종 페이로드 수신
        • C 부터 update_add_htlc 받으면 자신을 위한 지불임을 알게되고, 마지막 홉이라는 것도 알게 .
        • Onion 까서 확인하고, HTLC 사용하기 위해 update_fulfill_htlc C에게 응답.
        • update_fulfill_htlc A까지 역방향으로 전달되며, 모든 HTLC 사용되고 채널 잔액이 업데이트 된다. 결제 완료!!
    • 오류 반환 (Returning Errors)
      • https://github.com/lightningnetwork/lightning-rfc/blob/master/04-onion-routing.md#returning-errors 정의.
      • 지불, Onion, 홉에 문제가 있는 경우 에러를 역방향으로 전파하여모든 노드에 실패를 알리고 HTLC 해제해야 .
      • 아래와 같이 가지 범주로 나뉘며, 영구/일시적인 오류로 세분화 .
      • onion failure
      • node failure
      • channel failure
      • 에러는 아래와 같이 에러를 발견한 반환 노드에 의해 인코딩
        • [32*byte:hmac]
          [u16:failure_len]
          [failure_len*byte:failuremsg]
          [u16:pad_len]
          [pad_len*byte:pad]
      • hmac
        • 반환 패킷 HMAC 체크섬은 Onion에서 설정된 shared secret 에서 생성된 um 키로 계산.
      • 반환 노드는 ammag(감마의 반대) 키를 생성하고, ammag에서 생성된 바이트 스트림과 XOR 연산을 사용해 반환 패킷을 난독화.
      • Onion 패킷을 받은 홉으로 전달.
      • error 수신한 홉은 ammag 키를 생성ㅗ, ammag 바이트 스트림과 XOR하여 패킷을 다시 난독화.
      • 원본 노드가 패킷을 받으면, 홉에 대햇 ammag um 키를 생성해 반환 패킷이 나올때까지 XOR연산 반복.
      • Failure Messages
      • Stuck payment
        • LN 현재 구현에서는 결제 시도가 중단 가능성이 있음. 이때 HTLC 만료될 때까지 해결할 없음.
        • 해당 HTLC 약정된 자금은 HTLC 만료될때 까지 사용할 없고, 동일한 지불을 재시도할 수도 없다. (실패하거나 완료되어야 끝남)
      • Stuckless payments
        • 문제에 대해 제안된 솔루션 하나.
        • HTLC 다른 암호화 형식을 사용하는 PTLC(Point Time-Locked Contracts).
          • ECDSA 사용하면 복잡하지만, 비트코인의 Taproot Schnorr 서명 기능을 사용하면 휠씬 쉬움
        • Bitcoint 에서 기능이 활설화된 LN에서 PTLC 구현될 것으로 예상.

 

728x90
반응형

관련글 더보기