...
1
2
3 package internal
4
5 import (
6 "github.com/cloudflare/circl/internal/sha3"
7 "github.com/cloudflare/circl/pke/kyber/internal/common"
8 )
9
10
11 type PrivateKey struct {
12 sh Vec
13 }
14
15
16 type PublicKey struct {
17 rho [32]byte
18 th Vec
19
20
21 aT Mat
22 }
23
24
25 func (sk *PrivateKey) Pack(buf []byte) {
26 sk.sh.Pack(buf)
27 }
28
29
30 func (sk *PrivateKey) Unpack(buf []byte) {
31 sk.sh.Unpack(buf)
32 sk.sh.Normalize()
33 }
34
35
36 func (pk *PublicKey) Pack(buf []byte) {
37 pk.th.Pack(buf)
38 copy(buf[K*common.PolySize:], pk.rho[:])
39 }
40
41
42 func (pk *PublicKey) Unpack(buf []byte) {
43 pk.th.Unpack(buf)
44 pk.th.Normalize()
45 copy(pk.rho[:], buf[K*common.PolySize:])
46 pk.aT.Derive(&pk.rho, true)
47 }
48
49
50 func NewKeyFromSeed(seed []byte) (*PublicKey, *PrivateKey) {
51 var pk PublicKey
52 var sk PrivateKey
53
54 var expandedSeed [64]byte
55
56 h := sha3.New512()
57 _, _ = h.Write(seed)
58
59
60 _, _ = h.Read(expandedSeed[:])
61
62 copy(pk.rho[:], expandedSeed[:32])
63 sigma := expandedSeed[32:]
64
65 pk.aT.Derive(&pk.rho, false)
66
67 var eh Vec
68 sk.sh.DeriveNoise(sigma, 0, Eta1)
69 sk.sh.NTT()
70 sk.sh.Normalize()
71
72 eh.DeriveNoise(sigma, K, Eta1)
73 eh.NTT()
74
75
76 for i := 0; i < K; i++ {
77
78
79
80 PolyDotHat(&pk.th[i], &pk.aT[i], &sk.sh)
81
82
83
84
85
86 pk.th[i].ToMont()
87 }
88
89 pk.th.Add(&pk.th, &eh)
90 pk.th.Normalize()
91 pk.aT.Transpose()
92
93 return &pk, &sk
94 }
95
96
97 func (sk *PrivateKey) DecryptTo(pt, ct []byte) {
98 var u Vec
99 var v, m common.Poly
100
101 u.Decompress(ct, DU)
102 v.Decompress(ct[K*compressedPolySize(DU):], DV)
103
104
105 u.NTT()
106 PolyDotHat(&m, &sk.sh, &u)
107 m.BarrettReduce()
108 m.InvNTT()
109 m.Sub(&v, &m)
110 m.Normalize()
111
112
113 m.CompressMessageTo(pt)
114 }
115
116
117
118
119
120
121 func (pk *PublicKey) EncryptTo(ct, pt, seed []byte) {
122 var rh, e1, u Vec
123 var e2, v, m common.Poly
124
125
126 rh.DeriveNoise(seed, 0, Eta1)
127 rh.NTT()
128 rh.BarrettReduce()
129
130 e1.DeriveNoise(seed, K, common.Eta2)
131 e2.DeriveNoise(seed, 2*K, common.Eta2)
132
133
134 for i := 0; i < K; i++ {
135
136
137
138 PolyDotHat(&u[i], &pk.aT[i], &rh)
139 }
140
141 u.BarrettReduce()
142
143
144
145
146 u.InvNTT()
147
148 u.Add(&u, &e1)
149
150
151 PolyDotHat(&v, &pk.th, &rh)
152 v.BarrettReduce()
153 v.InvNTT()
154
155 m.DecompressMessage(pt)
156 v.Add(&v, &m)
157 v.Add(&v, &e2)
158
159
160 u.Normalize()
161 v.Normalize()
162
163 u.CompressTo(ct, DU)
164 v.CompressTo(ct[K*compressedPolySize(DU):], DV)
165 }
166
167
168 func (sk *PrivateKey) Equal(other *PrivateKey) bool {
169 ret := int16(0)
170 for i := 0; i < K; i++ {
171 for j := 0; j < common.N; j++ {
172 ret |= sk.sh[i][j] ^ other.sh[i][j]
173 }
174 }
175 return ret == 0
176 }
177
View as plain text