diff --git a/Benchmarks/RlweBenchmark/RlweBenchmark.swift b/Benchmarks/RlweBenchmark/RlweBenchmark.swift index 5db4bd79..b4b37706 100644 --- a/Benchmarks/RlweBenchmark/RlweBenchmark.swift +++ b/Benchmarks/RlweBenchmark/RlweBenchmark.swift @@ -43,7 +43,7 @@ func getRandomPlaintextData(count: Int, in range: Range) -> [T struct RlweBenchmarkContext: Sendable { var encryptionParameters: EncryptionParameters - var context: Context + var context: Context let data: [Scheme.Scalar] let signedData: [Scheme.SignedScalar] @@ -163,7 +163,7 @@ func contextInitBenchmark(_: Scheme.Type, config: EncryptionPa let encryptionParameters = try EncryptionParameters(config: config) benchmark.startMeasurement() for _ in benchmark.scaledIterations { - try blackHole(_ = Context(encryptionParameters: encryptionParameters)) + try blackHole(_ = Context(encryptionParameters: encryptionParameters)) } } } @@ -279,8 +279,7 @@ func decodeSignedSimdBenchmark(_: Scheme.Type) -> () -> Void { let benchmarkContext: RlweBenchmarkContext = try StaticRlweBenchmarkContext.getBenchmarkContext() benchmark.startMeasurement() for _ in benchmark.scaledIterations { - try blackHole( - benchmarkContext.coeffPlaintext.decode(format: .simd) as [Scheme.SignedScalar]) + try blackHole(benchmarkContext.coeffPlaintext.decode(format: .simd) as [Scheme.SignedScalar]) } } } @@ -292,7 +291,7 @@ func generateSecretKeyBenchmark(_: Scheme.Type) -> () -> Void let benchmarkContext: RlweBenchmarkContext = try StaticRlweBenchmarkContext.getBenchmarkContext() benchmark.startMeasurement() for _ in benchmark.scaledIterations { - try blackHole(benchmarkContext.context.generateSecretKey()) + try blackHole(benchmarkContext.context.generateSecretKey() as SecretKey) } } } @@ -320,8 +319,7 @@ func encryptBenchmark(_: Scheme.Type) -> () -> Void { let benchmarkContext: RlweBenchmarkContext = try StaticRlweBenchmarkContext.getBenchmarkContext() benchmark.startMeasurement() for _ in benchmark.scaledIterations { - try blackHole( - benchmarkContext.coeffPlaintext.encrypt(using: benchmarkContext.secretKey)) + try blackHole(benchmarkContext.coeffPlaintext.encrypt(using: benchmarkContext.secretKey)) } } } @@ -333,9 +331,7 @@ func decryptBenchmark(_: Scheme.Type) -> () -> Void { let benchmarkContext: RlweBenchmarkContext = try StaticRlweBenchmarkContext.getBenchmarkContext() benchmark.startMeasurement() for _ in benchmark.scaledIterations { - try blackHole( - benchmarkContext.evalCiphertext.decrypt( - using: benchmarkContext.secretKey)) + try blackHole(benchmarkContext.evalCiphertext.decrypt(using: benchmarkContext.secretKey)) } } } diff --git a/Snippets/HomomorphicEncryption/BasicsSnippet.swift b/Snippets/HomomorphicEncryption/BasicsSnippet.swift index e8050779..e350052c 100644 --- a/Snippets/HomomorphicEncryption/BasicsSnippet.swift +++ b/Snippets/HomomorphicEncryption/BasicsSnippet.swift @@ -24,7 +24,7 @@ import HomomorphicEncryption let encryptParams = try EncryptionParameters(from: .insecure_n_8_logq_5x18_logt_5) // Perform pre-computation for HE computation with these parameters. -let context = try Context>(encryptionParameters: encryptParams) +let context = try Context(encryptionParameters: encryptParams) // We encode N values using coefficient encoding. let values: [UInt64] = [8, 5, 12, 12, 15, 0, 8, 5] @@ -33,7 +33,7 @@ let plaintext: Bfv.CoeffPlaintext = try context.encode( format: .coefficient) // We generate a secret key and use it to encrypt the plaintext. -let secretKey = try context.generateSecretKey() +let secretKey: SecretKey> = try context.generateSecretKey() var ciphertext = try plaintext.encrypt(using: secretKey) // Decrypting the plaintext yields the original values. diff --git a/Snippets/HomomorphicEncryption/EncryptionParametersSnippet.swift b/Snippets/HomomorphicEncryption/EncryptionParametersSnippet.swift index ef12c2f7..1dcb7c57 100644 --- a/Snippets/HomomorphicEncryption/EncryptionParametersSnippet.swift +++ b/Snippets/HomomorphicEncryption/EncryptionParametersSnippet.swift @@ -85,11 +85,11 @@ func summarize( parameters: EncryptionParameters, _: Scheme.Type) throws { let values = (0..<8).map { Scheme.Scalar($0) } - let context = try Context(encryptionParameters: parameters) + let context = try Context(encryptionParameters: parameters) let plaintext: Scheme.CoeffPlaintext = try context.encode( values: values, format: .coefficient) - let secretKey = try context.generateSecretKey() + let secretKey: SecretKey = try context.generateSecretKey() let ciphertext = try plaintext.encrypt(using: secretKey) let noiseBudget = try ciphertext.noiseBudget( using: secretKey, diff --git a/Snippets/HomomorphicEncryption/EvaluationKeySnippet.swift b/Snippets/HomomorphicEncryption/EvaluationKeySnippet.swift index 6bcf99a6..c20e25f7 100644 --- a/Snippets/HomomorphicEncryption/EvaluationKeySnippet.swift +++ b/Snippets/HomomorphicEncryption/EvaluationKeySnippet.swift @@ -46,7 +46,7 @@ let encryptionParameters = try EncryptionParameters(from: .insecure_n_8_logq_5x18_logt_5) precondition(encryptionParameters.plaintextModulus == 17) // Perform pre-computation for HE computation with these parameters. -let context = try Context>(encryptionParameters: encryptionParameters) +let context = try Context(encryptionParameters: encryptionParameters) // We encode N values using SIMD encoding. // Each value is a Bfv.Scalar, which is UInt32. @@ -56,7 +56,7 @@ let plaintext: Bfv.CoeffPlaintext = try context.encode( format: .simd) // We generate a secret key and encrypt the plaintext. -let secretKey = try context.generateSecretKey() +let secretKey: SecretKey> = try context.generateSecretKey() var ciphertext = try plaintext.encrypt(using: secretKey) // We generate an evaluation key. This is a key used in some HE operations. diff --git a/Snippets/HomomorphicEncryption/MultiplicationSnippet.swift b/Snippets/HomomorphicEncryption/MultiplicationSnippet.swift index 084538cd..59ac993d 100644 --- a/Snippets/HomomorphicEncryption/MultiplicationSnippet.swift +++ b/Snippets/HomomorphicEncryption/MultiplicationSnippet.swift @@ -34,7 +34,7 @@ let encryptParams = try EncryptionParameters(from: .insecure_n_8_logq_5x18_logt_5) precondition(encryptParams.plaintextModulus == 17) // Perform pre-computation for HE computation with these parameters. -let context = try Context>(encryptionParameters: encryptParams) +let context = try Context(encryptionParameters: encryptParams) // We don't need to use all the slots in the encoding. // However, performing HE operations on ciphertexts with fewer slots doesn't give @@ -46,7 +46,7 @@ let plaintext: Bfv.CoeffPlaintext = try context.encode( format: .simd) // We generate a secret key and encrypt the plaintext. -let secretKey = try context.generateSecretKey() +let secretKey: SecretKey> = try context.generateSecretKey() let ciphertext = try plaintext.encrypt(using: secretKey) // Multiplication requires the ciphertext and plaintext to be in Evaluation diff --git a/Snippets/HomomorphicEncryption/NoiseBudgetSnippet.swift b/Snippets/HomomorphicEncryption/NoiseBudgetSnippet.swift index 95823d2f..d4f4be05 100644 --- a/Snippets/HomomorphicEncryption/NoiseBudgetSnippet.swift +++ b/Snippets/HomomorphicEncryption/NoiseBudgetSnippet.swift @@ -45,7 +45,7 @@ func checkDecryptsDecodes( let encryptionParameters = try EncryptionParameters(from: .insecure_n_8_logq_5x18_logt_5) // Perform pre-computation for HE computation with these parameters. -let context = try Context>(encryptionParameters: encryptionParameters) +let context = try Context(encryptionParameters: encryptionParameters) // We encode N values in coefficient format and SIMD encoding. let values = (0..<8).map { UInt32($0) } @@ -54,7 +54,7 @@ let plaintext: Bfv.CoeffPlaintext = try context.encode( format: .simd) // We generate a secret key and encrypt the plaintext. -let secretKey = try context.generateSecretKey() +let secretKey: SecretKey> = try context.generateSecretKey() var ciphertext = try plaintext.encrypt(using: secretKey) // The noiseBudget of a ciphertext is a measure of how many encrypted operations diff --git a/Snippets/HomomorphicEncryption/SerializationSnippet.swift b/Snippets/HomomorphicEncryption/SerializationSnippet.swift index b18ac6f3..2ffbe5be 100644 --- a/Snippets/HomomorphicEncryption/SerializationSnippet.swift +++ b/Snippets/HomomorphicEncryption/SerializationSnippet.swift @@ -36,7 +36,7 @@ extension SerializedCiphertext { let encryptionParameters = try EncryptionParameters(from: .n_4096_logq_27_28_28_logt_5) // Perform pre-computation for HE computation with these parameters. -let context = try Context>(encryptionParameters: encryptionParameters) +let context = try Context(encryptionParameters: encryptionParameters) // We encode some values in coefficient format and coefficient encoding. let values = (0..<8).map { UInt32($0) } @@ -45,7 +45,7 @@ let plaintext: Bfv.CoeffPlaintext = try context.encode( format: .coefficient) // We generate a secret key and encrypt the plaintext. -let secretKey = try context.generateSecretKey() +let secretKey: SecretKey> = try context.generateSecretKey() var ciphertext: Bfv.CanonicalCiphertext = try plaintext .encrypt(using: secretKey) diff --git a/Sources/BenchmarkUtilities/PirBenchmarkUtilities.swift b/Sources/BenchmarkUtilities/PirBenchmarkUtilities.swift index ba4e161d..7b2eddd1 100644 --- a/Sources/BenchmarkUtilities/PirBenchmarkUtilities.swift +++ b/Sources/BenchmarkUtilities/PirBenchmarkUtilities.swift @@ -83,7 +83,7 @@ extension PrivateInformationRetrieval.Response { struct ProcessBenchmarkContext { let database: [[UInt8]] - let context: Context + let context: Context let parameter: IndexPirParameter init(server _: Server.Type, pirConfig: IndexPirConfig, parameterConfig: PirEncryptionParametersConfig) throws @@ -171,7 +171,7 @@ struct IndexPirBenchmarkContext { let encryptParameter: EncryptionParameters = try EncryptionParameters(from: parameterConfig) - let context = try Context(encryptionParameters: encryptParameter) + let context = try Context(encryptionParameters: encryptParameter) let indexPirParameters = Server.generateParameter(config: pirConfig, with: context) let database = getDatabaseForTesting( numberOfEntries: pirConfig.entryCount, @@ -286,7 +286,7 @@ struct KeywordPirBenchmarkContext = try EncryptionParameters(from: parameterConfig) - let context = try Context(encryptionParameters: encryptParameter) + let context = try Context(encryptionParameters: encryptParameter) let rows = (0.. { let database: Database - let contexts: [Context] + let contexts: [Context] let serverConfig: ServerConfig init(databaseConfig: DatabaseConfig, @@ -305,7 +305,7 @@ struct PnnsBenchmarkContext { let database = getDatabaseForTesting(config: databaseConfig) let contexts = try clientConfig.encryptionParameters - .map { encryptionParameters in try Context(encryptionParameters: encryptionParameters) } + .map { encryptionParameters in try Context(encryptionParameters: encryptionParameters) } self.processedDatabase = try database.process(config: serverConfig, contexts: contexts) self.client = try Client(config: clientConfig, contexts: contexts) self.server = try Server(database: processedDatabase) diff --git a/Sources/HomomorphicEncryption/Bfv/Bfv+Encode.swift b/Sources/HomomorphicEncryption/Bfv/Bfv+Encode.swift index a40433d2..6eab5554 100644 --- a/Sources/HomomorphicEncryption/Bfv/Bfv+Encode.swift +++ b/Sources/HomomorphicEncryption/Bfv/Bfv+Encode.swift @@ -24,7 +24,7 @@ extension Bfv { @inlinable // swiftlint:disable:next missing_docs attributes - public static func encode(context: Context>, values: some Collection, + public static func encode(context: Context, values: some Collection, format: EncodeFormat) throws -> CoeffPlaintext { try context.encode(values: values, format: format) @@ -32,7 +32,7 @@ extension Bfv { @inlinable // swiftlint:disable:next missing_docs attributes - public static func encode(context: Context>, signedValues: some Collection, + public static func encode(context: Context, signedValues: some Collection, format: EncodeFormat) throws -> CoeffPlaintext { try context.encode(signedValues: signedValues, format: format) @@ -40,7 +40,7 @@ extension Bfv { @inlinable // swiftlint:disable:next missing_docs attributes - public static func encode(context: Context>, values: some Collection, format: EncodeFormat, + public static func encode(context: Context, values: some Collection, format: EncodeFormat, moduliCount: Int?) throws -> EvalPlaintext { let coeffPlaintext = try Self.encode(context: context, values: values, format: format) @@ -50,7 +50,7 @@ extension Bfv { @inlinable // swiftlint:disable:next missing_docs attributes public static func encode( - context: Context>, + context: Context, signedValues: some Collection, format: EncodeFormat, moduliCount: Int?) throws -> EvalPlaintext diff --git a/Sources/HomomorphicEncryption/Bfv/Bfv+Encrypt.swift b/Sources/HomomorphicEncryption/Bfv/Bfv+Encrypt.swift index b93359f5..9f7fef10 100644 --- a/Sources/HomomorphicEncryption/Bfv/Bfv+Encrypt.swift +++ b/Sources/HomomorphicEncryption/Bfv/Bfv+Encrypt.swift @@ -1,4 +1,4 @@ -// Copyright 2024 Apple Inc. and the Swift Homomorphic Encryption project authors +// Copyright 2024-2025 Apple Inc. and the Swift Homomorphic Encryption project authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -23,7 +23,7 @@ extension Bfv { @inlinable // swiftlint:disable:next missing_docs attributes - public static func zeroCiphertextCoeff(context: Context, moduliCount: Int?) throws -> CoeffCiphertext { + public static func zeroCiphertextCoeff(context: Context, moduliCount: Int?) throws -> CoeffCiphertext { let moduliCount = moduliCount ?? context.ciphertextContext.moduli.count let zeroPoly = try PolyRq.zero( context: context.ciphertextContext @@ -34,7 +34,7 @@ extension Bfv { @inlinable // swiftlint:disable:next missing_docs attributes - public static func zeroCiphertextEval(context: Context, moduliCount: Int?) throws -> EvalCiphertext { + public static func zeroCiphertextEval(context: Context, moduliCount: Int?) throws -> EvalCiphertext { let moduliCount = moduliCount ?? context.ciphertextContext.moduli.count let zeroPoly = try PolyRq.zero( context: context.ciphertextContext @@ -143,7 +143,7 @@ extension Bfv { } @inlinable - static func encryptZero(for context: Context>, + static func encryptZero(for context: Context, using secretKey: SecretKey>) throws -> CanonicalCiphertext { let ciphertextContext = context.ciphertextContext @@ -151,7 +151,7 @@ extension Bfv { } @inlinable - static func encryptZero(for context: Context>, + static func encryptZero(for context: Context, using secretKey: SecretKey>, with ciphertextContext: PolyContext) throws -> CanonicalCiphertext { diff --git a/Sources/HomomorphicEncryption/Bfv/Bfv+Keys.swift b/Sources/HomomorphicEncryption/Bfv/Bfv+Keys.swift index 49c05ac7..6d62ad42 100644 --- a/Sources/HomomorphicEncryption/Bfv/Bfv+Keys.swift +++ b/Sources/HomomorphicEncryption/Bfv/Bfv+Keys.swift @@ -1,4 +1,4 @@ -// Copyright 2024 Apple Inc. and the Swift Homomorphic Encryption project authors +// Copyright 2024-2025 Apple Inc. and the Swift Homomorphic Encryption project authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -17,7 +17,7 @@ import ModularArithmetic extension Bfv { @inlinable // swiftlint:disable:next missing_docs attributes - public static func generateSecretKey(context: Context) throws -> SecretKey> { + public static func generateSecretKey(context: Context) throws -> SecretKey> { var s = PolyRq.zero(context: context.secretKeyContext) var rng = SystemRandomNumberGenerator() s.randomizeTernary(using: &rng) @@ -28,7 +28,7 @@ extension Bfv { @inlinable // swiftlint:disable:next missing_docs attributes public static func generateEvaluationKey( - context: Context>, + context: Context, config: EvaluationKeyConfig, using secretKey: borrowing SecretKey>) throws -> EvaluationKey> { @@ -55,7 +55,7 @@ extension Bfv { } @inlinable - static func generateRelinearizationKey(context: Context, + static func generateRelinearizationKey(context: Context, secretKey: borrowing SecretKey) throws -> RelinearizationKey { @@ -65,7 +65,7 @@ extension Bfv { } @inlinable - static func generateKeySwitchKey(context: Context>, + static func generateKeySwitchKey(context: Context, currentKey: consuming PolyRq, targetKey: borrowing SecretKey>) throws -> KeySwitchKey> { @@ -120,7 +120,7 @@ extension Bfv { /// - seealso: ``Bfv/generateEvaluationKey(context:config:using:)``. @inlinable static func computeKeySwitchingUpdate( - context: Context>, + context: Context, target: PolyRq, keySwitchingKey: KeySwitchKey) throws -> [PolyRq] { diff --git a/Sources/HomomorphicEncryption/Ciphertext.swift b/Sources/HomomorphicEncryption/Ciphertext.swift index ce520640..61cf2689 100644 --- a/Sources/HomomorphicEncryption/Ciphertext.swift +++ b/Sources/HomomorphicEncryption/Ciphertext.swift @@ -17,7 +17,7 @@ public struct Ciphertext: Equatable, Senda public typealias Scalar = Scheme.Scalar /// Context for HE computation. - public let context: Context + public let context: Context @usableFromInline package var polys: [PolyRq] @usableFromInline var correctionFactor: Scalar @usableFromInline var seed: [UInt8] = [] @@ -33,7 +33,7 @@ public struct Ciphertext: Equatable, Senda @inlinable init( - context: Context, + context: Context, polys: [PolyRq], correctionFactor: Scalar, seed: [UInt8] = []) @@ -64,7 +64,9 @@ public struct Ciphertext: Equatable, Senda /// ``` /// - seelaso: ``Ciphertext/isTransparent()`` @inlinable - public static func zero(context: Context, moduliCount: Int? = nil) throws -> Ciphertext { + public static func zero(context: Context, + moduliCount: Int? = nil) throws -> Ciphertext + { try Scheme.zero(context: context, moduliCount: moduliCount) } diff --git a/Sources/HomomorphicEncryption/Context.swift b/Sources/HomomorphicEncryption/Context.swift index c5ee84be..e8c804c7 100644 --- a/Sources/HomomorphicEncryption/Context.swift +++ b/Sources/HomomorphicEncryption/Context.swift @@ -16,9 +16,7 @@ /// /// HE operations are typically only supported between objects, such as ``Ciphertext``, ``Plaintext``, /// ``EvaluationKey``, ``SecretKey``, with the same context. -public final class Context: Equatable, Sendable { - public typealias Scalar = Scheme.Scalar - +public final class Context: Equatable, Sendable { /// Encryption parameters. public let encryptionParameters: EncryptionParameters @@ -52,12 +50,6 @@ public final class Context: Equatable, Sendable { public var degree: Int { encryptionParameters.polyDegree } /// Whether or not the context supports ``EncodeFormat/simd`` encoding. public var supportsSimdEncoding: Bool { encryptionParameters.supportsSimdEncoding } - /// The (row, column) dimension counts for ``EncodeFormat/simd`` encoding. - /// - /// If the HE scheme does not support ``EncodeFormat/simd`` encoding, returns `nil`. - public var simdDimensions: SimdEncodingDimensions? { - Scheme.encodeSimdDimensions(for: encryptionParameters) - } /// Whether or not the context supports use of an ``EvaluationKey``. public var supportsEvaluationKey: Bool { encryptionParameters.supportsEvaluationKey } @@ -128,10 +120,19 @@ public final class Context: Equatable, Sendable { /// - rhs: Another context to compare. /// - Returns: Whether or not the two contexts are equal. @inlinable - public static func == (lhs: Context, rhs: Context) -> Bool { + public static func == (lhs: Context, rhs: Context) -> Bool { lhs === rhs || lhs.encryptionParameters == rhs.encryptionParameters } + /// The (row, column) dimension counts for ``EncodeFormat/simd`` encoding. + /// + /// If the HE scheme does not support ``EncodeFormat/simd`` encoding, returns `nil`. + public func simdDimensions(for _: Scheme.Type) -> SimdEncodingDimensions? + where Scheme.Scalar == Scalar + { + Scheme.encodeSimdDimensions(for: encryptionParameters) + } + @inlinable func getRnsTool(moduliCount: Int) -> RnsTool { precondition(moduliCount <= rnsTools.count && moduliCount > 0, "Invalid number of moduli") @@ -141,6 +142,6 @@ public final class Context: Equatable, Sendable { extension Context: CustomStringConvertible { public var description: String { - "Context<\(Scheme.self)>(encryptionParameters=\(encryptionParameters.description))" + "Context<\(Scalar.self)>(encryptionParameters=\(encryptionParameters.description))" } } diff --git a/Sources/HomomorphicEncryption/Encoding.swift b/Sources/HomomorphicEncryption/Encoding.swift index 61b98907..03aff6cd 100644 --- a/Sources/HomomorphicEncryption/Encoding.swift +++ b/Sources/HomomorphicEncryption/Encoding.swift @@ -27,8 +27,9 @@ extension Context { /// - Returns: The plaintext encoding `values`. /// - Throws: Error upon failure to encode. @inlinable - public func encode(values: some Collection, - format: EncodeFormat) throws -> Plaintext + public func encode(values: some Collection, + format: EncodeFormat) throws -> Plaintext + where Scheme.Scalar == Scalar { try validDataForEncoding(values: values) switch format { @@ -48,8 +49,9 @@ extension Context { /// - Returns: The plaintext encoding `signedValues`. /// - Throws: Error upon failure to encode. @inlinable - public func encode(signedValues: some Collection, - format: EncodeFormat) throws -> Plaintext + public func encode(signedValues: some Collection, + format: EncodeFormat) throws -> Plaintext + where Scheme.Scalar == Scalar { let signedModulus = Scheme.SignedScalar(plaintextModulus) let bounds = -(signedModulus >> 1)...((signedModulus - 1) >> 1) @@ -71,10 +73,11 @@ extension Context { /// - Returns: The plaintext encoding `values`. /// - Throws: Error upon failure to encode. @inlinable - public func encode( + public func encode( values: some Collection, format: EncodeFormat, moduliCount: Int? = nil) throws -> Plaintext + where Scheme.Scalar == Scalar { try Scheme.encode(context: self, values: values, format: format, moduliCount: moduliCount) } @@ -88,8 +91,9 @@ extension Context { /// - Returns: The plaintext encoding `signedValues`. /// - Throws: Error upon failure to encode. @inlinable - public func encode(signedValues: some Collection, format: EncodeFormat, - moduliCount: Int? = nil) throws -> Plaintext + public func encode(signedValues: some Collection, format: EncodeFormat, + moduliCount: Int? = nil) throws -> Plaintext + where Scheme.Scalar == Scalar { try Scheme.encode(context: self, signedValues: signedValues, format: format, moduliCount: moduliCount) } @@ -102,7 +106,9 @@ extension Context { /// - Returns: The decoded values. /// - Throws: Error upon failure to decode. @inlinable - func decode(plaintext: Plaintext, format: EncodeFormat) throws -> [Scalar] { + func decode(plaintext: Plaintext, format: EncodeFormat) throws -> [Scalar] + where Scheme.Scalar == Scalar + { switch format { case .coefficient: decodeCoefficient(plaintext: plaintext) @@ -119,7 +125,10 @@ extension Context { /// - Returns: The decoded signed values. /// - Throws: Error upon failure to decode. @inlinable - func decode(plaintext: Plaintext, format: EncodeFormat) throws -> [Scheme.SignedScalar] { + func decode(plaintext: Plaintext, + format: EncodeFormat) throws -> [Scheme.SignedScalar] + where Scheme.Scalar == Scalar + { let unsignedValues: [Scalar] = try decode(plaintext: plaintext, format: format) return unsignedValues.map { value in value.remainderToCentered(modulus: plaintextModulus) @@ -134,7 +143,9 @@ extension Context { /// - Returns: The decoded signed values. /// - Throws: Error upon failure to decode. @inlinable - func decode(plaintext: Plaintext, format: EncodeFormat) throws -> [Scheme.SignedScalar] { + func decode(plaintext: Plaintext, + format: EncodeFormat) throws -> [Scheme.SignedScalar] + { try Scheme.decodeEval(plaintext: plaintext, format: format) } @@ -159,8 +170,8 @@ extension Context { /// `f(x) = values_0 + values_1 x + ... values_{N_1} x^{N-1}`, padding /// with 0 coefficients if fewer than `N` values are provided. @inlinable - func encodeCoefficient(values: some Collection) throws - -> Plaintext + func encodeCoefficient(values: some Collection) throws + -> Plaintext where Scheme.Scalar == Scalar { if values.isEmpty { return Plaintext(context: self, poly: PolyRq.zero(context: plaintextContext)) @@ -182,7 +193,7 @@ extension Context { /// - Parameter plaintext: Plaintext to decode. /// - Returns: The decoded plaintext values, each in `[0, t - 1]` for plaintext modulus `t`. @inlinable - func decodeCoefficient(plaintext: Plaintext) -> [Scalar] { + func decodeCoefficient(plaintext: Plaintext) -> [Scheme.Scalar] { plaintext.poly.data.data } } @@ -215,7 +226,9 @@ extension Context { } @inlinable - func encodeSimd(values: some Collection) throws -> Plaintext { + func encodeSimd(values: some Collection) throws -> Plaintext + where Scheme.Scalar == Scalar + { guard !simdEncodingMatrix.isEmpty else { throw HeError.simdEncodingNotSupported(for: encryptionParameters) } let polyDegree = encryptionParameters.polyDegree var array = Array2d.zero(rowCount: 1, columnCount: polyDegree) @@ -228,7 +241,9 @@ extension Context { } @inlinable - func decodeSimd(plaintext: Plaintext) throws -> [Scalar] { + func decodeSimd(plaintext: Plaintext) throws -> [Scalar] + where Scheme.Scalar == Scalar + { guard !simdEncodingMatrix.isEmpty else { throw HeError.simdEncodingNotSupported(for: encryptionParameters) } diff --git a/Sources/HomomorphicEncryption/HeScheme.swift b/Sources/HomomorphicEncryption/HeScheme.swift index afce3aff..f3e37855 100644 --- a/Sources/HomomorphicEncryption/HeScheme.swift +++ b/Sources/HomomorphicEncryption/HeScheme.swift @@ -144,7 +144,7 @@ public protocol HeScheme { /// - Returns: A freshly generated secret key. /// - Throws: Error upon failure to generate a secret key. /// - seealso: ``Context/generateSecretKey()`` for an alternative API. - static func generateSecretKey(context: Context) throws -> SecretKey + static func generateSecretKey(context: Context) throws -> SecretKey /// Generates an ``EvaluationKey``. /// - Parameters: @@ -155,7 +155,7 @@ public protocol HeScheme { /// - Throws: Error upon failure to generate an evaluation key. /// - seealso: ``Context/generateEvaluationKey(config:using:)`` for an alternative API. static func generateEvaluationKey( - context: Context, + context: Context, config: EvaluationKeyConfig, using secretKey: SecretKey) throws -> EvaluationKey @@ -173,7 +173,7 @@ public protocol HeScheme { /// - Throws: Error upon failure to encode. /// - seealso: ``Context/encode(values:format:)`` for an alternative API. /// - seealso: ``HeScheme/encode(context:signedValues:format:)`` to encode signed values. - static func encode(context: Context, values: some Collection, format: EncodeFormat) throws + static func encode(context: Context, values: some Collection, format: EncodeFormat) throws -> CoeffPlaintext /// Encodes signed values into a plaintext with coefficient format. @@ -186,7 +186,10 @@ public protocol HeScheme { /// - Throws: Error upon failure to encode. /// - seealso: ``Context/encode(signedValues:format:)`` for an alternative API. /// - seealso: ``HeScheme/encode(context:values:format:)`` to encode unsigned values. - static func encode(context: Context, signedValues: some Collection, format: EncodeFormat) throws + static func encode( + context: Context, + signedValues: some Collection, + format: EncodeFormat) throws -> CoeffPlaintext /// Encodes values into a plaintext with evaluation format. @@ -202,7 +205,7 @@ public protocol HeScheme { /// - Throws: Error upon failure to encode. /// - seealso: ``Context/encode(values:format:moduliCount:)`` for an alternative API. /// - seealso: ``HeScheme/encode(context:signedValues:format:moduliCount:)`` to encode signed values. - static func encode(context: Context, values: some Collection, format: EncodeFormat, + static func encode(context: Context, values: some Collection, format: EncodeFormat, moduliCount: Int?) throws -> EvalPlaintext /// Encodes signed values into a plaintext with evaluation format. @@ -218,8 +221,11 @@ public protocol HeScheme { /// - Throws: Error upon failure to encode. /// - seealso: ``Context/encode(signedValues:format:moduliCount:)`` for an alternative API. /// - seealso: ``HeScheme/encode(context:values:format:moduliCount:)`` to encode unsigned values. - static func encode(context: Context, signedValues: some Collection, format: EncodeFormat, - moduliCount: Int?) throws -> EvalPlaintext + static func encode( + context: Context, + signedValues: some Collection, + format: EncodeFormat, + moduliCount: Int?) throws -> EvalPlaintext /// Decodes a plaintext in ``Coeff`` format. /// - Parameters: @@ -286,7 +292,7 @@ public protocol HeScheme { /// ``` /// - seealso: ``HeScheme/isTransparent(ciphertext:)`` /// - seealso: ``Ciphertext/zero(context:moduliCount:)`` for an alternative API. - static func zeroCiphertextCoeff(context: Context, moduliCount: Int?) throws -> CoeffCiphertext + static func zeroCiphertextCoeff(context: Context, moduliCount: Int?) throws -> CoeffCiphertext /// Generates a ciphertext of zeros in ``Eval`` format. /// @@ -308,7 +314,7 @@ public protocol HeScheme { /// ``` /// - seealso: ``HeScheme/isTransparent(ciphertext:)`` /// - seealso: ``Ciphertext/zero(context:moduliCount:)`` for an alternative API. - static func zeroCiphertextEval(context: Context, moduliCount: Int?) throws -> EvalCiphertext + static func zeroCiphertextEval(context: Context, moduliCount: Int?) throws -> EvalCiphertext /// Computes whether a ciphertext is transparent. /// @@ -849,7 +855,7 @@ public protocol HeScheme { /// - lhs: A Context to compare. /// - rhs: Another context to compare. /// - Throws: Error upon unequal contexts. - static func validateEquality(of lhs: Context, and rhs: Context) throws + static func validateEquality(of lhs: Context, and rhs: Context) throws /// Computes the noise budget of a ciphertext. /// @@ -1187,7 +1193,7 @@ extension HeScheme { /// ``` /// - seelaso: ``Ciphertext/isTransparent()`` @inlinable - public static func zero(context: Context, + public static func zero(context: Context, moduliCount: Int? = nil) throws -> Ciphertext { if Format.self == Coeff.self { @@ -1257,7 +1263,7 @@ extension HeScheme { extension HeScheme { @inlinable // swiftlint:disable:next missing_docs attributes - public static func validateEquality(of lhs: Context, and rhs: Context) throws { + public static func validateEquality(of lhs: Context, and rhs: Context) throws { guard lhs == rhs else { throw HeError.unequalContexts(got: lhs, expected: rhs) } @@ -1447,7 +1453,7 @@ extension Context { /// - Throws: Error upon failure to generate a secret key. /// - seealso: ``HeScheme/generateSecretKey(context:)`` for an alternative API. @inlinable - public func generateSecretKey() throws -> SecretKey { + public func generateSecretKey() throws -> SecretKey where Scheme.Scalar == Scalar { try Scheme.generateSecretKey(context: self) } @@ -1459,10 +1465,10 @@ extension Context { /// - Throws: Error upon failure to generate an evaluation key. /// - seealso: ``HeScheme/generateEvaluationKey(context:config:using:)`` for an alternative API. @inlinable - public func generateEvaluationKey( + public func generateEvaluationKey( config: EvaluationKeyConfig, using secretKey: SecretKey) throws - -> EvaluationKey + -> EvaluationKey where Scheme.Scalar == Scalar { try Scheme.generateEvaluationKey(context: self, config: config, using: secretKey) } diff --git a/Sources/HomomorphicEncryption/Keys.swift b/Sources/HomomorphicEncryption/Keys.swift index 6672c697..19c4f086 100644 --- a/Sources/HomomorphicEncryption/Keys.swift +++ b/Sources/HomomorphicEncryption/Keys.swift @@ -52,12 +52,12 @@ extension SecretKey: PolyCollection { @usableFromInline struct KeySwitchKey: Equatable, Sendable { /// The context used for key-switching operations. - @usableFromInline let context: Context + @usableFromInline let context: Context /// The ciphertexts of the key-switching key. @usableFromInline let ciphers: [Ciphertext] @inlinable - init(context: Context, ciphers: [Ciphertext]) { + init(context: Context, ciphers: [Ciphertext]) { self.context = context self.ciphers = ciphers } diff --git a/Sources/HomomorphicEncryption/NoOpScheme.swift b/Sources/HomomorphicEncryption/NoOpScheme.swift index 0cb9cb73..398c8ea1 100644 --- a/Sources/HomomorphicEncryption/NoOpScheme.swift +++ b/Sources/HomomorphicEncryption/NoOpScheme.swift @@ -28,17 +28,17 @@ public enum NoOpScheme: HeScheme { 0 } - public static func generateSecretKey(context: Context) -> SecretKey { + public static func generateSecretKey(context: Context) -> SecretKey { let poly = PolyRq.zero(context: context.secretKeyContext) return SecretKey(poly: poly) } public static func generateEvaluationKey( - context: Context, + context: Context, config: EvaluationKeyConfig, using _: SecretKey) throws -> EvaluationKey { - let keySwitchKey = KeySwitchKey(context: context, ciphers: []) - let galoisKeys = [Int: KeySwitchKey]( + let keySwitchKey = KeySwitchKey(context: context, ciphers: []) + let galoisKeys = [Int: KeySwitchKey]( config.galoisElements .map { g in (g, keySwitchKey) }) { first, _ in first } return EvaluationKey( @@ -56,19 +56,19 @@ public enum NoOpScheme: HeScheme { return SimdEncodingDimensions(rowCount: 2, columnCount: parameters.polyDegree / 2) } - public static func encode(context: Context, values: some Collection, + public static func encode(context: Context, values: some Collection, format: EncodeFormat) throws -> CoeffPlaintext { try context.encode(values: values, format: format) } - public static func encode(context: Context, signedValues: some Collection, + public static func encode(context: Context, signedValues: some Collection, format: EncodeFormat) throws -> CoeffPlaintext { try context.encode(signedValues: signedValues, format: format) } - public static func encode(context: Context, values: some Collection, + public static func encode(context: Context, values: some Collection, format: EncodeFormat, moduliCount _: Int?) throws -> EvalPlaintext { let coeffPlaintext = try Self.encode(context: context, values: values, format: format) @@ -76,7 +76,7 @@ public enum NoOpScheme: HeScheme { } public static func encode( - context: Context, + context: Context, signedValues: some Collection, format: EncodeFormat, moduliCount _: Int?) throws -> EvalPlaintext @@ -101,7 +101,7 @@ public enum NoOpScheme: HeScheme { try plaintext.inverseNtt().decode(format: format) } - public static func zeroCiphertextCoeff(context: Context, moduliCount _: Int?) throws -> CoeffCiphertext { + public static func zeroCiphertextCoeff(context: Context, moduliCount _: Int?) throws -> CoeffCiphertext { NoOpScheme .CoeffCiphertext( context: context, @@ -109,7 +109,7 @@ public enum NoOpScheme: HeScheme { correctionFactor: 1) } - public static func zeroCiphertextEval(context: Context, moduliCount _: Int?) throws -> EvalCiphertext { + public static func zeroCiphertextEval(context: Context, moduliCount _: Int?) throws -> EvalCiphertext { NoOpScheme .EvalCiphertext( context: context, diff --git a/Sources/HomomorphicEncryption/Plaintext.swift b/Sources/HomomorphicEncryption/Plaintext.swift index 9f324085..cd029821 100644 --- a/Sources/HomomorphicEncryption/Plaintext.swift +++ b/Sources/HomomorphicEncryption/Plaintext.swift @@ -1,4 +1,4 @@ -// Copyright 2024 Apple Inc. and the Swift Homomorphic Encryption project authors +// Copyright 2024-2025 Apple Inc. and the Swift Homomorphic Encryption project authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -19,12 +19,12 @@ public struct Plaintext: Equatable, Sendab public typealias SignedScalar = Scheme.SignedScalar /// Context for HE computation. - public let context: Context + public let context: Context @usableFromInline var poly: PolyRq @inlinable - package init(context: Context, poly: PolyRq) { + package init(context: Context, poly: PolyRq) { self.context = context self.poly = poly } diff --git a/Sources/HomomorphicEncryption/SerializedCiphertext.swift b/Sources/HomomorphicEncryption/SerializedCiphertext.swift index b54f2ccc..92111876 100644 --- a/Sources/HomomorphicEncryption/SerializedCiphertext.swift +++ b/Sources/HomomorphicEncryption/SerializedCiphertext.swift @@ -43,7 +43,7 @@ extension Ciphertext { @inlinable public init( deserialize serialized: SerializedCiphertext, - context: Context, + context: Context, moduliCount: Int? = nil) throws { self.context = context diff --git a/Sources/HomomorphicEncryption/SerializedKeys.swift b/Sources/HomomorphicEncryption/SerializedKeys.swift index a3bda53a..ba11dcee 100644 --- a/Sources/HomomorphicEncryption/SerializedKeys.swift +++ b/Sources/HomomorphicEncryption/SerializedKeys.swift @@ -30,7 +30,7 @@ extension SecretKey { /// - serialized: Serialized secret key. /// - context: Context to associate with the secret key. /// - Throws: ``HeError`` upon failure to deserialize. - public convenience init(deserialize serialized: SerializedSecretKey, context: Context) throws { + public convenience init(deserialize serialized: SerializedSecretKey, context: Context) throws { let polys: [PolyRq] = try Serialize.deserializePolys( from: serialized.polys, context: context.secretKeyContext) @@ -52,7 +52,7 @@ extension SecretKey { extension KeySwitchKey { @inlinable - init(deserialize ciphertexts: [SerializedCiphertext], context: Context) throws { + init(deserialize ciphertexts: [SerializedCiphertext], context: Context) throws { self.context = context self.ciphers = try ciphertexts.map { serializedCiphertext in try Ciphertext( @@ -81,7 +81,7 @@ public struct SerializedGaloisKey: Hashable, Codable, Sendab extension GaloisKey { @inlinable - init(deserialize serialized: SerializedGaloisKey, context: Context) throws { + init(deserialize serialized: SerializedGaloisKey, context: Context) throws { self.keys = try serialized.galoisKey.mapValues { serializedKeySwitchKey in try KeySwitchKey(deserialize: serializedKeySwitchKey, context: context) } @@ -106,7 +106,7 @@ public struct SerializedRelinearizationKey: Hashable, Codabl extension RelinearizationKey { @inlinable - init(deserialize serialized: SerializedRelinearizationKey, context: Context) throws { + init(deserialize serialized: SerializedRelinearizationKey, context: Context) throws { self.keySwitchKey = try KeySwitchKey(deserialize: serialized.relinKey, context: context) } @@ -139,7 +139,9 @@ extension EvaluationKey { /// - context: Context to associate with the evaluation key. /// - Throws: ``HeError`` upon failure to deserialize. @inlinable - public init(deserialize serialized: SerializedEvaluationKey, context: Context) throws { + public init(deserialize serialized: SerializedEvaluationKey, + context: Context) throws + { self.galoisKey = try serialized.galoisKey.map { serialized in try GaloisKey(deserialize: serialized, context: context) } diff --git a/Sources/HomomorphicEncryption/SerializedPlaintext.swift b/Sources/HomomorphicEncryption/SerializedPlaintext.swift index a3f86eba..b15c1734 100644 --- a/Sources/HomomorphicEncryption/SerializedPlaintext.swift +++ b/Sources/HomomorphicEncryption/SerializedPlaintext.swift @@ -1,4 +1,4 @@ -// Copyright 2024 Apple Inc. and the Swift Homomorphic Encryption project authors +// Copyright 2024-2025 Apple Inc. and the Swift Homomorphic Encryption project authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -38,7 +38,7 @@ extension Plaintext where Format == Coeff { /// - context: Context to associate with the plaintext. /// - Throws: Error upon failure to deserialize. @inlinable - public init(deserialize serialized: SerializedPlaintext, context: Context) throws { + public init(deserialize serialized: SerializedPlaintext, context: Context) throws { self.context = context self.poly = try PolyRq(deserialize: serialized.poly, context: context.plaintextContext) } @@ -53,7 +53,11 @@ extension Plaintext where Format == Eval { /// 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 { + public init( + deserialize serialized: SerializedPlaintext, + context: Context, + moduliCount: Int? = nil) throws + { self.context = context let moduliCount = moduliCount ?? context.ciphertextContext.moduli.count let plaintextContext = try context.ciphertextContext.getContext(moduliCount: moduliCount) diff --git a/Sources/HomomorphicEncryptionProtobuf/ConversionHe.swift b/Sources/HomomorphicEncryptionProtobuf/ConversionHe.swift index 8c6eff75..aa6b94bd 100644 --- a/Sources/HomomorphicEncryptionProtobuf/ConversionHe.swift +++ b/Sources/HomomorphicEncryptionProtobuf/ConversionHe.swift @@ -216,7 +216,7 @@ extension Apple_SwiftHomomorphicEncryption_V1_SerializedEvaluationKey { /// - Parameter context: Context to associate with the native object. /// - Returns: The converted native type. /// - Throws: Error upon upon invalid object. - public func native(context: Context) throws -> EvaluationKey { + public func native(context: Context) throws -> EvaluationKey { let serialized: SerializedEvaluationKey = try native() return try EvaluationKey(deserialize: serialized, context: context) } diff --git a/Sources/PIRProcessDatabase/main.swift b/Sources/PIRProcessDatabase/main.swift index 36cf420d..dd485808 100644 --- a/Sources/PIRProcessDatabase/main.swift +++ b/Sources/PIRProcessDatabase/main.swift @@ -386,7 +386,7 @@ struct ProcessDatabase: AsyncParsableCommand { keyCompression: config.keyCompression, trialsPerShard: config.trialsPerShard, symmetricPirConfig: config.symmetricPirConfig) - let context = try Context(encryptionParameters: processArgs.encryptionParameters) + let context = try Context(encryptionParameters: processArgs.encryptionParameters) let keywordDatabase = try KeywordDatabase( rows: database, sharding: processArgs.databaseConfig.sharding, @@ -405,7 +405,7 @@ struct ProcessDatabase: AsyncParsableCommand { shard: shard, config: config, context: context, - processArgs: processArgs) + processArgs: processArgs, scheme: scheme.self) } } @@ -419,7 +419,7 @@ struct ProcessDatabase: AsyncParsableCommand { shardID: shardID, shard: shard, config: config, context: context, - processArgs: processArgs) + processArgs: processArgs, scheme: scheme.self) evaluationKeyConfig = [evaluationKeyConfig, processedEvaluationKeyConfig].union() } } @@ -433,12 +433,14 @@ struct ProcessDatabase: AsyncParsableCommand { } } + // swiftlint:disable:next function_parameter_count private func processShard( shardID: String, shard: KeywordDatabaseShard, config: ResolvedArguments, - context: Context, - processArgs: ProcessKeywordDatabase.Arguments) async throws -> EvaluationKeyConfig + context: Context, + processArgs: ProcessKeywordDatabase.Arguments, + scheme _: Scheme.Type) async throws -> EvaluationKeyConfig { var logger = ProcessDatabase.logger logger[metadataKey: "shardID"] = .string(shardID) diff --git a/Sources/PrivateInformationRetrieval/IndexPirProtocol.swift b/Sources/PrivateInformationRetrieval/IndexPirProtocol.swift index 8be40a02..1945b062 100644 --- a/Sources/PrivateInformationRetrieval/IndexPirProtocol.swift +++ b/Sources/PrivateInformationRetrieval/IndexPirProtocol.swift @@ -167,7 +167,7 @@ public struct ProcessedDatabase: Equatable, Sendable { /// - context: Context for HE computation. /// - Throws: Error upon failure to load the database. @inlinable - public init(from path: String, context: Context) throws { + public init(from path: String, context: Context) throws { let loadedFile = try [UInt8](Data(contentsOf: URL(fileURLWithPath: path))) try self.init(from: loadedFile, context: context) } @@ -178,7 +178,7 @@ public struct ProcessedDatabase: Equatable, Sendable { /// - context: Context for HE computation. /// - Throws: Error upon failure to deserialize. @inlinable - public init(from buffer: [UInt8], context: Context) throws { + public init(from buffer: [UInt8], context: Context) throws { var offset = buffer.startIndex let versionNumber = buffer[offset] offset += MemoryLayout.size @@ -344,7 +344,7 @@ public protocol IndexPirProtocol { /// - config: Database configuration. /// - context: Context for HE computation. /// - Returns: The PIR parameters for the database. - static func generateParameter(config: IndexPirConfig, with context: Context) -> IndexPirParameter + static func generateParameter(config: IndexPirConfig, with context: Context) -> IndexPirParameter } /// Protocol for a server hosting index PIR databases for lookup. @@ -380,7 +380,7 @@ public protocol IndexPirServer: Sendable { /// - context: Context for HE computation. /// - database: Integer-indexed database. /// - Throws: Error upon failure to initialize the server. - init(parameter: IndexPirParameter, context: Context, database: Database) throws + init(parameter: IndexPirParameter, context: Context, database: Database) throws /// Initializes an ``IndexPirServer`` with databases. /// @@ -389,7 +389,7 @@ public protocol IndexPirServer: Sendable { /// - context: Context for HE computation. /// - databases: Integer-indexed databases, each compatible with the given `parameter`. /// - Throws: Error upon failure to initialize the server. - init(parameter: IndexPirParameter, context: Context, databases: [Database]) throws + init(parameter: IndexPirParameter, context: Context, databases: [Database]) throws /// Processes the database to prepare for PIR queries. /// @@ -401,7 +401,7 @@ public protocol IndexPirServer: Sendable { /// - Returns: A processed database. /// - Throws: Error upon failure to process the database. static func process(database: some Collection<[UInt8]>, - with context: Context, + with context: Context, using parameter: IndexPirParameter) throws -> Database /// Compute the encrypted response to a query lookup. @@ -422,7 +422,7 @@ extension IndexPirServer { /// - database: Database. /// - Throws: Error upon failure to initialize the server. @inlinable - public init(parameter: IndexPirParameter, context: Context, database: Database) throws { + public init(parameter: IndexPirParameter, context: Context, database: Database) throws { try self.init(parameter: parameter, context: context, databases: [database]) } @@ -432,7 +432,9 @@ extension IndexPirServer { /// - context: Context for HE computation. /// - Returns: The PIR parameters for the database. @inlinable - public static func generateParameter(config: IndexPirConfig, with context: Context) -> IndexPirParameter { + public static func generateParameter(config: IndexPirConfig, + with context: Context) -> IndexPirParameter + { IndexPir.generateParameter(config: config, with: context) } } @@ -460,7 +462,7 @@ public protocol IndexPirClient: Sendable { /// - Parameters: /// - parameter: Parameters for the database. /// - context: Context for HE computation. - init(parameter: IndexPirParameter, context: Context) + init(parameter: IndexPirParameter, context: Context) /// Generates an encrypted query. /// - Parameters: diff --git a/Sources/PrivateInformationRetrieval/KeywordDatabase.swift b/Sources/PrivateInformationRetrieval/KeywordDatabase.swift index 3d14c800..fe533e18 100644 --- a/Sources/PrivateInformationRetrieval/KeywordDatabase.swift +++ b/Sources/PrivateInformationRetrieval/KeywordDatabase.swift @@ -487,11 +487,10 @@ public enum ProcessKeywordDatabase { public static func processShard(shard: KeywordDatabaseShard, with arguments: Arguments, onEvent: @escaping (ProcessShardEvent) throws -> Void = { _ in - }) throws - -> ProcessedDatabaseWithParameters + }) throws -> ProcessedDatabaseWithParameters { let keywordConfig = arguments.databaseConfig.keywordPirConfig - let context = try Context(encryptionParameters: arguments.encryptionParameters) + let context = try Context(encryptionParameters: arguments.encryptionParameters) guard arguments.algorithm == .mulPir else { throw PirError.invalidPirAlgorithm(arguments.algorithm) } @@ -515,7 +514,7 @@ public enum ProcessKeywordDatabase { shard: ProcessedDatabaseWithParameters, row: KeywordValuePair, trials: Int, - context: Context) throws -> ShardValidationResult + context: Context) throws -> ShardValidationResult { guard trials > 0 else { throw PirError.validationError("Invalid trialsPerShard: \(trials)") @@ -537,8 +536,8 @@ public enum ProcessKeywordDatabase { var response = Response(ciphertexts: [[]]) let clock = ContinuousClock() var minNoiseBudget = Double.infinity - let results = try (0.. = try context.generateSecretKey() let trialEvaluationKey = try client.generateEvaluationKey(using: secretKey) let trialQuery = try client.generateQuery(at: row.keyword, using: secretKey) let computeTime = try clock.measure { @@ -596,7 +595,7 @@ public enum ProcessKeywordDatabase { var evaluationKeyConfig = EvaluationKeyConfig() let keywordConfig = arguments.databaseConfig.keywordPirConfig - let context = try Context(encryptionParameters: arguments.encryptionParameters) + let context = try Context(encryptionParameters: arguments.encryptionParameters) let keywordDatabase = try KeywordDatabase( rows: rows, sharding: arguments.databaseConfig.sharding, diff --git a/Sources/PrivateInformationRetrieval/KeywordPirProtocol.swift b/Sources/PrivateInformationRetrieval/KeywordPirProtocol.swift index e8b24e96..a473de43 100644 --- a/Sources/PrivateInformationRetrieval/KeywordPirProtocol.swift +++ b/Sources/PrivateInformationRetrieval/KeywordPirProtocol.swift @@ -154,7 +154,7 @@ public final class KeywordPirServer: KeywordPirProtoc /// - context: Context for HE computation. /// - processed: Processed database. /// - Throws: Error upon failure to initialize the server. - public required init(context: Context, + public required init(context: Context, processed: ProcessedDatabaseWithParameters) throws { if let keywordPirParameter = processed.keywordPirParameter { @@ -186,7 +186,7 @@ public final class KeywordPirServer: KeywordPirProtoc @inlinable public static func process(database: some Collection, config: KeywordPirConfig, - with context: Context, + with context: Context, onEvent: @escaping (ProcessKeywordDatabase.ProcessShardEvent) throws -> Void = { _ in }, symmetricPirConfig: SymmetricPirConfig? = nil) throws -> ProcessedDatabaseWithParameters @@ -288,7 +288,7 @@ public final class KeywordPirClient: KeywordPirProtoc public required init( keywordParameter: KeywordPirParameter, pirParameter: IndexPirParameter, - context: Context) + context: Context) { self.keywordParameter = keywordParameter self.indexPirClient = PirClient(parameter: pirParameter, context: context) diff --git a/Sources/PrivateInformationRetrieval/MulPir.swift b/Sources/PrivateInformationRetrieval/MulPir.swift index f350e6a8..0294c157 100644 --- a/Sources/PrivateInformationRetrieval/MulPir.swift +++ b/Sources/PrivateInformationRetrieval/MulPir.swift @@ -30,7 +30,9 @@ public enum MulPir: IndexPirProtocol { public static var algorithm: PirAlgorithm { .mulPir } - public static func generateParameter(config: IndexPirConfig, with context: Context) -> IndexPirParameter { + public static func generateParameter(config: IndexPirConfig, + with context: Context) -> IndexPirParameter + { let entrySizeInBytes = config.entrySizeInBytes let perChunkPlaintextCount = if entrySizeInBytes <= context.bytesPerPlaintext { config.entryCount.dividingCeil(context.bytesPerPlaintext / entrySizeInBytes, variableTime: true) @@ -121,7 +123,7 @@ public final class MulPirClient: IndexPirClient { public let parameter: IndexPirParameter /// Context for HE computation. - public let context: HomomorphicEncryption.Context + public let context: HomomorphicEncryption.Context public var evaluationKeyConfig: EvaluationKeyConfig { parameter.evaluationKeyConfig @@ -140,7 +142,7 @@ public final class MulPirClient: IndexPirClient { IndexPir.computePerChunkPlaintextCount(for: parameter) } - public init(parameter: IndexPirParameter, context: Context) { + public init(parameter: IndexPirParameter, context: Context) { self.parameter = parameter self.context = context } @@ -285,7 +287,7 @@ public final class MulPirServer: IndexPirServer { /// Context for HE computation. /// /// Must be the same between client and server. - public let context: HomomorphicEncryption.Context + public let context: HomomorphicEncryption.Context /// Evaluation key configuration. public var evaluationKeyConfig: EvaluationKeyConfig { @@ -317,7 +319,7 @@ public final class MulPirServer: IndexPirServer { /// - context: Context for HE computation. /// - databases: Databases, each compatible with the given `parameter`. /// - Throws: Error upon failure to initialize the server. - public init(parameter: IndexPirParameter, context: Context, databases: [Database]) throws { + public init(parameter: IndexPirParameter, context: Context, databases: [Database]) throws { self.parameter = parameter self.context = context self.databases = databases @@ -331,7 +333,7 @@ public final class MulPirServer: IndexPirServer { } @inlinable - package static func chunkCount(parameter: IndexPirParameter, context: Context) -> Int { + package static func chunkCount(parameter: IndexPirParameter, context: Context) -> Int { parameter.entrySizeInBytes.dividingCeil(context.bytesPerPlaintext, variableTime: true) } } @@ -423,7 +425,7 @@ extension MulPirServer { extension MulPirServer { @inlinable // swiftlint:disable:next attributes missing_docs - public static func process(database: some Collection<[UInt8]>, with context: Context, + public static func process(database: some Collection<[UInt8]>, with context: Context, using parameter: IndexPirParameter) throws -> Database { guard database.count == parameter.entryCount else { @@ -445,7 +447,7 @@ extension MulPirServer { @inlinable static func processSplitLargeEntries( database: some Collection<[UInt8]>, - with context: Context, + with context: Context, using parameter: IndexPirParameter) throws -> Database { let chunkCount = Self.chunkCount(parameter: parameter, context: context) @@ -490,7 +492,7 @@ extension MulPirServer { @inlinable static func processPackEntries( database: some Collection<[UInt8]>, - with context: Context, + with context: Context, using parameter: IndexPirParameter) throws -> Database { assert(database.count == parameter.entryCount) diff --git a/Sources/PrivateInformationRetrieval/PirUtil.swift b/Sources/PrivateInformationRetrieval/PirUtil.swift index 9aea4a86..413481f4 100644 --- a/Sources/PrivateInformationRetrieval/PirUtil.swift +++ b/Sources/PrivateInformationRetrieval/PirUtil.swift @@ -144,7 +144,8 @@ package enum PirUtil { /// The MulPir indices are the indices of non-zero results after expansion @inlinable package static func compressInputsForOneCiphertext(totalInputCount: Int, nonZeroInputs: [Int], - context: Context) throws -> Plaintext + context: Context) throws + -> Plaintext { precondition(totalInputCount <= context.degree) var rawData: [Scalar] = Array(repeating: 0, count: context.degree) @@ -166,7 +167,7 @@ package enum PirUtil { package static func compressInputs( totalInputCount: Int, nonZeroInputs: [Int], - context: Context, + context: Context, using secretKey: SecretKey) throws -> [CanonicalCiphertext] { var remainingInputs = totalInputCount diff --git a/Sources/PrivateInformationRetrieval/PrivateInformationRetrieval.docc/EncodingPipeline.md b/Sources/PrivateInformationRetrieval/PrivateInformationRetrieval.docc/EncodingPipeline.md index e439bd8a..9af41a88 100644 --- a/Sources/PrivateInformationRetrieval/PrivateInformationRetrieval.docc/EncodingPipeline.md +++ b/Sources/PrivateInformationRetrieval/PrivateInformationRetrieval.docc/EncodingPipeline.md @@ -70,8 +70,8 @@ let pirParameters = try processedDatabaseWithParameters.proto(context: context) ## Loading processed shard To load a processed shard, one needs two parts: -1. ``ProcessedDatabase`` can be loaded using ``ProcessedDatabase/init(from:context:)-9ppkq`` or -``ProcessedDatabase/init(from:context:)-4pmcl``. +1. ``ProcessedDatabase`` can be loaded using ``ProcessedDatabase/init(from:context:)-4so32`` or +``ProcessedDatabase/init(from:context:)-6tq82``. 2. Use the `pirParameters` from protobuf and add them in like this: ```swift diff --git a/Sources/PrivateInformationRetrievalProtobuf/ConversionApi.swift b/Sources/PrivateInformationRetrievalProtobuf/ConversionApi.swift index bc14c598..a0a8a156 100644 --- a/Sources/PrivateInformationRetrievalProtobuf/ConversionApi.swift +++ b/Sources/PrivateInformationRetrievalProtobuf/ConversionApi.swift @@ -1,4 +1,4 @@ -// Copyright 2024 Apple Inc. and the Swift Homomorphic Encryption project authors +// Copyright 2024-2025 Apple Inc. and the Swift Homomorphic Encryption project authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -21,7 +21,7 @@ extension Apple_SwiftHomomorphicEncryption_Api_Pir_V1_PIRResponse { /// - Parameter context: Context to associate with the native type. /// - Returns: The converted native type. /// - Throws: Error upon invalid protobuf object. - public func native(context: Context) throws -> Response { + public func native(context: Context) throws -> Response { let ciphertexts: [[Scheme.CoeffCiphertext]] = try replies.map { reply in let serializedCiphertexts: [SerializedCiphertext] = try reply.native() return try serializedCiphertexts.map { serialized in diff --git a/Sources/PrivateInformationRetrievalProtobuf/ConversionPir.swift b/Sources/PrivateInformationRetrievalProtobuf/ConversionPir.swift index c16b9969..a3d36e52 100644 --- a/Sources/PrivateInformationRetrievalProtobuf/ConversionPir.swift +++ b/Sources/PrivateInformationRetrievalProtobuf/ConversionPir.swift @@ -24,7 +24,7 @@ extension Apple_SwiftHomomorphicEncryption_Pir_V1_EncryptedIndices { /// - Parameter context: Context to associate with the native type. /// - Returns: The converted native type. /// - Throws: Error upon invalid protobuf object. - public func native(context: Context) throws -> Query { + public func native(context: Context) throws -> Query { let ciphertexts: [Scheme.CanonicalCiphertext] = try ciphertexts.map { ciphertext in let serializedCiphertext: SerializedCiphertext = try ciphertext.native() return try Ciphertext( @@ -54,7 +54,7 @@ extension ProcessedDatabaseWithParameters { /// - Parameter context: The context that was used to create processed database. /// - Returns: The PIR parameters protobuf object. /// - Throws: Error when the parameters cannot be represented as a protobuf object. - public func proto(context: Context) throws -> Apple_SwiftHomomorphicEncryption_Pir_V1_PirParameters { + public func proto(context: Context) throws -> Apple_SwiftHomomorphicEncryption_Pir_V1_PirParameters { let encryptionParameters = context.encryptionParameters return try Apple_SwiftHomomorphicEncryption_Pir_V1_PirParameters.with { params in params.encryptionParameters = try encryptionParameters.proto(scheme: Scheme.self) diff --git a/Sources/PrivateNearestNeighborSearch/CiphertextMatrix.swift b/Sources/PrivateNearestNeighborSearch/CiphertextMatrix.swift index e65f20b7..1e8699a5 100644 --- a/Sources/PrivateNearestNeighborSearch/CiphertextMatrix.swift +++ b/Sources/PrivateNearestNeighborSearch/CiphertextMatrix.swift @@ -32,7 +32,7 @@ public struct CiphertextMatrix: Equatable, @usableFromInline package var ciphertexts: [Ciphertext] /// The parameter context. - @usableFromInline var context: Context { + @usableFromInline var context: Context { precondition(!ciphertexts.isEmpty, "Ciphertext array cannot be empty") return ciphertexts[0].context } @@ -66,7 +66,7 @@ public struct CiphertextMatrix: Equatable, throw PnnsError.emptyCiphertextArray } let encryptionParameters = context.encryptionParameters - guard let simdDimensions = context.simdDimensions else { + guard let simdDimensions = context.simdDimensions(for: Scheme.self) else { throw PnnsError.simdEncodingNotSupported(for: encryptionParameters) } let expectedCiphertextCount = try PlaintextMatrix.plaintextCount( diff --git a/Sources/PrivateNearestNeighborSearch/Client.swift b/Sources/PrivateNearestNeighborSearch/Client.swift index ed636b59..853f8b07 100644 --- a/Sources/PrivateNearestNeighborSearch/Client.swift +++ b/Sources/PrivateNearestNeighborSearch/Client.swift @@ -24,7 +24,7 @@ public struct Client { public let config: ClientConfig /// One context per plaintext modulus. - public let contexts: [Context] + public let contexts: [Context] /// Performs composition of the plaintext CRT responses. @usableFromInline let crtComposer: CrtComposer @@ -43,7 +43,7 @@ public struct Client { /// - contexts: Contexts for HE computation, one per plaintext modulus. /// - Throws: Error upon failure to create the client. @inlinable - public init(config: ClientConfig, contexts: [Context] = []) throws { + public init(config: ClientConfig, contexts: [Context] = []) throws { guard config.distanceMetric == .cosineSimilarity else { throw PnnsError.wrongDistanceMetric(got: config.distanceMetric, expected: .cosineSimilarity) } @@ -79,7 +79,7 @@ public struct Client { let matrices = try contexts.map { context in // For a single plaintext modulus, reduction isn't necessary let shouldReduce = contexts.count > 1 - let plaintextMatrix = try PlaintextMatrix( + let plaintextMatrix = try PlaintextMatrix( context: context, dimensions: MatrixDimensions(vectors.shape), packing: config.queryPacking, diff --git a/Sources/PrivateNearestNeighborSearch/Config.swift b/Sources/PrivateNearestNeighborSearch/Config.swift index 762603e3..a54a06d3 100644 --- a/Sources/PrivateNearestNeighborSearch/Config.swift +++ b/Sources/PrivateNearestNeighborSearch/Config.swift @@ -121,7 +121,7 @@ public struct ClientConfig: Codable, Equatable, Hashable, Send /// - Parameter contexts: Contexts; one per plaintext modulus. /// - Throws: Error if the contexts are not valid. @inlinable - func validateContexts(contexts: [Context]) throws { + func validateContexts(contexts: [Context]) throws { guard contexts.count == encryptionParameters.count else { throw PnnsError.wrongContextsCount(got: contexts.count, expected: encryptionParameters.count) } @@ -190,7 +190,7 @@ public struct ServerConfig: Codable, Equatable, Hashable, Send /// - Parameter contexts: Contexts; one per plaintext modulus. /// - Throws: Error if the contexts are not valid. @inlinable - func validateContexts(contexts: [Context]) throws { + func validateContexts(contexts: [Context]) throws { try clientConfig.validateContexts(contexts: contexts) } } diff --git a/Sources/PrivateNearestNeighborSearch/Error.swift b/Sources/PrivateNearestNeighborSearch/Error.swift index 54620047..60c911ef 100644 --- a/Sources/PrivateNearestNeighborSearch/Error.swift +++ b/Sources/PrivateNearestNeighborSearch/Error.swift @@ -56,7 +56,7 @@ extension PnnsError { } @inlinable - static func wrongContext(got: Context, expected: Context) -> Self { + static func wrongContext(got: Context, expected: Context) -> Self { PnnsError.wrongContext(gotDescription: got.description, expectedDescription: expected.description) } diff --git a/Sources/PrivateNearestNeighborSearch/PlaintextMatrix.swift b/Sources/PrivateNearestNeighborSearch/PlaintextMatrix.swift index 2b203e38..eba684d7 100644 --- a/Sources/PrivateNearestNeighborSearch/PlaintextMatrix.swift +++ b/Sources/PrivateNearestNeighborSearch/PlaintextMatrix.swift @@ -88,7 +88,7 @@ public struct PlaintextMatrix: Equatable, @usableFromInline package let plaintexts: [Plaintext] /// The parameter context. - @usableFromInline package var context: Context { + @usableFromInline package var context: Context { precondition(!plaintexts.isEmpty, "Plaintext array cannot be empty") return plaintexts[0].context } @@ -121,7 +121,7 @@ public struct PlaintextMatrix: Equatable, } let context = plaintexts[0].context let encryptionParameters = context.encryptionParameters - guard let simdDimensions = context.simdDimensions else { + guard let simdDimensions = context.simdDimensions(for: Scheme.self) else { throw PnnsError.simdEncodingNotSupported(for: encryptionParameters) } let expectedPlaintextCount = try PlaintextMatrix.plaintextCount( @@ -153,7 +153,7 @@ public struct PlaintextMatrix: Equatable, /// - Throws: Error upon failure to create the plaitnext matrix. @inlinable public init( - context: Context, + context: Context, dimensions: MatrixDimensions, packing: MatrixPacking, signedValues: [Scheme.SignedScalar], @@ -187,7 +187,7 @@ public struct PlaintextMatrix: Equatable, /// - Throws: Error upon failure to create the plaitnext matrix. @inlinable package init( - context: Context, + context: Context, dimensions: MatrixDimensions, packing: MatrixPacking, values: [Scalar], @@ -272,11 +272,11 @@ public struct PlaintextMatrix: Equatable, /// - Returns: The plaintexts for `denseColumn` packing. /// - Throws: Error upon plaintext to compute the plaintexts. @inlinable - static func denseColumnPlaintexts(context: Context, dimensions: MatrixDimensions, + static func denseColumnPlaintexts(context: Context, dimensions: MatrixDimensions, values: [Scalar]) throws -> [Scheme.CoeffPlaintext] { let degree = context.degree - guard let simdColumnCount = context.simdDimensions?.columnCount else { + guard let simdColumnCount = context.simdDimensions(for: Scheme.self)?.columnCount else { throw PnnsError.simdEncodingNotSupported(for: context.encryptionParameters) } @@ -329,12 +329,12 @@ public struct PlaintextMatrix: Equatable, /// - Throws: Error upon failure to compute the plaintexts. @inlinable static func denseRowPlaintexts( - context: Context, + context: Context, dimensions: MatrixDimensions, values: [Scalar]) throws -> [Plaintext] { let encryptionParameters = context.encryptionParameters - guard let simdDimensions = context.simdDimensions else { + guard let simdDimensions = context.simdDimensions(for: Scheme.self) else { throw PnnsError.simdEncodingNotSupported(for: encryptionParameters) } guard simdDimensions.rowCount == 2 else { @@ -405,13 +405,13 @@ public struct PlaintextMatrix: Equatable, /// - Throws: Error upon failure to compute the plaintexts. @inlinable static func diagonalPlaintexts( - context: Context, + context: Context, dimensions: MatrixDimensions, packing: MatrixPacking, values: [Scalar]) throws -> [Scheme.CoeffPlaintext] { let encryptionParameters = context.encryptionParameters - guard let simdDimensions = context.simdDimensions else { + guard let simdDimensions = context.simdDimensions(for: Scheme.self) else { throw PnnsError.simdEncodingNotSupported(for: encryptionParameters) } let simdColumnCount = simdDimensions.columnCount @@ -463,7 +463,7 @@ public struct PlaintextMatrix: Equatable, chunk[chunk.startIndex.. = try context.encode(values: chunk, format: .simd) plaintexts.append(plaintext) } } diff --git a/Sources/PrivateNearestNeighborSearch/ProcessedDatabase.swift b/Sources/PrivateNearestNeighborSearch/ProcessedDatabase.swift index af3791f4..643f8408 100644 --- a/Sources/PrivateNearestNeighborSearch/ProcessedDatabase.swift +++ b/Sources/PrivateNearestNeighborSearch/ProcessedDatabase.swift @@ -1,4 +1,4 @@ -// Copyright 2024 Apple Inc. and the Swift Homomorphic Encryption project authors +// Copyright 2024-2025 Apple Inc. and the Swift Homomorphic Encryption project authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -17,7 +17,7 @@ import HomomorphicEncryption /// A database after processing to prepare for PNNS queries. public struct ProcessedDatabase: Equatable, Sendable { /// One context per plaintext modulus. - public let contexts: [Context] + public let contexts: [Context] /// The processed vectors in the database. public let plaintextMatrices: [PlaintextMatrix] @@ -33,7 +33,7 @@ public struct ProcessedDatabase: Equatable, Sendable { @inlinable public init( - contexts: [Context], + contexts: [Context], plaintextMatrices: [PlaintextMatrix], entryIds: [UInt64], entryMetadatas: [[UInt8]], @@ -52,7 +52,7 @@ public struct ProcessedDatabase: Equatable, Sendable { /// - serialized: Serialized processed database. /// - contexts: Contexts for HE computation, one per plaintext modulus. /// - Throws: Error upon failure to load the database. - public init(from serialized: SerializedProcessedDatabase, contexts: [Context] = []) throws { + public init(from serialized: SerializedProcessedDatabase, contexts: [Context] = []) throws { var contexts = contexts if contexts.isEmpty { contexts = try serialized.serverConfig.encryptionParameters.map { encryptionParameters in @@ -188,7 +188,7 @@ extension Database { /// - Throws: Error upon failure to process the database. @inlinable public func process(config: ServerConfig, - contexts: [Context] = []) throws -> ProcessedDatabase + contexts: [Context] = []) throws -> ProcessedDatabase { guard config.distanceMetric == .cosineSimilarity else { throw PnnsError.wrongDistanceMetric(got: config.distanceMetric, expected: .cosineSimilarity) diff --git a/Sources/PrivateNearestNeighborSearch/SerializedCiphertextMatrix.swift b/Sources/PrivateNearestNeighborSearch/SerializedCiphertextMatrix.swift index 793198b5..1f9c71f8 100644 --- a/Sources/PrivateNearestNeighborSearch/SerializedCiphertextMatrix.swift +++ b/Sources/PrivateNearestNeighborSearch/SerializedCiphertextMatrix.swift @@ -54,7 +54,7 @@ extension CiphertextMatrix { @inlinable public init( deserialize serialized: SerializedCiphertextMatrix, - context: Context, + context: Context, moduliCount: Int? = nil) throws { let ciphertexts: [Ciphertext] = try serialized.ciphertexts.map { serializedCiphertext in diff --git a/Sources/PrivateNearestNeighborSearch/SerializedPlaintextMatrix.swift b/Sources/PrivateNearestNeighborSearch/SerializedPlaintextMatrix.swift index ab6624b1..9f2322e6 100644 --- a/Sources/PrivateNearestNeighborSearch/SerializedPlaintextMatrix.swift +++ b/Sources/PrivateNearestNeighborSearch/SerializedPlaintextMatrix.swift @@ -1,4 +1,4 @@ -// Copyright 2024 Apple Inc. and the Swift Homomorphic Encryption project authors +// Copyright 2024-2025 Apple Inc. and the Swift Homomorphic Encryption project authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -60,9 +60,9 @@ extension PlaintextMatrix where Format == Coeff { /// - serialized: Serialized plaintext matrix. /// - context: Context to associate with the plaintext matrix. /// - Throws: Error upon failure to deserialize. - init(deserialize serialized: SerializedPlaintextMatrix, context: Context) throws { + init(deserialize serialized: SerializedPlaintextMatrix, context: Context) throws { let plaintexts = try serialized.plaintexts.map { serializedPlaintext in - try Plaintext(deserialize: serializedPlaintext, context: context) + try Plaintext(deserialize: serializedPlaintext, context: context) } try self.init(dimensions: serialized.dimensions, packing: serialized.packing, plaintexts: plaintexts) } @@ -78,11 +78,11 @@ extension PlaintextMatrix where Format == Eval { /// - Throws: Error upon failure to deserialize. init( deserialize serialized: SerializedPlaintextMatrix, - context: Context, + context: Context, moduliCount: Int? = nil) throws { let plaintexts = try serialized.plaintexts.map { serializedPlaintext in - try Plaintext(deserialize: serializedPlaintext, context: context, moduliCount: moduliCount) + try Plaintext(deserialize: serializedPlaintext, context: context, moduliCount: moduliCount) } try self.init(dimensions: serialized.dimensions, packing: serialized.packing, plaintexts: plaintexts) } diff --git a/Sources/PrivateNearestNeighborSearch/Server.swift b/Sources/PrivateNearestNeighborSearch/Server.swift index 6f75071d..fd54332e 100644 --- a/Sources/PrivateNearestNeighborSearch/Server.swift +++ b/Sources/PrivateNearestNeighborSearch/Server.swift @@ -1,4 +1,4 @@ -// Copyright 2024 Apple Inc. and the Swift Homomorphic Encryption project authors +// Copyright 2024-2025 Apple Inc. and the Swift Homomorphic Encryption project authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -35,7 +35,7 @@ public struct Server: Sendable { } /// One context per plaintext modulus. - public var contexts: [Context] { + public var contexts: [Context] { database.contexts } diff --git a/Sources/PrivateNearestNeighborSearchProtobuf/ConversionApi.swift b/Sources/PrivateNearestNeighborSearchProtobuf/ConversionApi.swift index 16606325..9f3f3b11 100644 --- a/Sources/PrivateNearestNeighborSearchProtobuf/ConversionApi.swift +++ b/Sources/PrivateNearestNeighborSearchProtobuf/ConversionApi.swift @@ -1,4 +1,4 @@ -// Copyright 2024 Apple Inc. and the Swift Homomorphic Encryption project authors +// Copyright 2024-2025 Apple Inc. and the Swift Homomorphic Encryption project authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -23,7 +23,7 @@ extension Apple_SwiftHomomorphicEncryption_Api_Pnns_V1_PNNSShardResponse { /// - Parameter contexts: Contexts to associate with the native type; one context per plaintext modulus. /// - Returns: The converted native type. /// - Throws: Error upon invalid protobuf object. - public func native(contexts: [Context]) throws -> Response { + public func native(contexts: [Context]) throws -> Response { precondition(contexts.count == reply.count) let matrices: [CiphertextMatrix] = try zip(reply, contexts).map { matrix, context in let serialized: SerializedCiphertextMatrix = try matrix.native() diff --git a/Sources/PrivateNearestNeighborSearchProtobuf/ConversionPnns.swift b/Sources/PrivateNearestNeighborSearchProtobuf/ConversionPnns.swift index 7182b48d..7f97edd5 100644 --- a/Sources/PrivateNearestNeighborSearchProtobuf/ConversionPnns.swift +++ b/Sources/PrivateNearestNeighborSearchProtobuf/ConversionPnns.swift @@ -315,7 +315,7 @@ extension [Apple_SwiftHomomorphicEncryption_Pnns_V1_SerializedCiphertextMatrix] /// Converts the native object into a protobuf object. /// - Returns: The converted protobuf object. /// - Throws: Error upon unsupported object. - public func native(context: Context) throws -> Query { + public func native(context: Context) throws -> Query { let matrices: [CiphertextMatrix] = try map { matrix in let native: SerializedCiphertextMatrix = try matrix.native() return try CiphertextMatrix(deserialize: native, context: context) diff --git a/Sources/TestUtilities/HeApiTestUtils.swift b/Sources/TestUtilities/HeApiTestUtils.swift index 1a26f6a7..74b85376 100644 --- a/Sources/TestUtilities/HeApiTestUtils.swift +++ b/Sources/TestUtilities/HeApiTestUtils.swift @@ -20,7 +20,7 @@ public enum HeAPITestHelpers { /// Test environment with plaintexts and ciphertexts ready for use public struct TestEnv { /// Context for testing. - public let context: Context + public let context: Context /// Raw data for first plaintext/ciphertext public let data1: [Scheme.Scalar] /// Raw data fro second plaintext/ciphertext @@ -46,7 +46,7 @@ public enum HeAPITestHelpers { /// Create the test environment. public init( - context: Context, + context: Context, format: EncodeFormat, galoisElements: [Int] = [], relinearizationKey: Bool = false) throws @@ -118,17 +118,17 @@ public enum HeAPITestHelpers { } /// generate the context for test - public static func getTestContext() throws -> Context { - try Context(encryptionParameters: EncryptionParameters( + public static func getTestContext() throws -> Context { + try Context(encryptionParameters: EncryptionParameters( polyDegree: TestUtils.testPolyDegree, - plaintextModulus: Scheme.Scalar(TestUtils.testPlaintextModulus), + plaintextModulus: Scalar(TestUtils.testPlaintextModulus), coefficientModuli: testCoefficientModuli(), errorStdDev: ErrorStdDev.stdDev32, securityLevel: SecurityLevel.unchecked)) } /// test the evaluation key configuration - public static func schemeEvaluationKeyTest(context _: Context) throws { + public static func schemeEvaluationKeyTest(context _: Context) throws { do { let config = EvaluationKeyConfig() #expect(!config.hasRelinearizationKey) @@ -151,10 +151,11 @@ public enum HeAPITestHelpers { @inlinable static func encodingTest( - context: Context, + context: Context, encodeFormat: EncodeFormat, polyFormat: (some PolyFormat).Type, - valueCount: Int) throws + valueCount: Int, + scheme _: Scheme.Type) throws { guard context.supportsSimdEncoding || encodeFormat != .simd else { return @@ -204,17 +205,20 @@ public enum HeAPITestHelpers { let bounds = -(signedModulus >> 1)...((signedModulus - 1) >> 1) signedData[0] = (Scheme.SignedScalar(context.plaintextModulus) - 1) / 2 + 1 #expect(throws: HeError.encodingDataOutOfBounds(bounds).self) { - try context.encode(signedValues: signedData, format: encodeFormat) + let _: Plaintext = try context.encode(signedValues: signedData, format: encodeFormat) } signedData[0] = -Scheme.SignedScalar(context.plaintextModulus) / 2 - 1 #expect(throws: HeError.encodingDataOutOfBounds(bounds).self) { - try context.encode(signedValues: signedData, format: encodeFormat) + let _: Plaintext = try context.encode(signedValues: signedData, format: encodeFormat) } } /// Testing the encoding/decoding functions of the scheme. @inlinable - public static func schemeEncodeDecodeTest(context: Context) throws { + public static func schemeEncodeDecodeTest( + context: Context, + scheme: Scheme.Type) throws + { for encodeFormat in EncodeFormat.allCases { for polyFormat: PolyFormat.Type in [Coeff.self, Eval.self] { for valueCount in [context.degree / 2, context.degree] { @@ -222,7 +226,7 @@ public enum HeAPITestHelpers { context: context, encodeFormat: encodeFormat, polyFormat: polyFormat, - valueCount: valueCount) + valueCount: valueCount, scheme: scheme) } } } @@ -230,8 +234,11 @@ public enum HeAPITestHelpers { /// Testing the encryption and decryption of the scheme. @inlinable - public static func schemeEncryptDecryptTest(context: Context) throws { - let testEnv = try TestEnv(context: context, format: .coefficient) + public static func schemeEncryptDecryptTest( + context: Context, + scheme _: Scheme.Type) throws + { + let testEnv = try TestEnv(context: context, format: .coefficient) var ciphertext1 = testEnv.ciphertext1 let evalCiphertext: Ciphertext = try ciphertext1.convertToEvalFormat() @@ -248,8 +255,11 @@ public enum HeAPITestHelpers { /// Testing zero-ciphertext generation of the scheme. @inlinable - public static func schemeEncryptZeroDecryptTest(context: Context) throws { - let testEnv = try TestEnv(context: context, format: .coefficient) + public static func schemeEncryptZeroDecryptTest( + context: Context, + scheme _: Scheme.Type) throws + { + let testEnv = try TestEnv(context: context, format: .coefficient) let zeros = [Scheme.Scalar](repeating: 0, count: context.degree) let coeffCiphertext = try Ciphertext.zero(context: context) @@ -274,8 +284,11 @@ public enum HeAPITestHelpers { /// Testing addition with zero-ciphertext of the scheme. @inlinable - public static func schemeEncryptZeroAddDecryptTest(context: Context) throws { - let testEnv = try TestEnv(context: context, format: .coefficient) + public static func schemeEncryptZeroAddDecryptTest( + context: Context, + scheme _: Scheme.Type) throws + { + let testEnv = try TestEnv(context: context, format: .coefficient) let expected = [Scheme.Scalar](repeating: 0, count: context.degree) let zeroCoeffCiphertext = try Ciphertext.zero(context: context) @@ -298,8 +311,11 @@ public enum HeAPITestHelpers { /// Testing multiplication with zero-ciphertext of the scheme. @inlinable - public static func schemeEncryptZeroMultiplyDecryptTest(context: Context) throws { - let testEnv = try TestEnv(context: context, format: .coefficient) + public static func schemeEncryptZeroMultiplyDecryptTest( + context: Context, + scheme _: Scheme.Type) throws + { + let testEnv = try TestEnv(context: context, format: .coefficient) let expected = [Scheme.Scalar](repeating: 0, count: context.degree) let zeroCiphertext = try Ciphertext.zero(context: context) @@ -311,8 +327,11 @@ public enum HeAPITestHelpers { /// Testing ciphertext addition of the scheme. @inlinable - public static func schemeCiphertextAddTest(context: Context) async throws { - let testEnv = try TestEnv(context: context, format: .coefficient) + public static func schemeCiphertextAddTest( + context: Context, + scheme _: Scheme.Type) async throws + { + let testEnv = try TestEnv(context: context, format: .coefficient) let data1 = testEnv.data1 let data2 = testEnv.data2 let sumData = zip(data1, data2).map { x, y in x.addMod(y, modulus: context.plaintextModulus) } @@ -415,8 +434,11 @@ public enum HeAPITestHelpers { /// Testing ciphertext subtraction of the scheme. @inlinable - public static func schemeCiphertextSubtractTest(context: Context) async throws { - let testEnv = try TestEnv(context: context, format: .coefficient) + public static func schemeCiphertextSubtractTest( + context: Context, + scheme _: Scheme.Type) async throws + { + let testEnv = try TestEnv(context: context, format: .coefficient) let data1 = testEnv.data1 let data2 = testEnv.data2 let diffData = zip(data1, data2).map { x, y in x.subtractMod(y, modulus: context.plaintextModulus) } @@ -521,12 +543,12 @@ public enum HeAPITestHelpers { /// testing ciphertext multiplication of the scheme. @inlinable public static func schemeCiphertextCiphertextMultiplyTest( - context: Context) async throws + context: Context, scheme _: Scheme.Type) async throws { guard context.supportsSimdEncoding, context.supportsEvaluationKey else { return } - let testEnv = try TestEnv(context: context, format: .simd, relinearizationKey: true) + let testEnv = try TestEnv(context: context, format: .simd, relinearizationKey: true) let data1 = testEnv.data1 let data2 = testEnv.data2 let productData = zip(data1, data2) @@ -560,9 +582,9 @@ public enum HeAPITestHelpers { /// Testing CT-PT inner product of the scheme. @inlinable public static func schemeCiphertextPlaintextInnerProductTest( - context: Context) async throws + context: Context, scheme _: Scheme.Type) async throws { - let testEnv = try TestEnv(context: context, format: .simd) + let testEnv = try TestEnv(context: context, format: .simd) let data1 = testEnv.data1 let data2 = testEnv.data2 for count in [4, 1257] { @@ -631,9 +653,9 @@ public enum HeAPITestHelpers { /// Testing CT-CT inner product of the scheme. @inlinable public static func schemeCiphertextCiphertextInnerProductTest( - context: Context) async throws + context: Context, scheme _: Scheme.Type) async throws { - let testEnv = try TestEnv(context: context, format: .simd) + let testEnv = try TestEnv(context: context, format: .simd) let data1 = testEnv.data1 let data2 = testEnv.data2 for count in [4, 257] { @@ -653,11 +675,15 @@ public enum HeAPITestHelpers { } /// Testing CT-CT multiplication followed by CT-CT addition of the scheme. - public static func schemeCiphertextMultiplyAddTest(context: Context) async throws { + @inlinable + public static func schemeCiphertextMultiplyAddTest( + context: Context, + scheme _: Scheme.Type) async throws + { guard context.supportsSimdEncoding else { return } - let testEnv = try TestEnv(context: context, format: .simd) + let testEnv = try TestEnv(context: context, format: .simd) let data1 = testEnv.data1 let data2 = testEnv.data2 let multiplyAddData = zip(data1, data2).map { data1, data2 in @@ -684,11 +710,14 @@ public enum HeAPITestHelpers { /// Testing CT-CT multiplication followed by CT-PT addition of the scheme. @inlinable - public static func schemeCiphertextMultiplyAddPlainTest(context: Context) throws { + public static func schemeCiphertextMultiplyAddPlainTest( + context: Context, + scheme _: Scheme.Type) throws + { guard context.supportsSimdEncoding else { return } - let testEnv = try TestEnv(context: context, format: .simd) + let testEnv = try TestEnv(context: context, format: .simd) let data1 = testEnv.data1 let data2 = testEnv.data2 let multiplyAddData = zip(data1, data2).map { data1, data2 in @@ -709,13 +738,14 @@ public enum HeAPITestHelpers { } /// Testing CT-CT multiplication followed by CT-PT subtraction of the scheme. + @inlinable public static func schemeCiphertextMultiplySubtractPlainTest( - context: Context) async throws + context: Context, scheme _: Scheme.Type) async throws { guard context.supportsSimdEncoding else { return } - let testEnv = try TestEnv(context: context, format: .simd) + let testEnv = try TestEnv(context: context, format: .simd) let data1 = testEnv.data1 let data2 = testEnv.data2 let multiplySubtractData = zip(data1, data2).map { data1, data2 in @@ -746,12 +776,12 @@ public enum HeAPITestHelpers { /// Testing CT-PT multiplication followed by CT-PT addition of the scheme. @inlinable public static func schemeCiphertextPlaintextMultiplyAddPlainTest( - context: Context) async throws + context: Context, scheme _: Scheme.Type) async throws { guard context.supportsSimdEncoding else { return } - let testEnv = try TestEnv(context: context, format: .simd) + let testEnv = try TestEnv(context: context, format: .simd) let data1 = testEnv.data1 let data2 = testEnv.data2 let multiplyAddData = zip(data1, data2).map { data1, data2 in @@ -781,12 +811,12 @@ public enum HeAPITestHelpers { /// Testing CT-PT multiplication followed by CT-PT subtraction of the scheme. @inlinable public static func schemeCiphertextPlaintextMultiplySubtractPlainTest( - context: Context) async throws + context: Context, scheme _: Scheme.Type) async throws { guard context.supportsSimdEncoding else { return } - let testEnv = try TestEnv(context: context, format: .simd) + let testEnv = try TestEnv(context: context, format: .simd) let data1 = testEnv.data1 let data2 = testEnv.data2 let multiplySubtractData = zip(data1, data2).map { data1, data2 in @@ -818,11 +848,14 @@ public enum HeAPITestHelpers { /// Testing CT-CT multiplication followed by CT-CT subtraction of the scheme. @inlinable - public static func schemeCiphertextMultiplySubtractTest(context: Context) async throws { + public static func schemeCiphertextMultiplySubtractTest( + context: Context, + scheme _: Scheme.Type) async throws + { guard context.supportsSimdEncoding else { return } - let testEnv = try TestEnv(context: context, format: .simd) + let testEnv = try TestEnv(context: context, format: .simd) let data1 = testEnv.data1 let data2 = testEnv.data2 let multiplySubtractData = zip(data1, data2).map { data1, data2 in @@ -852,8 +885,11 @@ public enum HeAPITestHelpers { /// Testing ciphertext negation of the scheme. @inlinable - public static func schemeCiphertextNegateTest(context: Context) async throws { - let testEnv = try TestEnv(context: context, format: .coefficient) + public static func schemeCiphertextNegateTest( + context: Context, + scheme _: Scheme.Type) async throws + { + let testEnv = try TestEnv(context: context, format: .coefficient) let negatedData = testEnv.data1.map { data1 in data1.negateMod(modulus: context.plaintextModulus) } @@ -879,11 +915,14 @@ public enum HeAPITestHelpers { /// Testing CT-PT addition of the scheme. @inlinable - public static func schemeCiphertextPlaintextAddTest(context: Context) async throws { + public static func schemeCiphertextPlaintextAddTest( + context: Context, + scheme _: Scheme.Type) async throws + { guard context.supportsSimdEncoding else { return } - let testEnv = try TestEnv(context: context, format: .simd) + let testEnv = try TestEnv(context: context, format: .simd) let data1 = testEnv.data1 let data2 = testEnv.data2 let sumData = zip(data1, data2).map { x, y in x.addMod(y, modulus: context.plaintextModulus) } @@ -998,12 +1037,12 @@ public enum HeAPITestHelpers { /// Testing CT-PT subtraction of the scheme. @inlinable public static func schemeCiphertextPlaintextSubtractTest( - context: Context) async throws + context: Context, scheme _: Scheme.Type) async throws { guard context.supportsSimdEncoding else { return } - let testEnv = try TestEnv(context: context, format: .simd) + let testEnv = try TestEnv(context: context, format: .simd) let data1 = testEnv.data1 let data2 = testEnv.data2 let diff1Minus2Data = zip(data1, data2).map { x, y in x.subtractMod(y, modulus: context.plaintextModulus) } @@ -1113,12 +1152,12 @@ public enum HeAPITestHelpers { /// Testing CT-PT multiplication of the scheme. @inlinable public static func schemeCiphertextPlaintextMultiplyTest( - context: Context) async throws + context: Context, scheme _: Scheme.Type) async throws { guard context.supportsSimdEncoding else { return } - let testEnv = try TestEnv(context: context, format: .simd) + let testEnv = try TestEnv(context: context, format: .simd) let data1 = testEnv.data1 let data2 = testEnv.data2 var productData = [Scheme.Scalar](repeating: 0, count: context.degree) @@ -1143,7 +1182,7 @@ public enum HeAPITestHelpers { var ciphertext = testEnv.ciphertext1 try ciphertext.modSwitchDown() let evalCiphertext = try ciphertext.convertToEvalFormat() - let evalPlaintext = try testEnv.context.encode( + let evalPlaintext: Plaintext = try testEnv.context.encode( values: testEnv.data2, format: .simd, moduliCount: evalCiphertext.moduli.count) @@ -1170,10 +1209,13 @@ public enum HeAPITestHelpers { /// Testing ciphertext rotation of the scheme. @inlinable - public static func schemeRotationTest(context: Context) async throws { - func runRotationTest(context: Context, galoisElements: [Int], multiStep: Bool) async throws { + public static func schemeRotationTest( + context: Context, + scheme _: Scheme.Type) async throws + { + func runRotationTest(context: Context, galoisElements: [Int], multiStep: Bool) async throws { let degree = context.degree - let testEnv = try TestEnv(context: context, format: .simd, galoisElements: galoisElements) + let testEnv = try TestEnv(context: context, format: .simd, galoisElements: galoisElements) let evaluationKey = try #require(testEnv.evaluationKey) for step in 1..(context: context, format: .simd, galoisElements: galoisElementsSwap) let evaluationKey = try #require(testEnv.evaluationKey) let expectedData = Array(testEnv.data1[degree / 2..(context: Context) async throws { + public static func schemeApplyGaloisTest( + context: Context, + scheme _: Scheme.Type) async throws + { guard context.supportsSimdEncoding, context.supportsEvaluationKey else { return } let elements = try (1..> 1)).map { step in try GaloisElement.rotatingColumns(by: -step, degree: context.degree) } - let testEnv = try TestEnv(context: context, format: .simd, galoisElements: elements) + let testEnv = try TestEnv(context: context, format: .simd, galoisElements: elements) let evaluationKey = try #require(testEnv.evaluationKey) let dataCount = testEnv.data1.count @@ -1292,8 +1337,10 @@ public enum HeAPITestHelpers { /// testing noise budget estimation. @inlinable - public static func noiseBudgetTest(context: Context) throws { - let testEnv = try TestEnv(context: context, format: .coefficient) + public static func noiseBudgetTest(context: Context, + scheme _: Scheme.Type) throws + { + let testEnv = try TestEnv(context: context, format: .coefficient) let zeroCoeffCiphertext = try Scheme.CoeffCiphertext.zero(context: context, moduliCount: 1) #expect(try zeroCoeffCiphertext.noiseBudget(using: testEnv.secretKey, variableTime: true) == Double.infinity) @@ -1338,7 +1385,10 @@ public enum HeAPITestHelpers { /// testing repeated addition. @inlinable - public static func repeatedAdditionTest(context: Context) async throws { + public static func repeatedAdditionTest( + context: Context, + scheme _: Scheme.Type) async throws + { let testEnv = try HeAPITestHelpers.TestEnv(context: context, format: .coefficient) var coeffCiphertext = testEnv.ciphertext1 @@ -1363,7 +1413,10 @@ public enum HeAPITestHelpers { /// testing multiply inverse power of x. @inlinable - public static func multiplyInverseTest(context: Context) async throws { + public static func multiplyInverseTest( + context: Context, + scheme _: Scheme.Type) async throws + { let testEnv = try HeAPITestHelpers.TestEnv(context: context, format: .coefficient) var coeffCiphertext1 = try testEnv.ciphertext1.convertToCoeffFormat() diff --git a/Sources/TestUtilities/PirUtilities/ExpansionTests.swift b/Sources/TestUtilities/PirUtilities/ExpansionTests.swift index e40ba7b5..9db62242 100644 --- a/Sources/TestUtilities/PirUtilities/ExpansionTests.swift +++ b/Sources/TestUtilities/PirUtilities/ExpansionTests.swift @@ -38,7 +38,7 @@ extension PirTestUtils { errorStdDev: ErrorStdDev.stdDev32, securityLevel: SecurityLevel.unchecked) - let context: Context = try Context(encryptionParameters: encryptionParameters) + let context: Context = try Context(encryptionParameters: encryptionParameters) let plaintextModulus = context.plaintextModulus let logDegree = degree.log2 for logStep in 1...logDegree { @@ -48,7 +48,7 @@ extension PirTestUtils { count: degree, in: 0.. = try context.encode(values: data, format: .coefficient) - let secretKey = try context.generateSecretKey() + let secretKey: SecretKey = try context.generateSecretKey() let expandedQueryCount = degree let EvaluationKeyConfig = MulPir.evaluationKeyConfig( @@ -78,7 +78,7 @@ extension PirTestUtils { /// Tests compressInputsForOneCiphertext and expandCiphertexts roundtrip. @inlinable public static func oneCiphertextRoundtrip(scheme _: Scheme.Type) throws { - let context: Context = try TestUtils.getTestContext() + let context: Context = try TestUtils.getTestContext() let degree = context.degree let logDegree = degree.log2 for inputCount in 1...degree { @@ -88,7 +88,7 @@ extension PirTestUtils { totalInputCount: inputCount, nonZeroInputs: nonZeroInputs, context: context) - let secretKey = try context.generateSecretKey() + let secretKey: SecretKey = try context.generateSecretKey() let evaluationKeyConfig = EvaluationKeyConfig(galoisElements: (1...logDegree).map { (1 << $0) + 1 }) let evaluationKey = try context.generateEvaluationKey(config: evaluationKeyConfig, using: secretKey) let ciphertext = try plaintext.encrypt(using: secretKey) @@ -113,13 +113,13 @@ extension PirTestUtils { /// Tests compressInputs and expandCiphertexts roundtrip with multiple ciphertexts. @inlinable public static func multipleCiphertextsRoundtrip(scheme _: Scheme.Type) throws { - let context: Context = try TestUtils.getTestContext() + let context: Context = try TestUtils.getTestContext() let degree = TestUtils.testPolyDegree let logDegree = degree.log2 for inputCount in 1...degree * 2 { let data: [Int] = (0.. = try context.generateSecretKey() let ciphertexts = try PirUtil.compressInputs( totalInputCount: inputCount, nonZeroInputs: nonZeroInputs, diff --git a/Sources/TestUtilities/PirUtilities/IndexPirTests.swift b/Sources/TestUtilities/PirUtilities/IndexPirTests.swift index 3ee2a532..c439576f 100644 --- a/Sources/TestUtilities/PirUtilities/IndexPirTests.swift +++ b/Sources/TestUtilities/PirUtilities/IndexPirTests.swift @@ -22,7 +22,7 @@ extension PirTestUtils { /// Testing client configuration. @inlinable func generateParameter() throws { - let context: Context> = try TestUtils.getTestContext() + let context: Context = try TestUtils.getTestContext() // unevenDimensions: false do { let config = try IndexPirConfig(entryCount: 16, @@ -31,7 +31,7 @@ extension PirTestUtils { batchSize: 1, unevenDimensions: false, keyCompression: .noCompression) - let parameter = MulPir.generateParameter(config: config, with: context) + let parameter = MulPir>.generateParameter(config: config, with: context) #expect(parameter.dimensions == [4, 4]) } do { @@ -41,7 +41,7 @@ extension PirTestUtils { batchSize: 2, unevenDimensions: false, keyCompression: .noCompression) - let parameter = MulPir.generateParameter(config: config, with: context) + let parameter = MulPir>.generateParameter(config: config, with: context) #expect(parameter.dimensions == [4, 3]) } // unevenDimensions: true @@ -52,7 +52,7 @@ extension PirTestUtils { batchSize: 1, unevenDimensions: true, keyCompression: .noCompression) - let parameter = MulPir.generateParameter(config: config, with: context) + let parameter = MulPir>.generateParameter(config: config, with: context) #expect(parameter.dimensions == [5, 3]) } do { @@ -62,7 +62,7 @@ extension PirTestUtils { batchSize: 2, unevenDimensions: true, keyCompression: .noCompression) - let parameter = MulPir.generateParameter(config: config, with: context) + let parameter = MulPir>.generateParameter(config: config, with: context) #expect(parameter.dimensions == [5, 3]) } do { @@ -72,7 +72,7 @@ extension PirTestUtils { batchSize: 2, unevenDimensions: true, keyCompression: .noCompression) - let parameter = MulPir.generateParameter(config: config, with: context) + let parameter = MulPir>.generateParameter(config: config, with: context) #expect(parameter.dimensions == [9, 2]) } // no key compression @@ -83,7 +83,7 @@ extension PirTestUtils { batchSize: 2, unevenDimensions: true, keyCompression: .noCompression) - let parameter = MulPir.generateParameter(config: config, with: context) + let parameter = MulPir>.generateParameter(config: config, with: context) let evalKeyConfig = EvaluationKeyConfig( galoisElements: [3, 5, 9, 17], hasRelinearizationKey: true) @@ -97,7 +97,7 @@ extension PirTestUtils { batchSize: 2, unevenDimensions: true, keyCompression: .hybridCompression) - let parameter = MulPir.generateParameter(config: config, with: context) + let parameter = MulPir>.generateParameter(config: config, with: context) let evalKeyConfig = EvaluationKeyConfig( galoisElements: [3, 5, 9, 17], hasRelinearizationKey: true) @@ -111,7 +111,7 @@ extension PirTestUtils { batchSize: 2, unevenDimensions: true, keyCompression: .maxCompression) - let parameter = MulPir.generateParameter(config: config, with: context) + let parameter = MulPir>.generateParameter(config: config, with: context) let evalKeyConfig = EvaluationKeyConfig( galoisElements: [3, 5, 9], hasRelinearizationKey: true) @@ -124,7 +124,7 @@ extension PirTestUtils { server _: Server.Type, client _: Client.Type, for parameter: IndexPirParameter, - with context: Context) throws + with context: Context) throws where Server.IndexPir == Client.IndexPir { let database = PirTestUtils.randomIndexPirDatabase( @@ -135,7 +135,7 @@ extension PirTestUtils { let server = try Server(parameter: parameter, context: context, database: processedDb) let client = Client(parameter: parameter, context: context) - let secretKey = try context.generateSecretKey() + let secretKey: SecretKey = try context.generateSecretKey() let evaluationKey = try client.generateEvaluationKey(using: secretKey) for _ in 0..<10 { @@ -199,7 +199,7 @@ extension PirTestUtils { keyCompression: .maxCompression), ] - let context: Context = try TestUtils.getTestContext() + let context: Context = try TestUtils.getTestContext() for config in configs { let parameter = Server.generateParameter(config: config, with: context) try indexPirTestForParameter(server: server, client: client, for: parameter, with: context) diff --git a/Sources/TestUtilities/PirUtilities/KeywordPirTests.swift b/Sources/TestUtilities/PirUtilities/KeywordPirTests.swift index b666f1e6..ef9c65e0 100644 --- a/Sources/TestUtilities/PirUtilities/KeywordPirTests.swift +++ b/Sources/TestUtilities/PirUtilities/KeywordPirTests.swift @@ -26,7 +26,7 @@ extension PirTestUtils { let valueSize = 10 let testDatabase = PirTestUtils.randomKeywordPirDatabase(rowCount: rowCount, valueSize: valueSize) let encryptionParameters: EncryptionParameters = try TestUtils.getTestEncryptionParameters() - let testContext: Context = try Context(encryptionParameters: encryptionParameters) + let testContext: Context = try Context(encryptionParameters: encryptionParameters) let keywordConfig = try KeywordPirConfig( dimensionCount: 2, @@ -52,7 +52,7 @@ extension PirTestUtils { server _: PirServer.Type, client _: PirClient.Type) throws where PirServer.IndexPir == PirClient.IndexPir { - let testContext: Context = try Context(encryptionParameters: encryptionParameters) + let testContext: Context = try Context(encryptionParameters: encryptionParameters) let valueSize = testContext.bytesPerPlaintext / 2 let testDatabase = PirTestUtils.randomKeywordPirDatabase(rowCount: 100, valueSize: valueSize) @@ -67,7 +67,7 @@ extension PirTestUtils { let client = KeywordPirClient( keywordParameter: keywordConfig.parameter, pirParameter: processed.pirParameter, context: testContext) - let secretKey = try testContext.generateSecretKey() + let secretKey: SecretKey = try testContext.generateSecretKey() let evaluationKey = try client.generateEvaluationKey(using: secretKey) let shuffledValues = Array(testDatabase.indices).shuffled() for index in shuffledValues.prefix(10) { @@ -240,7 +240,7 @@ extension PirTestUtils { let rowCount = 100 let valueSize = 9 let encryptionParams: EncryptionParameters = try TestUtils.getTestEncryptionParameters() - let testContext: Context = try Context(encryptionParameters: encryptionParams) + let testContext: Context = try Context(encryptionParameters: encryptionParams) var rng = TestRng() let (pirParameter, keywordConfig): (IndexPirParameter, KeywordPirConfig) = try { @@ -285,7 +285,7 @@ extension PirTestUtils { keywordParameter: keywordConfig.parameter, pirParameter: processed.pirParameter, context: testContext) - let secretKey = try testContext.generateSecretKey() + let secretKey: SecretKey = try testContext.generateSecretKey() let evaluationKey = try client.generateEvaluationKey(using: secretKey) let shuffledValues = Array(testDatabase.indices).shuffled() for index in shuffledValues.prefix(1) { @@ -322,7 +322,7 @@ extension PirTestUtils { let valueSize = 10 let rlweParameters = PredefinedRlweParameters.n_4096_logq_27_28_28_logt_5 let encryptionParameters = try EncryptionParameters(from: rlweParameters) - let testContext: Context = try Context( + let testContext: Context = try Context( encryptionParameters: encryptionParameters) let shardCount = 2 @@ -362,7 +362,7 @@ extension PirTestUtils { keywordParameter: keywordConfig.parameter, pirParameter: shard.value.pirParameter, context: testContext)) }) - let secretKey = try testContext.generateSecretKey() + let secretKey: SecretKey = try testContext.generateSecretKey() let evaluationKey = try PirClient.Scheme .generateEvaluationKey( context: testContext, @@ -405,7 +405,7 @@ extension PirTestUtils { // swiftlint:enable nesting let rlweParams = PredefinedRlweParameters.n_4096_logq_27_28_28_logt_5 - let context: Context = try Context(encryptionParameters: .init(from: rlweParams)) + let context: Context = try Context(encryptionParameters: .init(from: rlweParams)) let numberOfEntriesPerResponse = 8 let hashFunctionCount = 2 var testRng = TestRng() @@ -432,7 +432,7 @@ extension PirTestUtils { keywordParameter: config.parameter, pirParameter: processed.pirParameter, context: context) - let secretKey = try context.generateSecretKey() + let secretKey: SecretKey = try context.generateSecretKey() let evaluationKey = try client.generateEvaluationKey(using: secretKey) let randomKeyValuePair = try #require(testDatabase.randomElement()) let query = try client.generateQuery(at: randomKeyValuePair.keyword, using: secretKey) diff --git a/Sources/TestUtilities/PirUtilities/MulPirTests.swift b/Sources/TestUtilities/PirUtilities/MulPirTests.swift index 2006e47a..73e86b5c 100644 --- a/Sources/TestUtilities/PirUtilities/MulPirTests.swift +++ b/Sources/TestUtilities/PirUtilities/MulPirTests.swift @@ -77,14 +77,14 @@ extension PirTestUtils { { let entryCount = 200 let entrySizeInBytes = 16 - let context: Context = try TestUtils.getTestContext() - let secretKey = try context.generateSecretKey() + let context: Context = try TestUtils.getTestContext() + let secretKey: SecretKey = try context.generateSecretKey() let parameter = try PirTestUtils.getTestParameter( pir: MulPir.self, with: context, entryCount: entryCount, entrySizeInBytes: entrySizeInBytes, keyCompression: keyCompression) - let client = MulPirClient(parameter: parameter, context: context) + let client = MulPirClient(parameter: parameter, context: context) let evaluationKey = try client.generateEvaluationKey(using: secretKey) for _ in 0..<3 { @@ -128,7 +128,7 @@ extension PirTestUtils { /// Tests client computing query coordinates. @inlinable public static func computeCoordinates(scheme _: Scheme.Type) throws { - let context: Context = try TestUtils.getTestContext() + let context: Context = try TestUtils.getTestContext() let evalKeyConfig = EvaluationKeyConfig() // two dimensional case do { @@ -138,7 +138,7 @@ extension PirTestUtils { dimensions: [10, 10], batchSize: 1, evaluationKeyConfig: evalKeyConfig) - let client = MulPirClient(parameter: parameter, context: context) + let client = MulPirClient(parameter: parameter, context: context) let vectors = [ (0, [0, 0]), @@ -163,7 +163,7 @@ extension PirTestUtils { dimensions: [5, 3, 2], batchSize: 1, evaluationKeyConfig: evalKeyConfig) - let client = MulPirClient(parameter: parameter, context: context) + let client = MulPirClient(parameter: parameter, context: context) let vectors = [ (0, [0, 0, 0]), diff --git a/Sources/TestUtilities/PirUtilities/PirTestUtils.swift b/Sources/TestUtilities/PirUtilities/PirTestUtils.swift index 33e65ce2..9fad4d96 100644 --- a/Sources/TestUtilities/PirUtilities/PirTestUtils.swift +++ b/Sources/TestUtilities/PirUtilities/PirTestUtils.swift @@ -20,7 +20,7 @@ public enum PirTestUtils { /// Creates test parameters. public static func getTestParameter( pir _: Pir.Type, - with context: Context, + with context: Context, entryCount: Int, entrySizeInBytes: Int, keyCompression: PirKeyCompressionStrategy, diff --git a/Sources/TestUtilities/PirUtilities/SymmetricPirTests.swift b/Sources/TestUtilities/PirUtilities/SymmetricPirTests.swift index dad30618..52b19b27 100644 --- a/Sources/TestUtilities/PirUtilities/SymmetricPirTests.swift +++ b/Sources/TestUtilities/PirUtilities/SymmetricPirTests.swift @@ -45,7 +45,7 @@ extension PirTestUtils { symmetricPirClientConfig: symmetricPirConfig.clientConfig()) let encryptionParameters: EncryptionParameters = try TestUtils.getTestEncryptionParameters() - let context: Context = try Context(encryptionParameters: encryptionParameters) + let context: Context = try Context(encryptionParameters: encryptionParameters) let valueSize = context.bytesPerPlaintext / 2 let plainDatabase = PirTestUtils.randomKeywordPirDatabase(rowCount: 100, valueSize: valueSize) let encryptedDatabase = try KeywordDatabase.symmetricPIRProcess( @@ -61,7 +61,7 @@ extension PirTestUtils { let client = KeywordPirClient( keywordParameter: keywordConfig.parameter, pirParameter: processed.pirParameter, context: context) - let secretKey = try context.generateSecretKey() + let secretKey: SecretKey = try context.generateSecretKey() let evaluationKey = try client.generateEvaluationKey(using: secretKey) let shuffledValues = Array(plainDatabase.indices).shuffled() diff --git a/Sources/TestUtilities/PnnsUtilities/CiphertextMatrixTests.swift b/Sources/TestUtilities/PnnsUtilities/CiphertextMatrixTests.swift index e97b782c..4df1fa2f 100644 --- a/Sources/TestUtilities/PnnsUtilities/CiphertextMatrixTests.swift +++ b/Sources/TestUtilities/PnnsUtilities/CiphertextMatrixTests.swift @@ -42,7 +42,7 @@ extension PrivateNearestNeighborSearchUtil { let rlweParams = PredefinedRlweParameters.insecure_n_8_logq_5x18_logt_5 let encryptionParameters = try EncryptionParameters(from: rlweParams) #expect(encryptionParameters.supportsSimdEncoding) - let context = try Context(encryptionParameters: encryptionParameters) + let context = try Context(encryptionParameters: encryptionParameters) let dimensions = try MatrixDimensions(rowCount: 10, columnCount: 4) let encodeValues: [[Scheme.Scalar]] = increasingData( dimensions: dimensions, @@ -52,7 +52,7 @@ extension PrivateNearestNeighborSearchUtil { dimensions: dimensions, packing: .denseRow, values: encodeValues.flatMap(\.self)) - let secretKey = try context.generateSecretKey() + let secretKey: SecretKey = try context.generateSecretKey() var ciphertextMatrix = try plaintextMatrix.encrypt(using: secretKey) let plaintextMatrixRoundTrip = try ciphertextMatrix.decrypt(using: secretKey) #expect(plaintextMatrixRoundTrip == plaintextMatrix) @@ -71,7 +71,7 @@ extension PrivateNearestNeighborSearchUtil { let rlweParams = PredefinedRlweParameters.insecure_n_8_logq_5x18_logt_5 let encryptionParameters = try EncryptionParameters(from: rlweParams) #expect(encryptionParameters.supportsSimdEncoding) - let context = try Context(encryptionParameters: encryptionParameters) + let context = try Context(encryptionParameters: encryptionParameters) let dimensions = try MatrixDimensions(rowCount: 10, columnCount: 4) let encodeValues: [[Scheme.Scalar]] = increasingData( dimensions: dimensions, @@ -81,7 +81,7 @@ extension PrivateNearestNeighborSearchUtil { dimensions: dimensions, packing: .denseRow, values: encodeValues.flatMap(\.self)) - let secretKey = try context.generateSecretKey() + let secretKey: SecretKey = try context.generateSecretKey() let ciphertextCoeffMatrix: CiphertextMatrix = try plaintextMatrix.encrypt(using: secretKey) let ciphertextEvalMatrix = try ciphertextCoeffMatrix.convertToEvalFormat() let ciphertextMatrixRoundTrip = try ciphertextEvalMatrix.convertToCoeffFormat() @@ -108,7 +108,7 @@ extension PrivateNearestNeighborSearchUtil { errorStdDev: .stdDev32, securityLevel: .unchecked) #expect(encryptionParameters.supportsSimdEncoding) - let context = try Context(encryptionParameters: encryptionParameters) + let context = try Context(encryptionParameters: encryptionParameters) for rowCount in 1..<(2 * degree) { for columnCount in 1.. = try context.generateSecretKey() let ciphertextMatrix: CiphertextMatrix = try plaintextMatrix.encrypt(using: secretKey) let evaluationKeyConfig = try CiphertextMatrix.extractDenseRowConfig( diff --git a/Sources/TestUtilities/PnnsUtilities/ClientTests.swift b/Sources/TestUtilities/PnnsUtilities/ClientTests.swift index 24be888f..ec3ea792 100644 --- a/Sources/TestUtilities/PnnsUtilities/ClientTests.swift +++ b/Sources/TestUtilities/PnnsUtilities/ClientTests.swift @@ -120,7 +120,7 @@ extension PrivateNearestNeighborSearchUtil { errorStdDev: .stdDev32, securityLevel: .unchecked) #expect(encryptionParameters.supportsSimdEncoding) - let context = try Context(encryptionParameters: encryptionParameters) + let context = try Context(encryptionParameters: encryptionParameters) let vectorDimension = 32 let queryDimensions = try MatrixDimensions(rowCount: 1, columnCount: vectorDimension) @@ -128,7 +128,7 @@ extension PrivateNearestNeighborSearchUtil { dimensions: queryDimensions, modulus: context.plaintextModulus) let queryValues: Array2d = Array2d(data: encodeValues).map { value in Float(value) } - let secretKey = try context.generateSecretKey() + let secretKey: SecretKey = try context.generateSecretKey() let scalingFactor = 100 for extraPlaintextModuli in try [[], Scheme.Scalar.generatePrimes( @@ -150,7 +150,7 @@ extension PrivateNearestNeighborSearchUtil { let entryIds = [UInt64(42)] let entryMetadatas = [42.littleEndianBytes] // Treat the query as a response - let response = Response( + let response = Response( ciphertextMatrices: query.ciphertextMatrices, entryIds: entryIds, entryMetadatas: entryMetadatas) let databaseDistances = try client.decrypt(response: response, using: secretKey) diff --git a/Sources/TestUtilities/PnnsUtilities/MatrixMultiplicationTests.swift b/Sources/TestUtilities/PnnsUtilities/MatrixMultiplicationTests.swift index 50718784..ba6e2fb5 100644 --- a/Sources/TestUtilities/PnnsUtilities/MatrixMultiplicationTests.swift +++ b/Sources/TestUtilities/PnnsUtilities/MatrixMultiplicationTests.swift @@ -54,8 +54,8 @@ extension PrivateNearestNeighborSearchUtil { _ queryValues: [Scheme.Scalar]) throws { let encryptionParameters = try EncryptionParameters(from: .n_4096_logq_27_28_28_logt_16) - let context = try Context(encryptionParameters: encryptionParameters) - let secretKey = try context.generateSecretKey() + let context = try Context(encryptionParameters: encryptionParameters) + let secretKey: SecretKey = try context.generateSecretKey() var expected: [Scheme.Scalar] = try plaintextRows.mul( queryValues, @@ -67,7 +67,7 @@ extension PrivateNearestNeighborSearchUtil { } let babyStepGiantStep = BabyStepGiantStep(vectorDimension: queryValues.count) - let plaintextMatrix = try PlaintextMatrix( + let plaintextMatrix = try PlaintextMatrix( context: context, dimensions: plaintextMatrixDimensions, packing: .diagonal(babyStepGiantStep: babyStepGiantStep), @@ -139,12 +139,12 @@ extension PrivateNearestNeighborSearchUtil { @inlinable package static func matrixMulRunner( - context: Context, + context: Context, plaintextValues: [[Scheme.Scalar]], - queryValues: [[Scheme.Scalar]]) throws + queryValues: [[Scheme.Scalar]], for _: Scheme.Type) throws { let encryptionParameters = context.encryptionParameters - let secretKey = try context.generateSecretKey() + let secretKey: SecretKey = try context.generateSecretKey() let expected = try plaintextValues.mulTranspose(queryValues, modulus: context.plaintextModulus) // Query matrix let queryDimensions = try MatrixDimensions(rowCount: queryValues.count, columnCount: queryValues[0].count) @@ -158,7 +158,7 @@ extension PrivateNearestNeighborSearchUtil { let plaintextDimensions = try MatrixDimensions( rowCount: plaintextValues.count, columnCount: plaintextValues[0].count) - let plaintextMatrix = try PlaintextMatrix( + let plaintextMatrix = try PlaintextMatrix( context: context, dimensions: plaintextDimensions, packing: .diagonal(babyStepGiantStep: babyStepGiantStep), @@ -180,12 +180,12 @@ extension PrivateNearestNeighborSearchUtil { /// Testing matrix multiplication for large dimensions. @inlinable - public static func matrixMulLargeDimensions(for _: Scheme.Type) throws { + public static func matrixMulLargeDimensions(for scheme: Scheme.Type) throws { func testOnRandomData( plaintextRows: Int, plaintextCols: Int, ciphertextRows: Int, - context: Context) throws + context: Context) throws { let plaintextMatrixDimensions = try MatrixDimensions( rowCount: plaintextRows, @@ -202,7 +202,8 @@ extension PrivateNearestNeighborSearchUtil { try Self.matrixMulRunner( context: context, plaintextValues: plaintextValues, - queryValues: queryValues) + queryValues: queryValues, + for: scheme) } let degree = 2048 let coefficientModuli = try Scheme.Scalar.generatePrimes( @@ -220,7 +221,7 @@ extension PrivateNearestNeighborSearchUtil { errorStdDev: ErrorStdDev.stdDev32, securityLevel: SecurityLevel.unchecked) - let context = try Context(encryptionParameters: encryptionParameters) + let context = try Context(encryptionParameters: encryptionParameters) do { // Tall try testOnRandomData(plaintextRows: degree / 2, plaintextCols: 128, ciphertextRows: 3, context: context) @@ -299,11 +300,11 @@ extension PrivateNearestNeighborSearchUtil { /// Testing matrix multiplication for small dimensions @inlinable - public static func matrixMulSmallDimensions(for _: Scheme.Type) throws { + public static func matrixMulSmallDimensions(for scheme: Scheme.Type) throws { func testOnIncreasingData( plaintextDimensions: MatrixDimensions, queryDimensions: MatrixDimensions, - context: Context) throws + context: Context) throws { let plaintextModulus = context.encryptionParameters.plaintextModulus let plaintextValues: [[Scheme.Scalar]] = increasingData( @@ -315,11 +316,11 @@ extension PrivateNearestNeighborSearchUtil { try Self.matrixMulRunner( context: context, plaintextValues: plaintextValues, - queryValues: queryValues) + queryValues: queryValues, for: scheme) } let encryptionParameters = try EncryptionParameters(from: .insecure_n_8_logq_5x18_logt_5) - let context = try Context(encryptionParameters: encryptionParameters) + let context = try Context(encryptionParameters: encryptionParameters) do { // 8x4x2 let plaintextDimensions = try MatrixDimensions(rowCount: 8, columnCount: 4) diff --git a/Sources/TestUtilities/PnnsUtilities/PlaintextMatrixTests.swift b/Sources/TestUtilities/PnnsUtilities/PlaintextMatrixTests.swift index 7a1a0d58..999da39f 100644 --- a/Sources/TestUtilities/PnnsUtilities/PlaintextMatrixTests.swift +++ b/Sources/TestUtilities/PnnsUtilities/PlaintextMatrixTests.swift @@ -39,7 +39,7 @@ extension PrivateNearestNeighborSearchUtil { } let dims = try MatrixDimensions(rowCount: encryptionParameters.polyDegree, columnCount: 2) let packing = MatrixPacking.denseRow - let context = try Context(encryptionParameters: encryptionParameters) + let context = try Context(encryptionParameters: encryptionParameters) let values = TestUtils.getRandomPlaintextData( count: encryptionParameters.polyDegree, in: 0..(from: diffRlweParams) - let diffContext = try Context(encryptionParameters: diffEncryptionParams) + let diffContext = try Context(encryptionParameters: diffEncryptionParams) let diffValues = TestUtils.getRandomPlaintextData( count: diffEncryptionParams.polyDegree, in: 0..(for _: Scheme.Type) throws { let rlweParams = PredefinedRlweParameters.insecure_n_8_logq_5x18_logt_5 let encryptionParameters = try EncryptionParameters(from: rlweParams) - let context = try Context(encryptionParameters: encryptionParameters) + let context = try Context(encryptionParameters: encryptionParameters) let rowCount = encryptionParameters.polyDegree let columnCount = 2 let values = TestUtils.getRandomPlaintextData( @@ -115,7 +115,8 @@ extension PrivateNearestNeighborSearchUtil { @inlinable static func runPlaintextMatrixInitTest( - context: Context, + for _: Scheme.Type, + context: Context, dimensions: MatrixDimensions, packing: MatrixPacking, expected: [[Int]]) throws @@ -189,7 +190,7 @@ extension PrivateNearestNeighborSearchUtil { /// Errors for `denseColumn` packing. @inlinable - public static func plaintextMatrixDenseColumn(for _: Scheme.Type) throws { + public static func plaintextMatrixDenseColumn(for scheme: Scheme.Type) throws { let kats: [((rowCount: Int, columnCount: Int), expected: [[Int]])] = [ ((1, 1), [[1, 0, 0, 0, 0, 0, 0, 0]]), ((1, 2), [[1, 2, 0, 0, 0, 0, 0, 0]]), @@ -279,19 +280,19 @@ extension PrivateNearestNeighborSearchUtil { nttDegree: 8), errorStdDev: .stdDev32, securityLevel: .unchecked) - let context = try Context(encryptionParameters: encryptionParameters) + let context = try Context(encryptionParameters: encryptionParameters) for ((rowCount, columnCount), expected) in kats { let dimensions = try MatrixDimensions((rowCount, columnCount)) - try Self.runPlaintextMatrixInitTest( - context: context, - dimensions: dimensions, - packing: .denseColumn, expected: expected) + try Self.runPlaintextMatrixInitTest(for: scheme, + context: context, + dimensions: dimensions, + packing: .denseColumn, expected: expected) } } /// Testing `.denseRow` format. @inlinable - public static func plaintextMatrixDenseRow(for _: Scheme.Type) throws { + public static func plaintextMatrixDenseRow(for scheme: Scheme.Type) throws { let kats: [((rowCount: Int, columnCount: Int), expected: [[Int]])] = [ ((1, 1), [[1, 1, 1, 1, 1, 1, 1, 1]]), ((1, 2), [[1, 2, 1, 2, 1, 2, 1, 2]]), @@ -358,20 +359,20 @@ extension PrivateNearestNeighborSearchUtil { let rlweParams = PredefinedRlweParameters.insecure_n_8_logq_5x18_logt_5 let encryptionParameters = try EncryptionParameters(from: rlweParams) - let context = try Context(encryptionParameters: encryptionParameters) + let context = try Context(encryptionParameters: encryptionParameters) for ((rowCount, columnCount), expected) in kats { let dimensions = try MatrixDimensions((rowCount, columnCount)) - try Self.runPlaintextMatrixInitTest( - context: context, - dimensions: dimensions, - packing: .denseRow, - expected: expected) + try Self.runPlaintextMatrixInitTest(for: scheme, + context: context, + dimensions: dimensions, + packing: .denseRow, + expected: expected) } } /// Testing `.diagonal` format. @inlinable - public static func plaintextMatrixDiagonal(for _: Scheme.Type) throws { + public static func plaintextMatrixDiagonal(for scheme: Scheme.Type) throws { let kats: [((rowCount: Int, columnCount: Int), expected: [[Int]])] = [ ((1, 3), [ [1, 0, 0, 0, 0, 0, 0, 0], @@ -456,15 +457,15 @@ extension PrivateNearestNeighborSearchUtil { nttDegree: 8), errorStdDev: ErrorStdDev.stdDev32, securityLevel: SecurityLevel.unchecked) - let context = try Context(encryptionParameters: encryptionParameters) + let context = try Context(encryptionParameters: encryptionParameters) for ((rowCount, columnCount), expected) in kats { let dimensions = try MatrixDimensions((rowCount, columnCount)) let bsgs = BabyStepGiantStep(vectorDimension: dimensions.columnCount.nextPowerOfTwo) - try Self.runPlaintextMatrixInitTest( - context: context, - dimensions: dimensions, - packing: .diagonal(babyStepGiantStep: bsgs), - expected: expected) + try Self.runPlaintextMatrixInitTest(for: scheme, + context: context, + dimensions: dimensions, + packing: .diagonal(babyStepGiantStep: bsgs), + expected: expected) } } @@ -480,7 +481,7 @@ extension PrivateNearestNeighborSearchUtil { nttDegree: 16), errorStdDev: ErrorStdDev.stdDev32, securityLevel: SecurityLevel.unchecked) - let context = try Context(encryptionParameters: encryptionParameters) + let context = try Context(encryptionParameters: encryptionParameters) let dimensions = try MatrixDimensions(rowCount: 4, columnCount: 5) let bsgs = BabyStepGiantStep(vectorDimension: dimensions.columnCount) @@ -519,7 +520,7 @@ extension PrivateNearestNeighborSearchUtil { let rlweParams = PredefinedRlweParameters.insecure_n_8_logq_5x18_logt_5 let encryptionParameters = try EncryptionParameters(from: rlweParams) #expect(encryptionParameters.supportsSimdEncoding) - let context = try Context(encryptionParameters: encryptionParameters) + let context = try Context(encryptionParameters: encryptionParameters) let dimensions = try MatrixDimensions(rowCount: 10, columnCount: 4) let encodeValues: [[Scheme.Scalar]] = increasingData( dimensions: dimensions, diff --git a/Sources/TestUtilities/TestUtilities.swift b/Sources/TestUtilities/TestUtilities.swift index c301754e..aefc5f0e 100644 --- a/Sources/TestUtilities/TestUtilities.swift +++ b/Sources/TestUtilities/TestUtilities.swift @@ -326,7 +326,7 @@ extension TestUtils { } @inlinable - package static func getTestContext() throws -> Context { - try Context(encryptionParameters: getTestEncryptionParameters()) + package static func getTestContext() throws -> Context { + try Context(encryptionParameters: getTestEncryptionParameters()) } } diff --git a/Tests/HomomorphicEncryptionProtobufTests/ConversionTests.swift b/Tests/HomomorphicEncryptionProtobufTests/ConversionTests.swift index ee73bba8..82ea4bea 100644 --- a/Tests/HomomorphicEncryptionProtobufTests/ConversionTests.swift +++ b/Tests/HomomorphicEncryptionProtobufTests/ConversionTests.swift @@ -36,7 +36,7 @@ struct ConversionTests { @Test func encryptionParameters() throws { func runTest(_: Scheme.Type) throws { - let context: Context = try TestUtils.getTestContext() + let context: Context = try TestUtils.getTestContext() let parametersProto = try context.encryptionParameters.proto(scheme: Scheme.self) let _: EncryptionParameters = try parametersProto.native() @@ -56,10 +56,10 @@ struct ConversionTests { } func runTest(_: Scheme.Type) throws { - let context: Context = try TestUtils.getTestContext() + let context: Context = try TestUtils.getTestContext() let values = TestUtils.getRandomPlaintextData(count: context.degree, in: 0.. = try context.generateSecretKey() var ciphertext = try plaintext.encrypt(using: secretKey) func checkDeserialization( @@ -134,7 +134,7 @@ struct ConversionTests { @Test(arguments: EncodeFormat.allCases) func plaintextSerialization(format: EncodeFormat) throws { func runTest(_: Scheme.Type, format: EncodeFormat) throws { - let context: Context = try TestUtils.getTestContext() + let context: Context = try TestUtils.getTestContext() let values = TestUtils.getRandomPlaintextData(count: context.degree, in: 0..(_: Scheme.Type, format: EncodeFormat) throws { - let context: Context = try TestUtils.getTestContext() + let context: Context = try TestUtils.getTestContext() let values = TestUtils.getRandomPlaintextData(count: context.degree, in: 0..(_: Scheme.Type) throws { - let context: Context = try TestUtils.getTestContext() - let secretKey = try context.generateSecretKey() + let context: Context = try TestUtils.getTestContext() + let secretKey: SecretKey = try context.generateSecretKey() let proto = secretKey.serialize().proto() - let deserialized = try SecretKey(deserialize: proto.native(), context: context) + let deserialized = try SecretKey(deserialize: proto.native(), context: context) #expect(deserialized == secretKey) } @@ -199,13 +199,13 @@ struct ConversionTests { @Test func galoisKey() throws { func runTest(_: Scheme.Type) throws { - let context: Context = try TestUtils.getTestContext() - let secretKey = try context.generateSecretKey() + let context: Context = try TestUtils.getTestContext() + let secretKey: SecretKey = try context.generateSecretKey() let evaluationKey = try context.generateEvaluationKey( config: EvaluationKeyConfig(galoisElements: [3, 5, 7]), using: secretKey) let galoisKey = try #require(evaluationKey.galoisKey) let proto = galoisKey.serialize().proto() - let deserialized = try GaloisKey(deserialize: proto.native(), context: context) + let deserialized = try GaloisKey(deserialize: proto.native(), context: context) #expect(deserialized == galoisKey) } @@ -217,14 +217,14 @@ struct ConversionTests { @Test func relinearizationKey() throws { func runTest(_: Scheme.Type) throws { - let context: Context = try TestUtils.getTestContext() - let secretKey = try context.generateSecretKey() + let context: Context = try TestUtils.getTestContext() + let secretKey: SecretKey = try context.generateSecretKey() let evaluationKey = try context.generateEvaluationKey( config: EvaluationKeyConfig( hasRelinearizationKey: true), using: secretKey) let relinearizationKey = try #require(evaluationKey.relinearizationKey) let proto = relinearizationKey.serialize().proto() - let deserialized = try RelinearizationKey(deserialize: proto.native(), context: context) + let deserialized = try RelinearizationKey(deserialize: proto.native(), context: context) #expect(deserialized == relinearizationKey) } @@ -236,14 +236,14 @@ struct ConversionTests { @Test func evaluationKey() throws { func runTest(_: Scheme.Type) throws { - let context: Context = try TestUtils.getTestContext() - let secretKey = try context.generateSecretKey() + let context: Context = try TestUtils.getTestContext() + let secretKey: SecretKey = try context.generateSecretKey() let evaluationKey = try context.generateEvaluationKey( config: EvaluationKeyConfig( galoisElements: [3, 5, 7], hasRelinearizationKey: true), using: secretKey) let proto = evaluationKey.serialize().proto() - let deserialized = try EvaluationKey(deserialize: proto.native(), context: context) + let deserialized = try EvaluationKey(deserialize: proto.native(), context: context) #expect(deserialized == evaluationKey) } diff --git a/Tests/HomomorphicEncryptionTests/EncryptionParametersTests.swift b/Tests/HomomorphicEncryptionTests/EncryptionParametersTests.swift index 671d8500..2c19a836 100644 --- a/Tests/HomomorphicEncryptionTests/EncryptionParametersTests.swift +++ b/Tests/HomomorphicEncryptionTests/EncryptionParametersTests.swift @@ -243,10 +243,10 @@ struct EncryptionParametersTests { // check skipLSBsForDecryption do { - let context = try Context>(encryptionParameters: params) + let context = try Context(encryptionParameters: params) let data = TestUtils.getRandomPlaintextData(count: params.polyDegree, in: 0.., Coeff> = try context.encode(values: data, format: .coefficient) + let secretKey: SecretKey> = try context.generateSecretKey() var ciphertext = try plaintext.encrypt(using: secretKey) try ciphertext.modSwitchDownToSingle() let skipLSBs = try ciphertext.convertToCoeffFormat().skipLSBs(forDecryption: true) diff --git a/Tests/HomomorphicEncryptionTests/HeAPITests.swift b/Tests/HomomorphicEncryptionTests/HeAPITests.swift index 76a9172b..80c79691 100644 --- a/Tests/HomomorphicEncryptionTests/HeAPITests.swift +++ b/Tests/HomomorphicEncryptionTests/HeAPITests.swift @@ -19,7 +19,7 @@ import Testing @Suite struct HeAPITests { private struct TestEnv { - let context: Context + let context: Context let data1: [Scheme.Scalar] let data2: [Scheme.Scalar] let coeffPlaintext1: Plaintext @@ -33,7 +33,7 @@ struct HeAPITests { let evaluationKey: EvaluationKey? init( - context: Context, + context: Context, format: EncodeFormat, galoisElements: [Int] = [], relinearizationKey: Bool = false) throws @@ -86,37 +86,37 @@ struct HeAPITests { @Test func testNoOpScheme() async throws { - let context: Context = try TestUtils.getTestContext() - try HeAPITestHelpers.schemeEncodeDecodeTest(context: context) - try HeAPITestHelpers.schemeEncryptDecryptTest(context: context) - try HeAPITestHelpers.schemeEncryptZeroDecryptTest(context: context) - try HeAPITestHelpers.schemeEncryptZeroAddDecryptTest(context: context) - try HeAPITestHelpers.schemeEncryptZeroMultiplyDecryptTest(context: context) - try await HeAPITestHelpers.schemeCiphertextAddTest(context: context) - try await HeAPITestHelpers.schemeCiphertextSubtractTest(context: context) - try await HeAPITestHelpers.schemeCiphertextCiphertextMultiplyTest(context: context) - try await HeAPITestHelpers.schemeCiphertextPlaintextAddTest(context: context) - try await HeAPITestHelpers.schemeCiphertextPlaintextSubtractTest(context: context) - try await HeAPITestHelpers.schemeCiphertextPlaintextMultiplyTest(context: context) - try await HeAPITestHelpers.schemeCiphertextMultiplyAddTest(context: context) - try HeAPITestHelpers.schemeCiphertextMultiplyAddPlainTest(context: context) - try await HeAPITestHelpers.schemeCiphertextMultiplySubtractTest(context: context) - try await HeAPITestHelpers.schemeCiphertextMultiplySubtractPlainTest(context: context) - try await HeAPITestHelpers.schemeCiphertextNegateTest(context: context) - try await HeAPITestHelpers.schemeCiphertextPlaintextInnerProductTest(context: context) - try await HeAPITestHelpers.schemeCiphertextCiphertextInnerProductTest(context: context) + let context: Context = try TestUtils.getTestContext() + try HeAPITestHelpers.schemeEncodeDecodeTest(context: context, scheme: NoOpScheme.self) + try HeAPITestHelpers.schemeEncryptDecryptTest(context: context, scheme: NoOpScheme.self) + try HeAPITestHelpers.schemeEncryptZeroDecryptTest(context: context, scheme: NoOpScheme.self) + try HeAPITestHelpers.schemeEncryptZeroAddDecryptTest(context: context, scheme: NoOpScheme.self) + try HeAPITestHelpers.schemeEncryptZeroMultiplyDecryptTest(context: context, scheme: NoOpScheme.self) + try await HeAPITestHelpers.schemeCiphertextAddTest(context: context, scheme: NoOpScheme.self) + try await HeAPITestHelpers.schemeCiphertextSubtractTest(context: context, scheme: NoOpScheme.self) + try await HeAPITestHelpers.schemeCiphertextCiphertextMultiplyTest(context: context, scheme: NoOpScheme.self) + try await HeAPITestHelpers.schemeCiphertextPlaintextAddTest(context: context, scheme: NoOpScheme.self) + try await HeAPITestHelpers.schemeCiphertextPlaintextSubtractTest(context: context, scheme: NoOpScheme.self) + try await HeAPITestHelpers.schemeCiphertextPlaintextMultiplyTest(context: context, scheme: NoOpScheme.self) + try await HeAPITestHelpers.schemeCiphertextMultiplyAddTest(context: context, scheme: NoOpScheme.self) + try HeAPITestHelpers.schemeCiphertextMultiplyAddPlainTest(context: context, scheme: NoOpScheme.self) + try await HeAPITestHelpers.schemeCiphertextMultiplySubtractTest(context: context, scheme: NoOpScheme.self) + try await HeAPITestHelpers.schemeCiphertextMultiplySubtractPlainTest(context: context, scheme: NoOpScheme.self) + try await HeAPITestHelpers.schemeCiphertextNegateTest(context: context, scheme: NoOpScheme.self) + try await HeAPITestHelpers.schemeCiphertextPlaintextInnerProductTest(context: context, scheme: NoOpScheme.self) + try await HeAPITestHelpers.schemeCiphertextCiphertextInnerProductTest(context: context, scheme: NoOpScheme.self) try HeAPITestHelpers.schemeEvaluationKeyTest(context: context) - try await HeAPITestHelpers.schemeRotationTest(context: context) - try await HeAPITestHelpers.schemeApplyGaloisTest(context: context) + try await HeAPITestHelpers.schemeRotationTest(context: context, scheme: NoOpScheme.self) + try await HeAPITestHelpers.schemeApplyGaloisTest(context: context, scheme: NoOpScheme.self) } - private func bfvTestKeySwitching(context: Context>) throws { + private func bfvTestKeySwitching(context: Context) throws { guard context.supportsEvaluationKey else { return } - let testEnv = try TestEnv(context: context, format: .coefficient) - let newSecretKey = try context.generateSecretKey() + let testEnv = try TestEnv>(context: context, format: .coefficient) + let newSecretKey: SecretKey> = try context.generateSecretKey() let keySwitchKey = try Bfv.generateKeySwitchKey(context: context, currentKey: testEnv.secretKey.poly, @@ -126,7 +126,7 @@ struct HeAPITests { target: testEnv.ciphertext1.polys[1], keySwitchingKey: keySwitchKey) switchedPolys[0] += testEnv.ciphertext1.polys[0] - let switchedCiphertext = Ciphertext(context: context, polys: switchedPolys, correctionFactor: 1) + let switchedCiphertext = Bfv.CanonicalCiphertext(context: context, polys: switchedPolys, correctionFactor: 1) let plaintext = try switchedCiphertext.decrypt(using: newSecretKey) let decrypted: [T] = try plaintext.decode(format: .coefficient) @@ -163,32 +163,32 @@ struct HeAPITests { securityLevel: SecurityLevel.unchecked) for encryptionParameters in predefined + [custom, manyModuli] { - let context = try Context>(encryptionParameters: encryptionParameters) - try HeAPITestHelpers.schemeEncodeDecodeTest(context: context) - try HeAPITestHelpers.schemeEncryptDecryptTest(context: context) - try HeAPITestHelpers.schemeEncryptZeroDecryptTest(context: context) - try HeAPITestHelpers.schemeEncryptZeroAddDecryptTest(context: context) - try HeAPITestHelpers.schemeEncryptZeroMultiplyDecryptTest(context: context) - try await HeAPITestHelpers.schemeCiphertextAddTest(context: context) - try await HeAPITestHelpers.schemeCiphertextSubtractTest(context: context) - try await HeAPITestHelpers.schemeCiphertextCiphertextMultiplyTest(context: context) - try await HeAPITestHelpers.schemeCiphertextPlaintextAddTest(context: context) - try await HeAPITestHelpers.schemeCiphertextPlaintextSubtractTest(context: context) - try await HeAPITestHelpers.schemeCiphertextPlaintextMultiplyTest(context: context) - try await HeAPITestHelpers.schemeCiphertextMultiplyAddTest(context: context) - try HeAPITestHelpers.schemeCiphertextMultiplyAddPlainTest(context: context) - try await HeAPITestHelpers.schemeCiphertextMultiplySubtractTest(context: context) - try await HeAPITestHelpers.schemeCiphertextMultiplySubtractPlainTest(context: context) - try await HeAPITestHelpers.schemeCiphertextNegateTest(context: context) - try await HeAPITestHelpers.schemeCiphertextPlaintextInnerProductTest(context: context) - try await HeAPITestHelpers.schemeCiphertextCiphertextInnerProductTest(context: context) + let context = try Context(encryptionParameters: encryptionParameters) + try HeAPITestHelpers.schemeEncodeDecodeTest(context: context, scheme: Bfv.self) + try HeAPITestHelpers.schemeEncryptDecryptTest(context: context, scheme: Bfv.self) + try HeAPITestHelpers.schemeEncryptZeroDecryptTest(context: context, scheme: Bfv.self) + try HeAPITestHelpers.schemeEncryptZeroAddDecryptTest(context: context, scheme: Bfv.self) + try HeAPITestHelpers.schemeEncryptZeroMultiplyDecryptTest(context: context, scheme: Bfv.self) + try await HeAPITestHelpers.schemeCiphertextAddTest(context: context, scheme: Bfv.self) + try await HeAPITestHelpers.schemeCiphertextSubtractTest(context: context, scheme: Bfv.self) + try await HeAPITestHelpers.schemeCiphertextCiphertextMultiplyTest(context: context, scheme: Bfv.self) + try await HeAPITestHelpers.schemeCiphertextPlaintextAddTest(context: context, scheme: Bfv.self) + try await HeAPITestHelpers.schemeCiphertextPlaintextSubtractTest(context: context, scheme: Bfv.self) + try await HeAPITestHelpers.schemeCiphertextPlaintextMultiplyTest(context: context, scheme: Bfv.self) + try await HeAPITestHelpers.schemeCiphertextMultiplyAddTest(context: context, scheme: Bfv.self) + try HeAPITestHelpers.schemeCiphertextMultiplyAddPlainTest(context: context, scheme: Bfv.self) + try await HeAPITestHelpers.schemeCiphertextMultiplySubtractTest(context: context, scheme: Bfv.self) + try await HeAPITestHelpers.schemeCiphertextMultiplySubtractPlainTest(context: context, scheme: Bfv.self) + try await HeAPITestHelpers.schemeCiphertextNegateTest(context: context, scheme: Bfv.self) + try await HeAPITestHelpers.schemeCiphertextPlaintextInnerProductTest(context: context, scheme: Bfv.self) + try await HeAPITestHelpers.schemeCiphertextCiphertextInnerProductTest(context: context, scheme: Bfv.self) try HeAPITestHelpers.schemeEvaluationKeyTest(context: context) - try await HeAPITestHelpers.schemeRotationTest(context: context) - try await HeAPITestHelpers.schemeApplyGaloisTest(context: context) + try await HeAPITestHelpers.schemeRotationTest(context: context, scheme: Bfv.self) + try await HeAPITestHelpers.schemeApplyGaloisTest(context: context, scheme: Bfv.self) try bfvTestKeySwitching(context: context) - try HeAPITestHelpers.noiseBudgetTest(context: context) - try await HeAPITestHelpers.repeatedAdditionTest(context: context) - try await HeAPITestHelpers.multiplyInverseTest(context: context) + try HeAPITestHelpers.noiseBudgetTest(context: context, scheme: Bfv.self) + try await HeAPITestHelpers.repeatedAdditionTest(context: context, scheme: Bfv.self) + try await HeAPITestHelpers.multiplyInverseTest(context: context, scheme: Bfv.self) } } diff --git a/Tests/HomomorphicEncryptionTests/SerializationTests.swift b/Tests/HomomorphicEncryptionTests/SerializationTests.swift index c8f2cd1d..4d385b5f 100644 --- a/Tests/HomomorphicEncryptionTests/SerializationTests.swift +++ b/Tests/HomomorphicEncryptionTests/SerializationTests.swift @@ -26,10 +26,10 @@ struct SerializationTests { } func runTest(_: Scheme.Type) throws { - let context: Context = try TestUtils.getTestContext() + let context: Context = try TestUtils.getTestContext() let values = TestUtils.getRandomPlaintextData(count: context.degree, in: 0.. = try context.generateSecretKey() var ciphertext = try plaintext.encrypt(using: secretKey) func checkDeserialization( @@ -98,7 +98,7 @@ struct SerializationTests { @Test func plaintextSerialization() throws { func runTest(_: Scheme.Type, format: EncodeFormat) throws { - let context: Context = try TestUtils.getTestContext() + let context: Context = try TestUtils.getTestContext() let values = TestUtils.getRandomPlaintextData(count: context.degree, in: 0..(_: Scheme.Type, format: EncodeFormat) throws { - let context: Context = try TestUtils.getTestContext() + let context: Context = try TestUtils.getTestContext() let values = TestUtils.getRandomPlaintextData(count: context.degree, in: 0..(_: Scheme.Type) throws { - let context: Context = try TestUtils.getTestContext() - let secretKey = try context.generateSecretKey() + let context: Context = try TestUtils.getTestContext() + let secretKey: SecretKey = try context.generateSecretKey() let serialized = secretKey.serialize() - let deserialized = try SecretKey(deserialize: serialized, context: context) + let deserialized = try SecretKey(deserialize: serialized, context: context) #expect(deserialized == secretKey) } @@ -166,13 +166,13 @@ struct SerializationTests { @Test func galoisKey() throws { func runTest(_: Scheme.Type) throws { - let context: Context = try TestUtils.getTestContext() - let secretKey = try context.generateSecretKey() + let context: Context = try TestUtils.getTestContext() + let secretKey: SecretKey = try context.generateSecretKey() let evaluationKeyConfig = EvaluationKeyConfig(galoisElements: [3, 5, 7]) let evaluationKey = try context.generateEvaluationKey(config: evaluationKeyConfig, using: secretKey) let galoisKey = try #require(evaluationKey.galoisKey) let serialized = galoisKey.serialize() - let deserialized = try GaloisKey(deserialize: serialized, context: context) + let deserialized = try GaloisKey(deserialize: serialized, context: context) #expect(deserialized == galoisKey) } @@ -184,13 +184,13 @@ struct SerializationTests { @Test func relinearizationKey() throws { func runTest(_: Scheme.Type) throws { - let context: Context = try TestUtils.getTestContext() - let secretKey = try context.generateSecretKey() + let context: Context = try TestUtils.getTestContext() + let secretKey: SecretKey = try context.generateSecretKey() let evaluationKeyConfig = EvaluationKeyConfig(hasRelinearizationKey: true) let evaluationKey = try context.generateEvaluationKey(config: evaluationKeyConfig, using: secretKey) let relinearizationKey = try #require(evaluationKey.relinearizationKey) let serialized = relinearizationKey.serialize() - let deserialized = try RelinearizationKey(deserialize: serialized, context: context) + let deserialized = try RelinearizationKey(deserialize: serialized, context: context) #expect(deserialized == relinearizationKey) } @@ -202,14 +202,14 @@ struct SerializationTests { @Test func evaluationKey() throws { func runTest(_: Scheme.Type) throws { - let context: Context = try TestUtils.getTestContext() - let secretKey = try context.generateSecretKey() + let context: Context = try TestUtils.getTestContext() + let secretKey: SecretKey = try context.generateSecretKey() let evaluationKeyConfig = EvaluationKeyConfig( galoisElements: [3, 5, 7], hasRelinearizationKey: true) let evaluationKey = try context.generateEvaluationKey(config: evaluationKeyConfig, using: secretKey) let serialized = evaluationKey.serialize() - let deserialized = try EvaluationKey(deserialize: serialized, context: context) + let deserialized = try EvaluationKey(deserialize: serialized, context: context) #expect(deserialized == evaluationKey) func checkSeededCiphertext(_ ciphertexts: [SerializedCiphertext]) { diff --git a/Tests/PrivateInformationRetrievalProtobufTests/ConversionTests.swift b/Tests/PrivateInformationRetrievalProtobufTests/ConversionTests.swift index b89d84ee..f8af5cb0 100644 --- a/Tests/PrivateInformationRetrievalProtobufTests/ConversionTests.swift +++ b/Tests/PrivateInformationRetrievalProtobufTests/ConversionTests.swift @@ -43,7 +43,7 @@ struct ConversionTests { @Test func processedDatabaseWithParameters() throws { let rows = (0..<10).map { KeywordValuePair(keyword: Array(String($0).utf8), value: Array(String($0).utf8)) } - let context: Context> = try .init(encryptionParameters: .init(from: .n_4096_logq_27_28_28_logt_13)) + let context: Context = try .init(encryptionParameters: .init(from: .n_4096_logq_27_28_28_logt_13)) let config = try KeywordPirConfig( dimensionCount: 2, cuckooTableConfig: .defaultKeywordPir(maxSerializedBucketSize: context.bytesPerPlaintext), diff --git a/Tests/PrivateInformationRetrievalTests/IndexPirTests.swift b/Tests/PrivateInformationRetrievalTests/IndexPirTests.swift index f6c7e8db..78c4df05 100644 --- a/Tests/PrivateInformationRetrievalTests/IndexPirTests.swift +++ b/Tests/PrivateInformationRetrievalTests/IndexPirTests.swift @@ -21,7 +21,7 @@ import Testing struct IndexPirTests { @Test func generateParameter() throws { - let context: Context> = try TestUtils.getTestContext() + let context: Context = try TestUtils.getTestContext() // unevenDimensions: false do { let config = try IndexPirConfig(entryCount: 16, diff --git a/Tests/PrivateNearestNeighborSearchProtobufTests/ConversionTests.swift b/Tests/PrivateNearestNeighborSearchProtobufTests/ConversionTests.swift index 9656ef13..448d602f 100644 --- a/Tests/PrivateNearestNeighborSearchProtobufTests/ConversionTests.swift +++ b/Tests/PrivateNearestNeighborSearchProtobufTests/ConversionTests.swift @@ -104,27 +104,27 @@ struct ConversionTests { func serializedPlaintextMatrix() throws { func runTest(_: Scheme.Type) throws { let encryptionParameters = try EncryptionParameters(from: .insecure_n_8_logq_5x18_logt_5) - let context = try Context(encryptionParameters: encryptionParameters) + let context = try Context(encryptionParameters: encryptionParameters) let dimensions = try MatrixDimensions(rowCount: 5, columnCount: 4) let scalars: [[Scheme.Scalar]] = increasingData( dimensions: dimensions, modulus: encryptionParameters.plaintextModulus) - let plaintextMatrix = try PlaintextMatrix( + let plaintextMatrix = try PlaintextMatrix( context: context, dimensions: dimensions, packing: .denseColumn, values: scalars.flatMap(\.self)) let serialized = try plaintextMatrix.serialize() #expect(try serialized.proto().native() == serialized) - let deserialized = try PlaintextMatrix(deserialize: serialized, context: context) + let deserialized = try PlaintextMatrix(deserialize: serialized, context: context) #expect(deserialized == plaintextMatrix) for moduliCount in 1..( deserialize: serialized, context: context, moduliCount: moduliCount) @@ -140,14 +140,14 @@ struct ConversionTests { func serializedCiphertextMatrix() throws { func runTest(_: Scheme.Type) throws { let encryptionParameters = try EncryptionParameters(from: .insecure_n_8_logq_5x18_logt_5) - let context = try Context(encryptionParameters: encryptionParameters) - let secretKey = try context.generateSecretKey() + let context = try Context(encryptionParameters: encryptionParameters) + let secretKey: SecretKey = try context.generateSecretKey() let dimensions = try MatrixDimensions(rowCount: 5, columnCount: 4) let scalars: [[Scheme.Scalar]] = increasingData( dimensions: dimensions, modulus: encryptionParameters.plaintextModulus) - let plaintextMatrix = try PlaintextMatrix( + let plaintextMatrix = try PlaintextMatrix( context: context, dimensions: dimensions, packing: .denseColumn, @@ -198,14 +198,14 @@ struct ConversionTests { func query() throws { func runTest(_: Scheme.Type) throws { let encryptionParameters = try EncryptionParameters(from: .insecure_n_8_logq_5x18_logt_5) - let context = try Context(encryptionParameters: encryptionParameters) - let secretKey = try context.generateSecretKey() + let context = try Context(encryptionParameters: encryptionParameters) + let secretKey: SecretKey = try context.generateSecretKey() let dimensions = try MatrixDimensions(rowCount: 5, columnCount: 4) let scalars: [[Scheme.Scalar]] = increasingData( dimensions: dimensions, modulus: encryptionParameters.plaintextModulus) - let plaintextMatrix = try PlaintextMatrix( + let plaintextMatrix = try PlaintextMatrix( context: context, dimensions: dimensions, packing: .denseColumn, @@ -215,7 +215,7 @@ struct ConversionTests { } let query = Query(ciphertextMatrices: ciphertextMatrices) - let roundtrip = try query.proto().native(context: context) + let roundtrip: Query = try query.proto().native(context: context) #expect(roundtrip == query) } try runTest(Bfv.self)