Example #1
0
        /// <summary>
        /// Encrypts a zero plaintext with the secret key and stores the result in
        /// destination.
        /// </summary>
        /// <remarks>
        /// The encryption parameters for the resulting ciphertext correspond to the
        /// highest (data) level in the modulus switching chain. Dynamic memory
        /// allocations in the process are allocated from the memory pool pointed to
        /// by the given MemoryPoolHandle.
        ///
        /// Half of the polynomials in relinearization keys are randomly generated
        /// and are replaced with the seed used to compress output size. The output
        /// is in binary format and not human-readable. The output stream must have
        /// the "binary" flag set.
        /// </remarks>
        /// <param name="stream">The stream to save the Ciphertext to</param>
        /// <param name="comprMode">The desired compression mode</param>
        /// <param name="pool">The MemoryPoolHandle pointing to a valid memory
        /// pool</param>
        /// <exception cref="ArgumentNullException">if stream is null</exception>
        /// <exception cref="InvalidOperationException">if a secret key is not
        /// set</exception>
        /// <exception cref="ArgumentException">if the stream is closed or does not
        /// support writing</exception>
        /// <exception cref="IOException">if I/O operations failed</exception>
        /// <exception cref="InvalidOperationException">if compression mode is not
        /// supported, or if compression failed</exception>
        /// <exception cref="ArgumentException">if pool is uninitialized</exception>
        public long EncryptZeroSymmetricSave(
            Stream stream, ComprModeType?comprMode = null,
            MemoryPoolHandle pool = null)
        {
            if (null == stream)
            {
                throw new ArgumentNullException(nameof(stream));
            }

            comprMode = comprMode ?? Serialization.ComprModeDefault;
            if (!Serialization.IsSupportedComprMode(comprMode.Value))
            {
                throw new InvalidOperationException("Unsupported compression mode");
            }

            IntPtr poolHandle = pool?.NativePtr ?? IntPtr.Zero;

            using (Ciphertext destination = new Ciphertext(pool))
            {
                NativeMethods.Encryptor_EncryptZeroSymmetric2(
                    NativePtr, true, destination.NativePtr, poolHandle);

                return(destination.Save(stream, comprMode));
            }
        }
Example #2
0
        /// <summary>
        /// Encrypts a zero plaintext with the public key and returns the ciphertext
        /// as a serializable object.
        /// </summary>
        /// <remarks>
        /// <para>
        /// Encrypts a zero plaintext with the public key and returns the ciphertext
        /// as a serializable object.
        /// </para>
        /// <para>
        /// The encryption parameters for the resulting ciphertext correspond to the
        /// highest (data) level in the modulus switching chain. Dynamic memory
        /// allocations in the process are allocated from the memory pool pointed to
        /// by the given MemoryPoolHandle.
        /// </para>
        /// </remarks>
        /// <param name="pool">The MemoryPoolHandle pointing to a valid memory
        /// pool</param>
        /// <exception cref="InvalidOperationException">if a public key is not
        /// set</exception>
        /// <exception cref="ArgumentException">if pool is uninitialized</exception>
        public Serializable <Ciphertext> EncryptZero(MemoryPoolHandle pool = null)
        {
            Ciphertext destination = new Ciphertext();

            EncryptZero(destination, pool);
            return(new Serializable <Ciphertext>(destination));
        }
Example #3
0
        /// <summary>
        /// Loads a RelinKeys from an input stream overwriting the current RelinKeys.
        /// No checking of the validity of the RelinKeys data against encryption
        /// parameters is performed. This function should not be used unless the
        /// RelinKeys comes from a fully trusted source.
        /// </summary>
        /// <param name="stream">The stream to load the RelinKeys from</param>
        /// <exception cref="ArgumentNullException">if stream is null</exception>
        /// <exception cref="ArgumentException">if valid RelinKeys could not be read
        /// from stream</exception>
        public void UnsafeLoad(Stream stream)
        {
            if (null == stream)
            {
                throw new ArgumentNullException(nameof(stream));
            }

            try
            {
                // Read the ParmsId
                ParmsId parmsId = new ParmsId();
                parmsId.Load(stream);
                ParmsId = parmsId;

                using (BinaryReader reader = new BinaryReader(stream, Encoding.UTF8, leaveOpen: true))
                {
                    // Read the decomposition bit count
                    int dbc = reader.ReadInt32();
                    DecompositionBitCount = dbc;

                    // Read the size
                    ulong size = reader.ReadUInt64();

                    // Clear current data and reserve new size
                    NativeMethods.RelinKeys_ClearDataAndReserve(NativePtr, size);

                    // Read all lists
                    for (ulong i = 0; i < size; i++)
                    {
                        // Read size of second list
                        ulong             keySize = reader.ReadUInt64();
                        List <Ciphertext> ciphers = new List <Ciphertext>((int)keySize);

                        // Load all ciphertexts
                        for (ulong j = 0; j < keySize; j++)
                        {
                            Ciphertext cipher = new Ciphertext();
                            cipher.UnsafeLoad(reader.BaseStream);
                            ciphers.Add(cipher);
                        }

                        IntPtr[] pointers = ciphers.Select(c =>
                        {
                            return(c.NativePtr);
                        }).ToArray();

                        NativeMethods.RelinKeys_AddKeyList(NativePtr, (ulong)pointers.LongLength, pointers);
                    }
                }
            }
            catch (EndOfStreamException ex)
            {
                throw new ArgumentException("Stream ended unexpectedly", ex);
            }
            catch (IOException ex)
            {
                throw new ArgumentException("Error reading keys", ex);
            }
        }
Example #4
0
        /// <summary>
        /// Copies a given ciphertext to the current one.
        /// </summary>
        ///
        /// <param name="assign">The ciphertext to copy from</param>
        /// <exception cref="ArgumentNullException">if assign is null</exception>
        public void Set(Ciphertext assign)
        {
            if (null == assign)
            {
                throw new ArgumentNullException(nameof(assign));
            }

            NativeMethods.Ciphertext_Set(NativePtr, assign.NativePtr);
        }
Example #5
0
        /// <summary>
        /// Constructs a new ciphertext by copying a given one.
        /// </summary>
        /// <param name="copy">The ciphertext to copy from</param>
        /// <param name="pool">The MemoryPoolHandle pointing to a valid memory pool</param>
        /// <exception cref="ArgumentNullException">if either copy or pool are null</exception>
        /// <exception cref="ArgumentException">if pool is uninitialized</exception>
        public Ciphertext(Ciphertext copy, MemoryPoolHandle pool) : this(pool)
        {
            if (null == copy)
            {
                throw new ArgumentNullException(nameof(copy));
            }

            Set(copy);
        }
Example #6
0
        /// <summary>
        /// Encrypts a zero plaintext with the secret key and returns the ciphertext
        /// as a serializable object.
        /// </summary>
        /// <remarks>
        /// <para>
        /// Encrypts a zero plaintext with the secret key and returns the ciphertext
        /// as a serializable object.
        /// </para>
        /// <para>
        /// Half of the ciphertext data is pseudo-randomly generated from a seed to
        /// reduce the object size. The resulting serializable object cannot be used
        /// directly and is meant to be serialized for the size reduction to have an
        /// impact.
        /// </para>
        /// <para>
        /// The encryption parameters for the resulting ciphertext correspond to the
        /// highest (data) level in the modulus switching chain. Dynamic memory
        /// allocations in the process are allocated from the memory pool pointed to
        /// by the given MemoryPoolHandle.
        /// </para>
        /// </remarks>
        /// <param name="pool">The MemoryPoolHandle pointing to a valid memory
        /// pool</param>
        /// <exception cref="InvalidOperationException">if a secret key is not
        /// set</exception>
        /// <exception cref="ArgumentException">if pool is uninitialized</exception>
        public Serializable <Ciphertext> EncryptZeroSymmetric(MemoryPoolHandle pool = null)
        {
            IntPtr     poolHandle  = pool?.NativePtr ?? IntPtr.Zero;
            Ciphertext destination = new Ciphertext();

            NativeMethods.Encryptor_EncryptZeroSymmetric2(
                NativePtr, true, destination.NativePtr, poolHandle);
            return(new Serializable <Ciphertext>(destination));
        }
Example #7
0
        /// <summary>
        /// Computes the invariant noise budget (in bits) of a ciphertext. The invariant noise
        /// budget measures the amount of room there is for the noise to grow while ensuring
        /// correct decryptions. Dynamic memory allocations in the process are allocated from
        /// the memory pool pointed to by the given MemoryPoolHandle. This function works only
        /// with the BFV scheme.
        /// </summary>
        /// <remarks>
        /// <para>
        /// Invariant Noise Budget
        /// The invariant noise polynomial of a ciphertext is a rational coefficient polynomial,
        /// such that a ciphertext decrypts correctly as long as the coefficients of the invariant
        /// noise polynomial are of absolute value less than 1/2. Thus, we call the infinity-norm
        /// of the invariant noise polynomial the invariant noise, and for correct decryption require
        /// it to be less than 1/2. If v denotes the invariant noise, we define the invariant noise
        /// budget as -log2(2v). Thus, the invariant noise budget starts from some initial value,
        /// which depends on the encryption parameters, and decreases when computations are performed.
        /// When the budget reaches zero, the ciphertext becomes too noisy to decrypt correctly.
        /// </para>
        /// </remarks>
        /// <param name="encrypted">The ciphertext</param>
        /// <exception cref="ArgumentNullException">if encrypted is null</exception>
        /// <exception cref="ArgumentException">if the scheme is not BFV or BGV</exception>
        /// <exception cref="ArgumentException">if encrypted is not valid for the encryption parameters</exception>
        /// <exception cref="ArgumentException">if encrypted is in NTT form</exception>
        /// <exception cref="ArgumentException">if pool is uninitialized</exception>
        public int InvariantNoiseBudget(Ciphertext encrypted)
        {
            if (null == encrypted)
            {
                throw new ArgumentNullException(nameof(encrypted));
            }

            NativeMethods.Decryptor_InvariantNoiseBudget(NativePtr, encrypted.NativePtr, out int result);
            return(result);
        }
Example #8
0
        /// <summary>
        /// Constructs a new ciphertext by copying a given one.
        /// </summary>
        /// <param name="copy">The ciphertext to copy from</param>
        /// <exception cref="ArgumentNullException">if copy is null</exception>
        public Ciphertext(Ciphertext copy)
        {
            if (null == copy)
            {
                throw new ArgumentNullException(nameof(copy));
            }

            NativeMethods.Ciphertext_Create2(copy.NativePtr, out IntPtr ptr);
            NativePtr = ptr;
        }
Example #9
0
        /// <summary>
        /// Encrypts a zero plaintext with the public key and stores the result in
        /// destination.
        /// </summary>
        /// <remarks>
        /// <para>
        /// Encrypts a zero plaintext with the public key and stores the result in
        /// destination.
        /// </para>
        /// <para>
        /// The encryption parameters for the resulting ciphertext correspond to the
        /// highest (data) level in the modulus switching chain. Dynamic memory allocations
        /// in the process are allocated from the memory pool pointed to by the given
        /// MemoryPoolHandle.
        /// </para>
        /// </remarks>
        /// <param name="destination">The ciphertext to overwrite with the encrypted
        /// plaintext</param>
        /// <param name="pool">The MemoryPoolHandle pointing to a valid memory pool</param>
        /// <exception cref="ArgumentNullException">if destination is null</exception>
        /// <exception cref="InvalidOperationException">if a public key is not set</exception>
        /// <exception cref="ArgumentException">if pool is uninitialized</exception>
        public void EncryptZero(Ciphertext destination, MemoryPoolHandle pool = null)
        {
            if (null == destination)
            {
                throw new ArgumentNullException(nameof(destination));
            }

            IntPtr poolHandle = pool?.NativePtr ?? IntPtr.Zero;

            NativeMethods.Encryptor_EncryptZero2(NativePtr, destination.NativePtr, poolHandle);
        }
Example #10
0
        /// <summary>
        /// Decrypts a Ciphertext and stores the result in the destination parameter. Dynamic
        /// memory allocations in the process are allocated from the memory pool pointed to by
        /// the given MemoryPoolHandle.
        /// </summary>
        /// <param name="encrypted">The ciphertext to decrypt</param>
        /// <param name="destination">The plaintext to overwrite with the decrypted ciphertext</param>
        /// <exception cref="ArgumentNullException">if either encrypted or destination are null</exception>
        /// <exception cref="ArgumentException">if encrypted is not valid for the encryption parameters</exception>
        /// <exception cref="ArgumentException">if encrypted is not in the default NTT form</exception>
        /// <exception cref="ArgumentException">if pool is uninitialized</exception>
        public void Decrypt(Ciphertext encrypted, Plaintext destination)
        {
            if (null == encrypted)
            {
                throw new ArgumentNullException(nameof(encrypted));
            }
            if (null == destination)
            {
                throw new ArgumentNullException(nameof(destination));
            }

            NativeMethods.Decryptor_Decrypt(NativePtr, encrypted.NativePtr, destination.NativePtr);
        }
Example #11
0
        /// <summary>
        /// Check whether the given ciphertext is valid for a given SEALContext. If the
        /// given SEALContext is not set, the encryption parameters are invalid, or the
        /// ciphertext data does not match the SEALContext, this function returns false.
        /// Otherwise, returns true.
        /// </summary>
        /// <param name="ciphertext">The ciphertext to check</param>
        /// <param name="context">The SEALContext</param>
        /// <exception cref="ArgumentNullException">if either ciphertext or context is null</exception>
        public static bool IsValidFor(Ciphertext ciphertext, SEALContext context)
        {
            if (null == ciphertext)
            {
                throw new ArgumentNullException(nameof(ciphertext));
            }
            if (null == context)
            {
                throw new ArgumentNullException(nameof(context));
            }

            NativeMethods.ValCheck_Ciphertext_IsValidFor(ciphertext.NativePtr, context.NativePtr, out bool result);
            return(result);
        }
Example #12
0
        /// <summary>
        /// Encrypts a zero plaintext with the secret key and stores the result in destination.
        /// </summary>
        /// <remarks>
        /// The encryption parameters for the resulting ciphertext correspond to the
        /// highest (data) level in the modulus switching chain. Dynamic memory allocations in
        /// the process are allocated from the memory pool pointed to by the given MemoryPoolHandle.
        ///
        /// Half of the polynomials in relinearization keys are randomly generated
        /// and are replaced with the seed used to compress output size. The output
        /// is in binary format and not human-readable. The output stream must have
        /// the "binary" flag set.
        /// </remarks>
        /// <param name="stream">The stream to save the Ciphertext to</param>
        /// <param name="comprMode">The desired compression mode</param>
        /// <param name="pool">The MemoryPoolHandle pointing to a valid memory pool</param>
        /// <exception cref="ArgumentNullException">if stream is null</exception>
        /// <exception cref="ArgumentException">if pool is uninitialized</exception>
        public long EncryptZeroSymmetricSave(Stream stream, ComprModeType?comprMode = null, MemoryPoolHandle pool = null)
        {
            if (null == stream)
            {
                throw new ArgumentNullException(nameof(stream));
            }

            IntPtr poolHandle = pool?.NativePtr ?? IntPtr.Zero;

            using (Ciphertext destination = new Ciphertext(pool))
            {
                NativeMethods.Encryptor_EncryptZeroSymmetric2(NativePtr, true, destination.NativePtr, poolHandle);
                return(destination.Save(stream, comprMode));
            }
        }
Example #13
0
        /// <summary>
        /// Encrypts a zero plaintext with the secret key and stores the result in destination.
        /// </summary>
        /// <remarks>
        /// The encryption parameters for the resulting ciphertext correspond to the given
        /// parms_id. Dynamic memory allocations in the process are allocated from the memory
        /// pool pointed to by the given MemoryPoolHandle.
        /// </remarks>
        /// <param name="parmsId">The ParmsId for the resulting ciphertext</param>
        /// <param name="destination">The ciphertext to overwrite with the encrypted plaintext</param>
        /// <param name="pool">The MemoryPoolHandle pointing to a valid memory pool</param>
        /// <exception cref="ArgumentNullException">if either parmsId or destination are null</exception>
        /// <exception cref="ArgumentException">if parmsId is not valid for the encryption parameters</exception>
        /// <exception cref="ArgumentException">if pool is uninitialized</exception>
        public void EncryptZeroSymmetric(ParmsId parmsId, Ciphertext destination, MemoryPoolHandle pool = null)
        {
            if (null == parmsId)
            {
                throw new ArgumentNullException(nameof(parmsId));
            }
            if (null == destination)
            {
                throw new ArgumentNullException(nameof(destination));
            }

            IntPtr poolHandle = pool?.NativePtr ?? IntPtr.Zero;

            NativeMethods.Encryptor_EncryptZeroSymmetric1(NativePtr, parmsId.Block, false, destination.NativePtr, poolHandle);
        }
Example #14
0
        /// <summary>
        /// Encrypts a plaintext with the secret key and stores the result in destination.
        /// </summary>
        /// <remarks>
        /// The encryption parameters for the resulting ciphertext correspond to:
        /// 1) in BFV, the highest (data) level in the modulus switching chain,
        /// 2) in CKKS, the encryption parameters of the plaintext.
        /// Dynamic memory allocations in the process are allocated from the memory
        /// pool pointed to by the given MemoryPoolHandle.
        /// </remarks>
        /// <param name="plain">The plaintext to encrypt</param>
        /// <param name="destination">The ciphertext to overwrite with the encrypted plaintext</param>
        /// <param name="pool">The MemoryPoolHandle pointing to a valid memory pool</param>
        /// <exception cref="ArgumentNullException">if either plain or destination are null</exception>
        /// <exception cref="ArgumentException">if plain is not valid for the encryption parameters</exception>
        /// <exception cref="ArgumentException">if plain is not in default NTT form</exception>
        /// <exception cref="ArgumentException">if pool is uninitialized</exception>
        public void EncryptSymmetric(Plaintext plain, Ciphertext destination, MemoryPoolHandle pool = null)
        {
            if (null == plain)
            {
                throw new ArgumentNullException(nameof(plain));
            }
            if (null == destination)
            {
                throw new ArgumentNullException(nameof(destination));
            }

            IntPtr poolHandle = pool?.NativePtr ?? IntPtr.Zero;

            NativeMethods.Encryptor_EncryptSymmetric(NativePtr, plain.NativePtr, false, destination.NativePtr, poolHandle);
        }
Example #15
0
        /// <summary>
        /// Encrypts a zero plaintext with the secret key and returns the ciphertext
        /// as a serializable object.
        /// </summary>
        /// <remarks>
        /// <para>
        /// Encrypts a zero plaintext with the secret key and returns the ciphertext
        /// as a serializable object.
        /// </para>
        /// <para>
        /// Half of the ciphertext data is pseudo-randomly generated from a seed to
        /// reduce the object size. The resulting serializable object cannot be used
        /// directly and is meant to be serialized for the size reduction to have an
        /// impact.
        /// </para>
        /// <para>
        /// The encryption parameters for the resulting ciphertext correspond to
        /// the given ParmsId. Dynamic memory allocations in the process are allocated
        /// from the memory pool pointed to by the given MemoryPoolHandle.
        /// </para>
        /// </remarks>
        /// <param name="parmsId">The ParmsId for the resulting ciphertext</param>
        /// <param name="pool">The MemoryPoolHandle pointing to a valid memory
        /// pool</param>
        /// <exception cref="ArgumentNullException">if parmsId is null</exception>
        /// <exception cref="InvalidOperationException">if a secret key is not
        /// set</exception>
        /// <exception cref="ArgumentException">if parmsId is not valid for the
        /// encryption parameters</exception>
        /// <exception cref="ArgumentException">if pool is uninitialized</exception>
        public Serializable <Ciphertext> EncryptZeroSymmetric(
            ParmsId parmsId,
            MemoryPoolHandle pool = null)
        {
            if (null == parmsId)
            {
                throw new ArgumentNullException(nameof(parmsId));
            }

            IntPtr     poolHandle  = pool?.NativePtr ?? IntPtr.Zero;
            Ciphertext destination = new Ciphertext();

            NativeMethods.Encryptor_EncryptZeroSymmetric1(
                NativePtr, parmsId.Block, true, destination.NativePtr, poolHandle);
            return(new Serializable <Ciphertext>(destination));
        }
Example #16
0
        /// <summary>
        /// Encrypts a plaintext with the secret key and returns the ciphertext as
        /// a serializable object.
        /// </summary>
        /// <remarks>
        /// <para>
        /// Encrypts a plaintext with the secret key and returns the ciphertext as
        /// a serializable object.
        /// </para>
        /// <para>
        /// Half of the ciphertext data is pseudo-randomly generated from a seed to
        /// reduce the object size. The resulting serializable object cannot be used
        /// directly and is meant to be serialized for the size reduction to have an
        /// impact.
        /// </para>
        /// <para>
        /// The encryption parameters for the resulting ciphertext correspond to:
        /// 1) in BFV, the highest (data) level in the modulus switching chain,
        /// 2) in CKKS, the encryption parameters of the plaintext.
        /// Dynamic memory allocations in the process are allocated from the memory
        /// pool pointed to by the given MemoryPoolHandle.
        /// </para>
        /// </remarks>
        /// <param name="plain">The plaintext to encrypt</param>
        /// <param name="pool">The MemoryPoolHandle pointing to a valid memory pool</param>
        /// <exception cref="ArgumentNullException">if plain is null</exception>
        /// <exception cref="InvalidOperationException">if a secret key is not set</exception>
        /// <exception cref="ArgumentException">if plain is not valid for the encryption
        /// parameters</exception>
        /// <exception cref="ArgumentException">if plain is not in default NTT
        /// form</exception>
        /// <exception cref="ArgumentException">if pool is uninitialized</exception>
        public Serializable <Ciphertext> EncryptSymmetric(
            Plaintext plain,
            MemoryPoolHandle pool = null)
        {
            if (null == plain)
            {
                throw new ArgumentNullException(nameof(plain));
            }

            IntPtr     poolHandle  = pool?.NativePtr ?? IntPtr.Zero;
            Ciphertext destination = new Ciphertext();

            NativeMethods.Encryptor_EncryptSymmetric(
                NativePtr, plain.NativePtr, true, destination.NativePtr, poolHandle);
            return(new Serializable <Ciphertext>(destination));
        }