Skip to content

Commit

Permalink
new fmul
Browse files Browse the repository at this point in the history
  • Loading branch information
zhdllwyc committed Aug 30, 2022
1 parent 3aa5521 commit f1c4562
Show file tree
Hide file tree
Showing 3 changed files with 484 additions and 0 deletions.
234 changes: 234 additions & 0 deletions tss/ecdsa/ot/fmul/fmulLocal.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,234 @@
package fmul

import (
"crypto/rand"
"math/big"
"sync"

"github.com/cloudflare/circl/group"
"github.com/cloudflare/circl/ot/simot"
"golang.org/x/sync/errgroup"
)

// ---- Sender Initialization ----

// Input: myGroup, the group we operate in
// Input: a, the sender private input
// Input: n, the total number of SimOT
// Output: Array of A=[ai]G for n SimOT
func (sender *SenderFmul) SenderInit(myGroup group.Group, a group.Scalar, n int) []group.Element {
sender.myGroup = myGroup
sender.a = a.Copy()
sender.deltas = make([]group.Scalar, n)
sender.m0s = make([][]byte, n)
sender.m1s = make([][]byte, n)
sender.simOTsenders = make([]simot.SenderSimOT, n)

var fmulWait sync.WaitGroup
fmulWait.Add(n)
for i := 0; i < n; i++ {
go func(index int) {
defer fmulWait.Done()
sender.deltas[index] = myGroup.RandomNonZeroScalar(rand.Reader)
m0iScalar := myGroup.NewScalar()
m0iScalar.Sub(sender.deltas[index], sender.a)

m0iByte, err := m0iScalar.MarshalBinary()
if err != nil {
panic(err)
}
sender.m0s[index] = m0iByte

m1iScalar := myGroup.NewScalar()
m1iScalar.Add(sender.deltas[index], sender.a)

m1iByte, err := m1iScalar.MarshalBinary()
if err != nil {
panic(err)
}
sender.m1s[index] = m1iByte

// n Sim OT Sender Initialization
var simOTSender simot.SenderSimOT
simOTSender.InitSender(myGroup, sender.m0s[index], sender.m1s[index], index)
sender.simOTsenders[index] = simOTSender
}(i)
}
fmulWait.Wait()

sender.s1 = myGroup.NewScalar()
sender.s1.SetUint64(0)

As := make([]group.Element, n)
for i := 0; i < n; i++ {
As[i] = sender.simOTsenders[i].A.Copy()
}
return As
}

// ---- Round1: Sender sends As to receiver ----

// Receiver randomly generates n choice bits, either 0 or 1 for SimOT, either -1(Scalar) or 1(Scalar) for Fmul
// Matching 0 or 1 to -1(Scalar) or 1(Scalar) in constant time
// Input: myGroup, the group we operate in
// Input: As, the n [ai]G received from sender
// Input: b, the receiver private input
// Input: n, the total number of SimOT
// Output: Array of B = [b]G if c == 0, B = A+[b]G if c == 1
func (receiver *ReceiverFmul) ReceiverRound1(myGroup group.Group, As []group.Element, b group.Scalar, n int) []group.Element {
receiver.myGroup = myGroup
receiver.b = b.Copy()
receiver.ts = make([]int, n)
receiver.tsScalar = make([]group.Scalar, n)
receiver.zs = make([]group.Scalar, n)
receiver.vs = make([]group.Scalar, n)

Scalar1 := myGroup.NewScalar()
Scalar1.SetUint64(1)
Scalar1.Neg(Scalar1)

receiver.simOTreceivers = make([]simot.ReceiverSimOT, n)

var fmulWait sync.WaitGroup
fmulWait.Add(n)
for i := 0; i < n; i++ {
go func(index int) {
defer fmulWait.Done()
currScalar := myGroup.NewScalar()
binaryBig, err := rand.Int(rand.Reader, big.NewInt(2))
if err != nil {
panic(err)
}
receiver.ts[index] = int(binaryBig.Int64())
currScalar.SetUint64(uint64(2 * receiver.ts[index]))
currScalar.Neg(currScalar)
receiver.tsScalar[index] = Scalar1.Copy()
receiver.tsScalar[index].Sub(receiver.tsScalar[index], currScalar)
receiver.zs[index] = myGroup.NewScalar()
receiver.simOTreceivers[index].Round1Receiver(myGroup, receiver.ts[index], index, As[index])
}(i)
}
fmulWait.Wait()

receiver.s2 = myGroup.NewScalar()
receiver.s2.SetUint64(0)

Bs := make([]group.Element, n)
for i := 0; i < n; i++ {
Bs[i] = receiver.simOTreceivers[i].B.Copy()
}
return Bs
}

// ---- Round 2: Receiver sends Bs = [bi]G or Ai+[bi]G to sender ----

// Input: Bs, the n [bi]G or Ai+[bi]G received from receiver
// Input: n, the total number of SimOT
// Output: Array of m0s encryptions and m1s encryptions
func (sender *SenderFmul) SenderRound2(Bs []group.Element, n int) ([][]byte, [][]byte) {
var fmulWait sync.WaitGroup
fmulWait.Add(n)
for i := 0; i < n; i++ {
go func(index int) {
defer fmulWait.Done()
sender.simOTsenders[index].Round2Sender(Bs[index])
}(i)
}
fmulWait.Wait()

e0s := make([][]byte, n)
e1s := make([][]byte, n)
for i := 0; i < n; i++ {
e0s[i], e1s[i] = sender.simOTsenders[i].Returne0e1()
}

return e0s, e1s
}

// ---- Round 3: Sender sends e0s, e1s to receiver ----

// Input: e0s, e1s, the encryptions of m0s and m1s
// Input: n, the total number of SimOT
// Ouptut: Blinding sigma and Array of v
func (receiver *ReceiverFmul) ReceiverRound3(e0s, e1s [][]byte, n int) (group.Scalar, []group.Scalar, error) {
var errGroup errgroup.Group
receiver.s2.SetUint64(0)

for i := 0; i < n; i++ {
func(index int) {
errGroup.Go(func() error {
errDec := receiver.simOTreceivers[index].Round3Receiver(e0s[index], e1s[index], receiver.ts[index])
if errDec != nil {
return errDec
}
mc := receiver.simOTreceivers[index].Returnmc()
errByte := receiver.zs[index].UnmarshalBinary(mc)
if errByte != nil {
panic(errByte)
}
return nil
})
}(i)
}

if err := errGroup.Wait(); err != nil {
return nil, nil, err
}

// v \times t = b
vn := receiver.b.Copy()
for i := 0; i < n-1; i++ {
receiver.vs[i] = receiver.myGroup.RandomNonZeroScalar(rand.Reader)
vt := receiver.myGroup.NewScalar()
vt.Mul(receiver.tsScalar[i], receiver.vs[i])
vn.Sub(vn, vt)
}
tsnInv := receiver.myGroup.NewScalar()
tsnInv.Inv(receiver.tsScalar[n-1])
vn.Mul(vn, tsnInv)
receiver.vs[n-1] = vn
receiver.sigma = receiver.myGroup.RandomNonZeroScalar(rand.Reader)

for i := 0; i < n; i++ {
vzi := receiver.myGroup.NewScalar()
vzi.Mul(receiver.vs[i], receiver.zs[i])
receiver.s2.Add(receiver.s2, vzi)
}

// s2 = v \times z + sigma
receiver.s2.Add(receiver.s2, receiver.sigma)

sigma := receiver.sigma.Copy()
vs := make([]group.Scalar, n)
for i := 0; i < n; i++ {
vs[i] = receiver.vs[i].Copy()
}

return sigma, vs, nil
}

// ---- Round 4: receiver sends sigma as well as vs to sender ----

// Input: vs, from receiver
// Input: sigma, blinding from receiver
// Input: n, the total number of SimOT
func (sender *SenderFmul) SenderRound4(vs []group.Scalar, sigma group.Scalar, n int) {
sender.s1.SetUint64(0)

vdelta := sender.myGroup.NewScalar()

// s1 = - v \times delta - sigma
for i := 0; i < n; i++ {
vdelta.Mul(vs[i], sender.deltas[i])
sender.s1.Sub(sender.s1, vdelta)
}
sender.s1.Sub(sender.s1, sigma)
}

func (sender *SenderFmul) Returns1() group.Scalar {
return sender.s1
}

func (receiver *ReceiverFmul) Returns2() group.Scalar {
return receiver.s2
}
28 changes: 28 additions & 0 deletions tss/ecdsa/ot/fmul/fmulParty.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package fmul

import (
"github.com/cloudflare/circl/group"
"github.com/cloudflare/circl/ot/simot"
)

type SenderFmul struct {
a group.Scalar // The input of the sender
deltas []group.Scalar // The n random of the sender
m0s [][]byte // The n m0 messages of the sender
m1s [][]byte // The n m1 messages of the sender
simOTsenders []simot.SenderSimOT // The n senders for n simOT
s1 group.Scalar // The final additive share
myGroup group.Group // The elliptic curve we operate in
}

type ReceiverFmul struct {
b group.Scalar // The input of the receiver
ts []int // The n choice bits of the receiver, either 0 or 1
tsScalar []group.Scalar // The scalar version of n choice bits, either -1 or 1
zs []group.Scalar // The n OT transferred messages from the sender
vs []group.Scalar // The n random of the receiver such that v*t = b
sigma group.Scalar // The blinding scalar
simOTreceivers []simot.ReceiverSimOT // The n receivers for n simOT
s2 group.Scalar // The final additive share
myGroup group.Group // The elliptic curve we operate in
}
Loading

0 comments on commit f1c4562

Please sign in to comment.