Commit 401d7c05 authored by Anders Jensen Løvig's avatar Anders Jensen Løvig
Browse files

Stuff

parent 2383257e
......@@ -10,57 +10,64 @@ import (
)
////////////////////////////////////////////////////////////////
const NumInputs = 3 // How many inputs each player provide
const NumInputs = 6 // How many inputs each player provide
const NumWires = 11
const K = 128
////////////////////////////////////////////////////////////////
type Protocol struct {
A, B *Party
oblivP *oblivious.Protocol
}
func NewProtocol() *Protocol {
func NewProtocol() (p *Protocol, err error) {
connA2B := make(chan []byte)
connB2A := make(chan []byte)
obliv := oblivious.NewProtocol()
obliv := oblivious.NewProtocol(len(blood.Table))
return &Protocol{
A: NewParty(connA2B, connB2A),
B: NewParty(connB2A, connA2B),
A, err := NewParty(connA2B, connB2A, obliv.R)
if err != nil {
return
}
B, err := NewParty(connB2A, connA2B, obliv.S)
if err != nil {
return
}
oblivP: New,
p = &Protocol{
A: A,
B: B,
}
return
}
type Party struct {
// The oblivious transfer party
obliv *oblivious.Party
// Channels for communication
send chan []byte
receive chan []byte
x []bool
Circuit *garbled.Circuit
Out chan []byte
TableChan chan garbled.Table
encodedX []byte
*oblivious.Party
result bool
outChan chan []byte
circuit *garbled.Circuit
}
func NewParty(in chan []byte, out chan []byte) (p *Party) {
return &Party{
func NewParty(in chan []byte, out chan []byte, obliv *oblivious.Party) (p *Party, err error) {
c, err := garbled.NewCircuit(NumInputs, NumWires, K)
if err != nil {
return
}
p = &Party{
obliv: obliv,
send: in,
receive: out,
circuit: c,
}
return
}
func (alice *Party) RunAlice(x []bool) (err error) {
func (alice *Party) RunAlice(x int) (err error) {
// 1. Garble
F, _ := garbled.NewTable(NumWires-NumInputs*2, 4, K*2)
F.SetData(<-alice.receive)
......@@ -68,62 +75,85 @@ func (alice *Party) RunAlice(x []bool) (err error) {
// 2. Encode Bob's input
fmt.Println("Alice: Received Y from Bob")
_ = <-alice.receive
Y := <-alice.receive
// 3. Encode Alice's input
X, err := alice.obliv.Receive(x)
if err != nil {
return
}
// 4. Evaluation
evalInput := append(X, Y...)
fmt.Println(len(evalInput))
_, err = garbled.Evaluate(F, evalInput)
if err != nil {
return
}
return
}
func (bob *Party) RunBob(y []bool) (err error) {
func (bob *Party) RunBob(y int) (err error) {
// 1. Garble
bob.GenerateCircuit()
bob.Circuit, err = garbled.NewGarbBloodCircuit(NumInputs, NumWires, K)
if err != nil {
return
}
fmt.Println("Bob: Sending F to Alice")
bob.send <- bob.Circuit.F.GetData()
// 2. Encode Bob's input
Y := garbled.Encode(bob.Circuit.E[1], bob.x, len(bob.x))
Y := garbled.Encode(bob.Circuit.E[1], util.Int2Bools(y, 3))
fmt.Println("Bob: Sending Y to Alice")
bob.send <- Y
return
}
func (p *Party) GenerateCircuit() {
var err error
p.Circuit, err = garbled.NewGarbBloodCircuit(NumInputs, NumWires, K)
// 3. Encode Alice's input
// Create data for each possible encoding
data := make([][]byte, len(blood.Table))
for i := 0; i < len(data); i++ {
data[i] = garbled.Encode(bob.Circuit.E[0], util.Int2Bools(i, 3))
}
fmt.Println("Bob: Oblivious transfer encoding to Alice")
err = bob.obliv.Send(data)
if err != nil {
panic(err)
return
}
}
func (p *Party) OTSend() {
for i := 0; i < 3; i++ {
// p.Listen(p.Circuit.E[i+3])
p.Listen(nil)
}
}
// 4. Evaluation
func (p *Party) OTReceive() (res [][]byte, err error) {
res = make([][]byte, 3)
var val int
for i := range p.x {
if p.x[i] {
val = 1
} else {
val = 0
}
var result, err = p.ObliviousTransfer(2, val)
if err != nil {
return nil, err
}
res[i] = result
}
return res, nil
return
}
func OTransfer(sender, receiver *Party) {
sender.Party, receiver.Party = oblivious.NewPartyPair()
//sender.Listen(sender.Circuit.e)
}
// func (p *Party) OTSend() {
// for i := 0; i < 3; i++ {
// // p.Listen(p.Circuit.E[i+3])
// p.Listen(nil)
// }
// }
// func (p *Party) OTReceive() (res [][]byte, err error) {
// res = make([][]byte, 3)
// var val int
// for i := range p.x {
// if p.x[i] {
// val = 1
// } else {
// val = 0
// }
// var result, err = p.ObliviousTransfer(2, val)
// if err != nil {
// return nil, err
// }
// res[i] = result
// }
// return res, nil
// }
// func OTransfer(sender, receiver *Party) {
// sender.Party, receiver.Party = oblivious.NewPartyPair()
// //sender.Listen(sender.Circuit.e)
// }
// RunProtocol runs the protocol between receiving blood type x and donor blood
// type y.
......@@ -134,13 +164,13 @@ func RunProtocol(x, y int, outputMode int) (z bool, err error) {
// Concurrently run Bob
go func() {
err := p.B.RunBob(util.Int2Bools(y, 3))
err := p.B.RunBob(y)
if err != nil {
panic(err) // TODO do not panic
}
}()
err = p.A.RunAlice(util.Int2Bools(x, 3))
err = p.A.RunAlice(x)
return
......
......@@ -4,109 +4,37 @@ import (
"bytes"
cryptoUtil "crycomp/internal/crypto/util"
"crycomp/internal/util"
"crypto/rand"
"crypto/sha256"
"errors"
"fmt"
)
// Table contains the random or encoded strings of bit-length k.
type Table struct {
// data contains the raw byte data this table holds.
data []byte
// rows is the number of rows in data (not length).
// Normally this is the numbe of wires the table was created for.
rows int
// cols is the number of strings in each row. E.g the two input
// keys (K_0^i, K_1^i)
cols int
// valueLen contains the string length (of each value). This is always k/8.
valueLen int
}
// NewTable returns a new garbled table with n rows and each row containing numValues columns.
// Each value contains k/8 bytes. k must be a multiple of 8.
func NewTable(n, numValues, k int) (t *Table, err error) {
if k%8 != 0 {
return nil, errors.New("k must be multiple of 8")
}
t = &Table{
data: make([]byte, n*numValues*k/8),
rows: n,
cols: numValues,
valueLen: k / 8,
}
return
}
// index returns the data index for row i and column j.
func (t *Table) index(r, c int) int {
return r*t.cols*t.valueLen + c*t.valueLen
}
// getValue returns a byte slice containing the value at row i and column j.
func (t *Table) getValue(r, c int) []byte {
index := t.index(r, c)
return t.data[index : index+t.valueLen]
}
func (t *Table) setRow(r int, data []byte) {
if len(data) != t.cols*t.valueLen {
panic("data have invalid length")
}
index := t.index(r, 0)
copy(t.data[index:index+t.cols*t.valueLen], data)
}
func (t *Table) getRow(r int) []byte {
index := t.index(r, 0)
return t.data[index : index+t.cols*t.valueLen]
}
func (t *Table) getRows(r, count int) []byte {
index := t.index(r, 0)
return t.data[index : index+count*t.cols*t.valueLen]
}
func (t *Table) SetData(data []byte) {
if len(data) != len(t.data) {
panic("data have invalid length")
}
t.data = data
}
func (t *Table) GetData() []byte {
return t.data
}
func (t *Table) getKFirstValues(numInputWire int) [][][]byte {
values := make([][][]byte, 0)
for i := 0; i < numInputWire; i++ {
// values = append(values, t.GetRowOld(i))
}
return values
}
type Circuit struct {
numInputs, numWires, k int
func (t *Table) randomizeTable() error {
_, err := rand.Read(t.data)
return err
}
G func(a, b []byte, i int) []byte
type Circuit struct {
F *Table
E []*Table
D *Table
}
type Params struct {
G func(a, b []byte, i int) []byte
}
func NewCircuit(numInputs, numWires, k int) (c *Circuit, err error) {
F, err := NewTable(numWires-numInputs, 4, k*2)
if err != nil {
return
}
c = &Circuit{
numInputs: numInputs,
numWires: numWires,
k: k,
func NewGarbBloodCircuit(numInputs, numWires, k int) (c *Circuit, err error) {
p := Params{G}
F: F,
}
return
}
func (c *Circuit) GarbleBloodCircuit() (err error) {
// 1. Create two random strings for each wire.
kTable, err := NewTable(numWires, 2, k)
kTable, err := NewTable(c.numWires, 2, c.k)
if err != nil {
return
}
......@@ -115,78 +43,58 @@ func NewGarbBloodCircuit(numInputs, numWires, k int) (c *Circuit, err error) {
return
}
// 2. Create a garbled table for all fTable values (4 for each gate)
fTable, err := NewTable(numWires-numInputs*2, 4, k*2)
if err != nil {
return
}
// Create F
fTable.setRow(0, p.garbleGate(kTable, 0, 3, 6, ORGateWithNot))
fTable.setRow(1, p.garbleGate(kTable, 1, 4, 7, ORGateWithNot))
fTable.setRow(2, p.garbleGate(kTable, 2, 5, 8, ORGateWithNot))
// 2. Create a garbled table for all F values (4 for each gate)
c.F.setRow(0, c.garbleGate(kTable, 0, 3, 6, ORGateWithNot))
c.F.setRow(1, c.garbleGate(kTable, 1, 4, 7, ORGateWithNot))
c.F.setRow(2, c.garbleGate(kTable, 2, 5, 8, ORGateWithNot))
fTable.setRow(3, p.garbleGate(kTable, 6, 7, 9, ANDGate))
fTable.setRow(4, p.garbleGate(kTable, 8, 9, 10, ANDGate))
c.F.setRow(3, c.garbleGate(kTable, 6, 7, 9, ANDGate))
c.F.setRow(4, c.garbleGate(kTable, 8, 9, 10, ANDGate))
// Create e
e := make([]*Table, 2)
e[0], _ = NewTable(numInputs, 2, k)
e[0].SetData(kTable.getRows(0, numInputs))
c.E = make([]*Table, 2)
c.E[0], _ = NewTable(c.numInputs, 2, c.k)
c.E[0].SetData(kTable.getRows(0, c.numInputs))
e[1], _ = NewTable(numInputs, 2, k)
e[1].SetData(kTable.getRows(numInputs, numInputs))
c.E[1], _ = NewTable(c.numInputs, 2, c.k)
c.E[1].SetData(kTable.getRows(c.numInputs, c.numInputs))
// Create d
d, _ := NewTable(1, 2, k)
d.SetData(kTable.getRow(numWires - 1))
c.D, _ = NewTable(1, 2, c.k)
c.D.SetData(kTable.getRow(c.numWires - 1))
c = &Circuit{
F: fTable,
E: e,
D: d,
}
return
}
// Encode x using the e table. If ey == true, we use the second
// half of e, otherwise first half
func Encode(e *Table, x []bool, rowOffset int) (X []byte) {
func Encode(e *Table, x []bool) (X []byte) {
X = make([]byte, 0)
for i, b := range x {
if b {
X = append(X, e.getValue(i+rowOffset, 1)...)
X = append(X, e.getValue(i, 1)...)
} else {
X = append(X, e.getValue(i+rowOffset, 0)...)
X = append(X, e.getValue(i, 0)...)
}
}
if len(x)*e.valueLen != len(X) {
panic("Wrong length of X")
}
// X = make([][]byte, 0)
// for i, val := range x {
// if val {
// X = append(X, e[i][1])
// } else {
// X = append(X, e[i][0])
// }
// }
return
}
//Creates a row (C_0^i, C_1^i, C_2^i ,C_3^i) for the garbled table, where
func (p *Params) garbleGate(K *Table, Li, Ri, out int, c func(a, b int) int) []byte {
func (c *Circuit) garbleGate(K *Table, Li, Ri, out int, gateFun func(a, b int) int) []byte {
cRow := make([]byte, K.valueLen*8) // because 4 values of double length
perm := cryptoUtil.Perm(4) // Random permutation
// for (a,b) in {0,1} x {0,1}
for a := 0; a <= 1; a++ {
for b := 0; b <= 1; b++ {
left := p.G(K.getValue(Li, a), K.getValue(Ri, b), out)
left := c.G(K.getValue(Li, a), K.getValue(Ri, b), out)
right := make([]byte, K.valueLen*2)
copy(right[:K.valueLen], K.getValue(out, c(a, b)))
copy(right[:K.valueLen], K.getValue(out, gateFun(a, b)))
// The index to write this value to. This depends in the row permutation.
rowI := perm[a*2+b] * K.valueLen
......@@ -205,20 +113,36 @@ func G(A, B []byte, i int) []byte {
return hash.Sum(nil)
}
func Eval(C *Table, X [][]byte) ([]byte, error) {
var K = X
var res []byte
for i := 0; i < 3; i++ {
func Evaluate(F *Table, x []byte) ([]byte, error) {
K, err := NewTable(1, len(x)/F.valueLen, F.valueLen*8)
if err != nil {
return nil, err
}
K.SetData(x)
// For each circuit gate
for i := 0; i < len(F.data); i++ {
// For each C
for j := 0; j < 4; j++ {
// res = util.XOR(G(K[i], K[i+3], i), C.GetValueOld(i, j))
if bytes.Equal(res[16:], make([]byte, 16)) {
K = append(K, res[:16])
break
}
// dst := make([]byte, 2*F.valueLen)
// util.XOR(dst, K.getValue())
}
return nil, fmt.Errorf("Aborted while evaluating the garbled circuit, no match was found")
}
return K[len(K)-1], nil
// var K = x
// var res []byte
// for i := 0; i < 3; i++ {
// for j := 0; j < 4; j++ {
// // res = util.XOR(G(K[i], K[i+3], i), C.GetValueOld(i, j))
// if bytes.Equal(res[16:], make([]byte, 16)) {
// K = append(K, res[:16])
// break
// }
// }
// return nil, fmt.Errorf("Aborted while evaluating the garbled circuit, no match was found")
// }
// return K[len(K)-1], nil
return nil, nil
}
func Decode(d [][]byte, Z []byte) bool {
......
......@@ -5,71 +5,6 @@ import (
"testing"
)
func TestNewTable(t *testing.T) {
table, err := NewTable(1, 1, 8)
if err != nil {
t.Fatal(err)
}
if len(table.data) != 1 {
t.Errorf("Expected len(table.data) == 1, got %d", len(table.data))
}
table, err = NewTable(2, 1, 16)
if err != nil {
t.Fatal(err)
}
if len(table.data) != 4 {
t.Errorf("Expected len(table.data) == 4, got %d", len(table.data))
}
table, err = NewTable(2, 2, 16)
if err != nil {
t.Fatal(err)
}
if len(table.data) != 8 {
t.Errorf("Expected len(table.data) == 8, got %d", len(table.data))
}
}
func TestIndex(t *testing.T) {
table, _ := NewTable(2, 2, 16)
if i := table.index(0, 0); i != 0 {
t.Errorf("Expected table index(0, 0) == 0, got %d", i)
}
if i := table.index(0, 1); i != 2 {
t.Errorf("Expected table index(0, 1) == 2, got %d", i)
}
if i := table.index(1, 0); i != 4 {
t.Errorf("Expected table index(1, 0) == 4, got %d", i)
}
if i := table.index(1, 1); i != 6 {
t.Errorf("Expected table index(1, 1) == 8, got %d", i)
}
}
func AssertByteSlice(t *testing.T, actual, expected []byte) {
if !bytes.Equal(actual, expected) {
t.Errorf("Expected bytes to be equal")
}
}
func TestTableValue(t *testing.T) {
table, _ := NewTable(2, 2, 16)
table.setRow(0, []byte{123, 81, 0, 0})
table.setRow(1, []byte{1, 2, 3, 4})
AssertByteSlice(t, table.data, []byte{123, 81, 0, 0, 1, 2, 3, 4})
AssertByteSlice(t, table.getValue(0, 0), []byte{123, 81})
AssertByteSlice(t, table.getValue(0, 1), []byte{0, 0})
AssertByteSlice(t, table.getRow(0), []byte{123, 81, 0, 0})
AssertByteSlice(t, table.getValue(1, 0), []byte{1, 2})
AssertByteSlice(t, table.getValue(1, 1), []byte{3, 4})
AssertByteSlice(t, table.getRow(1), []byte{1, 2, 3, 4})
AssertByteSlice(t, table.getRows(0, 1), []byte{123, 81, 0, 0})
AssertByteSlice(t, table.getRows(0, 2), []byte{123, 81, 0, 0, 1, 2, 3, 4})
AssertByteSlice(t, table.getRows(1, 1), []byte{1, 2, 3, 4})
}
func TestGBC(t *testing.T) {
K, err := NewTable(3, 2, 16)
if err != nil {
......@@ -77,9 +12,8 @@ func TestGBC(t *testing.T) {
}
_ = K.randomizeTable()
p := Params{testingG}
res := p.garbleGate(K, 0, 1, 2, ORGate)
c := &Circuit{G: testingG}
res := c.garbleGate(K, 0, 1, 2, ORGate)
count := 0
for i := 0; i < 4; i++ {
index := i * K.valueLen
......@@ -91,7 +25,7 @@ func TestGBC(t *testing.T) {
t.Error("Function should return 3 true labels and 1 false label when using an OR Gate")
}
res = p.garbleGate(K, 0, 1, 2, ANDGate)
res = c.garbleGate(K, 0, 1, 2, ANDGate)
count = 0
for i := 0; i < 4; i++ {
index := i * K.valueLen
......
package garbled
import (
"crypto/rand"
"errors"
)
// Table contains the random or encoded strings of bit-length k.