集約されたデータの収集は、コンピューティングにおいて最も収益性の高い産業の1つですが、ユーザーのプライバシーを侵害することなく、どのように効率的にデータを収集できるでしょうか?その答えの1つが、マルチパーティ分散型集約プロトコル (DAP) であり、PRIO3メソッドは、その中でも最高の方法の1つです。
セキュリティは、静止時および伝送中のデータに適用されてきましたが、多くの場合、プレーンテキストデータで計算を行っています。これにより、多くの問題が発生します。特に、プロセッサがPII (個人識別情報) や秘密暗号化キーなどを特定できることです。1つのアプローチは、MPC (マルチパーティ計算) を使用することです。MPCでは、計算をより小さなブロックに分割し、各パーティに計算のシェアを提供できます。この最適なアプリケーションの1つは、プライバシーを考慮した方法で統計を収集することです。
たとえば、携帯電話メーカーは、特定の人物を明らかにすることなく、携帯電話の所有者の性別バランスを把握したいと考えるかもしれません。このために、各クライアントデバイスは、性別のSNIP (秘密分散非対話型証明) を作成します。PRIO3では、これは高速かつ効率的なゼロ知識証明です。次に、サーバーはこれらのSNIPを受信し、その有効性を確認できます。確認が完了すると、現在の統計集計のためにローカルアキュムレータを更新できます。そして、クライアントデバイスから性別バランスを明らかにしたい場合は、集計された合計を公開できます。
全体として、サーバーはクライアントが男性か女性かを判断できません。なぜなら、性別のゼロ知識証明が作成されるからです。しかし、合計を計算することはできます。PRIO3では、サーバーはプレーンテキストデータを一切見ることがなく、古典的な論文 [here][1] に基づいています:
PRIO3の実装は、一般的にプライバシー測定のためのマルチパーティ分散型集約プロトコル (DAP) の一部と見なすことができ、現在、IETF [here] で標準化が進められています:
PRIO3を使用して、ブール値 (カウント) の多数のシェアを作成し、データを集計して戻します。コア分析は、何かがTrueかFalseかに関する基本的なカウントであり、データセットは {true, false, true, true} であり、true値の数をカウントします [here]:
package main
import (
"fmt"
"crypto/rand"
"os"
"io"
"strconv"
"github.com/cloudflare/circl/vdaf/prio3/count"
)
func fromReader[T any](r io.Reader) (z T) {
switch zz := any(&z).(type) {
case *count.Nonce:
_, _ = r.Read(zz[:])
case *count.VerifyKey:
_, _ = r.Read(zz[:])
}
return
}
var Context = []byte("Test")
func main() {
NumShares := uint8(2)
input := []bool{true,false,true, true}
argCount := len(os.Args[1:])
if argCount > 0 {
a,_ := strconv.Atoi(os.Args[1])
NumShares=uint8(a)
}
c, _ := count.New(NumShares, Context)
params := c.Params()
shares := params.Shares()
aggShares := make([]count.AggShare, shares)
for i := range aggShares {
aggShares[i] = c.AggregateInit()
}
for _, mi := range input {
nonce := fromReader[count.Nonce](rand.Reader)
verifyKey := fromReader[count.VerifyKey](rand.Reader)
randb := make([]byte, params.RandSize())
_, _ = io.ReadFull(rand.Reader, randb)
var pubShare count.PublicShare
var inputShares []count.InputShare
pubShare, inputShares, _ = c.Shard(mi, &nonce , randb)
var prepStates []*count.PrepState
var outboundPrepShares []count.PrepShare
for i := range shares {
state, share, _ := c.PrepInit(&verifyKey, &nonce, i, pubShare, inputShares[i])
prepStates = append(prepStates, state)
outboundPrepShares = append(outboundPrepShares, *share)
}
var prepMsg *count.PrepMessage
prepMsg, _ = c.PrepSharesToPrep(outboundPrepShares)
var outShare *count.OutShare
for i := range shares {
outShare,_ = c.PrepNext(prepStates[i], prepMsg)
c.AggregateUpdate(&aggShares[i], outShare)
}
}
numMeas := uint(len(input))
aggResult, _ := c.Unshard(aggShares, numMeas)
fmt.Printf("Inputs: %v\n\n", input)
fmt.Printf("Number of inputs: %d\n\n", numMeas)
fmt.Printf("Number of shares: %d\n\n", NumShares)
fmt.Printf("Aggregated Count %d\n\n", *aggResult)
for i := range shares {
fmt.Printf("Share %v\n", aggShares[i])
}
}
サンプル実行 [here]:
Inputs: [true false true true]
Number of inputs: 4
Number of shares: 4
Aggregated Count 3
Share {[[7227276485192055052]]}
Share {[[673113590378828220]]}
Share {[[14679250781088487564]]}
Share {[[14313847295054699691]]}
合計の例はこちら:
PRIO3 for Verifiable Distributed Aggregation Functions for Summation with Goヒストグラムはこちら:
PRIO3 for Verifiable Distributed Aggregation Functions for Histograms with Go[1] Corrigan-Gibbs, H., & Boneh, D. (2017). Prio: Private, robust, and scalable computation of aggregate statistics. In 14th USENIX symposium on networked systems design and implementation (NSDI 17) (pp. 259–282).