github.com/cloudflare/circl@v1.5.0/pke/kyber/kyber512/kyber.go (about)

     1  // Code generated from pkg.templ.go. DO NOT EDIT.
     2  
     3  // kyber512 implements the IND-CPA-secure Public Key Encryption
     4  // scheme Kyber512.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 kyber512
     9  
    10  import (
    11  	cryptoRand "crypto/rand"
    12  	"io"
    13  
    14  	"github.com/cloudflare/circl/kem"
    15  	"github.com/cloudflare/circl/pke/kyber/kyber512/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 Kyber512.CPAPKE public key
    39  type PublicKey internal.PublicKey
    40  
    41  // PrivateKey is the type of Kyber512.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  }