// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
//
// This module is an implementation of the encryption pass of the 64bit PRESENT
// block cipher. It is a fully unrolled combinational implementation that
// supports both key sizes specified in the paper (80bit and 128bit). Further,
// the number of rounds is fully configurable, and the primitive supports a
// 32bit block cipher flavor which is not specified in the original paper. It
// should be noted, however, that the 32bit version is **not** secure and must
// not be used in a setting where cryptographic cipher strength is required. The
// 32bit variant is only intended to be used as a lightweight data scrambling
// device.
//
// See also: prim_prince, prim_cipher_pkg
//
// References: - https://en.wikipedia.org/wiki/PRESENT
//             - https://en.wikipedia.org/wiki/Prince_(cipher)
//             - http://www.lightweightcrypto.org/present/present_ches2007.pdf
//             - https://eprint.iacr.org/2012/529.pdf
//             - https://csrc.nist.gov/csrc/media/events/lightweight-cryptography-workshop-2015/
//               documents/papers/session7-maene-paper.pdf

`include "prim_assert.sv"
module prim_present #(
  parameter int DataWidth = 64,  // {32, 64}
  parameter int KeyWidth  = 128, // {64, 80, 128}
  parameter int NumRounds = 31,  // > 0
  // Note that the decryption pass needs a modified key,
  // to be calculated by performing NumRounds key updates
  parameter bit Decrypt   = 0    // 0: encrypt, 1: decrypt
) (
  input        [DataWidth-1:0] data_i,
  input        [KeyWidth-1:0]  key_i,
  // Starting round index for keyschedule [1 ... 31].
  // Set this to 5'd1 for a fully unrolled encryption, and 5'd31 for a fully unrolled decryption.
  input        [4:0]           idx_i,
  output logic [DataWidth-1:0] data_o,
  output logic [KeyWidth-1:0]  key_o,
  // Next round index for keyschedule (Enc: idx_i + NumRounds, Dec: idx_i - NumRounds)
  // Can be ignored for a fully unrolled implementation.
  output logic [4:0]           idx_o
);

  //////////////
  // datapath //
  //////////////

  logic [NumRounds:0][DataWidth-1:0] data_state;
  logic [NumRounds:0][KeyWidth-1:0]  round_key;
  logic [NumRounds:0][4:0]           round_idx;

  // initialize
  assign data_state[0] = data_i;
  assign round_key[0]  = key_i;
  assign round_idx[0]  = idx_i;

  for (genvar k = 0; k < NumRounds; k++) begin : gen_round
    logic [DataWidth-1:0] data_state_xor, data_state_sbox;
    // cipher layers
    assign data_state_xor  = data_state[k] ^ round_key[k][KeyWidth-1 : KeyWidth-DataWidth];
    ////////////////////////////////
    // decryption pass, performs inverse permutation, sbox and keyschedule
    if (Decrypt) begin : gen_dec
      // Decrement round count.
      assign round_idx[k+1] = round_idx[k] - 1'b1;
      // original 64bit variant
      if (DataWidth == 64) begin : gen_d64
        assign data_state_sbox = prim_cipher_pkg::perm_64bit(data_state_xor,
                                                             prim_cipher_pkg::PRESENT_PERM64_INV);
        assign data_state[k+1] = prim_cipher_pkg::sbox4_64bit(data_state_sbox,
                                                              prim_cipher_pkg::PRESENT_SBOX4_INV);
      // reduced 32bit variant
      end else begin : gen_d32
        assign data_state_sbox = prim_cipher_pkg::perm_32bit(data_state_xor,
                                                             prim_cipher_pkg::PRESENT_PERM32_INV);
        assign data_state[k+1] = prim_cipher_pkg::sbox4_32bit(data_state_sbox,
                                                              prim_cipher_pkg::PRESENT_SBOX4_INV);
      end
      // update round key, count goes from 1 to 31 (max)
      // original 128bit key variant
      if (KeyWidth == 128) begin : gen_k128
        assign round_key[k+1]  = prim_cipher_pkg::present_inv_update_key128(round_key[k],
                                                                            round_idx[k]);
      // original 80bit key variant
      end else if (KeyWidth == 80) begin : gen_k80
        assign round_key[k+1]  = prim_cipher_pkg::present_inv_update_key80(round_key[k],
                                                                           round_idx[k]);
      // reduced 64bit key variant
      end else begin : gen_k64
        assign round_key[k+1]  = prim_cipher_pkg::present_inv_update_key64(round_key[k],
                                                                           round_idx[k]);
      end
    ////////////////////////////////
    // encryption pass
    end else begin : gen_enc
      // Increment round count.
      assign round_idx[k+1] = round_idx[k] + 1'b1;
      // original 64bit variant
      if (DataWidth == 64) begin : gen_d64
        assign data_state_sbox = prim_cipher_pkg::sbox4_64bit(data_state_xor,
                                                              prim_cipher_pkg::PRESENT_SBOX4);
        assign data_state[k+1] = prim_cipher_pkg::perm_64bit(data_state_sbox,
                                                             prim_cipher_pkg::PRESENT_PERM64);
      // reduced 32bit variant
      end else begin : gen_d32
        assign data_state_sbox = prim_cipher_pkg::sbox4_32bit(data_state_xor,
                                                              prim_cipher_pkg::PRESENT_SBOX4);
        assign data_state[k+1] = prim_cipher_pkg::perm_32bit(data_state_sbox,
                                                             prim_cipher_pkg::PRESENT_PERM32);
      end
      // update round key, count goes from 1 to 31 (max)
      // original 128bit key variant
      if (KeyWidth == 128) begin : gen_k128
        assign round_key[k+1]  = prim_cipher_pkg::present_update_key128(round_key[k], round_idx[k]);
      // original 80bit key variant
      end else if (KeyWidth == 80) begin : gen_k80
        assign round_key[k+1]  = prim_cipher_pkg::present_update_key80(round_key[k], round_idx[k]);
      // reduced 64bit key variant
      end else begin : gen_k64
        assign round_key[k+1]  = prim_cipher_pkg::present_update_key64(round_key[k], round_idx[k]);
      end
    end // gen_enc
    ////////////////////////////////
  end // gen_round

  // finalize
  assign data_o = data_state[NumRounds] ^ round_key[NumRounds][KeyWidth-1 : KeyWidth-DataWidth];
  assign key_o  = round_key[NumRounds];
  assign idx_o  = round_idx[NumRounds];

  ////////////////
  // assertions //
  ////////////////

  `ASSERT_INIT(SupportedWidths_A, (DataWidth == 64 && KeyWidth inside {80, 128}) ||
                                  (DataWidth == 32 && KeyWidth == 64))
  `ASSERT_INIT(SupportedNumRounds_A, NumRounds > 0 && NumRounds <= 31)

endmodule : prim_present
