Commit 65481fd8 authored by Anders Jensen Løvig's avatar Anders Jensen Løvig
Browse files

Reactor dhe

parent 0d4a7015
......@@ -4,6 +4,7 @@ import (
"crycomp/internal/blood"
"crycomp/internal/crypto/homomorphic"
"crycomp/internal/crypto/util"
"crypto/rand"
"fmt"
"math/big"
)
......@@ -21,20 +22,10 @@ func main() {
}
type Party struct {
conn chan big.Int
x int
sKey *big.Int
HEProt homomorphic.Protocol
conn chan *big.Int
}
func NewParty(conn chan big.Int, p homomorphic.Protocol) (*Party, error) {
return &Party{
conn: conn,
HEProt: p,
}, nil
}
func (alice *Party) RunAlice(x int) (result bool, err error) {
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) {
......@@ -45,79 +36,57 @@ func (alice *Party) RunAlice(x int) (result bool, err error) {
// Send encoded input ints to bob
for i := 0; i < 3; i++ {
alice.conn <- *alice.HEProt.Encrypt(xval[i])
alice.conn <- homomorphic.Encrypt(xval[i], &priv.PublicKey)
// alice.conn <- *alice.HEProt.Encode(xval[i])
}
//Receive and decode result from bob
result = alice.HEProt.Decrypt(<-alice.conn, *alice.sKey) == 1 //Convert 1 -> true
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) (err error) {
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] = bob.HEProt.Encrypt(bit)
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 {
val := <-bob.conn
c_x[i] = &val
c_x[i] = <-bob.conn
}
bob.conn <- *bob.HEProt.Eval(c_x, c_y)
bob.conn <- homomorphic.Evaluate(c_x, c_y, pub)
// bob.conn <- *bob.HEProt.Eval(c_x, c_y)
return nil
}
type Protocol struct {
A, B *Party
}
func NewProtocol() (p *Protocol, err error) {
conn := make(chan big.Int)
params := homomorphic.NewParams(200, 100000, 1000000, 200)
sKey, HEp, err := homomorphic.NewProtocol(params)
if err != nil {
return
}
A, err := NewParty(conn, HEp)
if err != nil {
return nil, err
}
A.sKey = sKey
B, err := NewParty(conn, HEp)
if err != nil {
return nil, err
}
p = &Protocol{
A: A,
B: B,
}
return p, nil
}
// RunProtocol runs the protocol between receiving blood type x and donor blood
// type y.
func RunProtocol(x, y int) (z bool, err error) {
p, err := NewProtocol()
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 := p.B.RunBob(y)
err := Bob.RunBob(y, &privKey.PublicKey)
if err != nil {
panic(err) // TODO do not panic
}
}()
z, err = p.A.RunAlice(x)
z, err = Alice.RunAlice(x, privKey)
return
}
......@@ -56,7 +56,7 @@ func Encrypt(random io.Reader, pub *PublicKey, msg []byte) (c1, c2 *big.Int, err
}
m = encodeMessage(pub, m)
r, err := util.RandInt(random, pub.Q)
r, err := util.RandIntn(random, pub.Q)
if err != nil {
return
}
......
package homomorphic
import (
"crypto/rand"
"crycomp/internal/crypto/util"
"io"
"math/big"
mRand "math/rand"
)
var two = big.NewInt(2)
type Params struct {
pLen int
qLen int
rLen int
m int
n int
}
func NewParams(pLen, qLen, rLen, m int) *Params {
......@@ -18,107 +21,86 @@ func NewParams(pLen, qLen, rLen, m int) *Params {
pLen: pLen,
qLen: qLen,
rLen: rLen,
m: m,
n: m,
}
}
type Protocol struct {
pubKey []*big.Int
params *Params
type PublicKey struct {
y []*big.Int
n int
}
// Returns a random integer with the specified bit length.
func randInt(bitLen int) (n *big.Int, err error) {
// Calculate how many bytes are needed to have bitLen bits.
bytesLen := (bitLen + 7) / 8
// Fill bytes with random data
pBytes := make([]byte, bytesLen)
_, err = rand.Read(pBytes)
if err != nil {
return
}
// Clear the bits that exceed bitLen
pBytes[0] &= 0xff >> (8*len(pBytes) - bitLen)
n = new(big.Int).SetBytes(pBytes)
// Set the bitLen-1 bit. This ensures bitLen bits
// and the distribution is maintained (all other bits are random)
n.SetBit(n, bitLen-1, 1)
return
type PrivateKey struct {
PublicKey
p *big.Int
}
func NewProtocol(params *Params) (p *big.Int, pr Protocol, err error) {
// Choose a random big secret odd integer p
p, err = randInt(params.pLen)
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.
// res, err := util.RandInt(rand.Reader, big.NewInt(int64(params.pLen)))
// if err != nil {
// return
// }
// res.SetBit(res, 0, 1)
q := make([]*big.Int, params.m)
r := make([]*big.Int, params.m)
y := make([]*big.Int, params.m)
y := make([]*big.Int, n)
var q *big.Int
var r *big.Int
for i := range q {
q[i], err = rand.Int(rand.Reader, big.NewInt(int64(params.qLen)))
for i := 0; i < n; i++ {
q, err = util.RandIntk(random, qLen)
if err != nil {
return
}
r[i], err = rand.Int(rand.Reader, big.NewInt(int64(params.rLen)))
r, err = util.RandIntk(random, rLen)
if err != nil {
return
}
right := big.NewInt(2)
right.Mul(right, r[i])
left := right.Mul(p, q[i])
y[i] = right.Add(left, right)
y[i] = q.Mul(p, q).Add(q, r.Mul(r, two))
}
pr = Protocol{
pubKey: y,
params: params,
priv = &PrivateKey{
PublicKey: PublicKey{
y: y,
n: n,
},
p: p,
}
return
}
func (p *Protocol) Encrypt(m int) (c *big.Int) {
S := make([]int, p.params.m)
for i := 0; i < p.params.m; i++ {
func Encrypt(m int, pub *PublicKey) (c *big.Int) {
S := make([]int, pub.n)
for i := 0; i < pub.n; i++ {
S[i] = i
}
mRand.Shuffle(p.params.m, func(i, j int) { S[i], S[j] = S[j], S[i] })
S = S[:p.params.m]
// 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, p.pubKey[S[i]])
c = c.Add(c, pub.y[S[i]])
}
return
}
func (p *Protocol) Decrypt(c, sKey big.Int) int {
tmp := c.Mod(&c, &sKey)
m := tmp.Mod(tmp, big.NewInt(2))
func Decrypt(c *big.Int, priv *PrivateKey) int {
m := new(big.Int).Mod(c, priv.p)
m.Mod(m, two)
return int(m.Int64())
}
// Assumes x inputs are negated, so Eval can compute ¬(¬a+b) = a+¬b
func (p *Protocol) Eval(x, y []*big.Int) *big.Int {
one := p.Encrypt(1)
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++ {
xi := x[i]
yi := y[i]
var val big.Int
val.Mul(xi, yi)
val.Add(&val, one)
tmp[i] = &val
v := new(big.Int).Mul(x[i], y[i])
tmp[i] = v.Add(v, one)
}
var res big.Int
res.Mul(tmp[0], tmp[1])
res.Mul(&res, tmp[2])
return &res
result = new(big.Int).Mul(tmp[0], tmp[1])
result.Mul(result, tmp[2])
return
}
......@@ -21,7 +21,7 @@ type Encryption struct {
// using elgamal.GenerateKey. The way the key is generated the corresponding
// private key is unknown.
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 {
return
}
......
......@@ -42,8 +42,8 @@ func XOR(a, b []byte) (dst []byte) {
var one = big.NewInt(1)
// RandInt returns a random integer in the range [1, n).
func RandInt(random io.Reader, n *big.Int) (r *big.Int, err error) {
// RandIntn returns a random integer in the range [1, n).
func RandIntn(random io.Reader, n *big.Int) (r *big.Int, err error) {
tmp := new(big.Int).Set(n)
tmp.Sub(tmp, one)
......@@ -56,6 +56,25 @@ func RandInt(random io.Reader, n *big.Int) (r *big.Int, err error) {
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
func Perm(n int) []int {
......@@ -72,4 +91,4 @@ func (s *cryptoSource) Int63() int64 {
func (s *cryptoSource) Seed(seed int64) {
panic("seed")
}
\ No newline at end of file
}
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