mpc.mx raw
1 // Multi-party homomorphic encryption session.
2 package ring
3
4 import "errors"
5
6 type MPCSession struct {
7 AggPK *KEMPublicKey
8 RLK *RelinearizationKey
9 session *SessionWrapper
10 }
11
12 func NewMPCSession(pks []*KEMPublicKey, rlk *RelinearizationKey, gpvPK *GPVPublicKey, gpvSK *GPVSecretKey) (s *MPCSession, err error) {
13 aggPK, err := AggregateHEKeys(pks)
14 if err != nil {
15 return nil, err
16 }
17
18 sw := NewSession(aggPK, gpvPK, gpvSK)
19
20 return &MPCSession{
21 AggPK: aggPK,
22 RLK: rlk,
23 session: sw,
24 }, nil
25 }
26
27 func (s *MPCSession) SessionID() (id []byte) {
28 return s.session.SessionID
29 }
30
31 func (s *MPCSession) Encrypt(bit int32) (ct *HECiphertext) {
32 return HEEncrypt(s.AggPK, bit)
33 }
34
35 func (s *MPCSession) XOR(a, b *HECiphertext) (result *SecureHEResult) {
36 ct := HEXOR(a, b)
37 return s.session.Wrap(ct)
38 }
39
40 func (s *MPCSession) AND(a, b *HECiphertext) (result *SecureHEResult, err error) {
41 if s.RLK == nil {
42 return nil, errors.New("mpc: AND requires relinearization key")
43 }
44 ct := HEAND(a, b, s.RLK)
45 return s.session.Wrap(ct), nil
46 }
47
48 func (s *MPCSession) NOT(a *HECiphertext) (result *SecureHEResult) {
49 ct := HENot(a)
50 return s.session.Wrap(ct)
51 }
52
53 func (s *MPCSession) MPCAdd(a, b *HECiphertext) (result *SecureHEResult) {
54 ct := HEAdd(a, b)
55 return s.session.Wrap(ct)
56 }
57
58 func (s *MPCSession) Verify(result *SecureHEResult) (ok bool) {
59 return s.session.Verify(result)
60 }
61
62 func (s *MPCSession) Unwrap(result *SecureHEResult) (ct *HECiphertext) {
63 if !s.Verify(result) {
64 return nil
65 }
66 return result.Ciphertext
67 }
68
69 func DecryptDistributed(ct *HECiphertext, partials []*Poly) (result int32) {
70 return CombinePartialDecryptions(ct, partials)
71 }
72