-
Notifications
You must be signed in to change notification settings - Fork 143
/
kyber.go
145 lines (125 loc) · 4.02 KB
/
kyber.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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
// Code generated from modePkg.templ.go. DO NOT EDIT.
// kyber768 implements the IND-CPA-secure Public Key Encryption
// scheme Kyber768.CPAPKE as submitted to round 3 of the NIST PQC competition
// and described in
//
// https://pq-crystals.org/kyber/data/kyber-specification-round3.pdf
package kyber768
import (
cryptoRand "crypto/rand"
"io"
"github.com/cloudflare/circl/pke/kyber/kyber768/internal"
)
const (
// Size of seed for NewKeyFromSeed
KeySeedSize = internal.SeedSize
// Size of seed for EncryptTo
EncryptionSeedSize = internal.SeedSize
// Size of a packed PublicKey
PublicKeySize = internal.PublicKeySize
// Size of a packed PrivateKey
PrivateKeySize = internal.PrivateKeySize
// Size of a ciphertext
CiphertextSize = internal.CiphertextSize
// Size of a plaintext
PlaintextSize = internal.PlaintextSize
)
// PublicKey is the type of Kyber768.CPAPKE public key
type PublicKey internal.PublicKey
// PrivateKey is the type of Kyber768.CPAPKE private key
type PrivateKey internal.PrivateKey
// GenerateKey generates a public/private key pair using entropy from rand.
// If rand is nil, crypto/rand.Reader will be used.
func GenerateKey(rand io.Reader) (*PublicKey, *PrivateKey, error) {
var seed [KeySeedSize]byte
if rand == nil {
rand = cryptoRand.Reader
}
_, err := io.ReadFull(rand, seed[:])
if err != nil {
return nil, nil, err
}
pk, sk := internal.NewKeyFromSeed(seed[:])
return (*PublicKey)(pk), (*PrivateKey)(sk), nil
}
// NewKeyFromSeed derives a public/private key pair using the given seed.
//
// Panics if seed is not of length KeySeedSize.
func NewKeyFromSeed(seed []byte) (*PublicKey, *PrivateKey) {
if len(seed) != KeySeedSize {
panic("seed must be of length KeySeedSize")
}
pk, sk := internal.NewKeyFromSeed(seed)
return (*PublicKey)(pk), (*PrivateKey)(sk)
}
// EncryptTo encrypts message pt for the public key and writes the ciphertext
// to ct using randomness from seed.
//
// This function panics if the lengths of pt, seed, and ct are not
// PlaintextSize, EncryptionSeedSize, and CiphertextSize respectively.
func (pk *PublicKey) EncryptTo(ct []byte, pt []byte, seed []byte) {
if len(pt) != PlaintextSize {
panic("pt must be of length PlaintextSize")
}
if len(ct) != CiphertextSize {
panic("ct must be of length CiphertextSize")
}
if len(seed) != EncryptionSeedSize {
panic("seed must be of length EncryptionSeedSize")
}
(*internal.PublicKey)(pk).EncryptTo(ct, pt, seed)
}
// DecryptTo decrypts message ct for the private key and writes the
// plaintext to pt.
//
// This function panics if the lengths of ct and pt are not
// CiphertextSize and PlaintextSize respectively.
func (sk *PrivateKey) DecryptTo(pt []byte, ct []byte) {
if len(pt) != PlaintextSize {
panic("pt must be of length PlaintextSize")
}
if len(ct) != CiphertextSize {
panic("ct must be of length CiphertextSize")
}
(*internal.PrivateKey)(sk).DecryptTo(pt, ct)
}
// Packs pk into the given buffer.
//
// Panics if buf is not of length PublicKeySize.
func (pk *PublicKey) Pack(buf []byte) {
if len(buf) != PublicKeySize {
panic("buf must be of size PublicKeySize")
}
(*internal.PublicKey)(pk).Pack(buf)
}
// Packs sk into the given buffer.
//
// Panics if buf is not of length PrivateKeySize.
func (sk *PrivateKey) Pack(buf []byte) {
if len(buf) != PrivateKeySize {
panic("buf must be of size PrivateKeySize")
}
(*internal.PrivateKey)(sk).Pack(buf)
}
// Unpacks pk from the given buffer.
//
// Panics if buf is not of length PublicKeySize.
func (pk *PublicKey) Unpack(buf []byte) {
if len(buf) != PublicKeySize {
panic("buf must be of size PublicKeySize")
}
(*internal.PublicKey)(pk).Unpack(buf)
}
// Unpacks sk from the given buffer.
//
// Panics if buf is not of length PrivateKeySize.
func (sk *PrivateKey) Unpack(buf []byte) {
if len(buf) != PrivateKeySize {
panic("buf must be of size PrivateKeySize")
}
(*internal.PrivateKey)(sk).Unpack(buf)
}
// Returns whether the two private keys are equal.
func (sk *PrivateKey) Equal(other *PrivateKey) bool {
return (*internal.PrivateKey)(sk).Equal((*internal.PrivateKey)(other))
}