// Copyright 2024 The BoringSSL Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <openssl/mlkem.h>

#include "../fipsmodule/bcm_interface.h"


static_assert(sizeof(BCM_mlkem768_private_key) <= sizeof(MLKEM768_private_key));
static_assert(alignof(BCM_mlkem768_private_key) <=
              alignof(MLKEM768_private_key));
static_assert(sizeof(BCM_mlkem768_public_key) <= sizeof(MLKEM768_public_key));
static_assert(alignof(BCM_mlkem768_public_key) <= alignof(MLKEM768_public_key));
static_assert(MLKEM768_PUBLIC_KEY_BYTES == BCM_MLKEM768_PUBLIC_KEY_BYTES);
static_assert(MLKEM_SEED_BYTES == BCM_MLKEM_SEED_BYTES);
static_assert(MLKEM768_CIPHERTEXT_BYTES == BCM_MLKEM768_CIPHERTEXT_BYTES);
static_assert(MLKEM_SHARED_SECRET_BYTES == BCM_MLKEM_SHARED_SECRET_BYTES);
static_assert(MLKEM1024_PUBLIC_KEY_BYTES == BCM_MLKEM1024_PUBLIC_KEY_BYTES);
static_assert(MLKEM1024_CIPHERTEXT_BYTES == BCM_MLKEM1024_CIPHERTEXT_BYTES);

void MLKEM768_generate_key(
    uint8_t out_encoded_public_key[MLKEM768_PUBLIC_KEY_BYTES],
    uint8_t optional_out_seed[MLKEM_SEED_BYTES],
    struct MLKEM768_private_key *out_private_key) {
  BCM_mlkem768_generate_key(
      out_encoded_public_key, optional_out_seed,
      reinterpret_cast<BCM_mlkem768_private_key *>(out_private_key));
}

int MLKEM768_private_key_from_seed(struct MLKEM768_private_key *out_private_key,
                                   const uint8_t *seed, size_t seed_len) {
  return bcm_success(BCM_mlkem768_private_key_from_seed(
      reinterpret_cast<BCM_mlkem768_private_key *>(out_private_key), seed,
      seed_len));
}

void MLKEM768_public_from_private(
    struct MLKEM768_public_key *out_public_key,
    const struct MLKEM768_private_key *private_key) {
  (void)BCM_mlkem768_public_from_private(
      reinterpret_cast<BCM_mlkem768_public_key *>(out_public_key),
      reinterpret_cast<const BCM_mlkem768_private_key *>(private_key));
}

void MLKEM768_encap(uint8_t out_ciphertext[MLKEM768_CIPHERTEXT_BYTES],
                    uint8_t out_shared_secret[MLKEM_SHARED_SECRET_BYTES],
                    const struct MLKEM768_public_key *public_key) {
  (void)BCM_mlkem768_encap(
      out_ciphertext, out_shared_secret,
      reinterpret_cast<const BCM_mlkem768_public_key *>(public_key));
}

int MLKEM768_decap(uint8_t out_shared_secret[MLKEM_SHARED_SECRET_BYTES],
                   const uint8_t *ciphertext, size_t ciphertext_len,
                   const struct MLKEM768_private_key *private_key) {
  return bcm_success(BCM_mlkem768_decap(
      out_shared_secret, ciphertext, ciphertext_len,
      reinterpret_cast<const BCM_mlkem768_private_key *>(private_key)));
}

int MLKEM768_marshal_public_key(CBB *out,
                                const struct MLKEM768_public_key *public_key) {
  return bcm_success(BCM_mlkem768_marshal_public_key(
      out, reinterpret_cast<const BCM_mlkem768_public_key *>(public_key)));
}

int MLKEM768_parse_public_key(struct MLKEM768_public_key *out_public_key,
                              CBS *in) {
  return bcm_success(BCM_mlkem768_parse_public_key(
      reinterpret_cast<BCM_mlkem768_public_key *>(out_public_key), in));
}


static_assert(sizeof(BCM_mlkem1024_private_key) <=
              sizeof(MLKEM1024_private_key));
static_assert(alignof(BCM_mlkem1024_private_key) <=
              alignof(MLKEM1024_private_key));
static_assert(sizeof(BCM_mlkem1024_public_key) <= sizeof(MLKEM1024_public_key));
static_assert(alignof(BCM_mlkem1024_public_key) <=
              alignof(MLKEM1024_public_key));

void MLKEM1024_generate_key(
    uint8_t out_encoded_public_key[MLKEM1024_PUBLIC_KEY_BYTES],
    uint8_t optional_out_seed[MLKEM_SEED_BYTES],
    struct MLKEM1024_private_key *out_private_key) {
  (void)BCM_mlkem1024_generate_key(
      out_encoded_public_key, optional_out_seed,
      reinterpret_cast<BCM_mlkem1024_private_key *>(out_private_key));
}

int MLKEM1024_private_key_from_seed(
    struct MLKEM1024_private_key *out_private_key, const uint8_t *seed,
    size_t seed_len) {
  return bcm_success(BCM_mlkem1024_private_key_from_seed(
      reinterpret_cast<BCM_mlkem1024_private_key *>(out_private_key), seed,
      seed_len));
}

void MLKEM1024_public_from_private(
    struct MLKEM1024_public_key *out_public_key,
    const struct MLKEM1024_private_key *private_key) {
  (void)BCM_mlkem1024_public_from_private(
      reinterpret_cast<BCM_mlkem1024_public_key *>(out_public_key),
      reinterpret_cast<const BCM_mlkem1024_private_key *>(private_key));
}

void MLKEM1024_encap(uint8_t out_ciphertext[MLKEM1024_CIPHERTEXT_BYTES],
                     uint8_t out_shared_secret[MLKEM_SHARED_SECRET_BYTES],
                     const struct MLKEM1024_public_key *public_key) {
  (void)BCM_mlkem1024_encap(
      out_ciphertext, out_shared_secret,
      reinterpret_cast<const BCM_mlkem1024_public_key *>(public_key));
}

int MLKEM1024_decap(uint8_t out_shared_secret[MLKEM_SHARED_SECRET_BYTES],
                    const uint8_t *ciphertext, size_t ciphertext_len,
                    const struct MLKEM1024_private_key *private_key) {
  return bcm_success(BCM_mlkem1024_decap(
      out_shared_secret, ciphertext, ciphertext_len,
      reinterpret_cast<const BCM_mlkem1024_private_key *>(private_key)));
}

int MLKEM1024_marshal_public_key(
    CBB *out, const struct MLKEM1024_public_key *public_key) {
  return bcm_success(BCM_mlkem1024_marshal_public_key(
      out, reinterpret_cast<const BCM_mlkem1024_public_key *>(public_key)));
}

int MLKEM1024_parse_public_key(struct MLKEM1024_public_key *out_public_key,
                               CBS *in) {
  return bcm_success(BCM_mlkem1024_parse_public_key(
      reinterpret_cast<BCM_mlkem1024_public_key *>(out_public_key), in));
}
