Skip to content

Commit

Permalink
Implemented compiler.circuits.Allocator to allocate wires and gates.
Browse files Browse the repository at this point in the history
  • Loading branch information
markkurossi committed Aug 28, 2023
1 parent 1499b44 commit b4486b0
Show file tree
Hide file tree
Showing 19 changed files with 153 additions and 100 deletions.
58 changes: 58 additions & 0 deletions compiler/circuits/allocator.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
//
// Copyright (c) 2023 Markku Rossi
//
// All rights reserved.
//

package circuits

import (
"fmt"

"github.com/markkurossi/mpc/types"
)

// Allocator implements circuit wire and gate allocation.
type Allocator struct {
block []Wire
ofs int
numWire uint64
numWires uint64
}

// NewAllocator creates a new circuit allocator.
func NewAllocator() *Allocator {
return new(Allocator)
}

// Wire allocates a new Wire.
func (alloc *Allocator) Wire() *Wire {
alloc.numWire++
w := new(Wire)
w.Reset(UnassignedID)
return w
}

// Wires allocate an array of Wires.
func (alloc *Allocator) Wires(bits types.Size) []*Wire {
alloc.numWires += uint64(bits)
result := make([]*Wire, bits)
for i := 0; i < int(bits); i++ {
if alloc.ofs == 0 {
alloc.ofs = 8192
alloc.block = make([]Wire, alloc.ofs)
}
alloc.ofs--
w := &alloc.block[alloc.ofs]

w.id = UnassignedID
result[i] = w
}
return result
}

// Debug print debugging information about the circuit allocator.
func (alloc *Allocator) Debug() {
fmt.Printf("circuits.Allocator: #wire=%v, #wires=%v\n",
alloc.numWire, alloc.numWires)
}
12 changes: 6 additions & 6 deletions compiler/circuits/circ_adder.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//
// circ_adder.go
//
// Copyright (c) 2019-2021 Markku Rossi
// Copyright (c) 2019-2023 Markku Rossi
//
// All rights reserved.
//
Expand All @@ -25,9 +25,9 @@ func NewHalfAdder(compiler *Compiler, a, b, s, c *Wire) {

// NewFullAdder creates a full adder circuit
func NewFullAdder(compiler *Compiler, a, b, cin, s, cout *Wire) {
w1 := NewWire()
w2 := NewWire()
w3 := NewWire()
w1 := compiler.Calloc.Wire()
w2 := compiler.Calloc.Wire()
w3 := compiler.Calloc.Wire()

// s = a XOR b XOR cin
// cout = cin XOR ((a XOR cin) AND (b XOR cin)).
Expand Down Expand Up @@ -65,7 +65,7 @@ func NewAdder(compiler *Compiler, x, y, z []*Wire) error {
}
NewHalfAdder(compiler, x[0], y[0], z[0], cin)
} else {
cin := NewWire()
cin := compiler.Calloc.Wire()
NewHalfAdder(compiler, x[0], y[0], z[0], cin)

for i := 1; i < len(x); i++ {
Expand All @@ -78,7 +78,7 @@ func NewAdder(compiler *Compiler, x, y, z []*Wire) error {
cout = z[len(x)]
}
} else {
cout = NewWire()
cout = compiler.Calloc.Wire()
}

NewFullAdder(compiler, x[i], y[i], cin, z[i], cout)
Expand Down
4 changes: 2 additions & 2 deletions compiler/circuits/circ_binary.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright (c) 2020-2021 Markku Rossi
// Copyright (c) 2020-2021, 2023 Markku Rossi
//
// All rights reserved.
//
Expand Down Expand Up @@ -31,7 +31,7 @@ func NewBinaryClear(compiler *Compiler, x, y, r []*Wire) error {
y = y[0:len(r)]
}
for i := 0; i < len(x); i++ {
w := NewWire()
w := compiler.Calloc.Wire()
compiler.INV(y[i], w)
compiler.AddGate(NewBinary(circuit.AND, x[i], w, r[i]))
}
Expand Down
18 changes: 9 additions & 9 deletions compiler/circuits/circ_comparators.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright (c) 2020-2021 Markku Rossi
// Copyright (c) 2020-2023 Markku Rossi
//
// All rights reserved.
//
Expand All @@ -21,16 +21,16 @@ func comparator(compiler *Compiler, cin *Wire, x, y, r []*Wire) error {
}

for i := 0; i < len(x); i++ {
w1 := NewWire()
w1 := compiler.Calloc.Wire()
compiler.AddGate(NewBinary(circuit.XNOR, cin, y[i], w1))
w2 := NewWire()
w2 := compiler.Calloc.Wire()
compiler.AddGate(NewBinary(circuit.XOR, cin, x[i], w2))
w3 := NewWire()
w3 := compiler.Calloc.Wire()
compiler.AddGate(NewBinary(circuit.AND, w1, w2, w3))

var cout *Wire
if i+1 < len(x) {
cout = NewWire()
cout = compiler.Calloc.Wire()
} else {
cout = r[0]
}
Expand Down Expand Up @@ -72,18 +72,18 @@ func NewNeqComparator(compiler *Compiler, x, y, r []*Wire) error {
return nil
}

c := NewWire()
c := compiler.Calloc.Wire()
compiler.AddGate(NewBinary(circuit.XOR, x[0], y[0], c))

for i := 1; i < len(x); i++ {
xor := NewWire()
xor := compiler.Calloc.Wire()
compiler.AddGate(NewBinary(circuit.XOR, x[i], y[i], xor))

var out *Wire
if i+1 >= len(x) {
out = r[0]
} else {
out = NewWire()
out = compiler.Calloc.Wire()
}
compiler.AddGate(NewBinary(circuit.OR, c, xor, out))
c = out
Expand All @@ -98,7 +98,7 @@ func NewEqComparator(compiler *Compiler, x, y, r []*Wire) error {
}

// w = x == y
w := NewWire()
w := compiler.Calloc.Wire()
err := NewNeqComparator(compiler, x, y, []*Wire{w})
if err != nil {
return err
Expand Down
12 changes: 6 additions & 6 deletions compiler/circuits/circ_divider.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright (c) 2019 Markku Rossi
// Copyright (c) 2019-2023 Markku Rossi
//
// All rights reserved.
//
Expand All @@ -16,7 +16,7 @@ func NewDivider(compiler *Compiler, a, b, q, r []*Wire) error {
// Init bINV.
bINV := make([]*Wire, len(b))
for i := 0; i < len(b); i++ {
bINV[i] = NewWire()
bINV[i] = compiler.Calloc.Wire()
compiler.INV(b[i], bINV[i])
}

Expand All @@ -40,16 +40,16 @@ func NewDivider(compiler *Compiler, a, b, q, r []*Wire) error {
} else {
bw = compiler.OneWire() // INV(0)
}
co := NewWire()
ro := NewWire()
co := compiler.Calloc.Wire()
ro := compiler.Calloc.Wire()
NewFullAdder(compiler, rIn[x], bw, cIn, ro, co)
rOut[x] = ro
cIn = co
}

// Quotient y.
if len(a)-1-y < len(q) {
w := NewWire()
w := compiler.Calloc.Wire()
compiler.INV(cIn, w)
compiler.INV(w, q[len(a)-1-y])
}
Expand All @@ -60,7 +60,7 @@ func NewDivider(compiler *Compiler, a, b, q, r []*Wire) error {
if y+1 >= len(a) && x < len(r) {
ro = r[x]
} else {
ro = NewWire()
ro = compiler.Calloc.Wire()
}

err := NewMUX(compiler, []*Wire{cIn}, rOut[x:x+1], rIn[x:x+1],
Expand Down
6 changes: 3 additions & 3 deletions compiler/circuits/circ_hamming.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright (c) 2020-2021 Markku Rossi
// Copyright (c) 2020-2023 Markku Rossi
//
// All rights reserved.
//
Expand All @@ -18,7 +18,7 @@ func Hamming(compiler *Compiler, a, b, r []*Wire) error {

var arr [][]*Wire
for i := 0; i < len(a); i++ {
w := NewWire()
w := compiler.Calloc.Wire()
compiler.AddGate(NewBinary(circuit.XOR, a[i], b[i], w))
arr = append(arr, []*Wire{w})
}
Expand All @@ -27,7 +27,7 @@ func Hamming(compiler *Compiler, a, b, r []*Wire) error {
var n [][]*Wire
for i := 0; i < len(arr); i += 2 {
if i+1 < len(arr) {
result := MakeWires(types.Size(len(arr[i]) + 1))
result := compiler.Calloc.Wires(types.Size(len(arr[i]) + 1))
err := NewAdder(compiler, arr[i], arr[i+1], result)
if err != nil {
return err
Expand Down
6 changes: 3 additions & 3 deletions compiler/circuits/circ_index.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright (c) 2021 Markku Rossi
// Copyright (c) 2021-2023 Markku Rossi
//
// All rights reserved.
//
Expand Down Expand Up @@ -65,7 +65,7 @@ func newIndex(compiler *Compiler, bit, length, size int,

fVal := make([]*Wire, size)
for i := 0; i < size; i++ {
fVal[i] = NewWire()
fVal[i] = compiler.Calloc.Wire()
}
fArray := array
if n > length {
Expand All @@ -80,7 +80,7 @@ func newIndex(compiler *Compiler, bit, length, size int,
if n > length {
tVal = make([]*Wire, size)
for i := 0; i < size; i++ {
tVal[i] = NewWire()
tVal[i] = compiler.Calloc.Wire()
}
err = newIndex(compiler, bit-1, length, size,
array[length*size:], index, tVal)
Expand Down
28 changes: 14 additions & 14 deletions compiler/circuits/circ_multiplier.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ func NewArrayMultiplier(compiler *Compiler, x, y, z []*Wire) error {
if i == 0 {
s = z[0]
} else {
s = NewWire()
s = compiler.Calloc.Wire()
sums = append(sums, s)
}
compiler.AddGate(NewBinary(circuit.AND, xn, y[0], s))
Expand All @@ -67,7 +67,7 @@ func NewArrayMultiplier(compiler *Compiler, x, y, z []*Wire) error {
// ANDs for y(j)
var ands []*Wire
for _, xn := range x {
wire := NewWire()
wire := compiler.Calloc.Wire()
compiler.AddGate(NewBinary(circuit.AND, xn, y[j], wire))
ands = append(ands, wire)
}
Expand All @@ -76,13 +76,13 @@ func NewArrayMultiplier(compiler *Compiler, x, y, z []*Wire) error {
var nsums []*Wire
var c *Wire
for i := 0; i < len(ands); i++ {
cout := NewWire()
cout := compiler.Calloc.Wire()

var s *Wire
if i == 0 {
s = z[j]
} else {
s = NewWire()
s = compiler.Calloc.Wire()
nsums = append(nsums, s)
}

Expand All @@ -102,14 +102,14 @@ func NewArrayMultiplier(compiler *Compiler, x, y, z []*Wire) error {
// Construct final layer.
var c *Wire
for i, xn := range x {
and := NewWire()
and := compiler.Calloc.Wire()
compiler.AddGate(NewBinary(circuit.AND, xn, y[j], and))

var cout *Wire
if i+1 >= len(x) && j+i+1 < len(z) {
cout = z[j+i+1]
} else {
cout = NewWire()
cout = compiler.Calloc.Wire()
}

if j+i < len(z) {
Expand Down Expand Up @@ -169,42 +169,42 @@ func NewKaratsubaMultiplier(cc *Compiler, limit int, a, b, r []*Wire) error {
bLow := b[:mid]
bHigh := b[mid:]

z0 := MakeWires(types.Size(min(max(len(aLow), len(bLow))*2, len(r))))
z0 := cc.Calloc.Wires(types.Size(min(max(len(aLow), len(bLow))*2, len(r))))
if err := NewKaratsubaMultiplier(cc, limit, aLow, bLow, z0); err != nil {
return err
}
aSumLen := max(len(aLow), len(aHigh)) + 1
aSum := MakeWires(types.Size(aSumLen))
aSum := cc.Calloc.Wires(types.Size(aSumLen))
if err := NewAdder(cc, aLow, aHigh, aSum); err != nil {
return err
}
bSumLen := max(len(bLow), len(bHigh)) + 1
bSum := MakeWires(types.Size(bSumLen))
bSum := cc.Calloc.Wires(types.Size(bSumLen))
if err := NewAdder(cc, bLow, bHigh, bSum); err != nil {
return err
}
z1 := MakeWires(types.Size(min(max(aSumLen, bSumLen)*2, len(r))))
z1 := cc.Calloc.Wires(types.Size(min(max(aSumLen, bSumLen)*2, len(r))))
if err := NewKaratsubaMultiplier(cc, limit, aSum, bSum, z1); err != nil {
return err
}
z2 := MakeWires(types.Size(min(max(len(aHigh), len(bHigh))*2, len(r))))
z2 := cc.Calloc.Wires(types.Size(min(max(len(aHigh), len(bHigh))*2, len(r))))
if err := NewKaratsubaMultiplier(cc, limit, aHigh, bHigh, z2); err != nil {
return err
}

sub1 := MakeWires(types.Size(len(r)))
sub1 := cc.Calloc.Wires(types.Size(len(r)))
if err := NewSubtractor(cc, z1, z2, sub1); err != nil {
return err
}
sub2 := MakeWires(types.Size(len(r)))
sub2 := cc.Calloc.Wires(types.Size(len(r)))
if err := NewSubtractor(cc, sub1, z0, sub2); err != nil {
return err
}

shift1 := cc.ShiftLeft(z2, len(r), mid*2)
shift2 := cc.ShiftLeft(sub2, len(r), mid)

add1 := MakeWires(types.Size(len(r)))
add1 := cc.Calloc.Wires(types.Size(len(r)))
if err := NewAdder(cc, shift1, shift2, add1); err != nil {
return err
}
Expand Down
6 changes: 3 additions & 3 deletions compiler/circuits/circ_mux.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright (c) 2020 Markku Rossi
// Copyright (c) 2020-2023 Markku Rossi
//
// All rights reserved.
//
Expand All @@ -22,8 +22,8 @@ func NewMUX(compiler *Compiler, cond, t, f, out []*Wire) error {
}

for i := 0; i < len(t); i++ {
w1 := NewWire()
w2 := NewWire()
w1 := compiler.Calloc.Wire()
w2 := compiler.Calloc.Wire()

// w1 = XOR(f[i], t[i])
compiler.AddGate(NewBinary(circuit.XOR, f[i], t[i], w1))
Expand Down
Loading

0 comments on commit b4486b0

Please sign in to comment.