forked from tuneinsight/lattigo
-
Notifications
You must be signed in to change notification settings - Fork 0
/
encryptor.go
80 lines (66 loc) · 2.29 KB
/
encryptor.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
package rgsw
import (
"github.com/tuneinsight/lattigo/v4/rlwe"
"github.com/tuneinsight/lattigo/v4/rlwe/ringqp"
)
// Encryptor is a type for encrypting RGSW ciphertexts. It implements the rlwe.Encryptor
// interface overriding the `Encrypt` and `EncryptZero` methods to accept rgsw.Ciphertext
// types in addition to ciphertexts types in the rlwe package.
type Encryptor struct {
rlwe.Encryptor
params rlwe.Parameters
buffQP ringqp.Poly
}
// NewEncryptor creates a new Encryptor type. Note that only secret-key encryption is
// supported at the moment.
func NewEncryptor(params rlwe.Parameters, sk *rlwe.SecretKey) *Encryptor {
return &Encryptor{rlwe.NewEncryptor(params, sk), params, params.RingQP().NewPoly()}
}
// Encrypt encrypts a plaintext pt into a ciphertext ct, which can be a rgsw.Ciphertext
// or any of the `rlwe` cipheretxt types.
func (enc *Encryptor) Encrypt(pt *rlwe.Plaintext, ct interface{}) {
var rgswCt *Ciphertext
var isRGSW bool
if rgswCt, isRGSW = ct.(*Ciphertext); !isRGSW {
enc.Encryptor.Encrypt(pt, ct)
return
}
enc.EncryptZero(rgswCt)
ringQ := enc.params.RingQ()
levelQ := rgswCt.LevelQ()
if pt != nil {
ringQ.MFormLvl(levelQ, pt.Value, enc.buffQP.Q)
if !pt.Value.IsNTT {
ringQ.NTTLvl(levelQ, enc.buffQP.Q, enc.buffQP.Q)
}
rlwe.AddPolyTimesGadgetVectorToGadgetCiphertext(
enc.buffQP.Q,
[]rlwe.GadgetCiphertext{rgswCt.Value[0], rgswCt.Value[1]},
*enc.params.RingQP(),
enc.params.Pow2Base(),
enc.buffQP.Q)
}
}
// EncryptZero generates an encryption of zero into a ciphertext ct, which can be a rgsw.Ciphertext
// or any of the `rlwe` cipheretxt types.
func (enc *Encryptor) EncryptZero(ct interface{}) {
var rgswCt *Ciphertext
var isRGSW bool
if rgswCt, isRGSW = ct.(*Ciphertext); !isRGSW {
enc.Encryptor.EncryptZero(ct)
return
}
levelQ := rgswCt.LevelQ()
levelP := rgswCt.LevelP()
decompRNS := enc.params.DecompRNS(levelQ, levelP)
decompPw2 := enc.params.DecompPw2(levelQ, levelP)
for j := 0; j < decompPw2; j++ {
for i := 0; i < decompRNS; i++ {
enc.Encryptor.EncryptZero(&rgswCt.Value[0].Value[i][j])
enc.Encryptor.EncryptZero(&rgswCt.Value[1].Value[i][j])
}
}
}
func (enc *Encryptor) ShallowCopy() *Encryptor {
return &Encryptor{Encryptor: enc.Encryptor.ShallowCopy(), params: enc.params, buffQP: enc.params.RingQP().NewPoly()}
}