...

Source file src/github.com/cloudflare/circl/kem/kyber/kyber1024/kyber.go

Documentation: github.com/cloudflare/circl/kem/kyber/kyber1024

     1  // Code generated from pkg.templ.go. DO NOT EDIT.
     2  
     3  // Package kyber1024 implements the IND-CCA2 secure key encapsulation mechanism
     4  // Kyber1024.CCAKEM as submitted to round 3 of the NIST PQC competition and
     5  // described in
     6  //
     7  // https://pq-crystals.org/kyber/data/kyber-specification-round3.pdf
     8  package kyber1024
     9  
    10  import (
    11  	"bytes"
    12  	"crypto/subtle"
    13  	"io"
    14  
    15  	cryptoRand "crypto/rand"
    16  	"github.com/cloudflare/circl/internal/sha3"
    17  	"github.com/cloudflare/circl/kem"
    18  	cpapke "github.com/cloudflare/circl/pke/kyber/kyber1024"
    19  )
    20  
    21  const (
    22  	// Size of seed for NewKeyFromSeed
    23  	KeySeedSize = cpapke.KeySeedSize + 32
    24  
    25  	// Size of seed for EncapsulateTo.
    26  	EncapsulationSeedSize = 32
    27  
    28  	// Size of the established shared key.
    29  	SharedKeySize = 32
    30  
    31  	// Size of the encapsulated shared key.
    32  	CiphertextSize = cpapke.CiphertextSize
    33  
    34  	// Size of a packed public key.
    35  	PublicKeySize = cpapke.PublicKeySize
    36  
    37  	// Size of a packed private key.
    38  	PrivateKeySize = cpapke.PrivateKeySize + cpapke.PublicKeySize + 64
    39  )
    40  
    41  // Type of a Kyber1024.CCAKEM public key
    42  type PublicKey struct {
    43  	pk *cpapke.PublicKey
    44  
    45  	hpk [32]byte // H(pk)
    46  }
    47  
    48  // Type of a Kyber1024.CCAKEM private key
    49  type PrivateKey struct {
    50  	sk  *cpapke.PrivateKey
    51  	pk  *cpapke.PublicKey
    52  	hpk [32]byte // H(pk)
    53  	z   [32]byte
    54  }
    55  
    56  // NewKeyFromSeed derives a public/private keypair deterministically
    57  // from the given seed.
    58  //
    59  // Panics if seed is not of length KeySeedSize.
    60  func NewKeyFromSeed(seed []byte) (*PublicKey, *PrivateKey) {
    61  	var sk PrivateKey
    62  	var pk PublicKey
    63  
    64  	if len(seed) != KeySeedSize {
    65  		panic("seed must be of length KeySeedSize")
    66  	}
    67  
    68  	pk.pk, sk.sk = cpapke.NewKeyFromSeed(seed[:cpapke.KeySeedSize])
    69  	sk.pk = pk.pk
    70  	copy(sk.z[:], seed[cpapke.KeySeedSize:])
    71  
    72  	// Compute H(pk)
    73  	var ppk [cpapke.PublicKeySize]byte
    74  	sk.pk.Pack(ppk[:])
    75  	h := sha3.New256()
    76  	h.Write(ppk[:])
    77  	h.Read(sk.hpk[:])
    78  	copy(pk.hpk[:], sk.hpk[:])
    79  
    80  	return &pk, &sk
    81  }
    82  
    83  // GenerateKeyPair generates public and private keys using entropy from rand.
    84  // If rand is nil, crypto/rand.Reader will be used.
    85  func GenerateKeyPair(rand io.Reader) (*PublicKey, *PrivateKey, error) {
    86  	var seed [KeySeedSize]byte
    87  	if rand == nil {
    88  		rand = cryptoRand.Reader
    89  	}
    90  	_, err := io.ReadFull(rand, seed[:])
    91  	if err != nil {
    92  		return nil, nil, err
    93  	}
    94  	pk, sk := NewKeyFromSeed(seed[:])
    95  	return pk, sk, nil
    96  }
    97  
    98  // EncapsulateTo generates a shared key and ciphertext that contains it
    99  // for the public key using randomness from seed and writes the shared key
   100  // to ss and ciphertext to ct.
   101  //
   102  // Panics if ss, ct or seed are not of length SharedKeySize, CiphertextSize
   103  // and EncapsulationSeedSize respectively.
   104  //
   105  // seed may be nil, in which case crypto/rand.Reader is used to generate one.
   106  func (pk *PublicKey) EncapsulateTo(ct, ss []byte, seed []byte) {
   107  	if seed == nil {
   108  		seed = make([]byte, EncapsulationSeedSize)
   109  		if _, err := cryptoRand.Read(seed[:]); err != nil {
   110  			panic(err)
   111  		}
   112  	} else {
   113  		if len(seed) != EncapsulationSeedSize {
   114  			panic("seed must be of length EncapsulationSeedSize")
   115  		}
   116  	}
   117  
   118  	if len(ct) != CiphertextSize {
   119  		panic("ct must be of length CiphertextSize")
   120  	}
   121  
   122  	if len(ss) != SharedKeySize {
   123  		panic("ss must be of length SharedKeySize")
   124  	}
   125  
   126  	// m = H(seed)
   127  	var m [32]byte
   128  	h := sha3.New256()
   129  	h.Write(seed[:])
   130  	h.Read(m[:])
   131  
   132  	// (K', r) = G(m ‖ H(pk))
   133  	var kr [64]byte
   134  	g := sha3.New512()
   135  	g.Write(m[:])
   136  	g.Write(pk.hpk[:])
   137  	g.Read(kr[:])
   138  
   139  	// c = Kyber.CPAPKE.Enc(pk, m, r)
   140  	pk.pk.EncryptTo(ct, m[:], kr[32:])
   141  
   142  	// Compute H(c) and put in second slot of kr, which will be (K', H(c)).
   143  	h.Reset()
   144  	h.Write(ct[:CiphertextSize])
   145  	h.Read(kr[32:])
   146  
   147  	// K = KDF(K' ‖ H(c))
   148  	kdf := sha3.NewShake256()
   149  	kdf.Write(kr[:])
   150  	kdf.Read(ss[:SharedKeySize])
   151  }
   152  
   153  // DecapsulateTo computes the shared key which is encapsulated in ct
   154  // for the private key.
   155  //
   156  // Panics if ct or ss are not of length CiphertextSize and SharedKeySize
   157  // respectively.
   158  func (sk *PrivateKey) DecapsulateTo(ss, ct []byte) {
   159  	if len(ct) != CiphertextSize {
   160  		panic("ct must be of length CiphertextSize")
   161  	}
   162  
   163  	if len(ss) != SharedKeySize {
   164  		panic("ss must be of length SharedKeySize")
   165  	}
   166  
   167  	// m' = Kyber.CPAPKE.Dec(sk, ct)
   168  	var m2 [32]byte
   169  	sk.sk.DecryptTo(m2[:], ct)
   170  
   171  	// (K'', r') = G(m' ‖ H(pk))
   172  	var kr2 [64]byte
   173  	g := sha3.New512()
   174  	g.Write(m2[:])
   175  	g.Write(sk.hpk[:])
   176  	g.Read(kr2[:])
   177  
   178  	// c' = Kyber.CPAPKE.Enc(pk, m', r')
   179  	var ct2 [CiphertextSize]byte
   180  	sk.pk.EncryptTo(ct2[:], m2[:], kr2[32:])
   181  
   182  	// Compute H(c) and put in second slot of kr2, which will be (K'', H(c)).
   183  	h := sha3.New256()
   184  	h.Write(ct[:CiphertextSize])
   185  	h.Read(kr2[32:])
   186  
   187  	// Replace K'' by  z in the first slot of kr2 if c ≠ c'.
   188  	subtle.ConstantTimeCopy(
   189  		1-subtle.ConstantTimeCompare(ct, ct2[:]),
   190  		kr2[:32],
   191  		sk.z[:],
   192  	)
   193  
   194  	// K = KDF(K''/z, H(c))
   195  	kdf := sha3.NewShake256()
   196  	kdf.Write(kr2[:])
   197  	kdf.Read(ss[:SharedKeySize])
   198  }
   199  
   200  // Packs sk to buf.
   201  //
   202  // Panics if buf is not of size PrivateKeySize.
   203  func (sk *PrivateKey) Pack(buf []byte) {
   204  	if len(buf) != PrivateKeySize {
   205  		panic("buf must be of length PrivateKeySize")
   206  	}
   207  
   208  	sk.sk.Pack(buf[:cpapke.PrivateKeySize])
   209  	buf = buf[cpapke.PrivateKeySize:]
   210  	sk.pk.Pack(buf[:cpapke.PublicKeySize])
   211  	buf = buf[cpapke.PublicKeySize:]
   212  	copy(buf, sk.hpk[:])
   213  	buf = buf[32:]
   214  	copy(buf, sk.z[:])
   215  }
   216  
   217  // Unpacks sk from buf.
   218  //
   219  // Panics if buf is not of size PrivateKeySize.
   220  func (sk *PrivateKey) Unpack(buf []byte) {
   221  	if len(buf) != PrivateKeySize {
   222  		panic("buf must be of length PrivateKeySize")
   223  	}
   224  
   225  	sk.sk = new(cpapke.PrivateKey)
   226  	sk.sk.Unpack(buf[:cpapke.PrivateKeySize])
   227  	buf = buf[cpapke.PrivateKeySize:]
   228  	sk.pk = new(cpapke.PublicKey)
   229  	sk.pk.Unpack(buf[:cpapke.PublicKeySize])
   230  	buf = buf[cpapke.PublicKeySize:]
   231  	copy(sk.hpk[:], buf[:32])
   232  	copy(sk.z[:], buf[32:])
   233  }
   234  
   235  // Packs pk to buf.
   236  //
   237  // Panics if buf is not of size PublicKeySize.
   238  func (pk *PublicKey) Pack(buf []byte) {
   239  	if len(buf) != PublicKeySize {
   240  		panic("buf must be of length PublicKeySize")
   241  	}
   242  
   243  	pk.pk.Pack(buf)
   244  }
   245  
   246  // Unpacks pk from buf.
   247  //
   248  // Panics if buf is not of size PublicKeySize.
   249  func (pk *PublicKey) Unpack(buf []byte) {
   250  	if len(buf) != PublicKeySize {
   251  		panic("buf must be of length PublicKeySize")
   252  	}
   253  
   254  	pk.pk = new(cpapke.PublicKey)
   255  	pk.pk.Unpack(buf)
   256  
   257  	// Compute cached H(pk)
   258  	h := sha3.New256()
   259  	h.Write(buf)
   260  	h.Read(pk.hpk[:])
   261  }
   262  
   263  // Boilerplate down below for the KEM scheme API.
   264  
   265  type scheme struct{}
   266  
   267  var sch kem.Scheme = &scheme{}
   268  
   269  // Scheme returns a KEM interface.
   270  func Scheme() kem.Scheme { return sch }
   271  
   272  func (*scheme) Name() string               { return "Kyber1024" }
   273  func (*scheme) PublicKeySize() int         { return PublicKeySize }
   274  func (*scheme) PrivateKeySize() int        { return PrivateKeySize }
   275  func (*scheme) SeedSize() int              { return KeySeedSize }
   276  func (*scheme) SharedKeySize() int         { return SharedKeySize }
   277  func (*scheme) CiphertextSize() int        { return CiphertextSize }
   278  func (*scheme) EncapsulationSeedSize() int { return EncapsulationSeedSize }
   279  
   280  func (sk *PrivateKey) Scheme() kem.Scheme { return sch }
   281  func (pk *PublicKey) Scheme() kem.Scheme  { return sch }
   282  
   283  func (sk *PrivateKey) MarshalBinary() ([]byte, error) {
   284  	var ret [PrivateKeySize]byte
   285  	sk.Pack(ret[:])
   286  	return ret[:], nil
   287  }
   288  
   289  func (sk *PrivateKey) Equal(other kem.PrivateKey) bool {
   290  	oth, ok := other.(*PrivateKey)
   291  	if !ok {
   292  		return false
   293  	}
   294  	if sk.pk == nil && oth.pk == nil {
   295  		return true
   296  	}
   297  	if sk.pk == nil || oth.pk == nil {
   298  		return false
   299  	}
   300  	if !bytes.Equal(sk.hpk[:], oth.hpk[:]) ||
   301  		subtle.ConstantTimeCompare(sk.z[:], oth.z[:]) != 1 {
   302  		return false
   303  	}
   304  	return sk.sk.Equal(oth.sk)
   305  }
   306  
   307  func (pk *PublicKey) Equal(other kem.PublicKey) bool {
   308  	oth, ok := other.(*PublicKey)
   309  	if !ok {
   310  		return false
   311  	}
   312  	if pk.pk == nil && oth.pk == nil {
   313  		return true
   314  	}
   315  	if pk.pk == nil || oth.pk == nil {
   316  		return false
   317  	}
   318  	return bytes.Equal(pk.hpk[:], oth.hpk[:])
   319  }
   320  
   321  func (sk *PrivateKey) Public() kem.PublicKey {
   322  	pk := new(PublicKey)
   323  	pk.pk = sk.pk
   324  	copy(pk.hpk[:], sk.hpk[:])
   325  	return pk
   326  }
   327  
   328  func (pk *PublicKey) MarshalBinary() ([]byte, error) {
   329  	var ret [PublicKeySize]byte
   330  	pk.Pack(ret[:])
   331  	return ret[:], nil
   332  }
   333  
   334  func (*scheme) GenerateKeyPair() (kem.PublicKey, kem.PrivateKey, error) {
   335  	return GenerateKeyPair(cryptoRand.Reader)
   336  }
   337  
   338  func (*scheme) DeriveKeyPair(seed []byte) (kem.PublicKey, kem.PrivateKey) {
   339  	if len(seed) != KeySeedSize {
   340  		panic(kem.ErrSeedSize)
   341  	}
   342  	return NewKeyFromSeed(seed[:])
   343  }
   344  
   345  func (*scheme) Encapsulate(pk kem.PublicKey) (ct, ss []byte, err error) {
   346  	ct = make([]byte, CiphertextSize)
   347  	ss = make([]byte, SharedKeySize)
   348  
   349  	pub, ok := pk.(*PublicKey)
   350  	if !ok {
   351  		return nil, nil, kem.ErrTypeMismatch
   352  	}
   353  	pub.EncapsulateTo(ct, ss, nil)
   354  	return
   355  }
   356  
   357  func (*scheme) EncapsulateDeterministically(pk kem.PublicKey, seed []byte) (
   358  	ct, ss []byte, err error) {
   359  	if len(seed) != EncapsulationSeedSize {
   360  		return nil, nil, kem.ErrSeedSize
   361  	}
   362  
   363  	ct = make([]byte, CiphertextSize)
   364  	ss = make([]byte, SharedKeySize)
   365  
   366  	pub, ok := pk.(*PublicKey)
   367  	if !ok {
   368  		return nil, nil, kem.ErrTypeMismatch
   369  	}
   370  	pub.EncapsulateTo(ct, ss, seed)
   371  	return
   372  }
   373  
   374  func (*scheme) Decapsulate(sk kem.PrivateKey, ct []byte) ([]byte, error) {
   375  	if len(ct) != CiphertextSize {
   376  		return nil, kem.ErrCiphertextSize
   377  	}
   378  
   379  	priv, ok := sk.(*PrivateKey)
   380  	if !ok {
   381  		return nil, kem.ErrTypeMismatch
   382  	}
   383  	ss := make([]byte, SharedKeySize)
   384  	priv.DecapsulateTo(ss, ct)
   385  	return ss, nil
   386  }
   387  
   388  func (*scheme) UnmarshalBinaryPublicKey(buf []byte) (kem.PublicKey, error) {
   389  	if len(buf) != PublicKeySize {
   390  		return nil, kem.ErrPubKeySize
   391  	}
   392  	var ret PublicKey
   393  	ret.Unpack(buf)
   394  	return &ret, nil
   395  }
   396  
   397  func (*scheme) UnmarshalBinaryPrivateKey(buf []byte) (kem.PrivateKey, error) {
   398  	if len(buf) != PrivateKeySize {
   399  		return nil, kem.ErrPrivKeySize
   400  	}
   401  	var ret PrivateKey
   402  	ret.Unpack(buf)
   403  	return &ret, nil
   404  }
   405  

View as plain text