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