forked from kudelskisecurity/crystals-go
-
Notifications
You must be signed in to change notification settings - Fork 0
/
keys.go
107 lines (92 loc) · 2.77 KB
/
keys.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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
package kyber
import (
"crypto/subtle"
"golang.org/x/crypto/sha3"
)
// PublicKey holds the pk strct
type PublicKey struct {
T Vec //NTT(t)
Rho []byte //32
}
// PKEPrivateKey holds the ak strct for Kyber's PKE scheme
type PKEPrivateKey struct {
S Vec //NTT(s)
}
// PrivateKey holds the sk struct
type PrivateKey struct {
Z []byte
SkP []byte
Pk []byte
}
// SIZEPK returns the size in bytes of the public key of a kyber instance
func (k *Kyber) SIZEPK() int {
return k.params.SIZEPK
}
// SIZESK returns the size in bytes of the secret key of a kyber instance
func (k *Kyber) SIZESK() int {
return k.params.SIZESK
}
// SIZEPKESK returns the size in bytes of the PKE secret key of a kyber instance
func (k *Kyber) SIZEPKESK() int {
return k.params.SIZEPKESK
}
// SIZEC returns the size in bytes of the ciphertext of a kyber instance
func (k *Kyber) SIZEC() int {
return k.params.SIZEC
}
// PackPK packs a PublicKey into an array of bytes
func (k *Kyber) PackPK(pk *PublicKey) []byte {
ppk := make([]byte, k.params.SIZEPK)
copy(ppk[:], pack(pk.T, k.params.K))
copy(ppk[k.params.K*polysize:], pk.Rho[:])
return ppk
}
// UnpackPK reverses the packing operation and outputs a PublicKey struct
func (k *Kyber) UnpackPK(packedPK []byte) *PublicKey {
if len(packedPK) != k.params.SIZEPK {
println("cannot unpack this public key")
return nil
}
return &PublicKey{Rho: packedPK[k.params.K*polysize:], T: unpack(packedPK[:], k.params.K)}
}
// PackPKESK packs a PKE PrivateKey into a byte array
func (k *Kyber) PackPKESK(sk *PKEPrivateKey) []byte {
psk := make([]byte, k.params.SIZEPKESK)
copy(psk[:], pack(sk.S, k.params.K))
return psk
}
// UnpackPKESK reverses the packing operation and outputs a PKEPrivateKey struct
func (k *Kyber) UnpackPKESK(psk []byte) *PKEPrivateKey {
if len(psk) != k.params.SIZEPKESK {
println("cannot unpack this private key")
return nil
}
return &PKEPrivateKey{S: unpack(psk[:], k.params.K)}
}
// PackSK packs a PrivateKey into a byte array
func (k *Kyber) PackSK(sk *PrivateKey) []byte {
psk := make([]byte, k.params.SIZESK)
id := 0
K := k.params.K
subtle.ConstantTimeCopy(1, psk[id:id+K*polysize], sk.SkP[:])
id += K * polysize
hpk := sk.Pk[:]
copy(psk[id:], hpk)
id += k.params.SIZEPK
hState := sha3.New256()
hState.Write(hpk)
copy(psk[id:id+32], hState.Sum(nil))
id += 32
subtle.ConstantTimeCopy(1, psk[id:id+32], sk.Z[:])
return psk
}
// UnpackSK reverses the packing operation and outputs a PrivateKey struct
func (k *Kyber) UnpackSK(psk []byte) *PrivateKey {
if len(psk) != k.params.SIZESK {
println("cannot unpack this private key")
return nil
}
SIZEPKESK := k.params.SIZEPKESK
SIZEPK := k.params.SIZEPK
return &PrivateKey{Z: psk[SIZEPKESK+SIZEPK : SIZEPKESK+SIZEPK+32], SkP: psk[:SIZEPKESK], Pk: psk[SIZEPKESK : SIZEPKESK+SIZEPK]}
}