references/NIST-PQ-Submission-Kyber-20201001/Additional_Implementations/avx2/crypto_kem/kyber768/indcpa.c
/*************************************************
* Name:        indcpa_keypair
*
* Description: Generates public and private key for the CPA-secure
*              public-key encryption scheme underlying Kyber
*
* Arguments:   - uint8_t *pk: pointer to output public key
*                             (of length KYBER_INDCPA_PUBLICKEYBYTES bytes)
*              - uint8_t *sk: pointer to output private key
                              (of length KYBER_INDCPA_SECRETKEYBYTES bytes)
**************************************************/
indcpa_keypair
Description: Generates public and private key for the CPA-secure
public-key encryption scheme underlying Kyber

- uint8_t *pk: pointer to output public key
(of length KYBER_INDCPA_PUBLICKEYBYTES bytes)
uint8_t *sk: pointer to output private key
(of length KYBER_INDCPA_SECRETKEYBYTES bytes)
indcpa_keypair Description : Generates public and private key for the CPA - secure public - key encryption scheme underlying Kyber - uint8_t * pk : pointer to output public key ( of length KYBER_INDCPA_PUBLICKEYBYTES bytes ) uint8_t * sk : pointer to output private key ( of length KYBER_INDCPA_SECRETKEYBYTES bytes )
void indcpa_keypair(uint8_t pk[KYBER_INDCPA_PUBLICKEYBYTES],
                    uint8_t sk[KYBER_INDCPA_SECRETKEYBYTES])
{
  unsigned int i;
  __attribute__((aligned(32)))
  uint8_t buf[2*KYBER_SYMBYTES];
  const uint8_t *publicseed = buf;
  const uint8_t *noiseseed = buf+KYBER_SYMBYTES;
  polyvec a[KYBER_K], e, pkpv, skpv;
  randombytes(buf, KYBER_SYMBYTES);
  hash_g(buf, buf, KYBER_SYMBYTES);
  gen_a(a, publicseed);
#ifdef KYBER_90S
#define NBLOCKS ((2*KYBER_ETA1*32)/AES256CTR_BLOCKBYTES ) /* Assumes divisibility */
  __attribute__((aligned(16)))
  uint64_t nonce = 0;
  aes256ctr_ctx state;
  __attribute__((aligned(32)))
  uint8_t coins[AES256CTR_BLOCKBYTES*NBLOCKS+2]; 
  aes256ctr_init(&state, noiseseed, nonce++);
  for(i=0;i<KYBER_K;i++) {
    aes256ctr_squeezeblocks(coins, NBLOCKS, &state);
    state.n = _mm_loadl_epi64((__m128i *)&nonce);
    nonce++;
    cbd_eta1(&skpv.vec[i], coins);
  }
  for(i=0;i<KYBER_K;i++) {
    aes256ctr_squeezeblocks(coins, NBLOCKS, &state);
    state.n = _mm_loadl_epi64((__m128i *)&nonce);
    nonce++;
    cbd_eta1(&e.vec[i], coins);
  }
#else
#if KYBER_K == 2
  poly_getnoise_eta1_4x(skpv.vec+0, skpv.vec+1, e.vec+0, e.vec+1, noiseseed,
      0, 1, 2, 3);
#elif KYBER_K == 3
#if KYBER_ETA1 == KYBER_ETA2
  poly_getnoise_eta2_4x(skpv.vec+0, skpv.vec+1, skpv.vec+2, e.vec+0, noiseseed,
                  0, 1, 2, 3);
  poly_getnoise_eta2_4x(e.vec+1, e.vec+2, pkpv.vec+0, pkpv.vec+1, noiseseed,
                  4, 5, 6, 7);
#else
#error "We need eta1 == eta2 here"
#endif
#elif KYBER_K == 4
#if KYBER_ETA1 == KYBER_ETA2
  poly_getnoise_eta2_4x(skpv.vec+0, skpv.vec+1, skpv.vec+2, skpv.vec+3, noiseseed,
                  0, 1, 2, 3);
  poly_getnoise_eta2_4x(e.vec+0, e.vec+1, e.vec+2, e.vec+3, noiseseed,
                  4, 5, 6, 7);
#else
#error "We need eta1 == eta2 here"
#endif
#endif
#endif
  polyvec_ntt(&skpv);
  polyvec_reduce(&skpv);
  polyvec_ntt(&e);
  for(i=0;i<KYBER_K;i++) {
    polyvec_pointwise_acc_montgomery(&pkpv.vec[i], &a[i], &skpv);
    poly_tomont(&pkpv.vec[i]);
  }
  polyvec_add(&pkpv, &pkpv, &e);
  polyvec_reduce(&pkpv);
  pack_sk(sk, &skpv);
  pack_pk(pk, &pkpv, publicseed);
}
void indcpa_keypair ( uint8_t pk [ KYBER_INDCPA_PUBLICKEYBYTES ] , uint8_t sk [ KYBER_INDCPA_SECRETKEYBYTES ] ) { unsigned int i ; __attribute__ ( ( aligned ( 32 ) ) ) uint8_t buf [ 2 * KYBER_SYMBYTES ] ; const uint8_t * publicseed = buf ; const uint8_t * noiseseed = buf + KYBER_SYMBYTES ; polyvec a [ KYBER_K ] , e , pkpv , skpv ; randombytes ( buf , KYBER_SYMBYTES ) ; hash_g ( buf , buf , KYBER_SYMBYTES ) ; gen_a ( a , publicseed ) ; #ifdef KYBER_90S #define NBLOCKS  ((2*KYBER_ETA1*32)/AES256CTR_BLOCKBYTES ) /* Assumes divisibility */ __attribute__ ( ( aligned ( 16 ) ) ) uint64_t nonce = 0 ; aes256ctr_ctx state ; __attribute__ ( ( aligned ( 32 ) ) ) uint8_t coins [ AES256CTR_BLOCKBYTES * NBLOCKS + 2 ] ; aes256ctr_init ( & state , noiseseed , nonce ++ ) ; for ( i = 0 ; i < KYBER_K ; i ++ ) { aes256ctr_squeezeblocks ( coins , NBLOCKS , & state ) ; state . n = _mm_loadl_epi64 ( ( __m128i * ) & nonce ) ; nonce ++ ; cbd_eta1 ( & skpv . vec [ i ] , coins ) ; } for ( i = 0 ; i < KYBER_K ; i ++ ) { aes256ctr_squeezeblocks ( coins , NBLOCKS , & state ) ; state . n = _mm_loadl_epi64 ( ( __m128i * ) & nonce ) ; nonce ++ ; cbd_eta1 ( & e . vec [ i ] , coins ) ; } #else #if KYBER_K == 2 poly_getnoise_eta1_4x ( skpv . vec + 0 , skpv . vec + 1 , e . vec + 0 , e . vec + 1 , noiseseed , 0 , 1 , 2 , 3 ) ; #elif KYBER_K == 3 #if KYBER_ETA1 == KYBER_ETA2 poly_getnoise_eta2_4x ( skpv . vec + 0 , skpv . vec + 1 , skpv . vec + 2 , e . vec + 0 , noiseseed , 0 , 1 , 2 , 3 ) ; poly_getnoise_eta2_4x ( e . vec + 1 , e . vec + 2 , pkpv . vec + 0 , pkpv . vec + 1 , noiseseed , 4 , 5 , 6 , 7 ) ; #else #error  "We need eta1 == eta2 here" #endif #elif KYBER_K == 4 #if KYBER_ETA1 == KYBER_ETA2 poly_getnoise_eta2_4x ( skpv . vec + 0 , skpv . vec + 1 , skpv . vec + 2 , skpv . vec + 3 , noiseseed , 0 , 1 , 2 , 3 ) ; poly_getnoise_eta2_4x ( e . vec + 0 , e . vec + 1 , e . vec + 2 , e . vec + 3 , noiseseed , 4 , 5 , 6 , 7 ) ; #else #error  "We need eta1 == eta2 here" #endif #endif #endif polyvec_ntt ( & skpv ) ; polyvec_reduce ( & skpv ) ; polyvec_ntt ( & e ) ; for ( i = 0 ; i < KYBER_K ; i ++ ) { polyvec_pointwise_acc_montgomery ( & pkpv . vec [ i ] , & a [ i ] , & skpv ) ; poly_tomont ( & pkpv . vec [ i ] ) ; } polyvec_add ( & pkpv , & pkpv , & e ) ; polyvec_reduce ( & pkpv ) ; pack_sk ( sk , & skpv ) ; pack_pk ( pk , & pkpv , publicseed ) ; }
Name:        indcpa_keypair
Description: Generates public and private key for the CPA-secure
public-key encryption scheme underlying Kyber
Name : indcpa_keypair Description : Generates public and private key for the CPA - secure public - key encryption scheme underlying Kyber
/* +2 as required by cbd3 */ // matrix-vector multiplication