Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Thomas Hoffmann
CryComp
Commits
c7af0db5
Commit
c7af0db5
authored
Oct 03, 2021
by
Anders Jensen Løvig
Browse files
Builder
parent
91d638fc
Changes
6
Hide whitespace changes
Inline
Side-by-side
README.md
View file @
c7af0db5
# Cryptographic Computing - Handin 4
# Cryptographic Computing - Handin 4
A Go implementation of a passive secure two-party protocol for blood type compatibility based on oblivious transfer.
A Go implementation of a passive secure two-party protocol for blood type compatibility based on Yao's garbled circuit protocol.
## Implementation
## Implementation
...
...
cmd/handin5/main.go
View file @
c7af0db5
...
@@ -19,17 +19,17 @@ type Protocol struct {
...
@@ -19,17 +19,17 @@ type Protocol struct {
A
,
B
*
Party
A
,
B
*
Party
}
}
func
NewProtocol
()
(
p
*
Protocol
,
err
error
)
{
func
NewProtocol
(
builder
*
garbled
.
CircuitBuilder
)
(
p
*
Protocol
,
err
error
)
{
connA2B
:=
make
(
chan
[]
byte
)
connA2B
:=
make
(
chan
[]
byte
)
connB2A
:=
make
(
chan
[]
byte
)
connB2A
:=
make
(
chan
[]
byte
)
obliv
:=
oblivious
.
NewProtocol
(
len
(
blood
.
Table
))
obliv
:=
oblivious
.
NewProtocol
(
len
(
blood
.
Table
))
A
,
err
:=
NewParty
(
connA2B
,
connB2A
,
obliv
.
R
)
A
,
err
:=
NewParty
(
builder
,
connA2B
,
connB2A
,
obliv
.
R
)
if
err
!=
nil
{
if
err
!=
nil
{
return
return
}
}
B
,
err
:=
NewParty
(
connB2A
,
connA2B
,
obliv
.
S
)
B
,
err
:=
NewParty
(
builder
,
connB2A
,
connA2B
,
obliv
.
S
)
if
err
!=
nil
{
if
err
!=
nil
{
return
return
}
}
...
@@ -52,8 +52,8 @@ type Party struct {
...
@@ -52,8 +52,8 @@ type Party struct {
circuit
*
garbled
.
Circuit
circuit
*
garbled
.
Circuit
}
}
func
NewParty
(
in
chan
[]
byte
,
out
chan
[]
byte
,
obliv
*
oblivious
.
Party
)
(
p
*
Party
,
err
error
)
{
func
NewParty
(
builder
*
garbled
.
CircuitBuilder
,
in
chan
[]
byte
,
out
chan
[]
byte
,
obliv
*
oblivious
.
Party
)
(
p
*
Party
,
err
error
)
{
c
,
err
:=
garbled
.
NewCircuit
(
NumInputs
,
NumWires
,
K
)
c
,
err
:=
builder
.
Build
(
)
if
err
!=
nil
{
if
err
!=
nil
{
return
return
}
}
...
@@ -104,7 +104,7 @@ func (alice *Party) RunAlice(x int) (result bool, err error) {
...
@@ -104,7 +104,7 @@ func (alice *Party) RunAlice(x int) (result bool, err error) {
func
(
bob
*
Party
)
RunBob
(
y
int
)
(
err
error
)
{
func
(
bob
*
Party
)
RunBob
(
y
int
)
(
err
error
)
{
// 1. Garble
// 1. Garble
err
=
bob
.
circuit
.
Garble
BloodCircuit
()
err
=
bob
.
circuit
.
Garble
()
if
err
!=
nil
{
if
err
!=
nil
{
return
return
}
}
...
@@ -134,11 +134,28 @@ func (bob *Party) RunBob(y int) (err error) {
...
@@ -134,11 +134,28 @@ func (bob *Party) RunBob(y int) (err error) {
return
return
}
}
// Evaluates an OR gate with not b.
func
OrGateWithNot
(
a
,
b
bool
)
bool
{
return
a
||
!
b
}
// Evaluates and and gate.
func
AndGate
(
a
,
b
bool
)
bool
{
return
a
&&
b
}
// RunProtocol runs the protocol between receiving blood type x and donor blood
// RunProtocol runs the protocol between receiving blood type x and donor blood
// type y.
// type y.
// outputMode: 0: Alice learns, 1: Bob learns else both learns
// outputMode: 0: Alice learns, 1: Bob learns else both learns
func
RunProtocol
(
x
,
y
int
,
outputMode
int
)
(
z
bool
,
err
error
)
{
func
RunProtocol
(
x
,
y
int
,
outputMode
int
)
(
z
bool
,
err
error
)
{
p
,
err
:=
NewProtocol
()
builder
:=
garbled
.
NewCircuitBuilder
(
6
,
128
)
or1
:=
builder
.
AddGate
(
0
,
3
,
OrGateWithNot
)
or2
:=
builder
.
AddGate
(
1
,
4
,
OrGateWithNot
)
or3
:=
builder
.
AddGate
(
2
,
5
,
OrGateWithNot
)
and1
:=
builder
.
AddGate
(
or1
,
or2
,
AndGate
)
_
=
builder
.
AddGate
(
or3
,
and1
,
AndGate
)
p
,
err
:=
NewProtocol
(
builder
)
if
err
!=
nil
{
if
err
!=
nil
{
return
return
}
}
...
...
internal/crypto/garbled/builder.go
0 → 100644
View file @
c7af0db5
package
garbled
type
gate
struct
{
// left is the left input wire
left
int
// left is the left input wire
right
int
// out is the output wire
out
int
// fun is the gate evaluation function
fun
func
(
a
,
b
bool
)
bool
}
type
CircuitBuilder
struct
{
// k is the bit-length of encodings
k
int
// numInputs is the number of input wires
numInputs
int
// gates contain all created gates
gates
[]
*
gate
}
// Returns a new CircuitBuilder for a circuit with numInputs input wires.
func
NewCircuitBuilder
(
numInputs
,
k
int
)
*
CircuitBuilder
{
return
&
CircuitBuilder
{
k
:
k
,
numInputs
:
numInputs
,
gates
:
make
([]
*
gate
,
0
),
}
}
// Adds a gate with left and right input wire and evaluted by fun.
// Returns the output wire.
func
(
b
*
CircuitBuilder
)
AddGate
(
left
,
right
int
,
fun
func
(
a
,
b
bool
)
bool
)
(
out
int
)
{
out
=
b
.
numInputs
+
len
(
b
.
gates
)
b
.
gates
=
append
(
b
.
gates
,
&
gate
{
left
:
left
,
right
:
right
,
out
:
out
,
fun
:
fun
,
})
return
}
// Builds the circuit configured in this builder.
func
(
b
*
CircuitBuilder
)
Build
()
(
c
*
Circuit
,
err
error
)
{
numWires
:=
b
.
numInputs
+
len
(
b
.
gates
)
return
NewCircuit
(
b
.
numInputs
,
numWires
,
b
.
k
,
b
.
gates
)
}
internal/crypto/garbled/circuit.go
View file @
c7af0db5
...
@@ -9,8 +9,11 @@ import (
...
@@ -9,8 +9,11 @@ import (
)
)
type
Circuit
struct
{
type
Circuit
struct
{
// Parameters
numInputs
,
numWires
,
k
int
numInputs
,
numWires
,
k
int
gates
[]
*
gate
G
func
(
a
,
b
[]
byte
,
i
int
)
[]
byte
G
func
(
a
,
b
[]
byte
,
i
int
)
[]
byte
F
*
Table
F
*
Table
...
@@ -18,8 +21,12 @@ type Circuit struct {
...
@@ -18,8 +21,12 @@ type Circuit struct {
D
*
Table
D
*
Table
}
}
func
NewCircuit
(
numInputs
,
numWires
,
k
int
)
(
c
*
Circuit
,
err
error
)
{
func
NewCircuit
(
numInputs
,
numWires
,
k
int
,
gates
[]
*
gate
)
(
c
*
Circuit
,
err
error
)
{
F
,
err
:=
NewTable
(
numWires
-
numInputs
,
4
,
k
*
2
)
if
k
%
8
!=
0
{
return
nil
,
errors
.
New
(
"k must be multiple of 8"
)
}
numNonInputs
:=
numWires
-
numInputs
F
,
err
:=
NewTable
(
numNonInputs
,
4
,
k
*
2
)
if
err
!=
nil
{
if
err
!=
nil
{
return
return
}
}
...
@@ -28,13 +35,15 @@ func NewCircuit(numInputs, numWires, k int) (c *Circuit, err error) {
...
@@ -28,13 +35,15 @@ func NewCircuit(numInputs, numWires, k int) (c *Circuit, err error) {
numWires
:
numWires
,
numWires
:
numWires
,
k
:
k
,
k
:
k
,
gates
:
gates
,
G
:
G
,
G
:
G
,
F
:
F
,
F
:
F
,
}
}
return
return
}
}
func
(
c
*
Circuit
)
Garble
BloodCircuit
()
(
err
error
)
{
func
(
c
*
Circuit
)
Garble
()
(
err
error
)
{
// 1. Create two random strings for each wire.
// 1. Create two random strings for each wire.
kTable
,
err
:=
NewTable
(
c
.
numWires
,
2
,
c
.
k
)
kTable
,
err
:=
NewTable
(
c
.
numWires
,
2
,
c
.
k
)
if
err
!=
nil
{
if
err
!=
nil
{
...
@@ -46,12 +55,16 @@ func (c *Circuit) GarbleBloodCircuit() (err error) {
...
@@ -46,12 +55,16 @@ func (c *Circuit) GarbleBloodCircuit() (err error) {
}
}
// 2. Create a garbled table for all F values (4 for each gate)
// 2. Create a garbled table for all F values (4 for each gate)
c
.
F
.
setRow
(
0
,
c
.
garbleGate
(
kTable
,
0
,
3
,
6
,
ORGateWithNot
))
for
i
,
gate
:=
range
c
.
gates
{
c
.
F
.
setRow
(
1
,
c
.
garbleGate
(
kTable
,
1
,
4
,
7
,
ORGateWithNot
))
c
.
F
.
setRow
(
i
,
c
.
garbleGate
(
kTable
,
gate
))
c
.
F
.
setRow
(
2
,
c
.
garbleGate
(
kTable
,
2
,
5
,
8
,
ORGateWithNot
))
}
// 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))
c
.
F
.
setRow
(
3
,
c
.
garbleGate
(
kTable
,
6
,
7
,
9
,
ANDGate
))
//
c.F.setRow(3, c.garbleGate(kTable, 6, 7, 9, ANDGate))
c
.
F
.
setRow
(
4
,
c
.
garbleGate
(
kTable
,
8
,
9
,
10
,
ANDGate
))
//
c.F.setRow(4, c.garbleGate(kTable, 8, 9, 10, ANDGate))
// Create e
// Create e
c
.
E
=
make
([]
*
Table
,
2
)
c
.
E
=
make
([]
*
Table
,
2
)
...
@@ -73,7 +86,6 @@ func (c *Circuit) GarbleBloodCircuit() (err error) {
...
@@ -73,7 +86,6 @@ func (c *Circuit) GarbleBloodCircuit() (err error) {
return
return
}
}
c
.
D
.
SetData
(
kTable
.
getRow
(
c
.
numWires
-
1
))
c
.
D
.
SetData
(
kTable
.
getRow
(
c
.
numWires
-
1
))
return
return
}
}
...
@@ -105,17 +117,22 @@ func Decode(d *Table, Z []byte) (bool, error) {
...
@@ -105,17 +117,22 @@ func Decode(d *Table, Z []byte) (bool, error) {
}
}
//Creates a row (C_0^i, C_1^i, C_2^i ,C_3^i) for the garbled table, where
//Creates a row (C_0^i, C_1^i, C_2^i ,C_3^i) for the garbled table, where
func
(
c
*
Circuit
)
garbleGate
(
K
*
Table
,
Li
,
Ri
,
out
int
,
gateFun
func
(
a
,
b
int
)
int
)
[]
byte
{
func
(
c
*
Circuit
)
garbleGate
(
K
*
Table
,
gate
*
gate
)
[]
byte
{
cRow
:=
make
([]
byte
,
4
*
2
*
K
.
valueLen
)
// because 4 values of double length
cRow
:=
make
([]
byte
,
4
*
2
*
K
.
valueLen
)
// because 4 values of double length
perm
:=
util
.
Perm
(
4
)
// Random permutation
perm
:=
util
.
Perm
(
4
)
// Random permutation
// for (a,b) in {0,1} x {0,1}
// for (a,b) in {0,1} x {0,1}
for
a
:=
0
;
a
<=
1
;
a
++
{
for
a
:=
0
;
a
<=
1
;
a
++
{
for
b
:=
0
;
b
<=
1
;
b
++
{
for
b
:=
0
;
b
<=
1
;
b
++
{
left
:=
c
.
G
(
K
.
getValue
(
Li
,
a
),
K
.
getValue
(
Ri
,
b
),
out
)
left
:=
c
.
G
(
K
.
getValue
(
gate
.
left
,
a
),
K
.
getValue
(
gate
.
right
,
b
),
gate
.
out
)
right
:=
make
([]
byte
,
K
.
valueLen
*
2
)
right
:=
make
([]
byte
,
K
.
valueLen
*
2
)
copy
(
right
[
:
K
.
valueLen
],
K
.
getValue
(
out
,
gateFun
(
a
,
b
)))
c
:=
0
if
gate
.
fun
(
a
==
1
,
b
==
1
)
{
c
=
1
}
copy
(
right
[
:
K
.
valueLen
],
K
.
getValue
(
gate
.
out
,
c
))
dst
:=
util
.
XOR
(
left
,
right
)
// XOR with left as destination.
dst
:=
util
.
XOR
(
left
,
right
)
// XOR with left as destination.
...
@@ -143,18 +160,13 @@ func (c *Circuit) Evaluate(x []byte) ([]byte, error) {
...
@@ -143,18 +160,13 @@ func (c *Circuit) Evaluate(x []byte) ([]byte, error) {
}
}
copy
(
K
.
data
[
:
len
(
x
)],
x
)
copy
(
K
.
data
[
:
len
(
x
)],
x
)
Li
:=
[]
int
{
0
,
1
,
2
,
6
,
8
}
Ri
:=
[]
int
{
3
,
4
,
5
,
7
,
9
}
Oi
:=
[]
int
{
6
,
7
,
8
,
9
,
10
}
zeroes
:=
make
([]
byte
,
K
.
valueLen
)
zeroes
:=
make
([]
byte
,
K
.
valueLen
)
// For each circuit gate
// For each circuit gate
for
i
:=
0
;
i
<
c
.
F
.
rows
;
i
++
{
for
i
,
gate
:=
range
c
.
gates
{
// For each C
success
:=
false
success
:=
false
for
j
:=
0
;
j
<
4
;
j
++
{
for
j
:=
0
;
j
<
4
;
j
++
{
left
:=
c
.
G
(
K
.
getValue
(
0
,
Li
[
i
]
),
K
.
getValue
(
0
,
Ri
[
i
]),
Oi
[
i
]
)
left
:=
c
.
G
(
K
.
getValue
(
0
,
gate
.
left
),
K
.
getValue
(
0
,
gate
.
right
),
gate
.
out
)
right
:=
c
.
F
.
getValue
(
i
,
j
)
right
:=
c
.
F
.
getValue
(
i
,
j
)
dst
:=
util
.
XOR
(
left
,
right
)
dst
:=
util
.
XOR
(
left
,
right
)
...
@@ -169,29 +181,28 @@ func (c *Circuit) Evaluate(x []byte) ([]byte, error) {
...
@@ -169,29 +181,28 @@ func (c *Circuit) Evaluate(x []byte) ([]byte, error) {
}
}
}
}
// for i := 0; i < c.F.rows; i++ {
// // For each C
// success := false
// for j := 0; j < 4; j++ {
// left := c.G(K.getValue(0, Li[i]), K.getValue(0, Ri[i]), Oi[i])
// right := c.F.getValue(i, j)
// dst := util.XOR(left, right)
// if bytes.Equal(zeroes, dst[K.valueLen:]) {
// K.setValue(0, i+c.numInputs, dst[:K.valueLen])
// success = true
// break
// }
// }
// if !success {
// return nil, fmt.Errorf("failed to evaluate circuit layer %d", i)
// }
// }
return
K
.
getValue
(
0
,
c
.
numWires
-
1
),
nil
return
K
.
getValue
(
0
,
c
.
numWires
-
1
),
nil
}
}
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
// GATES
// GATES
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
func
ORGate
(
a
,
b
int
)
int
{
if
a
+
b
!=
0
{
return
1
}
else
{
return
0
}
}
func
ORGateWithNot
(
a
,
b
int
)
int
{
if
((
1
-
b
)
+
a
)
==
0
{
return
0
}
else
{
return
1
}
}
func
ANDGate
(
a
,
b
int
)
int
{
return
a
*
b
}
internal/crypto/garbled/circuit_test.go
View file @
c7af0db5
...
@@ -13,7 +13,7 @@ func TestGBC(t *testing.T) {
...
@@ -13,7 +13,7 @@ func TestGBC(t *testing.T) {
_
=
K
.
randomizeTable
()
_
=
K
.
randomizeTable
()
c
:=
&
Circuit
{
G
:
testingG
}
c
:=
&
Circuit
{
G
:
testingG
}
res
:=
c
.
garbleGate
(
K
,
0
,
1
,
2
,
ORGate
)
res
:=
c
.
garbleGate
(
K
,
&
gate
{
0
,
1
,
2
,
or
}
)
count
:=
0
count
:=
0
for
i
:=
0
;
i
<
4
;
i
++
{
for
i
:=
0
;
i
<
4
;
i
++
{
index
:=
i
*
2
*
K
.
valueLen
index
:=
i
*
2
*
K
.
valueLen
...
@@ -25,7 +25,7 @@ func TestGBC(t *testing.T) {
...
@@ -25,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"
)
t
.
Error
(
"Function should return 3 true labels and 1 false label when using an OR Gate"
)
}
}
res
=
c
.
garbleGate
(
K
,
0
,
1
,
2
,
ANDGate
)
res
=
c
.
garbleGate
(
K
,
&
gate
{
0
,
1
,
2
,
and
}
)
count
=
0
count
=
0
for
i
:=
0
;
i
<
4
;
i
++
{
for
i
:=
0
;
i
<
4
;
i
++
{
index
:=
i
*
2
*
K
.
valueLen
index
:=
i
*
2
*
K
.
valueLen
...
@@ -42,6 +42,14 @@ func testingG(A, B []byte, i int) []byte {
...
@@ -42,6 +42,14 @@ func testingG(A, B []byte, i int) []byte {
return
make
([]
byte
,
len
(
A
)
*
2
)
return
make
([]
byte
,
len
(
A
)
*
2
)
}
}
func
or
(
a
,
b
bool
)
bool
{
return
a
||
b
}
func
and
(
a
,
b
bool
)
bool
{
return
a
&&
b
}
func
TestDecode
(
t
*
testing
.
T
)
{
func
TestDecode
(
t
*
testing
.
T
)
{
}
}
internal/crypto/garbled/table_test.go
View file @
c7af0db5
...
@@ -69,13 +69,3 @@ func TestTableValue(t *testing.T) {
...
@@ -69,13 +69,3 @@ func TestTableValue(t *testing.T) {
AssertByteSlice
(
t
,
table
.
getRows
(
0
,
2
),
[]
byte
{
123
,
81
,
0
,
0
,
1
,
2
,
3
,
4
})
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
})
AssertByteSlice
(
t
,
table
.
getRows
(
1
,
1
),
[]
byte
{
1
,
2
,
3
,
4
})
}
}
func
TestGetData
(
t
*
testing
.
T
)
{
c
,
_
:=
NewCircuit
(
6
,
11
,
128
)
_
=
c
.
GarbleBloodCircuit
()
data
:=
c
.
F
.
GetData
()
if
!
bytes
.
Equal
(
data
,
c
.
F
.
data
)
{
t
.
Errorf
(
"Bytes not equal"
)
}
}
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment