/// <summary> /// Saves the ciphertext to an output stream. The output is in binary /// format and not human-readable. The output stream must have the /// "binary" flag set. /// </summary> /// <param name="stream">The stream to save the ciphertext to</param> /// <exception cref="ArgumentNullException">if stream is null</exception> /// <exception cref="ArgumentException">if the ciphertext could not be written to stream</exception> public void Save(Stream stream) { if (null == stream) { throw new ArgumentNullException(nameof(stream)); } try { using (BinaryWriter writer = new BinaryWriter(stream, Encoding.UTF8, leaveOpen: true)) { ParmsId.Save(writer.BaseStream); writer.Write(IsNTTForm); writer.Write(Size); writer.Write(PolyModulusDegree); writer.Write(CoeffModCount); ulong ulongCount = checked (Size * PolyModulusDegree * CoeffModCount); for (ulong i = 0; i < ulongCount; i++) { writer.Write(this[i]); } } } catch (IOException ex) { throw new ArgumentException("Could not write Ciphertext", ex); } }
/// <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. /// /// 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="parmsId">The ParmsId for the resulting ciphertext</param> /// <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 parmsId or 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 parmsId is not valid for the /// encryption parameters</exception> /// <exception cref="ArgumentException">if pool is uninitialized</exception> public long EncryptZeroSymmetricSave( ParmsId parmsId, Stream stream, ComprModeType?comprMode = null, MemoryPoolHandle pool = null) { if (null == parmsId) { throw new ArgumentNullException(nameof(parmsId)); } 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_EncryptZeroSymmetric1( NativePtr, parmsId.Block, true, destination.NativePtr, poolHandle); return(destination.Save(stream, comprMode)); } }
/// <summary> /// Encodes double-precision floating-point complex numbers into a plaintext /// polynomial. Dynamic memory allocations in the process are allocated from the /// memory pool pointed to by the given MemoryPoolHandle. /// </summary> /// <param name="values">The enumeration of double-precision complex numbers /// to encode</param> /// <param name="parmsId">parmsId determining the encryption parameters to be used /// by the result plaintext</param> /// <param name="scale">Scaling parameter defining encoding precision</param> /// <param name="destination">The plaintext polynomial to overwrite with the result</param> /// <param name="pool">The MemoryPoolHandle pointing to a valid memory pool</param> /// <exception cref="ArgumentNullException">if either values, parmsId or destionation are null.</exception> /// <exception cref="ArgumentException">if values has invalid size</exception> /// <exception cref="ArgumentException">if parmsId is not valid for the encryption /// parameters </exception> /// <exception cref="ArgumentException">if scale is not strictly positive</exception> /// <exception cref="ArgumentException">if encoding is too large for the encryption /// parameters</exception> /// <exception cref="ArgumentException">if pool is uninitialized</exception> public void Encode(IEnumerable <Complex> values, ParmsId parmsId, double scale, Plaintext destination, MemoryPoolHandle pool = null) { if (null == values) { throw new ArgumentNullException(nameof(values)); } if (null == parmsId) { throw new ArgumentNullException(nameof(parmsId)); } if (null == destination) { throw new ArgumentNullException(nameof(destination)); } IntPtr poolPtr = pool?.NativePtr ?? IntPtr.Zero; double[] valuearray = new double[values.LongCount() * 2]; ulong idx = 0; foreach (Complex complex in values) { valuearray[idx++] = complex.Real; valuearray[idx++] = complex.Imaginary; } // Note that we should pass values.Count as the length instead of valuearray.Length, // since we are using two doubles in the array per element. NativeMethods.CKKSEncoder_EncodeComplex(NativePtr, (ulong)values.LongCount(), valuearray, parmsId.Block, scale, destination.NativePtr, poolPtr); }
/// <summary> /// Saves the plaintext to an output stream. /// </summary> /// <remarks> /// Saves the plaintext to an output stream. 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 plaintext to</param> /// <exception cref="ArgumentNullException">if stream is null</exception> /// <exception cref="ArgumentException">if the plaintext could not be written /// to stream</exception> public void Save(Stream stream) { if (null == stream) { throw new ArgumentNullException(nameof(stream)); } try { using (BinaryWriter writer = new BinaryWriter(stream, Encoding.UTF8, leaveOpen: true)) { ParmsId.Save(stream); writer.Write(Scale); writer.Write(CoeffCount); for (ulong i = 0; i < CoeffCount; i++) { ulong data = this[i]; writer.Write(data); } } } catch (IOException ex) { throw new ArgumentException("Could not write KSwitchKeys", ex); } }
/// <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); } }
/// <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 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 public 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> EncryptZero( ParmsId parmsId, MemoryPoolHandle pool = null) { Ciphertext destination = new Ciphertext(); EncryptZero(parmsId, destination, pool); return(new Serializable <Ciphertext>(destination)); }
/// <summary> /// Loads a KSwitchKeys from an input stream overwriting the current KSwitchKeys. /// </summary> /// <remarks> /// Loads a KSwitchKeys from an input stream overwriting the current KSwitchKeys. /// No checking of the validity of the KSwitchKeys data against encryption /// parameters is performed. This function should not be used unless the /// KSwitchKeys comes from a fully trusted source. /// </remarks> /// <param name="stream">The stream to load the KSwitchKeys from</param> /// <exception cref="ArgumentNullException">if stream is null</exception> /// <exception cref="ArgumentException">if KSwitchKeys 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 size ulong size = reader.ReadUInt64(); // Clear current data and reserve new size NativeMethods.KSwitchKeys_ClearDataAndReserve(NativePtr, size); // Read all lists for (ulong i = 0; i < size; i++) { // Read size of second list ulong keySize = reader.ReadUInt64(); List <PublicKey> key = new List <PublicKey>(checked ((int)keySize)); // Load all ciphertexts for (ulong j = 0; j < keySize; j++) { PublicKey pkey = new PublicKey(); pkey.UnsafeLoad(reader.BaseStream); key.Add(pkey); } IntPtr[] pointers = key.Select(c => { return(c.NativePtr); }).ToArray(); NativeMethods.KSwitchKeys_AddKeyList(NativePtr, (ulong)pointers.LongLength, pointers); } } } catch (EndOfStreamException ex) { throw new ArgumentException("Stream ended unexpectedly", ex); } catch (IOException ex) { throw new ArgumentException("Could not load KSwitchKeys", ex); } }
/// <summary> /// Encodes an integer number into a plaintext polynomial without any scaling. /// </summary> /// <param name="value">The integer number to encode</param> /// <param name="parmsId">parmsId determining the encryption parameters to be used /// by the result plaintext</param> /// <param name="destination">The plaintext polynomial to overwrite with the result</param> /// <exception cref="ArgumentNullException">if either parmsId or destionation are null</exception> /// <exception cref="ArgumentException">if parmsId is not valid for the encryption /// parameters </exception> public void Encode(long value, ParmsId parmsId, Plaintext destination) { if (null == parmsId) { throw new ArgumentNullException(nameof(parmsId)); } if (null == destination) { throw new ArgumentNullException(nameof(destination)); } NativeMethods.CKKSEncoder_Encode(NativePtr, value, parmsId.Block, destination.NativePtr); }
/// <summary> /// Resizes the ciphertext to given size, reallocating if the capacity /// of the ciphertext is too small. The ciphertext parameters are /// determined by the given SEALContext and parmsId. /// /// This function is mainly intended for internal use and is called /// automatically by functions such as Evaluator::multiply and /// Evaluator::relinearize. A normal user should never have a reason /// to manually resize a ciphertext. /// </summary> /// <param name="context">The SEALContext</param> /// <param name="parmsId">The ParmsId corresponding to the encryption /// parameters to be used</param> /// <param name="size">The new size</param> /// <exception cref="ArgumentNullException">if either context or parmsId are null</exception> /// <exception cref="ArgumentException">if the context is not set or encryption /// parameters are not valid</exception> /// <exception cref="ArgumentException">if parmsId is not valid for the encryption /// parameters</exception> /// <exception cref="ArgumentException">if size is less than 2 or too large</exception> public void Resize(SEALContext context, ParmsId parmsId, ulong size) { if (null == context) { throw new ArgumentNullException(nameof(context)); } if (null == parmsId) { throw new ArgumentNullException(nameof(parmsId)); } NativeMethods.Ciphertext_Resize(NativePtr, context.NativePtr, parmsId.Block, size); }
/// <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); }
/// <summary> /// Constructs an empty ciphertext with capacity 2. In addition to the /// capacity, the allocation size is determined by the encryption parameters /// with given ParmsId. /// </summary> /// <param name="context">The SEALContext</param> /// <param name="parmsId">The ParmsId corresponding to the encryption /// parameters to be used</param> /// <param name="pool">The MemoryPoolHandle pointing to a valid memory pool</param> /// <exception cref="ArgumentNullException">if either context or parmsId are null</exception> /// <exception cref="ArgumentException">if the context is not set or encryption /// parameters are not valid</exception> /// <exception cref="ArgumentException">if parmsId is not valid for the encryption /// parameters</exception> /// <exception cref="ArgumentException">if pool is uninitialized</exception> public Ciphertext(SEALContext context, ParmsId parmsId, MemoryPoolHandle pool = null) { if (null == context) { throw new ArgumentNullException(nameof(context)); } if (null == parmsId) { throw new ArgumentNullException(nameof(parmsId)); } IntPtr poolPtr = pool?.NativePtr ?? IntPtr.Zero; NativeMethods.Ciphertext_Create4(context.NativePtr, parmsId.Block, poolPtr, out IntPtr ptr); NativePtr = ptr; }
/// <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)); }
/// <summary> /// Encodes a double-precision complex number into a plaintext polynomial. Dynamic /// memory allocations in the process are allocated from the memory pool pointed to /// by the given MemoryPoolHandle. /// </summary> /// <param name="value">The double-precision complex number to encode</param> /// <param name="parmsId">parmsId determining the encryption parameters to be used /// by the result plaintext</param> /// <param name="scale">Scaling parameter defining encoding precision</param> /// <param name="destination">The plaintext polynomial to overwrite with the result</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 scale is not strictly positive</exception> /// <exception cref="ArgumentException">if encoding is too large for the encryption /// parameters</exception> /// <exception cref="ArgumentException">if pool is uninitialized</exception> public void Encode(Complex value, ParmsId parmsId, double scale, Plaintext destination, MemoryPoolHandle pool = null) { if (null == parmsId) { throw new ArgumentNullException(nameof(parmsId)); } if (null == destination) { throw new ArgumentNullException(nameof(destination)); } IntPtr poolPtr = pool?.NativePtr ?? IntPtr.Zero; NativeMethods.CKKSEncoder_Encode(NativePtr, value.Real, value.Imaginary, parmsId.Block, scale, destination.NativePtr, poolPtr); }
/// <summary> /// Returns an optional ContextData object class corresponding to /// the parameters with a given parmsId. If parameters with the given parmsId /// are not found then the function returns null. /// </summary> /// /// <param name="parmsId">The parmsId of the encryption parameters</param> /// <exception cref="ArgumentNullException">if parmsId is null</exception> public ContextData GetContextData(ParmsId parmsId) { if (null == parmsId) { throw new ArgumentNullException(nameof(parmsId)); } NativeMethods.SEALContext_GetContextData(NativePtr, parmsId.Block, out IntPtr contextData); if (IntPtr.Zero.Equals(contextData)) { return(null); } ContextData data = new ContextData(contextData, owned: false); return(data); }
/// <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. /// /// 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="parmsId">The ParmsId for the resulting ciphertext</param> /// <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 parmsId or stream is null</exception> /// <exception cref="ArgumentException">if parmsId is not valid for the encryption parameters</exception> /// <exception cref="ArgumentException">if pool is uninitialized</exception> public long EncryptZeroSymmetricSave(ParmsId parmsId, Stream stream, ComprModeType?comprMode = null, MemoryPoolHandle pool = null) { if (null == parmsId) { throw new ArgumentNullException(nameof(parmsId)); } if (null == stream) { throw new ArgumentNullException(nameof(stream)); } IntPtr poolHandle = pool?.NativePtr ?? IntPtr.Zero; using (Ciphertext destination = new Ciphertext(pool)) { NativeMethods.Encryptor_EncryptZeroSymmetric1(NativePtr, parmsId.Block, true, destination.NativePtr, poolHandle); return(destination.Save(stream, comprMode)); } }
/// <summary> /// Saves the plaintext to an output stream. /// </summary> /// /// <remarks> /// Saves the plaintext to an output stream. 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 plaintext to</param> /// <exception cref="ArgumentNullException">if stream is null</exception> /// <seealso cref="Load(SEALContext, Stream)">See Load() to load a saved plaintext.</seealso> public void Save(Stream stream) { if (null == stream) { throw new ArgumentNullException(nameof(stream)); } // First the ParmsId ParmsId.Save(stream); using (BinaryWriter writer = new BinaryWriter(stream, Encoding.UTF8, leaveOpen: true)) { writer.Write(Scale); writer.Write(CoeffCount); for (ulong i = 0; i < CoeffCount; i++) { ulong data = this[i]; writer.Write(data); } } }
/// <summary> /// Loads a ciphertext from an input stream overwriting the current ciphertext. /// No checking of the validity of the ciphertext data against encryption /// parameters is performed. This function should not be used unless the /// ciphertext comes from a fully trusted source. /// </summary> /// <param name="stream">The stream to load the ciphertext from</param> /// <exception cref="ArgumentNullException">if stream is null</exception> /// <exception cref="ArgumentException">if a valid ciphertext could not be read from stream</exception> public void UnsafeLoad(Stream stream) { if (null == stream) { throw new ArgumentNullException(nameof(stream)); } try { using (BinaryReader reader = new BinaryReader(stream, Encoding.UTF8, leaveOpen: true)) { ParmsId parms = new ParmsId(); parms.Load(reader.BaseStream); ParmsId = parms; bool isNTT = reader.ReadBoolean(); ulong size = reader.ReadUInt64(); ulong polyModulusDegree = reader.ReadUInt64(); ulong coeffModCount = reader.ReadUInt64(); ulong ulongCount = size * polyModulusDegree * coeffModCount; IsNTTForm = isNTT; Resize(size, polyModulusDegree, coeffModCount); for (ulong i = 0; i < ulongCount; i++) { this[i] = reader.ReadUInt64(); } } } catch (EndOfStreamException ex) { throw new ArgumentException("Stream ended unexpectedly", ex); } catch (IOException ex) { throw new ArgumentException("Error reading ciphertext", ex); } }
/// <summary> /// Encodes double-precision floating-point real numbers into a plaintext /// polynomial. Dynamic memory allocations in the process are allocated from the /// memory pool pointed to by the given MemoryPoolHandle. /// </summary> /// <param name="values">The enumeration of double-precision floating-point numbers /// to encode</param> /// <param name="parmsId">parmsId determining the encryption parameters to be used /// by the result plaintext</param> /// <param name="scale">Scaling parameter defining encoding precision</param> /// <param name="destination">The plaintext polynomial to overwrite with the result</param> /// <param name="pool">The MemoryPoolHandle pointing to a valid memory pool</param> /// <exception cref="ArgumentNullException">if either values, parmsId or destionation are null.</exception> /// <exception cref="ArgumentException">if values has invalid size</exception> /// <exception cref="ArgumentException">if parmsId is not valid for the encryption /// parameters </exception> /// <exception cref="ArgumentException">if scale is not strictly positive</exception> /// <exception cref="ArgumentException">if encoding is too large for the encryption /// parameters</exception> /// <exception cref="ArgumentException">if pool is uninitialized</exception> public void Encode(IEnumerable <double> values, ParmsId parmsId, double scale, Plaintext destination, MemoryPoolHandle pool = null) { if (null == values) { throw new ArgumentNullException(nameof(values)); } if (null == parmsId) { throw new ArgumentNullException(nameof(parmsId)); } if (null == destination) { throw new ArgumentNullException(nameof(destination)); } IntPtr poolPtr = pool?.NativePtr ?? IntPtr.Zero; double[] valuearray = values.ToArray(); NativeMethods.CKKSEncoder_EncodeDouble(NativePtr, (ulong)valuearray.LongLength, valuearray, parmsId.Block, scale, destination.NativePtr, poolPtr); }
/// <summary> /// Loads a plaintext from an input stream overwriting the current plaintext. /// No checking of the validity of the plaintext data against encryption /// parameters is performed. This function should not be used unless the /// plaintext comes from a fully trusted source. /// </summary> /// <param name="stream">The stream to load the plaintext from</param> /// <exception cref="ArgumentNullException">if stream is null</exception> /// <exception cref="ArgumentException">if a valid plaintext could not be read from stream</exception> public void UnsafeLoad(Stream stream) { if (null == stream) { throw new ArgumentNullException(nameof(stream)); } try { ParmsId parms = new ParmsId(); parms.Load(stream); ParmsId = parms; using (BinaryReader reader = new BinaryReader(stream)) { double scale = reader.ReadDouble(); ulong coeffCount = reader.ReadUInt64(); Scale = scale; ulong[] newData = new ulong[coeffCount]; for (ulong i = 0; i < coeffCount; i++) { newData[i] = reader.ReadUInt64(); } NativeMethods.Plaintext_SwapData(NativePtr, coeffCount, newData); } } catch (EndOfStreamException ex) { throw new ArgumentException("Stream ended unexpectedly", ex); } catch (IOException ex) { throw new ArgumentException("Could not read Plaintext", ex); } }