dhe.go 2 KB
Newer Older
Thomas Hoffmann's avatar
Thomas Hoffmann committed
1
2
3
package homomorphic

import (
Thomas Hoffmann's avatar
Fixed    
Thomas Hoffmann committed
4
	"crycomp/internal/crypto/util"
Thomas Hoffmann's avatar
Thomas Hoffmann committed
5
	"crypto/rand"
Thomas Hoffmann's avatar
Fixed    
Thomas Hoffmann committed
6
	"math/big"
Thomas Hoffmann's avatar
Thomas Hoffmann committed
7
8
9
	mRand "math/rand"
)

Thomas Hoffmann's avatar
Fixed    
Thomas Hoffmann committed
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
type Params struct {
	len_sKey int
	len_q int
	len_r int
	m int
}
func NewParams(len_sKey, len_q, len_r, m int) *Params {
	return &Params{
		len_sKey : len_sKey,
		len_q : len_q,
		len_r : len_r,
		m : m,
	}
}

Thomas Hoffmann's avatar
Thomas Hoffmann committed
25
26
type Protocol struct {
	pubKey []*big.Int
Thomas Hoffmann's avatar
Fixed    
Thomas Hoffmann committed
27
	params *Params
Thomas Hoffmann's avatar
Thomas Hoffmann committed
28
29
}

Thomas Hoffmann's avatar
Fixed    
Thomas Hoffmann committed
30
31
32
func NewProtocol(params *Params) (sKey *big.Int, pr Protocol, err error) {
	//set private key to a random odd 2000-bit integer
	res, err := util.RandInt(rand.Reader, big.NewInt(int64(params.len_sKey)))
Thomas Hoffmann's avatar
Thomas Hoffmann committed
33
	if err != nil {return}
Thomas Hoffmann's avatar
Fixed    
Thomas Hoffmann committed
34
35
	res.SetBit(res, 0, 1)
	sKey = res
Thomas Hoffmann's avatar
Thomas Hoffmann committed
36

Thomas Hoffmann's avatar
Fixed    
Thomas Hoffmann committed
37
38
39
	q := make([]*big.Int, params.m)
	r := make([]*big.Int, params.m)
	y := make([]*big.Int, params.m)
Thomas Hoffmann's avatar
Thomas Hoffmann committed
40
41

	for i := range q {
Thomas Hoffmann's avatar
Fixed    
Thomas Hoffmann committed
42
		q[i], err = rand.Int(rand.Reader, big.NewInt(int64(params.len_q)))
Thomas Hoffmann's avatar
Thomas Hoffmann committed
43
		if err != nil {return}
Thomas Hoffmann's avatar
Fixed    
Thomas Hoffmann committed
44
		r[i], err = rand.Int(rand.Reader, big.NewInt(int64(params.len_r)))
Thomas Hoffmann's avatar
Thomas Hoffmann committed
45
46
47
48
49
50
51
52
		if err != nil {return}
		right := big.NewInt(2)
		right.Mul(right,r[i])
		left := right.Mul(sKey,q[i])
		y[i] = right.Add(left, right)
	}
	pr = Protocol{
		pubKey : y,
Thomas Hoffmann's avatar
Fixed    
Thomas Hoffmann committed
53
		params : params,
Thomas Hoffmann's avatar
Thomas Hoffmann committed
54
55
56
57
58
	}
	return sKey, pr, err
}

func (p *Protocol) Encode(m int) (c *big.Int) {
Thomas Hoffmann's avatar
Fixed    
Thomas Hoffmann committed
59
60
	S := make([]int, p.params.m)
	for i := 0; i < p.params.m; i++ {
Thomas Hoffmann's avatar
Thomas Hoffmann committed
61
62
		S[i] = i
	}
Thomas Hoffmann's avatar
Fixed    
Thomas Hoffmann committed
63
	mRand.Shuffle(p.params.m, func(i,j int) {S[i],S[j] = S[j], S[i]})
Thomas Hoffmann's avatar
Thomas Hoffmann committed
64
	S = S[:p.params.m]
Thomas Hoffmann's avatar
Thomas Hoffmann committed
65
66
67
68
69
70
71
	c = big.NewInt(int64(m))
	for i := range S {
		c = c.Add(c, p.pubKey[S[i]])
	}
	return
}

Thomas Hoffmann's avatar
Thomas Hoffmann committed
72
73
func (p *Protocol) Decode(c, sKey big.Int) int {
	tmp:= c.Mod(&c, &sKey)
Thomas Hoffmann's avatar
Thomas Hoffmann committed
74
75
76
77
78
	m := tmp.Mod(tmp, big.NewInt(2))
	return int(m.Int64())
}

// Assumes x inputs are negated, so Eval can compute ¬(¬a+b) = a+¬b 
Thomas Hoffmann's avatar
Thomas Hoffmann committed
79
func (p *Protocol) Eval(x,y []*big.Int) *big.Int {
Thomas Hoffmann's avatar
Thomas Hoffmann committed
80
81
82
	one := p.Encode(1)
	tmp := make([]*big.Int,3)
	for i := 0; i < 3; i++ {
Thomas Hoffmann's avatar
Thomas Hoffmann committed
83
84
85
86
87
88
		xi := x[i]
		yi := y[i]
		var val big.Int
		val.Mul(xi,yi)
		val.Add(&val,one)
		tmp[i] = &val
Thomas Hoffmann's avatar
Thomas Hoffmann committed
89
	}
Thomas Hoffmann's avatar
Thomas Hoffmann committed
90
	var res big.Int
Thomas Hoffmann's avatar
Thomas Hoffmann committed
91
	res.Mul(tmp[0],tmp[1])
Thomas Hoffmann's avatar
Thomas Hoffmann committed
92
93
	res.Mul(&res,tmp[2])
	return &res
Thomas Hoffmann's avatar
Thomas Hoffmann committed
94
}