/*
 * Copyright (c) 2022 Cisco and/or its affiliates.
 * 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:
 *
 *     http://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.
 */
/*
 * PCG Random Number Generation for C.
 *
 * Copyright 2014-2019 Melissa O'Neill <oneill@pcg-random.org>,
 *                     and the PCG Project contributors.
 *
 * SPDX-License-Identifier: (Apache-2.0 OR MIT)
 *
 * Licensed under the Apache License, Version 2.0 (provided in
 * LICENSE-APACHE.txt and at http://www.apache.org/licenses/LICENSE-2.0)
 * or under the MIT license (provided in LICENSE-MIT.txt and at
 * http://opensource.org/licenses/MIT), at your option. This file may not
 * be copied, modified, or distributed except according to those terms.
 *
 * Distributed on an "AS IS" BASIS, WITHOUT WARRANTY OF ANY KIND, either
 * express or implied.  See your chosen license for details.
 *
 * For additional information about the PCG random number generation scheme,
 * visit http://www.pcg-random.org/.
 */

/* This implements the pcg64i_random_t PCG specialized generator:
 * https://www.pcg-random.org/using-pcg-c.html#specialized-generators
 * This generator produces each 64-bits output exactly once, which is
 * perfectly suited to generated non-repeating IVs. However, because of this
 * property the entire internal state is revealed with each output.
 * It has a 2^64 period and supports 2^63 non-overlaping streams */

#define clib_pcg64i_random_r  clib_pcg_setseq_64_rxs_m_xs_64_random_r
#define clib_pcg64i_srandom_r clib_pcg_setseq_64_srandom_r

typedef struct
{
  u64 state;
  u64 inc;
} clib_pcg_state_setseq_64_t;

typedef clib_pcg_state_setseq_64_t clib_pcg64i_random_t;

static_always_inline void
clib_pcg_setseq_64_step_r (clib_pcg_state_setseq_64_t *rng)
{
  rng->state = rng->state * 6364136223846793005ULL + rng->inc;
}

static_always_inline u64
clib_pcg_output_rxs_m_xs_64_64 (u64 state)
{
  u64 word =
    ((state >> ((state >> 59u) + 5u)) ^ state) * 12605985483714917081ull;
  return (word >> 43u) ^ word;
}

static_always_inline u64
clib_pcg_setseq_64_rxs_m_xs_64_random_r (clib_pcg_state_setseq_64_t *rng)
{
  u64 oldstate = rng->state;
  clib_pcg_setseq_64_step_r (rng);
  return clib_pcg_output_rxs_m_xs_64_64 (oldstate);
}

static_always_inline void
clib_pcg_setseq_64_srandom_r (clib_pcg_state_setseq_64_t *rng, u64 initstate,
			      u64 initseq)
{
  rng->state = 0U;
  rng->inc = (initseq << 1u) | 1u;
  clib_pcg_setseq_64_step_r (rng);
  rng->state += initstate;
  clib_pcg_setseq_64_step_r (rng);
}
