mirror of
https://github.com/QuilibriumNetwork/ceremonyclient.git
synced 2026-02-21 10:27:26 +08:00
* v2.1.0 [omit consensus and adjacent] - this commit will be amended with the full release after the file copy is complete * 2.1.0 main node rollup
97 lines
1.9 KiB
Go
97 lines
1.9 KiB
Go
//
|
|
// circ_adder.go
|
|
//
|
|
// Copyright (c) 2019-2023 Markku Rossi
|
|
//
|
|
// All rights reserved.
|
|
//
|
|
|
|
package circuits
|
|
|
|
import (
|
|
"source.quilibrium.com/quilibrium/monorepo/bedlam/circuit"
|
|
)
|
|
|
|
// NewHalfAdder creates a half adder circuit.
|
|
func NewHalfAdder(cc *Compiler, a, b, s, c *Wire) {
|
|
// S = XOR(A, B)
|
|
cc.AddGate(cc.Calloc.BinaryGate(circuit.XOR, a, b, s))
|
|
|
|
if c != nil {
|
|
// C = AND(A, B)
|
|
cc.AddGate(cc.Calloc.BinaryGate(circuit.AND, a, b, c))
|
|
}
|
|
}
|
|
|
|
// NewFullAdder creates a full adder circuit
|
|
func NewFullAdder(cc *Compiler, a, b, cin, s, cout *Wire) {
|
|
w1 := cc.Calloc.Wire()
|
|
w2 := cc.Calloc.Wire()
|
|
w3 := cc.Calloc.Wire()
|
|
|
|
// s = a XOR b XOR cin
|
|
// cout = cin XOR ((a XOR cin) AND (b XOR cin)).
|
|
|
|
// w1 = XOR(b, cin)
|
|
cc.AddGate(cc.Calloc.BinaryGate(circuit.XOR, b, cin, w1))
|
|
|
|
// s = XOR(a, w1)
|
|
cc.AddGate(cc.Calloc.BinaryGate(circuit.XOR, a, w1, s))
|
|
|
|
if cout != nil {
|
|
// w2 = XOR(a, cin)
|
|
cc.AddGate(cc.Calloc.BinaryGate(circuit.XOR, a, cin, w2))
|
|
|
|
// w3 = AND(w1, w2)
|
|
cc.AddGate(cc.Calloc.BinaryGate(circuit.AND, w1, w2, w3))
|
|
|
|
// cout = XOR(cin, w3)
|
|
cc.AddGate(cc.Calloc.BinaryGate(circuit.XOR, cin, w3, cout))
|
|
}
|
|
}
|
|
|
|
// NewAdder creates a new adder circuit implementing z=x+y.
|
|
func NewAdder(cc *Compiler, x, y, z []*Wire) error {
|
|
x, y = cc.ZeroPad(x, y)
|
|
if len(x) > len(z) {
|
|
x = x[0:len(z)]
|
|
y = y[0:len(z)]
|
|
}
|
|
|
|
if len(x) == 1 {
|
|
var cin *Wire
|
|
if len(z) > 1 {
|
|
cin = z[1]
|
|
}
|
|
NewHalfAdder(cc, x[0], y[0], z[0], cin)
|
|
} else {
|
|
cin := cc.Calloc.Wire()
|
|
NewHalfAdder(cc, x[0], y[0], z[0], cin)
|
|
|
|
for i := 1; i < len(x); i++ {
|
|
var cout *Wire
|
|
if i+1 >= len(x) {
|
|
if i+1 >= len(z) {
|
|
// N+N=N, overflow, drop carry bit.
|
|
cout = nil
|
|
} else {
|
|
cout = z[len(x)]
|
|
}
|
|
} else {
|
|
cout = cc.Calloc.Wire()
|
|
}
|
|
|
|
NewFullAdder(cc, x[i], y[i], cin, z[i], cout)
|
|
|
|
cin = cout
|
|
}
|
|
}
|
|
|
|
// Set all leftover bits to zero.
|
|
for i := len(x) + 1; i < len(z); i++ {
|
|
z[i] = cc.ZeroWire()
|
|
}
|
|
|
|
return nil
|
|
}
|