Commit 505e337c authored by Anders Jensen Løvig's avatar Anders Jensen Løvig
Browse files

Merge branch 'dev-thomas' into dev-anders

parents 5cc707fb 65481fd8
package main
import (
"crycomp/internal/blood"
"crycomp/internal/crypto/homomorphic"
"crycomp/internal/crypto/util"
"crypto/rand"
"fmt"
"math/big"
)
func main() {
bloodA, bloodB := blood.Type_ABn, blood.Type_ABn
z, err := RunProtocol(bloodA, bloodB)
if err != nil {
fmt.Println("Protocol failed with error:", err)
} else if z == blood.Table[bloodA][bloodB] {
fmt.Println("Protocol succeded")
} else {
fmt.Printf("Protocol failed, output was %t, but should be %t", z, blood.Table[bloodA][bloodB])
}
}
type Party struct {
conn chan *big.Int
}
func (alice *Party) RunAlice(x int, priv *homomorphic.PrivateKey) (result bool, err error) {
xval := make([]int, 3)
//Negate values
for i, val := range util.Int2Bools(x, 3) {
if !val {
xval[i] = 1
}
}
// Send encoded input ints to bob
for i := 0; i < 3; i++ {
alice.conn <- homomorphic.Encrypt(xval[i], &priv.PublicKey)
// alice.conn <- *alice.HEProt.Encode(xval[i])
}
//Receive and decode result from bob
result = homomorphic.Decrypt(<-alice.conn, priv) == 1 //Convert 1 -> true
// result = alice.HEProt.Decode(<-alice.conn, *alice.sKey) == 1 //Convert 1 -> true
return
}
func (bob *Party) RunBob(y int, pub *homomorphic.PublicKey) (err error) {
c_y := make([]*big.Int, 3)
for i, val := range util.Int2Bools(y, 3) {
bit := 0
if val {
bit = 1
}
c_y[i] = homomorphic.Encrypt(bit, pub)
// c_y[i] = bob.HEProt.Encode(bit)
}
//Receive ciphertexts from alice
c_x := make([]*big.Int, 3)
for i := range c_x {
c_x[i] = <-bob.conn
}
bob.conn <- homomorphic.Evaluate(c_x, c_y, pub)
// bob.conn <- *bob.HEProt.Eval(c_x, c_y)
return nil
}
// RunProtocol runs the protocol between receiving blood type x and donor blood
// type y.
func RunProtocol(x, y int) (z bool, err error) {
conn := make(chan *big.Int)
Alice := &Party{conn}
Bob := &Party{conn}
privKey, err := homomorphic.GenerateKey(rand.Reader, 2000, 100000, 60, 2000)
if err != nil {
return
}
// Concurrently run Bob
go func() {
err := Bob.RunBob(y, &privKey.PublicKey)
if err != nil {
panic(err) // TODO do not panic
}
}()
z, err = Alice.RunAlice(x, privKey)
return
}
package main
import (
"crycomp/internal/blood"
"fmt"
"testing"
)
func TestBloodTable(t *testing.T) {
// Check the dimensions of BloodTable.
if len(blood.Table) != 8 {
t.Fatalf("Expected 8 rows, got %d", len(blood.Table))
}
for i := range blood.Table {
if len(blood.Table[i]) != 8 {
t.Fatalf("Expected columns in row %d, got %d", i, len(blood.Table))
}
}
}
func TestProtocol(t *testing.T) {
// Runs the protocol for all combinations of recipient and donor blood types.
n := len(blood.Table)
for x := 0; x < n; x++ {
for y := 0; y < n; y++ {
testName := fmt.Sprintf("(x=%s,y=%s)", blood.Names[x], blood.Names[y])
t.Run(testName, func(t *testing.T) {
z, err := RunProtocol(x, y)
if err != nil {
t.Errorf("Protocol error: %s", err)
} else if z != blood.Table[x][y] {
t.Fatalf("Failed blood compatibility test for index [%d,%d]. Expected %t, got %t", x, y, !z, z)
}
})
}
}
}
...@@ -56,7 +56,7 @@ func Encrypt(random io.Reader, pub *PublicKey, msg []byte) (c1, c2 *big.Int, err ...@@ -56,7 +56,7 @@ func Encrypt(random io.Reader, pub *PublicKey, msg []byte) (c1, c2 *big.Int, err
} }
m = encodeMessage(pub, m) m = encodeMessage(pub, m)
r, err := util.RandInt(random, pub.Q) r, err := util.RandIntn(random, pub.Q)
if err != nil { if err != nil {
return return
} }
......
package homomorphic
import (
"crycomp/internal/crypto/util"
"io"
"math/big"
mRand "math/rand"
)
var two = big.NewInt(2)
type Params struct {
pLen int
qLen int
rLen int
n int
}
func NewParams(pLen, qLen, rLen, m int) *Params {
return &Params{
pLen: pLen,
qLen: qLen,
rLen: rLen,
n: m,
}
}
type PublicKey struct {
y []*big.Int
n int
}
type PrivateKey struct {
PublicKey
p *big.Int
}
func GenerateKey(random io.Reader, pLen, qLen, rLen, n int) (priv *PrivateKey, err error) {
// Chose a random big secret odd integer p.
p, err := util.RandIntk(random, pLen)
if err != nil {
return
}
p.SetBit(p, 0, 1) // Make p odd.
y := make([]*big.Int, n)
var q *big.Int
var r *big.Int
for i := 0; i < n; i++ {
q, err = util.RandIntk(random, qLen)
if err != nil {
return
}
r, err = util.RandIntk(random, rLen)
if err != nil {
return
}
y[i] = q.Mul(p, q).Add(q, r.Mul(r, two))
}
priv = &PrivateKey{
PublicKey: PublicKey{
y: y,
n: n,
},
p: p,
}
return
}
func Encrypt(m int, pub *PublicKey) (c *big.Int) {
S := make([]int, pub.n)
for i := 0; i < pub.n; i++ {
S[i] = i
}
// TODO crypto rand
mRand.Shuffle(pub.n, func(i, j int) { S[i], S[j] = S[j], S[i] })
S = S[:pub.n]
c = big.NewInt(int64(m))
for i := range S {
c = c.Add(c, pub.y[S[i]])
}
return
}
func Decrypt(c *big.Int, priv *PrivateKey) int {
m := new(big.Int).Mod(c, priv.p)
m.Mod(m, two)
return int(m.Int64())
}
func Evaluate(x, y []*big.Int, pub *PublicKey) (result *big.Int) {
one := Encrypt(1, pub)
tmp := make([]*big.Int, 3)
for i := 0; i < 3; i++ {
v := new(big.Int).Mul(x[i], y[i])
tmp[i] = v.Add(v, one)
}
result = new(big.Int).Mul(tmp[0], tmp[1])
result.Mul(result, tmp[2])
return
}
...@@ -21,7 +21,7 @@ type Encryption struct { ...@@ -21,7 +21,7 @@ type Encryption struct {
// using elgamal.GenerateKey. The way the key is generated the corresponding // using elgamal.GenerateKey. The way the key is generated the corresponding
// private key is unknown. // private key is unknown.
func oGenElgamel(random io.Reader, params *group.Params) (pub *elgamal.PublicKey, err error) { func oGenElgamel(random io.Reader, params *group.Params) (pub *elgamal.PublicKey, err error) {
s, err := util.RandInt(random, params.P) s, err := util.RandIntn(random, params.P)
if err != nil { if err != nil {
return return
} }
......
...@@ -42,8 +42,8 @@ func XOR(a, b []byte) (dst []byte) { ...@@ -42,8 +42,8 @@ func XOR(a, b []byte) (dst []byte) {
var one = big.NewInt(1) var one = big.NewInt(1)
// RandInt returns a random integer in the range [1, n). // RandIntn returns a random integer in the range [1, n).
func RandInt(random io.Reader, n *big.Int) (r *big.Int, err error) { func RandIntn(random io.Reader, n *big.Int) (r *big.Int, err error) {
tmp := new(big.Int).Set(n) tmp := new(big.Int).Set(n)
tmp.Sub(tmp, one) tmp.Sub(tmp, one)
...@@ -56,6 +56,25 @@ func RandInt(random io.Reader, n *big.Int) (r *big.Int, err error) { ...@@ -56,6 +56,25 @@ func RandInt(random io.Reader, n *big.Int) (r *big.Int, err error) {
return return
} }
// RandIntk returns a random k-bit integer.
func RandIntk(random io.Reader, k int) (r *big.Int, err error) {
// Calculate how many bytes are needed to have k bits.
bLen := (k + 7) / 8
// Fill bytes with random data
bytes := make([]byte, bLen)
_, err = io.ReadFull(random, bytes)
if err != nil {
return
}
// Clear the bits that exceed k bits
bytes[0] &= 0xff >> (8*len(bytes) - k)
r = new(big.Int).SetBytes(bytes)
// Set the k-1 bit. This ensures a k-bits integer
// and the distribution is maintained (all other bits are random)
r.SetBit(r, k-1, 1)
return
}
type cryptoSource [8]byte type cryptoSource [8]byte
func Perm(n int) []int { func Perm(n int) []int {
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment