MPC (Secure Multi-Party Computation ) 이해하기 -1 / 2

Jake Kim·2024년 8월 28일

PSE2024

목록 보기
16/17

EF (Ethereum Foundation)에서 진행하는 PSE (Privacy, Scaling Exploration) 과정 5주차 마지막 과정으로, MPC에 대한 조사를 맡았다.

최근 PSE에서 운영하는 블로그에 MPC, 특히 Secure-MPC에 관련한 포스트가 업로드 되어 해당 글을 읽고 이해해 본다. 또 한글 번역본으로 남겨 해당 주제에 대한 전파를 돕고자 한다.

MPC란 서로 다른 구성원이 각자의 데이터만 가지고 특정 기능을 수행하되, 서로의 데이터에는 접근이 불가하다. 이것을 구성원들이 각자의 데이터를 공유하지 않고, 중앙화된 관리 주체 없이 가능하게 하는 것이 MPC 프로토콜의 주요 목적이다.

ZK분야는 정말 마법과 같다. (genuinely magical)

Introduction

MPC 란 각자의 비밀 데이터를 오픈하지 않고, MPC Protocol로 하여금 수집하여 최종 결과를 도출해 내는 과정이다. 어떤 작업이나 함수의 결과만을 제출한다.

예를 들어, 특정 비밀 키 (Secret Key)를 파편화하여 나누어 분배 받은 후 각자 Protocol에 집어 넣고 실행히켜 최종 서명을 완성하는 경우다.

어떠한 주체도 모든 (혹은 충분한) 구성원들의 제출 없이 서명을 완성할 수 없으며 비밀키도 복원해 낼 수 없다.

Protocol Scope (Generic / Specialized) 일반적 / 특정적 프로토콜

Specialized Protocols

특정적 프로토콜은 특정 작업을 위해 만들어진 프로토콜이다. 예를 들어 PSI (Private Set Intersection)가 있다. PSI란 예를 들어 두 회사가 서로의 고객 목록에서 겹치는 고객들을 알고 싶어할 때 사용한다. 나머지는 투표 (Voting)이다.

나는 일전에 Sales 파트에서 일했던 경험이 있는데, 서로 이익을 공유하는 사이끼리도 고객 리스트는 잘 공유하지 않았다. 지사장 급에서 모두에게 고객 리스트 접수해서 확인하면 모를까, 마치 대외비처럼 관리했다.
투표도 마찬가지로 전 세계 적으로 현재 잡음이 많은 분야다. 잡음이 없으려면 속도와 편리성을 희생해야 한다. 많은 도장을 찍고 일일히 수개표 하는 방식.
이처럼 응용 분야가 많다.

Generic Protocol

일반적 프로토콜은 어떤 함수라도 고정된 사이즈의 써킷(Circuit)으로 표현하는 방식이다. 야오의 암호화된 써킷 (Yao's Garbled Circuits protocol)이 한 예이다. 일반적이고 넓은 범위에 적용 가능하다.

안전한 프로토콜 (MPC) 의 요구조건

이상적으로 아래 조건을 만족해야 한다.

  • Privacy (프라이버시): 아무도 함수의 출력 외에는 아무 것도 알 수 없어야 한다.

  • Correctness (정확성): 각 당사자는 올바른 출력을 받을 수 있어야 한다.

  • Independence of Inputs (입력의 독립성): 각 당사자는 다른 당사자와 독립적으로 자신의 입력을 결정할 수 있어야 한다.

  • Guaranteed Output Delivery (출력 전달 보장): 어떤 당사자도 다른 당사자들이 함수 출력을 받지 못하도록 막을 수 없어야 한다.

  • Fairness (공정성): 한 당사자가 함수 출력을 받으면 모든 당사자가 출력을 받아야 한다.

    입력의 투명함 및 결과 정보

    구성원들이 의도적으로 부적합한 입력값을 제출할 수 있다. 경매 방식에서 실제 입찰 금액보다 월등히 높은 금액을 제출 함으로써 기타 참여자들의 입찰을 방해할 수 있다. 이때는 구성원들이 서명까지 제출하게 하여 방지할 수 있는데, 더 많은 자원을 필요로 하게 된다. 또 결과 정보를 통해 입력 정보를 유추할 수 도 있다. 최고 입찰 금액이 밝혀지면 해당 입찰자의 예산 범위등을 알아낼 수 있다.

    활용 예 (Use Cases)

    개인정보 머신 러닝 (Privacy Perserving Machine Learning)

    Privacy Preserving을 개인정보로 의역했다. 모델 훈련 단계에서는 여러 당사자가 개별 데이터 세트를 공개하지 않고 협력하여 모델을 훈련할 수 있다. 또 추론 단계에서는 클라이언트의 입력 데이터와 서버의 모델 모두 비공개로 유지할 수 있다. 이를 통해 클라이언트는 자신의 데이터가 노출되지 않고 모델 출력을 받을 수 있으며, 제공자의 모델 또한 비공개로 유지될 수 있다.

전 직장에서 일할 때, 클라이언트 사 중에 신용카드 회사들이 있었다. 개인정보 보호에 매우 민감했기에 모든 데이터는 철저히 격리 되어 관리 되고 있었다. 아마도, 각 신용카드 회사는 자신들의 고객 정보를 이용해 ML 훈련을 시도하고 있을 것이다. 이는 곧 한계에 부딪힌다. H 카드사 고객들은 좀 더 고소득인 경향이 있다거나, S 카드사 직원들은 오랜 충성 고객 경향이 좀 더 강하다는 등의 추론은 해 낼 수 없다. 물론 컨설팅 펌이나 증권사 등에서 레포트가 나오지만, 정확도와 비용, 실시간성 측면에서 MPC 방식을 따라갈 수 없다. (연봉 몇 억의 인력들이 몇개월간 분석하는 내용을 ML은 몇 분만에 해낼 수 있다.)

보안키 관리 강화

회사는 키 보호를 강화하기 위해 키 공유를 여러 안전한 환경에 분산할 수 있다. 이를 통해 단일 장소에서 전체 개인 키를 보유하지 않게 되어 키 유출 위험을 줄일 수 있다. 공격자가 전체 키에 접근하기 위해서는 모든 환경을 해킹해야만 한다. 이 방식은 암호화 키를 보호하고, 인증 프로세스를 안전하게 하며, 서명 승인 정책을 시행하는 데 도움을 준다.

협력적 데이터 분석

여러 당사자가 개인 정보를 공개하지 않고 데이터 세트를 결합하고 분석할 수 있다. 조직은 다양한 기록을 안전하게 통합하여 트렌드를 연구할 수 있으며, 개인정보 보호 규정을 준수할 수 있다. 이 방식은 기밀성을 침해하지 않고 데이터 분석을 가능하게 한다.

써킷 (Circuits)

써킷은 ZK 분야를 공부하다 보면 늘 만나게 되는 방식이다. 내 느낌에은 써킷이란 것은 어떠한 사고방식 중 하나다. R1CS 혹은 Plonk에서도 접하게 된다.

위 예를 보면 그림에서 표현하고자 하는 것은

Output=(A+B)(C+D)+EOutput = {(A + B) * (C + D)}+E

이 간단한 수식인데, 이 단순한 서킷으로 여러가지 복잡한 수식도 표현해 낼 수 있다.
서킷에는 불리언 회로, 산술 회로가 있다.

불리언 회로(Boolean circuits) 는 각 비트 폭에 대해 기본 연산을 재정의해야 합니다. 예를 들어, n-비트 정수에 대한 산술 연산을 지원하려면 n-비트 덧셈 및 곱셈 회로를 구현해야 합니다.

산술 회로(Arithmetic circuits)는 일반적으로 미리 설정된 크기의 유한 필드에서 작동한다. 산술 회로는 주로 산술 연산을 위해 설계되지만, 비교 및 동등성 검사와 같은 비산술 연산도 구현할 수 있다.

모든 함수가 쉽게 써킷 형식으로 쉽게 변환될 수 있는 것은 아니지만, 컴파일러를 사용하여 이를 수행할 수 있다. 그러나 모든 함수는 결정적(Deterministic) 해야 하며 무한 루프가 없어야 한다.

컴파일러는 특정 언어로 작성된 프로그램을 써킷으로 변환한다. 그런 다음 이 써킷들은 MPC 프로토콜로 전달되어 실행하고 출력을 생성한다.

예를 들어 Circom을 이용하는 2X2 행렬 곱셈을 시도해 보자.

template matrixElementMul (m,n) { //행렬 연산
    signal input a[m][n]; //A 행렬
    signal input b[m][n]; //B 행렬
    signal output out[m][n]; //결과 행렬
    
    for (var i=0; i < m; i++) { //행 진행
        for (var j=0; j < n; j++) { // 열 진행
            out[i][j] <== a[i][j] * b[i][j]; //행렬 인자 곱셈값 삽입
        }
    }
}

component main = matrixElementMul(2,2); // 메인 함수 지정

위 연산은 네 개의 게이트로 구성된다. 게이트 하나는 써킷 하나와 대응된다.

[{"op":"AMul","lh_in":0,"rh_in":4,"out":8}, //op 는 operation, 즉 여기서는 곱셈이다.
 {"op":"AMul","lh_in":1,"rh_in":5,"out":9},
 {"op":"AMul","lh_in":2,"rh_in":6,"out":11},
 {"op":"AMul","lh_in":3,"rh_in":7,"out":10}]
// lh_in 은 왼쪽 입력, rh_in 은 오른쪽 입력, out은 출력을 나타낸다.

써킷 회로도

이 예제는 너무 간단해, 직접 회로도를 그리는 것이 더 빨랐겠지만, 아무튼 위의 과정을 통해 함수를 게이트로 바꿨으며, 이를 응용하면 더 복잡한 행렬 연산도 가능하다.

profile
세일즈 출신 개발자 제이크입니다.

0개의 댓글