SEAL开源库源码05

本文详细剖析了SEAL开源库中的DynArray类,讨论了其内存管理、线程安全及动态调整大小的功能。同时,介绍了随机数生成的相关类,如UniformRandomGenerator,探讨了随机数生成器的创建、使用和种子管理。通过对加密参数EncryptionParameters的分析,展示了如何设置加密方案的关键参数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

SEAL开源库源码05

文章目录


最终目的要分析 seal/encryptionparams.h

seal/dynarray.h

引用的头文件

#include "seal/memorymanager.h"
#include "seal/serialization.h"
#include "seal/version.h"
#include "seal/util/common.h"
#include "seal/util/defines.h"
#include "seal/util/pointer.h"
#include <algorithm>
#include <iostream>
#include <limits>
#include <type_traits>
#ifdef SEAL_USE_MSGSL
#include "gsl/span"
#endif

一些声明

namespace seal
{
   
   
    class Ciphertext;

    // Forward-declaring the deflate_size_bound function
    namespace util
    {
   
   
        namespace ztools
        {
   
   
            template <typename SizeT>
            SEAL_NODISCARD SizeT deflate_size_bound(SizeT in_size);
        } // namespace ztools
    } // namespace util

DynArray 类,位于 namespace seal 中

类说明

/**
A dynamic array for storing objects allocated from a Microsoft SEAL memory
pool. The DynArray class is mainly intended for internal use and provides
the underlying data structure for Plaintext and Ciphertext classes.

@par Size and Capacity
DynArray allows the user to pre-allocate memory (capacity) for the array
in cases where the array is known to be resized in the future and memory
moves are to be avoided at the time of resizing. The size of the DynArray
can never exceed its capacity. The capacity and size can be changed using
the reserve and resize functions, respectively.

@par Thread Safety
In general, reading from DynArray is thread-safe as long as no other thread
is concurrently mutating it.
*/

一个动态数组,用于存储从Microsoft SEAL内存池分配的对象。DynArray类主要用于内部使用,并为明文和密文类提供底层数据结构。

@par大小和容量
DynArray允许用户为数组预分配内存(容量),在数组已知将在未来调整大小的情况下,并在调整大小时避免内存移动。DynArray的大小永远不能超过它的容量。容量和大小可以分别使用reserve和resize函数进行更改。

@par线程安全
一般来说,从DynArray读取数据是线程安全的,只要没有其他线程并发地修改它。

声明友元类

    template <typename T>
    class DynArray
    {
   
   
        friend class Ciphertext;

定义别名


    public:
        using type = T;

构造函数,不分配空间

        /**
        Creates a new DynArray. No memory is allocated by this constructor.

        @param[in] pool The MemoryPoolHandle pointing to a valid memory pool
        @throws std::invalid_argument if pool is uninitialized
        */
        DynArray(MemoryPoolHandle pool = MemoryManager::GetPool()) : pool_(std::move(pool))  // 默认参数是default
        {
   
   
            if (!pool_)
            {
   
   
                throw std::invalid_argument("pool is uninitialized");
            }
        }

给定 size 的构造函数,调用 resize 函数

        /**
        Creates a new DynArray with given size.

        @param[in] size The size of the array
        @param[in] pool The MemoryPoolHandle pointing to a valid memory pool
        @throws std::invalid_argument if pool is uninitialized
        */
        explicit DynArray(std::size_t size, MemoryPoolHandle pool = MemoryManager::GetPool()) : pool_(std::move(pool))
        {
   
   
            if (!pool_)
            {
   
   
                throw std::invalid_argument("pool is uninitialized");
            }

            // Reserve memory, resize, and set to zero
            resize(size);
        }

给定 capacity 和 size 的构造函数,调用 reserve(预留) 和 resize 函数

        /**
        Creates a new DynArray with given capacity and size.

        @param[in] capacity The capacity of the array
        @param[in] size The size of the array
        @param[in] pool The MemoryPoolHandle pointing to a valid memory pool
        @throws std::invalid_argument if capacity is less than size
        @throws std::invalid_argument if pool is uninitialized
        */
        explicit DynArray(std::size_t capacity, std::size_t size, MemoryPoolHandle pool = MemoryManager::GetPool())
            : pool_(std::move(pool))
        {
   
   
            if (!pool_)
            {
   
   
                throw std::invalid_argument("pool is uninitialized");
            }
            if (capacity < size)
            {
   
   
                throw std::invalid_argument("capacity cannot be smaller than size");
            }

            // Reserve memory, resize, and set to zero
            reserve(capacity);
            resize(size);
        }

包装指针的构造函数

创建一个给定大小的新DynArray包装给定的指针。这个构造函数不分配内存。如果DynArray超出作用域,这里给出的指针对象将被销毁。在调整DynArray的大小到更大的大小,数据将被复制到一个新的分配内存池指针由给定的MemoryPoolHandle和这里给出的指针对象随后将被销毁。与其他构造函数不同,这个构造函数提供了不自动填充已分配内存的选项。

        /**
        Creates a new DynArray with given size wrapping a given pointer. This
        constructor allocates no memory. If the DynArray goes out of scope, the
        Pointer object given here is destroyed. On resizing the DynArray to larger
        size, the data will be copied over to a new allocation from the memory pool
        pointer to by the given MemoryPoolHandle and the Pointer object given here
        will subsequently be destroyed. Unlike the other constructors, this one
        exposes the option of not automatically zero-filling the allocated memory.

        @param[in] ptr An initial Pointer object to wrap
        @param[in] capacity The capacity of the array
        @param[in] size The size of the array
        @param[in] fill_zero If true, fills ptr with zeros
        @param[in] pool The MemoryPoolHandle pointing to a valid memory pool
        @throws std::invalid_argument if ptr is null and capacity is positive
        @throws std::invalid_argument if capacity is less than size
        @throws std::invalid_argument if pool is uninitialized
        */
        explicit DynArray(
            util::Pointer<T> &&ptr, std::size_t capacity, std::size_t size, bool fill_zero,
            MemoryPoolHandle pool = MemoryManager::GetPool())
            : pool_(std::move(pool)), capacity_(capacity)
        {
   
   
            if (!ptr && capacity)
            {
   
   
                throw std::invalid_argument("ptr cannot be null");
            }
            if (!pool_)
            {
   
   
                throw std::invalid_argument("pool is uninitialized");
            }
            if (capacity < size)
            {
   
   
                throw std::invalid_argument("capacity cannot be smaller than size");
            }

            // Grab the given Pointer
            data_ = std::move(ptr);

            // Resize, and optionally set to zero
            resize(size, fill_zero);
        }

        /**
        Creates a new DynArray with given size wrapping a given pointer. This
        constructor allocates no memory. If the DynArray goes out of scope, the
        Pointer object given here is destroyed. On resizing the DynArray to larger
        size, the data will be copied over to a new allocation from the memory pool
        pointer to by the given MemoryPoolHandle and the Pointer object given here
        will subsequently be destroyed. Unlike the other constructors, this one
        exposes the option of not automatically zero-filling the allocated memory.

        @param[in] ptr An initial Pointer object to wrap
        @param[in] size The size of the array
        @param[in] fill_zero If true, fills ptr with zeros
        @param[in] pool The MemoryPoolHandle pointing to a valid memory pool
        @throws std::invalid_argument if ptr is null and size is positive
        @throws std::invalid_argument if pool is uninitialized
        */
        explicit DynArray(
            util::Pointer<T> &&ptr, std::size_t size, bool fill_zero, MemoryPoolHandle pool = MemoryManager::GetPool())
            : DynArray(std::move(ptr), size, size, fill_zero, std::move(pool))
        {
   
   }

构造函数, initialized with data from a given buffer.

#ifdef SEAL_USE_MSGSL
        /**
        Creates a new DynArray with given capacity, initialized with data from
        a given buffer.

        @param[in] values Desired contents of the array
        @param[in] capacity The capacity of the array
        @param[in] pool The MemoryPoolHandle pointing to a valid memory pool
        @throws std::invalid_argument if capacity is less than the size of values
        @throws std::invalid_argument if pool is uninitialized
        */
        explicit DynArray(
            gsl::span<const T> values, std::size_t capacity, MemoryPoolHandle pool = MemoryManager::GetPool())
            : DynArray(capacity, values.size(), std::move(pool))
        {
   
   
            std::copy(values.begin(), values.end(), data_.get());
        }

        /**
        Creates a new DynArray initialized with data from a given buffer.

        @param[in] values Desired contents of the array
        @param[in] pool The MemoryPoolHandle pointing to a valid memory pool
        @throws std::invalid_argument if pool is uninitialized
        */
        explicit DynArray(gsl::span<const T> values, MemoryPoolHandle pool = MemoryManager::GetPool())
            : DynArray(values, values.size(), std::move(pool))
        {
   
   }
#endif

拷贝构造和移动构造

        /**
        Creates a new DynArray by copying a given one.

        @param[in] copy The DynArray to copy from
        */
        DynArray(const DynArray<T> &copy)
            : pool_(MemoryManager::GetPool()), capacity_(copy.size_), size_(copy.size_),
              data_(util::allocate<T>(copy.size_, pool_))
        {
   
   
            // Copy over value
            std::copy(copy.cbegin(), copy.cend(), begin());
        }

        /**
        Creates a new DynArray by moving a given one.

        @param[in] source The DynArray to move from
        */
        DynArray(DynArray<T> &&source) noexcept
            : pool_(std::move(source.pool_)), capacity_(source.capacity_), size_(source.size_),
              data_(std::move(source.data_))
        {
   
   }

析构函数

        /**
        Destroys the DynArray.
        */
        ~DynArray()
        {
   
   
            release();
        }

begin 函数,返回指向第一个元素的指针

        /**
        Returns a pointer to the beginning of the array data.
        */
        SEAL_NODISCARD inline T *begin() noexcept
        {
   
   
            return data_.get();
        }

begin函数 和 cbegin 函数,返回指向第一个元素的常量指针

常量指针

        /**
        Returns a constant pointer to the beginning of the array data.
        */
        SEAL_NODISCARD inline const T *begin() const noexcept
        {
   
   
            return cbegin();
        }

        /**
        Returns a constant pointer to the beginning of the array data.
        */
        SEAL_NODISCARD inline const T *cbegin() const noexcept
        {
   
   
            return data_.get();
        }

end 函数,返回指向最后一个元素的指针,跟 begin 类似

        /**
        Returns a pointer to the end of the array data.
        */
        SEAL_NODISCARD inline T *end() noexcept
        {
   
   
            return begin() + size_;
        }

        /**
        Returns a constant pointer to the end of the array data.
        */
        SEAL_NODISCARD inline const T *end() const noexcept
        {
   
   
            return cend();
        }

        /**
        Returns a constant pointer to the end of the array data.
        */
        SEAL_NODISCARD inline const T *cend() const noexcept
        {
   
   
            return cbegin() + size_;
        }

gsl span

GSL库入门
GSL参考手册

#ifdef SEAL_USE_MSGSL
        /**
        Returns a span pointing to the beginning of the DynArray.
        */
        SEAL_NODISCARD inline gsl::span<T> span()
        {
   
   
            return gsl::span<T>(begin(), size_);
        }

        /**
        Returns a span pointing to the beginning of the DynArray.
        */
        SEAL_NODISCARD inline gsl::span<const T> span() const
        {
   
   
            return gsl::span<const T>(cbegin(), size_);
        }
#endif

at 函数,两个版本

        /**
        Returns a constant reference to the array element at a given index.
        This function performs bounds checking and will throw an error if
        the index is out of range.

        @param[in] index The index of the array element
        @throws std::out_of_range if index is out of range
        */
        SEAL_NODISCARD inline const T &at(std::size_t index) const
        {
   
   
            if (index >= size_)
            {
   
   
                throw std::out_of_range("index must be within [0, size)");
            }
            return data_[index];
        }

        /**
        Returns a reference to the array element at a given index. This
        function performs bounds checking and will throw an error if the
        index is out of range.

        @param[in] index The index of the array element
        @throws std::out_of_range if index is out of range
        */
        SEAL_NODISCARD inline T &at(std::size_t index)
        {
   
   
            if (index >= size_)
            {
   
   
                throw std::out_of_range("index must be within [0, size)");
            }
            return data_[index];
        }

[ ] 运算符,跟 at 函数差不多

        /**
        Returns a constant reference to the array element at a given index.
        This function does not perform bounds checking.

        @param[in] index The index of the array element
        */
        SEAL_NODISCARD inline const T &operator[](std::size_t index) const
        {
   
   
            return data_[index];
        }

        /**
        Returns a reference to the array element at a given index. This
        function does not perform bounds checking.

        @param[in] index The index of the array element
        */
        SEAL_NODISCARD inline T &operator[](std::size_t index)
        {
   
   
            return data_[index];
        }

empty 函数,判断是否为空


        /**
        Returns whether the array has size zero.
        */
        SEAL_NODISCARD inline bool empty() const noexcept
        {
   
   
            return (size_ == 0);
        }

max_size 函数,返回数组可能的最大size

        /**
        Returns the largest possible array size.
        */
        SEAL_NODISCARD inline std::size_t max_size() const noexcept
        {
   
   
            return (std::numeric_limits<std::size_t>::max)();
        }

size 函数,返回此时数组的大小

        /**
        Returns the size of the array.
        */
        SEAL_NODISCARD inline std::size_t size() const noexcept
        {
   
   
            return size_;
        }

capacity 函数

        /**
        Returns the capacity of the array.
        */
        SEAL_NODISCARD inline std::size_t capacity() const noexcept
        {
   
   
            return capacity_;
        }

pool 函数


        /**
        Returns the currently used MemoryPoolHandle.
        */
        SEAL_NODISCARD inline MemoryPoolHandle pool() const noexcept
        {
   
   
            return pool_;
        }

release 函数,把内存还给 memory pool

        /**
        Releases any allocated memory to the memory pool and sets the size
        and capacity of the array to zero.
        */
        inline void release() noexcept
        {
   
   
            capacity_ = 0;
            size_ = 0;
            data_.release();
        }

clear 函数

        /**
        Sets the size of the array to zero. The capacity is not changed.
        */
        inline void clear() noexcept
        {
   
   
            size_ = 0;
        }

reserve 函数

    Allocates enough memory for storing a given number of elements without
    changing the size of the array. If the given capacity is smaller than
    the current size, the size is automatically set to equal the new capacity.

std::copy_n
功能:第一个参数为源起始位置,第二个参数是要复制的大小,第三个参数是目标起始位置

        /**
        Allocates enough memory for storing a given number of elements without
        changing the size of the array. If the given capacity is smaller than
        the current size, the size is automatically set to equal the new capacity.

        @param[in] capacity The capacity of the array
        */
        inline void reserve(std::size_t capacity)
        {
   
   
            std::size_t copy_size = std::min<>(capacity, size_);

            // Create new allocation and copy over value
            auto new_data(util::allocate<T>(capacity, pool_));
            std::copy_n(cbegin(), copy_size, new_data.get());
            std::swap(data_, new_data);

            // Set the coeff_count and capacity
            capacity_ = capacity;
            size_ = copy_size;
        }

shrink_to_fit 函数


        /**
        Reallocates the array so that its capacity exactly matches its size.
        */
        inline void shrink_to_fit()
        {
   
   
            reserve(size_);
        }

resize 函数

	Resizes the array to given size. When resizing to larger size the data
    in the array remains unchanged and any new space is initialized to zero
    if fill_zero is set to true; when resizing to smaller size the last
    elements of the array are dropped. If the capacity is not already large
    enough to hold the new size, the array is also reallocated.

将数组的大小调整为给定的大小。当调整到更大的大小,数组中的数据保持不变,任何新的空间初始化为零,如果fill_zero设置为true;当将数组大小调整为更小时,将删除数组的最后一个元素。如果容量还不足以容纳新大小,则还会重新分配数组。

        /**
        Resizes the array to given size. When resizing to larger size the data
        in the array remains unchanged and any new space is initialized to zero
        if fill_zero is set to true; when resizing to smaller size the last
        elements of the array are dropped. If the capacity is not already large
   
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值