github.com/cloudflare/circl@v1.5.0/pke/kyber/kyber768/kyber.go (about) 1 // Code generated from pkg.templ.go. DO NOT EDIT. 2 3 // kyber768 implements the IND-CPA-secure Public Key Encryption 4 // scheme Kyber768.CPAPKE as submitted to round 3 of the NIST PQC competition 5 // and described in 6 // 7 // https://pq-crystals.org/kyber/data/kyber-specification-round3.pdf 8 package kyber768 9 10 import ( 11 cryptoRand "crypto/rand" 12 "io" 13 14 "github.com/cloudflare/circl/kem" 15 "github.com/cloudflare/circl/pke/kyber/kyber768/internal" 16 ) 17 18 const ( 19 // Size of seed for NewKeyFromSeed 20 KeySeedSize = internal.SeedSize 21 22 // Size of seed for EncryptTo 23 EncryptionSeedSize = internal.SeedSize 24 25 // Size of a packed PublicKey 26 PublicKeySize = internal.PublicKeySize 27 28 // Size of a packed PrivateKey 29 PrivateKeySize = internal.PrivateKeySize 30 31 // Size of a ciphertext 32 CiphertextSize = internal.CiphertextSize 33 34 // Size of a plaintext 35 PlaintextSize = internal.PlaintextSize 36 ) 37 38 // PublicKey is the type of Kyber768.CPAPKE public key 39 type PublicKey internal.PublicKey 40 41 // PrivateKey is the type of Kyber768.CPAPKE private key 42 type PrivateKey internal.PrivateKey 43 44 // GenerateKey generates a public/private key pair using entropy from rand. 45 // If rand is nil, crypto/rand.Reader will be used. 46 func GenerateKey(rand io.Reader) (*PublicKey, *PrivateKey, error) { 47 var seed [KeySeedSize]byte 48 if rand == nil { 49 rand = cryptoRand.Reader 50 } 51 _, err := io.ReadFull(rand, seed[:]) 52 if err != nil { 53 return nil, nil, err 54 } 55 pk, sk := internal.NewKeyFromSeed(seed[:]) 56 return (*PublicKey)(pk), (*PrivateKey)(sk), nil 57 } 58 59 // NewKeyFromSeed derives a public/private key pair using the given seed. 60 // 61 // Note: does not include the domain separation of ML-KEM (line 1, algorithm 13 62 // of FIPS 203). For that use NewKeyFromSeedMLKEM(). 63 // 64 // Panics if seed is not of length KeySeedSize. 65 func NewKeyFromSeed(seed []byte) (*PublicKey, *PrivateKey) { 66 if len(seed) != KeySeedSize { 67 panic("seed must be of length KeySeedSize") 68 } 69 pk, sk := internal.NewKeyFromSeed(seed) 70 return (*PublicKey)(pk), (*PrivateKey)(sk) 71 } 72 73 // NewKeyFromSeedMLKEM derives a public/private key pair using the given seed 74 // using the domain separation of ML-KEM. 75 // 76 // Panics if seed is not of length KeySeedSize. 77 func NewKeyFromSeedMLKEM(seed []byte) (*PublicKey, *PrivateKey) { 78 if len(seed) != KeySeedSize { 79 panic("seed must be of length KeySeedSize") 80 } 81 var seed2 [33]byte 82 copy(seed2[:32], seed) 83 seed2[32] = byte(internal.K) 84 pk, sk := internal.NewKeyFromSeed(seed2[:]) 85 return (*PublicKey)(pk), (*PrivateKey)(sk) 86 } 87 88 // EncryptTo encrypts message pt for the public key and writes the ciphertext 89 // to ct using randomness from seed. 90 // 91 // This function panics if the lengths of pt, seed, and ct are not 92 // PlaintextSize, EncryptionSeedSize, and CiphertextSize respectively. 93 func (pk *PublicKey) EncryptTo(ct []byte, pt []byte, seed []byte) { 94 if len(pt) != PlaintextSize { 95 panic("pt must be of length PlaintextSize") 96 } 97 if len(ct) != CiphertextSize { 98 panic("ct must be of length CiphertextSize") 99 } 100 if len(seed) != EncryptionSeedSize { 101 panic("seed must be of length EncryptionSeedSize") 102 } 103 (*internal.PublicKey)(pk).EncryptTo(ct, pt, seed) 104 } 105 106 // DecryptTo decrypts message ct for the private key and writes the 107 // plaintext to pt. 108 // 109 // This function panics if the lengths of ct and pt are not 110 // CiphertextSize and PlaintextSize respectively. 111 func (sk *PrivateKey) DecryptTo(pt []byte, ct []byte) { 112 if len(pt) != PlaintextSize { 113 panic("pt must be of length PlaintextSize") 114 } 115 if len(ct) != CiphertextSize { 116 panic("ct must be of length CiphertextSize") 117 } 118 (*internal.PrivateKey)(sk).DecryptTo(pt, ct) 119 } 120 121 // Packs pk into the given buffer. 122 // 123 // Panics if buf is not of length PublicKeySize. 124 func (pk *PublicKey) Pack(buf []byte) { 125 if len(buf) != PublicKeySize { 126 panic("buf must be of size PublicKeySize") 127 } 128 (*internal.PublicKey)(pk).Pack(buf) 129 } 130 131 // Packs sk into the given buffer. 132 // 133 // Panics if buf is not of length PrivateKeySize. 134 func (sk *PrivateKey) Pack(buf []byte) { 135 if len(buf) != PrivateKeySize { 136 panic("buf must be of size PrivateKeySize") 137 } 138 (*internal.PrivateKey)(sk).Pack(buf) 139 } 140 141 // Unpacks pk from the given buffer. 142 // 143 // Panics if buf is not of length PublicKeySize. 144 func (pk *PublicKey) Unpack(buf []byte) { 145 if len(buf) != PublicKeySize { 146 panic("buf must be of size PublicKeySize") 147 } 148 (*internal.PublicKey)(pk).Unpack(buf) 149 } 150 151 // Unpacks pk from the given buffer. 152 // 153 // Returns an error if the buffer is not of the right size, or the public 154 // key is not normalized. 155 func (pk *PublicKey) UnpackMLKEM(buf []byte) error { 156 if len(buf) != PublicKeySize { 157 return kem.ErrPubKeySize 158 } 159 return (*internal.PublicKey)(pk).UnpackMLKEM(buf) 160 } 161 162 // Unpacks sk from the given buffer. 163 // 164 // Panics if buf is not of length PrivateKeySize. 165 func (sk *PrivateKey) Unpack(buf []byte) { 166 if len(buf) != PrivateKeySize { 167 panic("buf must be of size PrivateKeySize") 168 } 169 (*internal.PrivateKey)(sk).Unpack(buf) 170 } 171 172 // Returns whether the two private keys are equal. 173 func (sk *PrivateKey) Equal(other *PrivateKey) bool { 174 return (*internal.PrivateKey)(sk).Equal((*internal.PrivateKey)(other)) 175 }