Skip to content

Commit

Permalink
Merge pull request #14 from markkurossi/topic/streamer_mem
Browse files Browse the repository at this point in the history
Topic/streamer mem
  • Loading branch information
markkurossi authored Sep 4, 2023
2 parents d7d0cb3 + dbb9761 commit 7f08d6b
Show file tree
Hide file tree
Showing 45 changed files with 1,380 additions and 845 deletions.
Binary file modified apps/garbled/default.pgo
Binary file not shown.
11 changes: 11 additions & 0 deletions apps/garbled/examples/aesblock.mpcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// -*- go -*-

package main

import (
"crypto/aes"
)

func main(key, data [16]byte) []byte {
return aes.EncryptBlock(key, data)
}
11 changes: 11 additions & 0 deletions apps/garbled/examples/aesblock2.mpcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// -*- go -*-

package main

import (
"crypto/aes"
)

func main(key, data [16]byte) []byte {
return aes.Block128(key, data)
}
11 changes: 11 additions & 0 deletions apps/garbled/examples/aesexpand.mpcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// -*- go -*-

package main

import (
"crypto/aes"
)

func main(key, data [16]byte) []uint {
return aes.ExpandEncryptionKey(key)
}
43 changes: 43 additions & 0 deletions apps/garbled/examples/encrypt.mpcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// -*- go -*-

// Run the Evaluator with two inputs: evaluator's key and nonce shares:
//
// $ ./garbled -e -i 0x8cd98b88adab08d6d60fe57c8b8a33f3,0xfd5e0f8f155e7102aa526ad0 examples/encrypt.mpcl
//
// The Garbler takes three arguments: the message to encrypt, and its
// key and nonce shares:
//
// $ ./garbled -i 0x48656c6c6f2c20776f726c6421,0xed800b17b0c9d2334b249332155ddef5,0xa300751458c775a08762c2cd examples/encrypt.mpcl

package main

import (
"crypto/cipher/gcm"
)

type Garbler struct {
msg [64]byte
keyShare [16]byte
nonceShare [12]byte
}

type Evaluator struct {
keyShare [16]byte
nonceShare [12]byte
}

func main(g Garbler, e Evaluator) []byte {
var key [16]byte

for i := 0; i < len(key); i++ {
key[i] = g.keyShare[i] ^ e.keyShare[i]
}

var nonce [12]byte

for i := 0; i < len(nonce); i++ {
nonce[i] = g.nonceShare[i] ^ e.nonceShare[i]
}

return gcm.EncryptAES128(key, nonce, g.msg, []byte("unused"))
}
83 changes: 45 additions & 38 deletions apps/garbled/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
"github.com/markkurossi/mpc/compiler/utils"
"github.com/markkurossi/mpc/ot"
"github.com/markkurossi/mpc/p2p"
"github.com/markkurossi/mpc/types"
)

var (
Expand Down Expand Up @@ -407,10 +408,11 @@ func printResults(results []*big.Int, outputs circuit.IO) {
func printResult(result *big.Int, output circuit.IOArg, short bool) string {
var str string

if strings.HasPrefix(output.Type, "string") {
switch output.Type.Type {
case types.TString:
mask := big.NewInt(0xff)

for i := 0; i < output.Size/8; i++ {
for i := 0; i < int(output.Type.Bits)/8; i++ {
tmp := new(big.Int).Rsh(result, uint(i*8))
r := rune(tmp.And(tmp, mask).Uint64())
if unicode.IsPrint(r) {
Expand All @@ -419,11 +421,10 @@ func printResult(result *big.Int, output circuit.IOArg, short bool) string {
str += fmt.Sprintf("\\u%04x", r)
}
}
} else if strings.HasPrefix(output.Type, "uint") ||
strings.HasPrefix(output.Type, "int") {

if output.Type[0] == 'i' {
bits := circuit.Size(output.Type)
case types.TUint, types.TInt:
if output.Type.Type == types.TInt {
bits := int(output.Type.Bits)
if result.Bit(bits-1) == 1 {
// Negative number.
tmp := new(big.Int)
Expand All @@ -439,47 +440,53 @@ func printResult(result *big.Int, output circuit.IOArg, short bool) string {
}
if short {
str = fmt.Sprintf("%v", result)
} else if output.Size <= 64 {
} else if output.Type.Bits <= 64 {
str = fmt.Sprintf("0x%x\t%v", bytes, result)
} else {
str = fmt.Sprintf("0x%x", bytes)
}
} else if strings.HasPrefix(output.Type, "bool") {

case types.TBool:
str = fmt.Sprintf("%v", result.Uint64() != 0)
} else {
ok, count, elSize, elType := circuit.ParseArrayType(output.Type)
if ok {
mask := new(big.Int)
for i := 0; i < elSize; i++ {
mask.SetBit(mask, i, 1)
}

hexString := elType == "uint8"
if !hexString {
str = "["
}
for i := 0; i < count; i++ {
r := new(big.Int).Rsh(result, uint(i*elSize))
r = r.And(r, mask)

if hexString {
str += fmt.Sprintf("%02x", r.Int64())
} else {
if i > 0 {
str += " "
}
str += printResult(r, circuit.IOArg{
Type: elType,
Size: elSize,
}, true)
case types.TArray:
count := int(output.Type.ArraySize)
elSize := int(output.Type.ElementType.Bits)

mask := new(big.Int)
for i := 0; i < elSize; i++ {
mask.SetBit(mask, i, 1)
}

var hexString bool
if output.Type.ElementType.Type == types.TUint &&
output.Type.ElementType.Bits == 8 {
hexString = true
}
if !hexString {
str = "["
}
for i := 0; i < count; i++ {
r := new(big.Int).Rsh(result, uint(i*elSize))
r = r.And(r, mask)

if hexString {
str += fmt.Sprintf("%02x", r.Int64())
} else {
if i > 0 {
str += " "
}
str += printResult(r, circuit.IOArg{
Type: *output.Type.ElementType,
}, true)
}
if !hexString {
str += "]"
}
} else {
str = fmt.Sprintf("%v (%s)", result, output.Type)
}
if !hexString {
str += "]"
}

default:
str = fmt.Sprintf("%v (%s)", result, output.Type)
}

return str
Expand Down
79 changes: 79 additions & 0 deletions benchmarks.md
Original file line number Diff line number Diff line change
Expand Up @@ -538,6 +538,85 @@ Max permanent wires: 53913890, cached circuits: 25
#gates=830166294 (XOR=533177896 XNOR=28813441 AND=267575026 OR=496562 INV=103369 xor=561991337 !xor=268174957 levels=10548 width=1796) #w=853882864
```

Value.HashValue based `WireAllocator`:

```
┌──────────────┬────────────────┬─────────┬────────┐
│ Op │ Time │ % │ Xfer │
├──────────────┼────────────────┼─────────┼────────┤
│ Compile │ 1.89192514s │ 2.70% │ │
│ Init │ 2.706353ms │ 0.00% │ 0B │
│ OT Init │ 11.731µs │ 0.00% │ 16kB │
│ Peer Inputs │ 45.549977ms │ 0.07% │ 57kB │
│ Stream │ 1m8.029901416s │ 97.23% │ 15GB │
│ ├╴InstrInit │ 2.933100244s │ 4.31% │ │
│ ├╴CircComp │ 30.339124ms │ 0.04% │ │
│ ├╴StreamInit │ 2.608974096s │ 3.84% │ │
│ ╰╴Garble │ 1m1.560371684s │ 90.49% │ │
│ Result │ 324.555µs │ 0.00% │ 8kB │
│ Total │ 1m9.970419172s │ │ 15GB │
│ ├╴Sent │ │ 100.00% │ 15GB │
│ ├╴Rcvd │ │ 0.00% │ 45kB │
│ ╰╴Flcd │ │ │ 231284 │
└──────────────┴────────────────┴─────────┴────────┘
Max permanent wires: 53913890, cached circuits: 25
#gates=830166294 (XOR=533177896 XNOR=28813441 AND=267575026 OR=496562 INV=103369 xor=561991337 !xor=268174957 levels=10548 width=1796) #w=853882864
```

Optimized `compiler/circuits/Wire`:

```
┌──────────────┬────────────────┬─────────┬────────┐
│ Op │ Time │ % │ Xfer │
├──────────────┼────────────────┼─────────┼────────┤
│ Compile │ 1.870993069s │ 2.71% │ │
│ Init │ 2.331431ms │ 0.00% │ 0B │
│ OT Init │ 10.949µs │ 0.00% │ 16kB │
│ Peer Inputs │ 44.089085ms │ 0.06% │ 57kB │
│ Stream │ 1m7.0813688s │ 97.22% │ 15GB │
│ ├╴InstrInit │ 2.421297578s │ 3.61% │ │
│ ├╴CircComp │ 17.09415ms │ 0.03% │ │
│ ├╴StreamInit │ 2.155089182s │ 3.21% │ │
│ ╰╴Garble │ 1m1.550598148s │ 91.76% │ │
│ Result │ 432.27µs │ 0.00% │ 8kB │
│ Total │ 1m8.999225604s │ │ 15GB │
│ ├╴Sent │ │ 100.00% │ 15GB │
│ ├╴Rcvd │ │ 0.00% │ 45kB │
│ ╰╴Flcd │ │ │ 231284 │
└──────────────┴────────────────┴─────────┴────────┘
Max permanent wires: 53913890, cached circuits: 25
#gates=830166294 (XOR=533177896 XNOR=28813441 AND=267575026 OR=496562 INV=103369 xor=561991337 !xor=268174957 levels=10548 width=1796) #w=853882864
```

Optimized streamer to use `circuit.Wire` instead of
`compiler/circuits/Wire` in wire cache:

```
┌──────────────┬────────────────┬─────────┬────────┐
│ Op │ Time │ % │ Xfer │
├──────────────┼────────────────┼─────────┼────────┤
│ Compile │ 1.755362404s │ 2.64% │ │
│ Init │ 2.79287ms │ 0.00% │ 0B │
│ OT Init │ 13.525µs │ 0.00% │ 16kB │
│ Peer Inputs │ 45.376796ms │ 0.07% │ 57kB │
│ Stream │ 1m4.624303427s │ 97.28% │ 15GB │
│ ├╴InstrInit │ 1.166489974s │ 1.81% │ │
│ ├╴CircComp │ 18.17144ms │ 0.03% │ │
│ ├╴StreamInit │ 1.886360054s │ 2.92% │ │
│ ╰╴Garble │ 1m0.866348862s │ 94.18% │ │
│ Result │ 225.299µs │ 0.00% │ 8kB │
│ Total │ 1m6.428074321s │ │ 15GB │
│ ├╴Sent │ │ 100.00% │ 15GB │
│ ├╴Rcvd │ │ 0.00% │ 45kB │
│ ╰╴Flcd │ │ │ 231284 │
└──────────────┴────────────────┴─────────┴────────┘
Max permanent wires: 53913890, cached circuits: 25
#gates=830166294 (XOR=533177896 XNOR=28813441 AND=267575026 OR=496562 INV=103369 xor=561991337 !xor=268174957 levels=10548 width=1796) #w=853882864
66.59 real 69.15 user 6.69 sys
3568140288 maximum resident set size
4119990272 peak memory footprint
```

Theoretical minimum single-threaded garbling time:

```
Expand Down
6 changes: 3 additions & 3 deletions bmr/player.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright (c) 2022 Markku Rossi
// Copyright (c) 2022-2023 Markku Rossi
//
// All rights reserved.
//
Expand Down Expand Up @@ -86,11 +86,11 @@ func (p *Player) offlinePhase() error {
var inputIndex int
for id, input := range p.c.Inputs {
if id != p.id {
for i := 0; i < input.Size; i++ {
for i := 0; i < int(input.Type.Bits); i++ {
p.lambda.SetBit(p.lambda, inputIndex+i, 0)
}
}
inputIndex += input.Size
inputIndex += int(input.Type.Bits)
}

wires := make([]Wire, p.c.NumWires)
Expand Down
Loading

0 comments on commit 7f08d6b

Please sign in to comment.