diff --git a/Benchmarks/RlweBenchmark/RlweBenchmark.swift b/Benchmarks/RlweBenchmark/RlweBenchmark.swift index ce3f37ff..f2a1b359 100644 --- a/Benchmarks/RlweBenchmark/RlweBenchmark.swift +++ b/Benchmarks/RlweBenchmark/RlweBenchmark.swift @@ -412,6 +412,66 @@ func ciphertextSwapRowsBenchmark(_: Scheme.Type) -> () -> Void } } +// MARK: Serialization + +func coeffPlaintextSerializeBenchmark(_: Scheme.Type) -> () -> Void { + { + benchmark("CoeffPlaintextSerialize", Scheme.self) { benchmark in + let benchmarkContext: RlweBenchmarkContext = try StaticRlweBenchmarkContext.getBenchmarkContext() + let plaintext = benchmarkContext.coeffPlaintext + benchmark.startMeasurement() + for _ in benchmark.scaledIterations { + blackHole(plaintext.serialize()) + } + } + } +} + +func evalPlaintextSerializeBenchmark(_: Scheme.Type) -> () -> Void { + { + benchmark("EvalPlaintextSerialize", Scheme.self) { benchmark in + let benchmarkContext: RlweBenchmarkContext = try StaticRlweBenchmarkContext.getBenchmarkContext() + let plaintext = benchmarkContext.evalPlaintext + benchmark.startMeasurement() + for _ in benchmark.scaledIterations { + blackHole(plaintext.serialize()) + } + } + } +} + +func coeffPlaintextDeserializeBenchmark(_: Scheme.Type) -> () -> Void { + { + benchmark("CoeffPlaintextDeserialize", Scheme.self) { benchmark in + let benchmarkContext: RlweBenchmarkContext = try StaticRlweBenchmarkContext.getBenchmarkContext() + let plaintext = benchmarkContext.coeffPlaintext + let serialized = plaintext.serialize() + benchmark.startMeasurement() + for _ in benchmark.scaledIterations { + try blackHole(_ = Scheme.CoeffPlaintext( + deserialize: serialized, + context: benchmarkContext.context)) + } + } + } +} + +func evalPlaintextDeserializeBenchmark(_: Scheme.Type) -> () -> Void { + { + benchmark("EvalPlaintextDeserialize", Scheme.self) { benchmark in + let benchmarkContext: RlweBenchmarkContext = try StaticRlweBenchmarkContext.getBenchmarkContext() + let plaintext = benchmarkContext.evalPlaintext + let serialized = plaintext.serialize() + benchmark.startMeasurement() + for _ in benchmark.scaledIterations { + try blackHole(_ = Scheme.EvalPlaintext( + deserialize: serialized, + context: benchmarkContext.context)) + } + } + } +} + func ciphertextSerializeFullBenchmark(_: Scheme.Type) -> () -> Void { { benchmark("CiphertextSerializeFull", Scheme.self) { benchmark in @@ -554,6 +614,16 @@ nonisolated(unsafe) let benchmarks: () -> Void = { ciphertextSwapRowsBenchmark(Bfv.self)() // Serialization + coeffPlaintextSerializeBenchmark(Bfv.self)() + coeffPlaintextSerializeBenchmark(Bfv.self)() + evalPlaintextSerializeBenchmark(Bfv.self)() + evalPlaintextSerializeBenchmark(Bfv.self)() + + coeffPlaintextDeserializeBenchmark(Bfv.self)() + coeffPlaintextDeserializeBenchmark(Bfv.self)() + evalPlaintextDeserializeBenchmark(Bfv.self)() + evalPlaintextDeserializeBenchmark(Bfv.self)() + ciphertextSerializeFullBenchmark(Bfv.self)() ciphertextSerializeFullBenchmark(Bfv.self)() ciphertextSerializeSeedBenchmark(Bfv.self)() diff --git a/Sources/HomomorphicEncryption/SerializedPlaintext.swift b/Sources/HomomorphicEncryption/SerializedPlaintext.swift index 9210b516..a3f86eba 100644 --- a/Sources/HomomorphicEncryption/SerializedPlaintext.swift +++ b/Sources/HomomorphicEncryption/SerializedPlaintext.swift @@ -37,6 +37,7 @@ extension Plaintext where Format == Coeff { /// - serialized: Serialized plaintext. /// - context: Context to associate with the plaintext. /// - Throws: Error upon failure to deserialize. + @inlinable public init(deserialize serialized: SerializedPlaintext, context: Context) throws { self.context = context self.poly = try PolyRq(deserialize: serialized.poly, context: context.plaintextContext) @@ -51,6 +52,7 @@ extension Plaintext where Format == Eval { /// - moduliCount: Optional number of moduli to associate with the plaintext. If not set, the plaintext will have /// the top-level ciphertext context with all the moduli. /// - Throws: Error upon failure to deserialize. + @inlinable public init(deserialize serialized: SerializedPlaintext, context: Context, moduliCount: Int? = nil) throws { self.context = context let moduliCount = moduliCount ?? context.ciphertextContext.moduli.count diff --git a/Sources/PrivateInformationRetrieval/IndexPirProtocol.swift b/Sources/PrivateInformationRetrieval/IndexPirProtocol.swift index 02bb7300..835f07e5 100644 --- a/Sources/PrivateInformationRetrieval/IndexPirProtocol.swift +++ b/Sources/PrivateInformationRetrieval/IndexPirProtocol.swift @@ -166,6 +166,7 @@ public struct ProcessedDatabase: Equatable, Sendable { /// - path: Filepath storing serialized plaintexts. /// - context: Context for HE computation. /// - Throws: Error upon failure to load the database. + @inlinable public init(from path: String, context: Context) throws { let loadedFile = try [UInt8](Data(contentsOf: URL(fileURLWithPath: path))) try self.init(from: loadedFile, context: context) @@ -176,6 +177,7 @@ public struct ProcessedDatabase: Equatable, Sendable { /// - buffer: Serialized plaintexts. /// - context: Context for HE computation. /// - Throws: Error upon failure to deserialize. + @inlinable public init(from buffer: [UInt8], context: Context) throws { var offset = buffer.startIndex let versionNumber = buffer[offset]