Skip to content

Commit

Permalink
Throw error when incompatible platform is used (#50)
Browse files Browse the repository at this point in the history
Configuring sharding function is not backwards compatible.
  • Loading branch information
karulont authored Nov 12, 2024
1 parent e220657 commit 3ddfb4f
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 4 deletions.
2 changes: 1 addition & 1 deletion Sources/PIRService/Controllers/PIRServiceController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ struct PIRServiceController {
if let usecase = requestedUsecases[usecaseName] {
var config = try usecase.config(existingConfigId: Array(configId))
if let platform = context.platform {
config.makeCompatible(with: platform)
try config.makeCompatible(with: platform)
}
configs[usecaseName] = config
}
Expand Down
22 changes: 21 additions & 1 deletion Sources/PIRService/Extensions/PirConfig+compatible.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

import Hummingbird
import PrivateInformationRetrievalProtobuf
import Util

Expand All @@ -26,12 +27,23 @@ extension Platform {
fatalError("Unsupported platform \(self)")
}
}

var supportsShardingFunctionDoubleMod: Bool {
switch osType {
case .iOS:
osVersion >= .init(major: 18, minor: 2)
case .macOS:
osVersion >= .init(major: 15, minor: 2)
default:
fatalError("Unsupported platform \(self)")
}
}
}

public extension Apple_SwiftHomomorphicEncryption_Api_Pir_V1_Config {
/// Makes the configuration compatible with the given platform.
/// - Parameter platform: Device platform.
mutating func makeCompatible(with platform: Platform) {
mutating func makeCompatible(with platform: Platform) throws {
if !platform.supportsPirFixedShardConfig {
// Check for PIRFixedShardConfig, introduced in iOS 18.2
switch pirConfig.pirShardConfigs.shardConfigs {
Expand All @@ -44,5 +56,13 @@ public extension Apple_SwiftHomomorphicEncryption_Api_Pir_V1_Config {
break
}
}

if !platform.supportsShardingFunctionDoubleMod {
if pirConfig.keywordPirParams.shardingFunction.native() != .sha256 {
throw HTTPError(
.internalServerError,
message: "Platform \(platform) does not support sharding functions other than SHA256.")
}
}
}
}
6 changes: 6 additions & 0 deletions Sources/PIRService/PIRService.docc/TestingInstructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,12 @@ After introduction in iOS 18.0, `Live Caller ID Lookup` introduced further featu

* `Reusing existing config id` (iOS 18.2). During the `config` request, if a client has a cached configuration, it will send the config id of that cached configuration. Then, if the configuration is unchanged, the server may respond with a config setting `reuseExistingConfig = true` and omit any other fields. This helps reduce the response size for the config fetch.

* `Sharding function configurability` (iOS 18.2). [Sharding
function](https://swiftpackageindex.com/apple/swift-homomorphic-encryption/main/documentation/pirprocessdatabase#Sharding-function)
can be configured. The `doubleMod` sharding function was designed specifically for the use case where multiple
requests are made with the same keyword, like in Live Caller ID Lookup, where we use the same phone number to look up
blocking information and Identity information. Note: this option is not backward compatible with older iOS versions.

## Writing the application extension

> Important: Please see [Getting up-to-date calling and blocking information for your
Expand Down
2 changes: 1 addition & 1 deletion Tests/PIRServiceTests/PIRServiceControllerTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ class PIRServiceControllerTests: XCTestCase {
{ response in
XCTAssertEqual(response.status, .ok)
var expectedConfig = try exampleUsecase.config()
expectedConfig.makeCompatible(with: platform)
try expectedConfig.makeCompatible(with: platform)
let configResponse = try response
.message(as: Apple_SwiftHomomorphicEncryption_Api_Pir_V1_ConfigResponse.self)
XCTAssertEqual(configResponse.configs["test"], expectedConfig)
Expand Down
9 changes: 8 additions & 1 deletion Tests/PIRServiceTests/PIRServiceTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -141,13 +141,20 @@ class PIRServiceTests: XCTestCase {
let shard0Config = config.pirConfig.shardConfig(shardIndex: 0)
XCTAssertEqual(config.pirConfig.shardCount, 5)

config.makeCompatible(with: .iOS18)
try config.makeCompatible(with: .iOS18)
XCTAssertEqual(config.pirConfig.shardConfigs.count, 5)
XCTAssertEqual(config.pirConfig.shardConfigs, Array(repeating: shard0Config, count: 5))
for shardIndex in 0..<5 {
XCTAssertEqual(config.pirConfig.shardConfig(shardIndex: shardIndex), shard0Config)
}
XCTAssertEqual(config.pirConfig.shardCount, 5)

config.pirConfig.keywordPirParams.shardingFunction.function = .doubleMod(.with { doubleMod in
doubleMod.otherShardCount = 5
})

XCTAssertThrowsError(try config.makeCompatible(with: .iOS18))
XCTAssertNoThrow(try config.makeCompatible(with: .iOS18_2))
}
}

Expand Down

0 comments on commit 3ddfb4f

Please sign in to comment.