Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fmul #373

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open

Fmul #373

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions go.mod
Expand Up @@ -5,5 +5,6 @@ go 1.16
require (
github.com/bwesterb/go-ristretto v1.2.2
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 // indirect
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10
)
2 changes: 2 additions & 0 deletions go.sum
Expand Up @@ -3,6 +3,8 @@ github.com/bwesterb/go-ristretto v1.2.2/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7N
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa h1:zuSxTR4o9y82ebqCUJYNGJbGPo6sKVl54f/TVDObg1c=
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 h1:uVc8UZUe6tr40fFVnUP5Oj+veunVezqYl9z7DYw9xzw=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
Expand Down
231 changes: 231 additions & 0 deletions ot/simot/simot_test.go
@@ -0,0 +1,231 @@
// Reference: https://eprint.iacr.org/2015/267.pdf (1 out of 2 OT case)
// Sender has 2 messages m0, m1
// Receiver receives mc based on the choice bit c

package simot

import (
"bytes"
"crypto/rand"
"testing"

"github.com/cloudflare/circl/group"
)

const testSimOTCount = 100

func simOT(myGroup group.Group, sender *SenderSimOT, receiver *ReceiverSimOT, m0, m1 []byte, choice, index int) error {
// Initialization
A := sender.InitSender(myGroup, m0, m1, index)

// Round 1
// Sender sends A to receiver
B := receiver.Round1Receiver(myGroup, choice, index, A)

// Round 2
// Receiver sends B to sender
e0, e1 := sender.Round2Sender(B)

// Round 3
// Sender sends e0 e1 to receiver
errDec := receiver.Round3Receiver(e0, e1, receiver.c)
if errDec != nil {
return errDec
}

return nil
}

func testNegativeSimOT(t *testing.T, myGroup group.Group, choice int) {
var sender SenderSimOT
var receiver ReceiverSimOT
m0 := make([]byte, myGroup.Params().ScalarLength)
m1 := make([]byte, myGroup.Params().ScalarLength)
_, errRand := rand.Read(m0)
if errRand != nil {
panic(errRand)
}
_, errRand = rand.Read(m1)
if errRand != nil {
panic(errRand)
}

// Initialization
A := sender.InitSender(myGroup, m0, m1, 0)

// Round 1
B := receiver.Round1Receiver(myGroup, choice, 0, A)

// Round 2
e0, e1 := sender.Round2Sender(B)
// Round 3

// Here we pass in the flipped choice bit, to prove the decryption will fail
// The receiver will not learn anything about m_{1-c}
errDec := receiver.Round3Receiver(e0, e1, 1-choice)
if errDec == nil {
t.Error("SimOT decryption failed", errDec)
}

if choice == 0 {
equal0 := bytes.Compare(sender.m0, receiver.mc)
if equal0 == 0 {
t.Error("Receiver decryption should fail")
}
equal1 := bytes.Compare(sender.m1, receiver.mc)
if equal1 == 0 {
t.Error("Receiver decryption should fail")
}
} else {
equal0 := bytes.Compare(sender.m0, receiver.mc)
if equal0 == 0 {
t.Error("Receiver decryption should fail")
}
equal1 := bytes.Compare(sender.m1, receiver.mc)
if equal1 == 0 {
t.Error("Receiver decryption should fail")
}
}
}

// Input: myGroup, the group we operate in
func testSimOT(t *testing.T, myGroup group.Group, choice int) {
var sender SenderSimOT
var receiver ReceiverSimOT

m0 := make([]byte, myGroup.Params().ScalarLength)
m1 := make([]byte, myGroup.Params().ScalarLength)
_, errRand := rand.Read(m0)
if errRand != nil {
panic(errRand)
}
_, errRand = rand.Read(m1)
if errRand != nil {
panic(errRand)
}

errDec := simOT(myGroup, &sender, &receiver, m0, m1, choice, 0)
if errDec != nil {
t.Error("AES GCM Decryption failed")
}

if choice == 0 {
equal0 := bytes.Compare(sender.m0, receiver.mc)
if equal0 != 0 {
t.Error("Receiver decryption failed")
}
} else {
equal1 := bytes.Compare(sender.m1, receiver.mc)
if equal1 != 0 {
t.Error("Receiver decryption failed")
}
}
}

func benchmarSimOT(b *testing.B, myGroup group.Group) {
var sender SenderSimOT
var receiver ReceiverSimOT
m0 := make([]byte, myGroup.Params().ScalarLength)
m1 := make([]byte, myGroup.Params().ScalarLength)
_, errRand := rand.Read(m0)
if errRand != nil {
panic(errRand)
}
_, errRand = rand.Read(m1)
if errRand != nil {
panic(errRand)
}

for iter := 0; iter < b.N; iter++ {
errDec := simOT(myGroup, &sender, &receiver, m0, m1, iter%2, 0)
if errDec != nil {
b.Error("AES GCM Decryption failed")
}
}
}

func benchmarkSimOTRound(b *testing.B, myGroup group.Group) {
var sender SenderSimOT
var receiver ReceiverSimOT
m0 := make([]byte, myGroup.Params().ScalarLength)
m1 := make([]byte, myGroup.Params().ScalarLength)
_, errRand := rand.Read(m0)
if errRand != nil {
panic(errRand)
}
_, errRand = rand.Read(m1)
if errRand != nil {
panic(errRand)
}

b.Run("Sender-Initialization", func(b *testing.B) {
for i := 0; i < b.N; i++ {
sender.InitSender(myGroup, m0, m1, 0)
}
})

A := sender.InitSender(myGroup, m0, m1, 0)

b.Run("Receiver-Round1", func(b *testing.B) {
for i := 0; i < b.N; i++ {
receiver.Round1Receiver(myGroup, 0, 0, A)
}
})

B := receiver.Round1Receiver(myGroup, 0, 0, A)

b.Run("Sender-Round2", func(b *testing.B) {
for i := 0; i < b.N; i++ {
sender.Round2Sender(B)
}
})

e0, e1 := sender.Round2Sender(B)

b.Run("Receiver-Round3", func(b *testing.B) {
for i := 0; i < b.N; i++ {
errDec := receiver.Round3Receiver(e0, e1, receiver.c)
if errDec != nil {
b.Error("Receiver-Round3 decryption failed")
}
}
})

errDec := receiver.Round3Receiver(e0, e1, receiver.c)
if errDec != nil {
b.Error("Receiver-Round3 decryption failed")
}

// Confirm
equal0 := bytes.Compare(sender.m0, receiver.mc)
if equal0 != 0 {
b.Error("Receiver decryption failed")
}
}

func TestSimOT(t *testing.T) {
t.Run("SimOT", func(t *testing.T) {
for i := 0; i < testSimOTCount; i++ {
currGroup := group.P256
choice := i % 2
testSimOT(t, currGroup, choice)
}
})
t.Run("SimOTNegative", func(t *testing.T) {
for i := 0; i < testSimOTCount; i++ {
currGroup := group.P256
choice := i % 2
testNegativeSimOT(t, currGroup, choice)
}
})
}

func BenchmarkSimOT(b *testing.B) {
currGroup := group.P256
benchmarSimOT(b, currGroup)
}

func BenchmarkSimOTRound(b *testing.B) {
currGroup := group.P256
benchmarkSimOTRound(b, currGroup)
}