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
191 lines
3.4 KiB
Go
191 lines
3.4 KiB
Go
//
|
|
// ferret.go
|
|
//
|
|
// Copyright (c) 2024-2025 Quilibrium, Inc.
|
|
//
|
|
// All rights reserved.
|
|
//
|
|
|
|
package ot
|
|
|
|
import (
|
|
"encoding/binary"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"github.com/pkg/errors"
|
|
"source.quilibrium.com/quilibrium/monorepo/ferret"
|
|
)
|
|
|
|
var (
|
|
bo = binary.BigEndian
|
|
_ OT = &Ferret{}
|
|
)
|
|
|
|
// Ferret implements FERRET OT as the OT interface.
|
|
type Ferret struct {
|
|
party uint8
|
|
address string
|
|
io IO
|
|
}
|
|
|
|
// NewFerret creates a new FERRET OT implementing the OT interface.
|
|
func NewFerret(party uint8, address string) *Ferret {
|
|
return &Ferret{
|
|
party: party,
|
|
address: address,
|
|
io: nil,
|
|
}
|
|
}
|
|
|
|
// InitSender initializes the OT sender.
|
|
func (ferret *Ferret) InitSender(io IO) error {
|
|
ferret.io = io
|
|
return nil
|
|
}
|
|
|
|
// InitReceiver initializes the OT receiver.
|
|
func (ferret *Ferret) InitReceiver(io IO) error {
|
|
ferret.io = io
|
|
return nil
|
|
}
|
|
|
|
func xor(a, b []byte) []byte {
|
|
l := len(a)
|
|
if len(b) < l {
|
|
l = len(b)
|
|
}
|
|
for i := 0; i < l; i++ {
|
|
a[i] ^= b[i]
|
|
}
|
|
return a[:l]
|
|
}
|
|
|
|
// Send sends the wire labels with OT.
|
|
func (f *Ferret) Send(wires []Wire) error {
|
|
wiresCnt := len(wires)
|
|
errch := make(chan error)
|
|
portStr := strings.Split(f.address, ":")[1]
|
|
addr := strings.Split(f.address, ":")[0]
|
|
port, err := strconv.ParseInt(portStr, 10, 0)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
go func() {
|
|
alice, err := ferret.NewFerretOT(
|
|
1,
|
|
addr,
|
|
int(port),
|
|
1,
|
|
uint64(wiresCnt),
|
|
make([]bool, 0),
|
|
true,
|
|
)
|
|
if err != nil {
|
|
errch <- errors.Wrap(err, "send")
|
|
return
|
|
}
|
|
|
|
alice.SendCOT()
|
|
alice.SendROT()
|
|
|
|
// Transfer the random values to wire labels
|
|
for i := 0; i < wiresCnt; i++ {
|
|
// Get block data for label 0 and label 1
|
|
l0Data := alice.SenderGetBlockData(false, uint64(i))
|
|
l1Data := alice.SenderGetBlockData(true, uint64(i))
|
|
var labelData LabelData
|
|
|
|
wires[i].L0.GetData(&labelData)
|
|
e0 := xor(l0Data, labelData[:])
|
|
if err := f.io.SendData(e0); err != nil {
|
|
errch <- err
|
|
return
|
|
}
|
|
wires[i].L1.GetData(&labelData)
|
|
e1 := xor(l1Data, labelData[:])
|
|
if err := f.io.SendData(e1); err != nil {
|
|
errch <- err
|
|
return
|
|
}
|
|
}
|
|
errch <- nil
|
|
}()
|
|
|
|
err = <-errch
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := f.io.Flush(); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// Receive receives the wire labels with OT based on the flag values.
|
|
func (f *Ferret) Receive(flags []bool, result []Label) error {
|
|
flagsCnt := len(flags)
|
|
|
|
errch := make(chan error)
|
|
|
|
portStr := strings.Split(f.address, ":")[1]
|
|
addr := strings.Split(f.address, ":")[0]
|
|
port, err := strconv.ParseInt(portStr, 10, 0)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
go func() {
|
|
bob, err := ferret.NewFerretOT(2, addr, int(port), 1, uint64(flagsCnt), flags, true)
|
|
if err != nil {
|
|
errch <- errors.Wrap(err, "receive")
|
|
return
|
|
}
|
|
|
|
bob.RecvCOT()
|
|
bob.RecvROT()
|
|
|
|
for i := 0; i < flagsCnt; i++ {
|
|
data := bob.ReceiverGetBlockData(uint64(i))
|
|
|
|
var e []byte
|
|
if flags[i] {
|
|
_, err = f.io.ReceiveData()
|
|
if err != nil {
|
|
errch <- err
|
|
return
|
|
}
|
|
e, err := f.io.ReceiveData()
|
|
if err != nil {
|
|
errch <- err
|
|
return
|
|
}
|
|
data = xor(data, e)
|
|
} else {
|
|
e, err = f.io.ReceiveData()
|
|
if err != nil {
|
|
errch <- err
|
|
return
|
|
}
|
|
data = xor(data, e)
|
|
_, err := f.io.ReceiveData()
|
|
if err != nil {
|
|
errch <- err
|
|
return
|
|
}
|
|
}
|
|
result[i].SetBytes(data)
|
|
}
|
|
errch <- nil
|
|
}()
|
|
|
|
err = <-errch
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|