mirror of
https://github.com/QuilibriumNetwork/ceremonyclient.git
synced 2026-02-22 02:47:26 +08:00
160 lines
3.3 KiB
Go
160 lines
3.3 KiB
Go
//
|
|
// evaluator.go
|
|
//
|
|
// Copyright (c) 2019-2023 Markku Rossi
|
|
//
|
|
// All rights reserved.
|
|
//
|
|
|
|
package circuit
|
|
|
|
import (
|
|
"fmt"
|
|
"math/big"
|
|
|
|
"source.quilibrium.com/quilibrium/monorepo/bedlam/ot"
|
|
"source.quilibrium.com/quilibrium/monorepo/bedlam/p2p"
|
|
)
|
|
|
|
var (
|
|
debug = false
|
|
)
|
|
|
|
// Evaluator runs the evaluator on the P2P network.
|
|
func Evaluator(conn *p2p.Conn, oti ot.OT, circ *Circuit, inputs *big.Int,
|
|
verbose bool) ([]*big.Int, error) {
|
|
|
|
timing := NewTiming()
|
|
|
|
garbled := make([][]ot.Label, circ.NumGates)
|
|
|
|
// Receive program info.
|
|
if verbose {
|
|
fmt.Printf(" - Waiting for circuit info...\n")
|
|
}
|
|
key, err := conn.ReceiveData()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Receive garbled tables.
|
|
timing.Sample("Wait", nil)
|
|
if verbose {
|
|
fmt.Printf(" - Receiving garbled circuit...\n")
|
|
}
|
|
count, err := conn.ReceiveUint32()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if count != circ.NumGates {
|
|
return nil, fmt.Errorf("wrong number of gates: got %d, expected %d",
|
|
count, circ.NumGates)
|
|
}
|
|
var label ot.Label
|
|
var labelData ot.LabelData
|
|
for i := 0; i < circ.NumGates; i++ {
|
|
count, err := conn.ReceiveUint32()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
values := make([]ot.Label, count)
|
|
for j := 0; j < count; j++ {
|
|
err := conn.ReceiveLabel(&label, &labelData)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
values[j] = label
|
|
}
|
|
garbled[i] = values
|
|
}
|
|
|
|
wires := make([]ot.Label, circ.NumWires)
|
|
|
|
// Receive peer inputs.
|
|
for i := 0; i < int(circ.Inputs[0].Type.Bits); i++ {
|
|
err := conn.ReceiveLabel(&label, &labelData)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
wires[Wire(i)] = label
|
|
}
|
|
|
|
// Init oblivious transfer.
|
|
err = oti.InitReceiver(conn)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
ioStats := conn.Stats.Sum()
|
|
timing.Sample("Recv", []string{FileSize(ioStats).String()})
|
|
|
|
// Query our inputs.
|
|
if verbose {
|
|
fmt.Printf(" - Querying our inputs...\n")
|
|
}
|
|
// Wire offset.
|
|
if err := conn.SendUint32(int(circ.Inputs[0].Type.Bits)); err != nil {
|
|
return nil, err
|
|
}
|
|
// Wire count.
|
|
if err := conn.SendUint32(int(circ.Inputs[1].Type.Bits)); err != nil {
|
|
return nil, err
|
|
}
|
|
if err := conn.Flush(); err != nil {
|
|
return nil, err
|
|
}
|
|
flags := make([]bool, int(circ.Inputs[1].Type.Bits))
|
|
for i := 0; i < int(circ.Inputs[1].Type.Bits); i++ {
|
|
if inputs.Bit(i) == 1 {
|
|
flags[i] = true
|
|
}
|
|
}
|
|
if err := oti.Receive(flags, wires[circ.Inputs[0].Type.Bits:]); err != nil {
|
|
return nil, err
|
|
}
|
|
xfer := conn.Stats.Sum() - ioStats
|
|
ioStats = conn.Stats.Sum()
|
|
timing.Sample("Inputs", []string{FileSize(xfer).String()})
|
|
|
|
// Evaluate gates.
|
|
if verbose {
|
|
fmt.Printf(" - Evaluating circuit...\n")
|
|
}
|
|
err = circ.Eval(key[:], wires, garbled)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
timing.Sample("Eval", nil)
|
|
|
|
// Resolve result values.
|
|
|
|
var labels []ot.Label
|
|
|
|
for i := 0; i < circ.Outputs.Size(); i++ {
|
|
r := wires[Wire(circ.NumWires-circ.Outputs.Size()+i)]
|
|
labels = append(labels, r)
|
|
}
|
|
for _, l := range labels {
|
|
if err := conn.SendLabel(l, &labelData); err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
if err := conn.Flush(); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
result, err := conn.ReceiveData()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
raw := big.NewInt(0).SetBytes(result)
|
|
|
|
xfer = conn.Stats.Sum() - ioStats
|
|
timing.Sample("Result", []string{FileSize(xfer).String()})
|
|
if verbose {
|
|
timing.Print(conn.Stats)
|
|
}
|
|
|
|
return circ.Outputs.Split(raw), nil
|
|
}
|