Program Listing for File random.cuh

Return to documentation for file (src/include/heongpu/util/random.cuh)

// Copyright 2024-2026 Alişah Özcan
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
// Developer: Alişah Özcan

#ifndef HEONGPU_RANDOM_GENERATOR_CLASS_H
#define HEONGPU_RANDOM_GENERATOR_CLASS_H

#include <mutex>
#include <memory>
#include <vector>
#include <sys/sysinfo.h>
#include "gpuntt/common/common.cuh"
#include "gpufft/complex.cuh"
#include "rngongpu/rand_aes/aes_rng.cuh"

// --------------------- //
// Author: Alisah Ozcan
// --------------------- //

namespace heongpu
{
    struct RNGSeed
    {
        std::vector<unsigned char> key_;
        std::vector<unsigned char> nonce_;
        std::vector<unsigned char> personalization_string_;

        RNGSeed()
        {
            key_ = std::vector<unsigned char>(16); // for 128 bit
            if (1 != RAND_bytes(key_.data(), key_.size()))
                throw std::runtime_error("RAND_bytes failed");
            nonce_ = std::vector<unsigned char>(8); // for 128 bit
            if (1 != RAND_bytes(nonce_.data(), nonce_.size()))
                throw std::runtime_error("RAND_bytes failed");
        }

        RNGSeed(const std::vector<unsigned char>& key,
                const std::vector<unsigned char>& nonce,
                const std::vector<unsigned char>& personalization_string)
            : key_(key), nonce_(nonce),
              personalization_string_(personalization_string)
        {
            if (key_.size() < 16)
            {
                throw std::invalid_argument("Invalid key size!");
            }
        }
    };

    class RandomNumberGenerator
    {
      public:
        static RandomNumberGenerator& instance();

        void
        initialize(const std::vector<unsigned char>& key,
                   const std::vector<unsigned char>& nonce,
                   const std::vector<unsigned char>& personalization_string,
                   rngongpu::SecurityLevel security_level,
                   bool prediction_resistance_enabled);

        ~RandomNumberGenerator();

        void set(const std::vector<unsigned char>& entropy_input,
                 const std::vector<unsigned char>& nonce,
                 const std::vector<unsigned char>& personalization_string,
                 cudaStream_t stream = cudaStreamDefault);

        __host__ void modular_uniform_random_number_generation(
            Data64* pointer, Modulus64* modulus, Data64 log_size, int mod_count,
            int repeat_count, cudaStream_t stream = cudaStreamDefault);

        __host__ void modular_uniform_random_number_generation(
            Data64* pointer, Modulus64* modulus, Data64 log_size, int mod_count,
            int repeat_count, std::vector<unsigned char>& entropy_input,
            std::vector<unsigned char> additional_input,
            cudaStream_t stream = cudaStreamDefault);

        __host__ void modular_uniform_random_number_generation(
            Data64* pointer, Modulus64* modulus, Data64 log_size, int mod_count,
            int* mod_index, int repeat_count,
            cudaStream_t stream = cudaStreamDefault);

        __host__ void modular_uniform_random_number_generation(
            Data64* pointer, Modulus64* modulus, Data64 log_size, int mod_count,
            int* mod_index, int repeat_count,
            std::vector<unsigned char>& entropy_input,
            std::vector<unsigned char> additional_input,
            cudaStream_t stream = cudaStreamDefault);

        __host__ void modular_gaussian_random_number_generation(
            Float64 std_dev, Data64* pointer, Modulus64* modulus,
            Data64 log_size, int mod_count, int repeat_count,
            cudaStream_t stream = cudaStreamDefault);

        __host__ void modular_gaussian_random_number_generation(
            Float64 std_dev, Data64* pointer, Modulus64* modulus,
            Data64 log_size, int mod_count, int repeat_count,
            std::vector<unsigned char>& entropy_input,
            std::vector<unsigned char> additional_input,
            cudaStream_t stream = cudaStreamDefault);

        __host__ void modular_gaussian_random_number_generation(
            Float64 std_dev, Data64* pointer, Modulus64* modulus,
            Data64 log_size, int mod_count, int* mod_index, int repeat_count,
            cudaStream_t stream = cudaStreamDefault);

        __host__ void modular_gaussian_random_number_generation(
            Float64 std_dev, Data64* pointer, Modulus64* modulus,
            Data64 log_size, int mod_count, int* mod_index, int repeat_count,
            std::vector<unsigned char>& entropy_input,
            std::vector<unsigned char> additional_input,
            cudaStream_t stream = cudaStreamDefault);

        __host__ void modular_ternary_random_number_generation(
            Data64* pointer, Modulus64* modulus, Data64 log_size, int mod_count,
            int repeat_count, cudaStream_t stream = cudaStreamDefault);

        __host__ void modular_ternary_random_number_generation(
            Data64* pointer, Modulus64* modulus, Data64 log_size, int mod_count,
            int repeat_count, std::vector<unsigned char>& entropy_input,
            std::vector<unsigned char> additional_input,
            cudaStream_t stream = cudaStreamDefault);

        __host__ void modular_ternary_random_number_generation(
            Data64* pointer, Modulus64* modulus, Data64 log_size, int mod_count,
            int* mod_index, int repeat_count,
            cudaStream_t stream = cudaStreamDefault);

        __host__ void modular_ternary_random_number_generation(
            Data64* pointer, Modulus64* modulus, Data64 log_size, int mod_count,
            int* mod_index, int repeat_count,
            std::vector<unsigned char>& entropy_input,
            std::vector<unsigned char> additional_input,
            cudaStream_t stream = cudaStreamDefault);

      private:
        RandomNumberGenerator();
        RandomNumberGenerator(const RandomNumberGenerator&) = delete;
        RandomNumberGenerator& operator=(const RandomNumberGenerator&) = delete;

        static std::shared_ptr<rngongpu::RNG<rngongpu::Mode::AES>> generator_;
        static bool initialized_;
        static std::mutex mutex_;
    };

} // namespace heongpu
#endif // HEONGPU_RANDOM_GENERATOR_CLASS_H