<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Walrus on Jeongseup Blog</title><link>https://jeongseup.github.io/tags/walrus/</link><description>Recent content in Walrus on Jeongseup Blog</description><generator>Hugo -- gohugo.io</generator><language>en</language><lastBuildDate>Fri, 27 Feb 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://jeongseup.github.io/tags/walrus/index.xml" rel="self" type="application/rss+xml"/><item><title>Seal Protocol: Sui 위의 탈중앙화 비밀 관리(DSM) 프로토콜 분석</title><link>https://jeongseup.github.io/p/seal-protocol-study/</link><pubDate>Fri, 27 Feb 2026 00:00:00 +0000</pubDate><guid>https://jeongseup.github.io/p/seal-protocol-study/</guid><description>&lt;blockquote&gt;
&lt;p&gt;Seal은 Sui 블록체인의 접근 제어(Access Control) 기능을 활용하여 데이터를 안전하게 암호화·복호화하는 &lt;strong&gt;탈중앙화 키 관리 프로토콜&lt;/strong&gt;이다. Walrus와 같은 분산 스토리지나 온체인/오프체인 스토리지에 저장된 민감한 데이터를 보호하기 위해 설계되었으며, 중앙화된 키 저장소 없이 **수학적 파생(Derivation)**과 &lt;strong&gt;Threshold Cryptography&lt;/strong&gt;로 보안을 유지한다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="1-핵심-아키텍처"&gt;1. 핵심 아키텍처
&lt;/h2&gt;&lt;p&gt;Seal은 데이터를 지키는 것이 아니라, 데이터를 잠근 **열쇠(AES Key)**를 지키는 역할을 수행한다.&lt;/p&gt;
&lt;h3 id="하이브리드-암호화-모델-envelope-encryption"&gt;하이브리드 암호화 모델 (Envelope Encryption)
&lt;/h3&gt;&lt;p&gt;Seal은 대용량 데이터 처리를 위해 &lt;strong&gt;봉투 암호화(Envelope Encryption)&lt;/strong&gt; 방식을 채택했다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;데이터 암호화&lt;/strong&gt;: 빠르고 강력한 &lt;strong&gt;AES-256(대칭키)&lt;/strong&gt; 알고리즘으로 실제 데이터를 암호화한다. 키는 매번 랜덤 생성된다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;키 암호화&lt;/strong&gt;: 생성된 AES Key를 Seal 프로토콜(IBE)을 통해 암호화하여 데이터 옆에 붙여둔다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;비유하자면, Seal은 금고(데이터)를 직접 지키는 게 아니라 &lt;strong&gt;금고 열쇠(AES Key)를 지키는 경비원&lt;/strong&gt;이다.&lt;/p&gt;
&lt;h3 id="stateless-key-server"&gt;Stateless Key Server
&lt;/h3&gt;&lt;p&gt;Seal의 Key Server는 AWS KMS와 달리 사용자 키를 DB에 저장하지 않는다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Master Key Only&lt;/strong&gt;: 서버는 오직 자신의 &lt;strong&gt;Master Key Pair&lt;/strong&gt; 하나만 관리한다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Key Derivation&lt;/strong&gt;: 복호화 요청이 오면 &lt;code&gt;Master Key + User ID&lt;/code&gt;를 결합하여 사용자용 키를 **즉석에서 계산(Derive)**한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;유저가 수백만 명으로 늘어나도 서버의 DB 용량은 증가하지 않으며, 해킹을 당해도 특정 유저의 키가 저장되어 있지 않아 상대적으로 안전하다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="2-기술적-배경"&gt;2. 기술적 배경
&lt;/h2&gt;&lt;h3 id="ibe-identity-based-encryption"&gt;IBE (Identity-Based Encryption)
&lt;/h3&gt;&lt;p&gt;기존 PKI(인증서 방식)와 달리, &lt;strong&gt;사용자의 신원(ID String, 이메일 등)&lt;/strong&gt; 그 자체를 &lt;strong&gt;Public Key&lt;/strong&gt;로 사용하는 암호화 방식이다. 복잡한 인증서 발급·관리 절차가 필요 없으며, ID만 알면 누구나 데이터를 암호화해서 보낼 수 있다.&lt;/p&gt;
&lt;h3 id="threshold-cryptography"&gt;Threshold Cryptography
&lt;/h3&gt;&lt;p&gt;단일 서버 실패(SPOF)를 방지하기 위해 비밀을 $n$개의 조각(Share)으로 나눈다. $n$개의 서버 중 &lt;strong&gt;$t$개 이상&lt;/strong&gt;이 살아있고 승인해야만 원본 키를 복구할 수 있다. 예를 들어, 3개 서버 중 2개 승인 시 복호화가 가능하다. 이를 통해 고가용성(Liveness)과 보안성(Privacy)을 동시에 보장한다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="3-작동-플로우"&gt;3. 작동 플로우
&lt;/h2&gt;&lt;p&gt;모든 암호화 및 복호화 연산은 **Client-Side(사용자 환경)**에서 이루어진다.&lt;/p&gt;
&lt;h3 id="1단계-수집-collection"&gt;1단계: 수집 (Collection)
&lt;/h3&gt;&lt;p&gt;사용자는 복호화를 위해 분산된 Key Server들에게 접근 권한을 증명한다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Client → Server A: &amp;ldquo;나 권한 있어(Proof)&amp;rdquo; → &lt;strong&gt;키 조각 A&lt;/strong&gt; 획득&lt;/li&gt;
&lt;li&gt;Client → Server B: &amp;ldquo;나 권한 있어(Proof)&amp;rdquo; → &lt;strong&gt;키 조각 B&lt;/strong&gt; 획득&lt;/li&gt;
&lt;li&gt;Server C가 응답하지 않아도 Threshold가 충족되면 진행 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="2단계-재조립-reconstruction"&gt;2단계: 재조립 (Reconstruction)
&lt;/h3&gt;&lt;p&gt;클라이언트는 로컬 메모리 상에서 수집한 조각들을 합친다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;라그랑주 보간법(Lagrange Interpolation)&lt;/strong&gt; 등 수학 공식을 통해 &lt;code&gt;[조각 A + 조각 B]&lt;/code&gt;를 결합하고, 그 결과로 데이터를 잠갔던 **원본 대칭키(AES Key)**가 복구된다.&lt;/p&gt;
&lt;h3 id="3단계-해제-decryption"&gt;3단계: 해제 (Decryption)
&lt;/h3&gt;&lt;p&gt;복구된 AES Key를 사용하여 암호화된 객체(Encrypted Object)를 풀고, 최종적으로 원본 데이터(Plaintext)를 획득한다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="4-aws-kms-vs-seal-비교"&gt;4. AWS KMS vs Seal 비교
&lt;/h2&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;특징&lt;/th&gt;
&lt;th&gt;AWS KMS (저장소 모델)&lt;/th&gt;
&lt;th&gt;Seal (파생 모델)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;키 관리 방식&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Stateful — 키를 DB/HSM에 영구 저장&lt;/td&gt;
&lt;td&gt;Stateless — 유저 키를 저장하지 않음&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;스토리지 부담&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;유저/앱이 늘어날수록 관리할 키 데이터 증가&lt;/td&gt;
&lt;td&gt;유저가 늘어나도 &lt;strong&gt;Master Key 1개&lt;/strong&gt;만 관리&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;보안 리스크&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;저장소가 털리면 저장된 모든 키 유출 위험&lt;/td&gt;
&lt;td&gt;저장소를 털어도 유저 키 데이터가 없음&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;백업/복구&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;모든 개별 키(CMK, DEK)를 백업해야 함&lt;/td&gt;
&lt;td&gt;Master Key 하나만 백업하면 모든 유저 키 복구 가능&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;작동 원리&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Key Lookup (DB 조회)&lt;/td&gt;
&lt;td&gt;Key Derivation (수학적 계산)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="5-seal-내부-구조-두-가지-핵심-컴포넌트"&gt;5. Seal 내부 구조: 두 가지 핵심 컴포넌트
&lt;/h2&gt;&lt;p&gt;Seal은 크게 두 가지 컴포넌트로 구성된다.&lt;/p&gt;
&lt;h3 id="access-policies-on-chain-sui"&gt;Access Policies (On-chain, Sui)
&lt;/h3&gt;&lt;p&gt;Move 패키지(&lt;code&gt;PkgId&lt;/code&gt;)가 IBE identity의 subdomain &lt;code&gt;[PkgId]*&lt;/code&gt;를 제어한다. 패키지가 Move 코드를 통해 누가 해당 identity subdomain의 키에 접근할 수 있는지를 정의한다.&lt;/p&gt;
&lt;h3 id="off-chain-key-servers"&gt;Off-chain Key Servers
&lt;/h3&gt;&lt;p&gt;각 Key Server는 단일 IBE Master Secret Key를 보유한다. 사용자가 특정 identity에 대한 파생 키를 요청하면, 온체인 접근 정책이 승인한 경우에만 파생 키를 반환한다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="6-코드-레벨-분석"&gt;6. 코드 레벨 분석
&lt;/h2&gt;&lt;h3 id="encryption-과정"&gt;Encryption 과정
&lt;/h3&gt;&lt;p&gt;사용자 측에서 Seal Client SDK를 통해 데이터를 암호화하는 과정이다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mysecret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;mysupersecret&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;encoder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;TextEncoder&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mysecretBz&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;encoder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mysecret&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;encryptedObject&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;sealClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;encrypt&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;threshold&lt;/span&gt;: &lt;span class="kt"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;packageId&lt;/span&gt;: &lt;span class="kt"&gt;PACKAGE_ID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;0000&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;data&lt;/span&gt;: &lt;span class="kt"&gt;mysecretBz&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="encrypt-내부-로직"&gt;encrypt 내부 로직
&lt;/h3&gt;&lt;p&gt;SDK 내부에서는 다음 과정을 거친다.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;랜덤 Base Key 생성&lt;/strong&gt;: &lt;code&gt;encryptionInput.generateKey()&lt;/code&gt;로 AES-256 키를 랜덤 생성&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;키 분할&lt;/strong&gt;: &lt;code&gt;split(baseKey, threshold, keyServers.length)&lt;/code&gt;로 Shamir Secret Sharing 수행&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Share 암호화&lt;/strong&gt;: 각 Key Server의 Public Key로 개별 Share를 IBE 암호화&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;DEM Key 파생&lt;/strong&gt;: Base Key + 암호화된 Share 정보로 실제 데이터 암호화용 키를 파생&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;데이터 암호화&lt;/strong&gt;: 파생된 DEM Key로 원본 데이터를 AES-GCM 암호화&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;직렬화&lt;/strong&gt;: 모든 메타데이터와 ciphertext를 BCS 포맷으로 직렬화하여 반환&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 핵심 흐름 요약
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;baseKey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;encryptionInput&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;generateKey&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;shares&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;baseKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;threshold&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;keyServers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;encryptedShares&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;encryptBatched&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;keyServers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;kemType&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fullId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;shares&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;baseKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;threshold&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;demKey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;deriveKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;KeyPurpose&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DEM&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;baseKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;encryptedShares&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;threshold&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;serverIds&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ciphertext&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;encryptionInput&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;encrypt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;demKey&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="7-limitations"&gt;7. Limitations
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;seal_approve*&lt;/code&gt; 함수는 풀 노드에서 &lt;code&gt;dry_run_transaction_block&lt;/code&gt; RPC 호출을 통해 평가된다. 풀 노드는 비동기적으로 동작하기 때문에 다음 사항에 유의해야 한다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;온체인 상태 변경이 전파되는 데 시간이 걸릴 수 있어, 풀 노드가 항상 최신 상태를 반영하지는 않는다.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;seal_approve*&lt;/code&gt; 함수는 모든 Key Server에 걸쳐 원자적으로 평가되지 않는다. 자주 변경되는 상태에 의존하여 접근 권한을 결정하면 안 된다.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;seal_approve*&lt;/code&gt; 함수는 side-effect가 없어야 하며, 온체인 상태를 수정할 수 없다.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Random&lt;/code&gt; 모듈은 사용 가능하지만, 풀 노드 간에 결정적이지 않으므로 &lt;code&gt;seal_approve*&lt;/code&gt; 함수 내에서 사용하면 안 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="8-결론"&gt;8. 결론
&lt;/h2&gt;&lt;p&gt;Seal은 메시지를 encrypt &amp;amp; decrypt 해주는 프로토콜이다. IBE(Identity-Based Encryption)에 기초해서 동작하며, 이 모델이 서비스되기 위해 필요한 핵심 컴포넌트는 Key Server다.&lt;/p&gt;
&lt;p&gt;Key Server들은 Master Key를 보유하고, 클라이언트의 ID를 바탕으로 파생 키를 만든다(이 형태가 IBE). 다만 Seal에서는 실제 고용량 데이터를 직접 IBE로 암호화하지 않고, 매번 랜덤하게 새로운 AES Key를 생성한 뒤 이 키를 각 Key Server들이 나눠 갖는 형태(Envelope Encryption + Secret Sharing)로 운영된다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Sui 블록체인&lt;/strong&gt;을 접근 제어 레이어로, &lt;strong&gt;IBE&lt;/strong&gt;와 &lt;strong&gt;Threshold Cryptography&lt;/strong&gt;를 키 관리 레이어로 사용하는 Stateless 아키텍처를 통해 보안성과 확장성을 동시에 달성한 프로토콜이다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="references"&gt;References
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://seal.mystenlabs.com/" target="_blank" rel="noopener"
&gt;Seal Official&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://seal-docs.wal.app/" target="_blank" rel="noopener"
&gt;Seal Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://only-fins.wal.app/" target="_blank" rel="noopener"
&gt;Only Fins (Demo App)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://en.wikipedia.org/wiki/Identity-based_encryption" target="_blank" rel="noopener"
&gt;Identity-Based Encryption — Wikipedia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/MystenLabs/ts-sdks/tree/main/packages/seal" target="_blank" rel="noopener"
&gt;MystenLabs/ts-sdks — Seal Package&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item></channel></rss>