自社製品を開発し、運用し続けています。

Fantagramは、3つの分野で専門的なノウハウを蓄積してきたAIネイティブなチームです。KTRENZではデータ、Welikeではコマース、Kryptonではプライベートなコミュニケーションを手がけています。

[email protected]

01製品

  1. KTRENZ

    状態:ktrenz.comで公開中

    KTRENZのデータレポート画面。過去90日間にKTRENZが追跡したK-popのリリースのうち41%が第3世代のアーティストだったという英語の見出しと、大きな41%の数字、世代別のリリースの割合を示す棒グラフがあります。
    ktrenz.comのデータレポート

    韓流を測る、英語ファーストのKカルチャー・データプラットフォーム兼メディアです。

    • Trendは、韓国での検索量・YouTube・報道・チャレンジをまたいだ7日間の伸びで、アーティストを順位づけします。
    • オープンデータは、キー不要の公開RESTエンドポイント4つで提供しています。
    • K-Trackは、KTRENZ自身のサーバーログから、各リリースページをどのアンサーエンジンが取得したかを数えます。
    対応環境
    Web(レスポンシブ)
    技術スタック
    • Next.js 14、React 18、TypeScript
    • Supabase(Postgres)
    • Cloudflare Pages、Workers

    ktrenz.comしくみ

  2. Welike

    状態:公開前(登録受付中)

    Welikeのクリエイター向けページ。暗い背景に、本当に投稿したくなる韓国コスメの案件に招待されよう、という英語の大きな見出しがあり、その下に、クリエイターを韓国コスメの案件とマッチングするという説明があります。
    welike.showのクリエイター向けページ

    韓国コスメブランドが、米国法人・米国内の物流・現地チームなしで米国のTikTok Shopで販売できる、マネージド型のプラットフォームです。

    • ブランドと米国のTikTokクリエイターを結びつけ、招待、無料サンプル、コミッションまでを扱います。
    • 公開前の動画を1本ずつ、FTCの#ad表示(広告であることの開示)とFDA/MoCRAの化粧品の効能表現ルールに沿っているか確認します。
    • TikTok Shop Open API(OAuth、Webhook)と連携し、入金と支払いはStripe Connectで行います。

    開発・保守はFantagramが担当しています。Welikeを運営するのは、Merchant of Record(販売事業者)でありTikTok Shopの出品者でもあるMilestone Innovation Labs Inc.(米国)と、주식회사 위라이크(韓国)です。

    対応環境
    Web:ブランド向けアプリ(韓国語)、クリエイター向けアプリ(英語)
    技術スタック
    • React 18、Vite、TypeScript
    • Supabase(Postgres、Edge Functions 18本)
    • Cloudflare Pages

    welike.showしくみ

  3. Krypton

    状態:iOSはTestFlightで配布中、Androidはビルド済み

    スマホで見たkrypton.todayの「つながり」のセクション。つながりと2次のつながりの説明の下に、「わたし」とつながる人たちの図があります。 スマホで見たkrypton.todayの「封をする」のセクション。エンドツーエンド暗号化の説明の下に、名前と自己紹介が暗号文で表示されたパネルがあります。
    スマホで見たkrypton.today

    実際に知り合いどうしの人たちのための、招待制のソーシャルアプリです。

    • 投稿・返信・写真・動画・プロフィールをエンドツーエンドで暗号化します。当社のサーバーはその内容を読めません。
    • 登録に電話番号もメールアドレスも不要です。アカウントは、スマホの中で作られる鍵です。取り戻す方法を準備しておけば、スマホをなくしても、暗証番号と、鍵のかけらを預けたつながりによってアカウントを取り戻せます。
    • 広告はありません。画面キャプチャはブロックされます。
    対応環境
    iOS、Android
    技術スタック
    • Expo、React Native、TypeScript
    • Rust製の暗号コア、Swift、Kotlin
    • Supabase
    • Cloudflare Workers、R2

    krypton.todayしくみセキュリティ設計

02しくみ

KTRENZ

KTRENZは公開データを定期的に収集して測定し、その結果を自社サイトとオープンデータとして公開します。

公開情報からオープンデータへ
  1. 1

    情報源:YouTube、Naver、X、TikTok、Ticketmaster、TMDB、韓国の公共データ、そしてKTRENZ自身のサーバーログ。

  2. 2

    収集:Cloudflare Workersのcronが1分ごとと10分ごとに起動し、17種類の定期ジョブを走らせます。ジョブはSupabase上のPostgresに書き込みます。

  3. 3

    測定:Trendは、韓国での検索量・YouTube・報道・チャレンジをまたいだ7日間の伸びで、アーティストを順位づけします。K-Trackは、各リリースページをどのアンサーエンジンが取得したかを、KTRENZ自身のサーバーログから数えます(破線)。

  4. 4

    公開:ktrenz.com、キー不要のRESTエンドポイント4つ、そして公式のMCP Registryに掲載されたリモートMCPサーバーとnpmパッケージ。

Welike

Welikeは、韓国コスメブランドが米国のクリエイターを通じて米国のTikTok Shopで販売できるようにし、ブランドや動画が公開される前にチェックを行います。Welikeはまだ公開前です。以下は、構築済みの製品が行う手順です。

商品登録から支払いまで
  1. 1

    ブランド:韓国語のブランド向けWebアプリで商品を登録するか、Amazonから取り込みます。

  2. 2

    チェック:ブランドごとのコンプライアンス・チェックリストと、書類の2段階審査。審査結果は参考にとどめ、判断は人が行います。

  3. 3

    クリエイター:英語のクリエイター向けアプリで、米国のクリエイターをマッチングして招待します。クリエイターは無料サンプルを受け取り、コミッションを得ます。

  4. 4

    チェック:クリエイターの動画は1本ずつ、公開前に、FTCの#ad表示と、FDA/MoCRAの化粧品の効能表現ルールに沿っているかを確認します。

  5. 5

    TikTok Shop:注文はTikTok Shop Open APIを通じて、OAuthとWebhookで届きます。

  6. 6

    Stripe:入金と支払いはStripe Connectで行います。

Krypton

Kryptonでは、書いた内容に、書いた人のスマホの中で封をします(暗号化)。

投稿に封をする
  1. 1

    書く人のスマホが、Rustコアの中で新しいコンテンツ鍵を作ります。

  2. 2

    その鍵で投稿(テキスト・写真・動画)を暗号化します。テキストは先に段階的なサイズまでパディングするため、正確な長さは表に出ません。プロフィールもスマホの中で封をします。

  3. 3

    コンテンツ鍵を、読む人それぞれの暗号化鍵宛ての封筒に入れて封をします。読む人1人につき、104バイトの封筒が1通です。

  4. 4

    読む人のスマホは、Rustコアの中で、自分の暗号化鍵を使って自分宛ての封筒を開けます。

  5. 5

    投稿を復号します。

その間、サーバーは暗号文と封筒を保存し、受け渡します。サーバーには誰が誰にいつ送ったかが見えますが、投稿・返信・写真・動画・名前・プロフィールは読めません。サーバーに見えるもの・見えないものの一覧は、下のセキュリティ設計にあります。

新しいスマホでアカウントを取り戻す
  • 準備:6桁の暗証番号と、2〜7人のつながりを選びます。スマホは、TとUの2つの半分からなる秘密Sで、アカウント鍵と暗号化鍵に封をしてバックアップにします。Tは鍵のかけらに分けられ、どの2つからでもTを組み立て直せます。かけらは1つずつ、別々のつながりに宛てて封をします。当社のサーバーはU、バックアップ、封をしたかけらを保管しますが、各かけらを開けられるのは、宛先のつながりのスマホだけです。スマホが送るのは暗証番号をストレッチングした値だけで、サーバーは間違えた回数を数えます。

  • スマホをなくしたら:つながりの1人が、1回だけ使える取り戻し用のリンクを送ってくれます。新しいスマホで暗証番号を入力します。かけらを預かったつながりは、電話で本人であることを確かめ、自分のかけらを開けて、新しいスマホの鍵に宛てて封をし直します。

  • 待機:サーバーがUとバックアップを渡すのは、かけらを預かった人2人が承認し、かつ正しい暗証番号の入力から48時間が過ぎたとき、または暗証番号なしの場合(つながりを4人以上選んでいたときだけ)は、預かった人4人が承認し、かつ14日が過ぎたときです。古いスマホには通知が届き、そこから取り消せます。暗証番号を5回間違えると、取り戻しは1日ロックされます。

  • 復帰:新しいスマホはRustコアの中でSを組み立て直し、バックアップを開け、取り戻したアカウント鍵で新しい端末鍵に署名します。それまでの端末はサインアウトされます。

  • 誰も単独ではできません:預かった人1人ではできません。預かった人たちもUがなければできず、Uをサーバーが渡すのは上の条件を満たしたときだけです。サーバーもTがなければできません。預かった人は、当社のサーバーが中継してきた新しいスマホの鍵に宛ててかけらに封をし直しますが、通話中に新しいスマホの画面に出る6桁の数字を聞いて入力し、一致したときだけ封をします。サーバーがすり替えた鍵でこの数字が一致する確率は、預かった人ごとに100万分の1です。この確認では、通話の声のなりすましは防げず、古い版のアプリを使っている預かった人には働きません。準備のときに預かった人の鍵をすり替えることは、受け取る人の確認を有効にするまで防げません。

招待で参加する
  1. 1

    リクエスト:鍵は自分のスマホの中で作られ、電話番号もメールアドレスも使いません。知っている会員に、招待リクエストをリンクかQRコードで送ります。リンクに名前は載りません。名前と自己紹介は、リンクの#の後ろにある秘密から導いた鍵で封をし、当社のサーバーはその秘密を受け取りません。その後の手順でも、名前は封をした形かソルト付きハッシュとしてだけ運ばれます。

  2. 2

    招待と確認:既存の会員か、Kryptonチームが招待し、確認します。原則として会員2人が一緒に招待し、それぞれが確認します。Kryptonの会員が決まった数に達するまでは、1人で足ります。招待と確認には、招待・確認した人それぞれの鍵で署名し、当社のサーバーがそれを記録します。名前のない招待を有効にするまでは、招待リンクの#の後ろに招待した人の名前が載ります。

  3. 3

    会員:参加できました。自分を確認してくれた人が推薦人となり、自分の名刺に表示されます。

03セキュリティ設計

Kryptonの暗号処理は、iOSとAndroidが共有する1つのRustコアで動きます。

Rustコアの暗号プリミティブ
プリミティブ用途
X25519コンテンツ鍵を読む人宛ての封筒に入れて封をします。封筒ごとに、使い捨ての新しい鍵ペアと、読む人の公開鍵を使います。共有秘密がすべてゼロになる場合は拒否します。
Ed25519アカウントの識別鍵と、各端末の鍵。アカウント鍵が、各端末の証明書と、アカウントの暗号化鍵に署名します。
XChaCha20-Poly1305封をするすべてのもの(投稿本文、封筒、ラップした鍵、取り戻し用のバックアップ、写真、動画)の暗号化と認証。ノンスは24バイトのランダム値です。ファイルのチャンクには、ランダムなベースノンスとチャンク番号を組み合わせて使います。
HKDF-SHA256封筒ごとの鍵を、双方の公開鍵をソルトにしてX25519の共有秘密から導出します。取り戻し用の秘密も、その2つの半分から導出します。用途ごとに固有のラベルを使います。
GF(28)上のShamir秘密分散取り戻し用の秘密の片方の半分(T)を、鍵のかけらに分けます。有限体の演算は、参照テーブルを使わずに定数時間で行います。
OSの乱数生成器すべての鍵、ノンス、鍵のかけらの係数。
鍵の置き場所
秘密鍵
Rustコア内の4つのスロット:アカウント(Ed25519)、端末(Ed25519)、暗号化(X25519)、一時的な取り戻し用の鍵(X25519)。
コンテンツ鍵
項目ごとに新しいランダムな鍵を作り、コアの中に保持します。アプリが受け取るのは、鍵の素材ではない不透明なハンドルです。
保存時
iOSではKeychainに保存します。Androidでは、Android Keystoreにある鍵で暗号化して保存します。秘密鍵がコアの外に出るのは、ネイティブのラッパーがそこへ保存するときだけです。
JavaScript
アプリのJavaScriptに秘密鍵を返す呼び出しはありません。また、境界チェックが、アプリのコードに鍵を扱う箇所がないかを走査します。
当社のサーバー
公開鍵。取り戻し用として、バックアップ、サーバー側の半分U、そして各つながりの鍵のかけら(そのつながりのスマホだけが開けられるよう封をしたもの)。これらのどれも、Tがなければバックアップを開けられません(上の取り戻しの図を参照)。取り戻し用のリンクは鍵付きハッシュ(HMAC)としてのみ保存し、取り戻しの手続きが終わってから3日後に消去します。このほか、KryptonチームのWeb用アカウントの鍵も置かれていますが、当社のサーバーが持たないパスフレーズでロックされています。
鍵の確認
スマホは互いの公開鍵を当社のサーバーから受け取り、各暗号化鍵がそのアカウント鍵で署名されていることを確かめます。アプリ内で鍵を見比べる方法はまだありません。そのため、この確認は、当社のサーバーが正しいアカウント鍵を配っていることに依存しています。受け取る人の確認(創設者とKryptonチームからつながる会員の証明書、つながりごとの2人の署名、2次のつながりについては確認済みのつながりを経由する経路)は作ってありますが、まだ有効にしていません。有効にするまでは、当社のサーバーに偽の会員・つながり・鍵が入り込むと、スマホがそちらにも封をすることがあります。取り戻しでは、かけらを預かった人が通話中に6桁の数字で新しいスマホの鍵も確かめます。
Kryptonのサーバーに見えるもの・見えないもの

読めないもの

  • 投稿、返信、写真、動画。ファイルは暗号文として保存されます。
  • 名前、一行の自己紹介、プロフィール写真。名刺(名前、一行の自己紹介、推薦人のアカウント番号、写真の粗いモザイク)と半分ぼかした写真は、名刺の持ち主が「1次のみ」を選ぶとつながりそれぞれに、「2次まで」(初期設定で、創設者は「全体に公開」から始まります)か「全体に公開」を選ぶとつながりと2次のつながりそれぞれに宛てて、別々に封をします。「全体に公開」にした名刺は会員鍵でも封をするため、Kryptonチーム自身のアカウントを含むすべての会員が開けます。会員1人の鍵と当社のデータベースの写しを両方持つ人は、そうした名刺をすべて読めます。半分ぼかした写真はどの範囲でも2次のつながりより先には届かず、写真そのものを開けるのはつながりだけです。範囲を狭めると、当社のサーバーは会員鍵で封をしたものをすぐに消去し、「1次のみ」ならつながりではない人宛ての封筒もすぐに消去します。そのあとスマホが新しい鍵で名刺に封をし直し、写真が開き続けるように写真の鍵はそのまま使います。範囲が広かった間にすでに受け取られた鍵や、すでに見られた内容は取り戻せません。「1次のみ」にした名刺については、アプリがどの版であっても、当社のサーバーはつながりではない人宛ての封筒を受け付けません。範囲が適用されるのはこの名刺だけで、一人に送る名刺(次の項目)には適用されません。2段階だけを表示する以前の版のアプリでは狭いほうが「2次まで」にあたり、そこでどちらを選んでも「1次のみ」は解除されます。公開範囲がなかった版のアプリでアップロードした名刺は、アプリを更新してアップロードし直すまで会員鍵で封をしたままです。チームのアカウントから会員鍵を外す仕組みは作ってありますが、まだ有効にしていません。
  • 一人に送る名刺。つながりの申し込みやスクリーンショット・写真の保存の通知に添える名刺、会話にいる人に送る名刺は、受け取る人ごとに別々に封をします。QRコード、つながりのリンク、招待リクエストのリンクに添える名刺は、リンクの#の後ろにある秘密から導いた鍵で封をします。当社のサーバーはその秘密を受け取りません。消去されるまでは、リンクと当社のデータベースの写しを両方持つ人なら開けられます。これらの写しは、申し込みやリクエストが終わったとき、つながりのリンクが1日で期限切れになったとき、その人が会話から退出したときに消去し、申し込み・リクエストと通知は30日が過ぎると削除します。リンクに名前を載せない招待は作ってありますが、まだ有効にしていません。今は招待リンクの#の後ろに、招待した人の名前が載ります。
  • リンクのプレビュー。書く人のスマホが作り、投稿と一緒に封をします。
  • 投稿の正確な長さ。テキストは、256バイトから始まる段階的なサイズまでパディングされます。
  • 新着メッセージの内容。サーバーが送るのは決まった文言の通知と、封をしたその写しです。ロックが解除されたiPhoneは写しを開け、誰が書いたかを表示します。
  • 電話番号とメールアドレス。これらは一切収集しません。

見えるもの

  • アカウントごとのランダムなアカウント番号、会員の状態、公開鍵、名刺の公開範囲。
  • 誰が誰とつながっているか、誰が誰を招待・確認したか、およびその日時。
  • 誰が誰に投稿を手渡したか。
  • 各投稿の封筒を誰が持っているか、各会話に誰がいるか、いつ参加・退出したか。
  • 各投稿・返信の書き手、受け取る人、時刻。
  • ブロック、通報、通知用の端末トークン。
  • スクリーンショットの試みと写真の保存:誰が、誰の投稿またはページで、いつ行ったか。
  • ファイルサイズ。写真と動画はパディングしません。
  • 通報された投稿と、その書き手の名前。通報した人が当社に向けて開いたものです。
  • IPアドレスとリクエスト時刻(当社が利用するホスティング事業者のアクセスログに残ります)。招待なしの登録については、登録数を制限するため、IPの鍵付きハッシュを当社のデータベースに2日間保存します。
実装と検証
メモリ
Rustコアの中では、鍵と復号したデータは、解放時にゼロで上書きされるバッファに置かれます。SwiftとKotlinのラッパーに渡すバッファも同じです。復号した写真と動画は、次に開くときにもう一度復号しなくて済むよう、復号済みのままスマホのキャッシュに保存されます。このキャッシュは、サインアウト時とアカウント削除時に消去されます。
unsafeコード
クレート全体でunsafeを禁止しています。許可しているのは、Swift(C ABI)とKotlin(JNI)向けの2つの境界ファイルだけです。
境界
コアのコードを実行するすべてのCエントリポイントはpanicを捕捉します。そのため、コア内部で失敗しても、アプリにはエラーコードが返ります。
大きなファイル
認証付きの64 KiBチャンク単位で暗号化します。ファイルを切り詰めたり、並べ替えたり、末尾に付け足したり、つなぎ合わせたりすると、どれも失敗になります。復号したファイルは、ファイル全体の検証が通ってはじめて現れ、失敗したファイルは何も残しません。
Rustのテスト
22件:単体テスト19件、共有テストベクターに対するテスト2件、Cヘッダーがエクスポートされた関数と一致するかの確認1件。
テストベクター
RustコアとアプリのJavaScript開発用コアは同じバイト形式を使い、互いの固定テストベクターを開けなければなりません。
レビュー
公開前の社内レビューで、データベースの権限、サーバー関数、レート制限、メディアの保存、アプリ、運営者ツール、シークレットの7つの領域を調べました。コードを読み、サーバーのローカルコピーに対して攻撃を試しました。独立した第三者による監査は、まだ行われていません。

04技術

対応環境
Web、iOS、Android
開発言語
TypeScript、SQL、Rust、Swift、Kotlin
インフラ
Cloudflare、Supabase(Postgres)
自動テスト
3つのコードベースで合わせて5,000件を超えるテストケース
  • クロスプラットフォームのモバイル開発ExpoとReact Nativeのアプリに、Swift(iOS)とKotlin(Android)のネイティブモジュールを組み合わせています。使用製品:Krypton
  • 応用暗号iOSとAndroidで共有する1つのRust製暗号コア、KeychainとKeystoreでの鍵の保管、Shamir秘密分散による、つながりを介した鍵の取り戻し。使用製品:Krypton
  • エッジで動くWebプラットフォームエッジランタイム上のNext.jsと、Pages Functionsを使うReactアプリ。どちらもCloudflareにデプロイしています。使用製品:KTRENZ、Welike
  • データパイプラインと測定YouTube、Naver、X、TikTok、Ticketmaster、TMDB、韓国の公共データから収集するCloudflare Workers上の定期ジョブと、そのデータから作る7日間の伸びのランキング。使用製品:KTRENZ
  • 公開APIキー不要のRESTエンドポイントと、公式のMCP Registryに掲載されたリモートMCPサーバーとnpmパッケージ。使用製品:KTRENZ
  • コマースと決済TikTok Shop Open API、Stripe Connectによる支払い、Stripeのサブスクリプション、サーバー通知を使うApp Storeのサブスクリプション。使用製品:KTRENZ、Welike、Krypton
  • コンプライアンス・ツールFTCの広告表示とFDA/MoCRAの化粧品の効能表現ルールのチェック、ブランド書類の2段階審査(審査結果は参考にとどめ、判断は人が行います)。使用製品:Welike
  • Postgresバックエンド行レベルセキュリティ、Edge Functions、管理された741件のマイグレーションを備えたSupabase Postgres。使用製品:KTRENZ、Welike、Krypton
  • 多言語の製品1つのアプリで韓国語・英語・日本語に対応。韓国語のブランド向けアプリと英語のクリエイター向けアプリを並べて運用。使用製品:Welike、Krypton

05お問い合わせ

提携、取材、その他のお問い合わせ。

[email protected]

製品に関するご質問は、各製品のサイトからお寄せください。