Skip to content

Commit

Permalink
Adopt swift 6
Browse files Browse the repository at this point in the history
  • Loading branch information
fboemer committed Oct 29, 2024
1 parent 98bd4ef commit 2c0df72
Show file tree
Hide file tree
Showing 16 changed files with 82 additions and 87 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ jobs:
strategy:
fail-fast: false
matrix:
swift: ["5.10", "6.0"]
swift: ["6.0"]
name: swift ${{ matrix.swift }} tests
steps:
- uses: slashmo/[email protected]
Expand Down
3 changes: 2 additions & 1 deletion Benchmarks/PolyBenchmark/PolyBenchmark.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
// limitations under the License.

// Benchmarks for PolyRq functions.
// These benchmarks can be triggered with `swift package benchmark --target PolyBenchmark`
// These benchmarks can be triggered with
// swift package benchmark --target PolyBenchmark

import Benchmark
import HomomorphicEncryption
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
// limitations under the License.

// Benchmarks for Pir functions.
// These benchmarks can be triggered with `swift package benchmark --target PIRBenchmark`
// These benchmarks can be triggered with
// swift package benchmark --target PIRBenchmark

import Benchmark
import Foundation
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
// limitations under the License.

// Benchmarks for Pnns functions.
// These benchmarks can be triggered with `swift package benchmark --target PNNSBenchmark`
// These benchmarks can be triggered with
// swift package benchmark --target PNNSBenchmark

import Benchmark
import Foundation
Expand Down
3 changes: 2 additions & 1 deletion Benchmarks/RlweBenchmark/RlweBenchmark.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
// limitations under the License.

// Benchmarks for Rlwe functions.
// These benchmarks can be triggered with `swift package benchmark --target RlweBenchmark`
// These benchmarks can be triggered with
// swift package benchmark --target RlweBenchmark

import Benchmark
import HomomorphicEncryption
Expand Down
10 changes: 5 additions & 5 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// swift-tools-version: 5.10
// swift-tools-version: 6.0
// The swift-tools-version declares the minimum version of Swift required to build this package.
// Remember to update CI if changing

Expand All @@ -17,9 +17,7 @@
// limitations under the License.
import PackageDescription

let librarySettings: [SwiftSetting] = [
.enableExperimentalFeature("StrictConcurrency"),
]
let librarySettings: [SwiftSetting] = []

let executableSettings: [SwiftSetting] =
librarySettings +
Expand Down Expand Up @@ -282,6 +280,8 @@ package.targets += [
]

// Set the minimum macOS version for the package
#if canImport(Darwin)
package.platforms = [
.macOS(.v14), // Constrained by Swift 5.10 support for Xcode (https://developer.apple.com/support/xcode/)
.macOS(.v15), // Constrained by UInt128 support
]
#endif
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ The PNNS implementation in Swift Homomorphic Encryption uses homomorphic encrypt
Swift Homomorphic Encryption requires:
* 64-bit processor with little-endian memory representation
* macOS or Linux operating system
* [Swift](https://www.swift.org/) version 5.10 or later
* [Swift](https://www.swift.org/) version 6.0 or later

> [!NOTE]
> Swift Homomorphic Encryption relies on [SystemRandomNumberGenerator](https://developer.apple.com/documentation/swift/systemrandomnumbergenerator) as a cryptographically secure random number generator, which may have platform-dependent behavior.
Expand Down
1 change: 0 additions & 1 deletion Sources/HomomorphicEncryption/DoubleWidthUInt.swift
Original file line number Diff line number Diff line change
Expand Up @@ -717,6 +717,5 @@ extension DoubleWidthUInt: UnsignedInteger where Base: FixedWidthInteger & Unsig
}
}

@usableFromInline typealias DWUInt128 = DoubleWidthUInt<UInt64>
@usableFromInline typealias QuadWidth<T: FixedWidthInteger & UnsignedInteger> = DoubleWidthUInt<DoubleWidthUInt<T>>
@usableFromInline typealias OctoWidth<T: FixedWidthInteger & UnsignedInteger> = DoubleWidthUInt<QuadWidth<T>>
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Get started using Swift Homomorphic Encryption.
Swift Homomorphic Encryption requires:
* 64-bit processor with little-endian memory representation
* macOS or Linux operating system
* [Swift](https://www.swift.org/) version 5.10 or later
* [Swift](https://www.swift.org/) version 6.0 or later

> Note: Swift Homomorphic Encryption relies on [SystemRandomNumberGenerator](https://developer.apple.com/documentation/swift/systemrandomnumbergenerator) as a cryptographically secure random number generator, which may have platform-dependent behavior.
Expand Down
6 changes: 3 additions & 3 deletions Sources/HomomorphicEncryption/PolyRq/PolyRq+Randomize.swift
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ extension PolyRq {
@inlinable
public mutating func randomizeUniform(using rng: inout some PseudoRandomNumberGenerator) {
let chunkCount = min(degree, 1024)
let uint128ByteCount = MemoryLayout<DWUInt128>.size
let uint128ByteCount = MemoryLayout<UInt128>.size
var randomBytes: [UInt8] = .init(repeating: 0, count: chunkCount * uint128ByteCount)
// We can sample directly in Coeff or Eval domain
for (rnsIndex, reduceModulus) in context.reduceModuliUInt64.enumerated() {
Expand All @@ -65,7 +65,7 @@ extension PolyRq {
for index in 0..<chunkCount {
// NOTE: for interoperability always ask rng for a UInt128 and reduces it
let u128 =
DWUInt128(littleEndianBytes: randomBytes[index * uint128ByteCount..<(index + 1) *
UInt128(littleEndianBytes: randomBytes[index * uint128ByteCount..<(index + 1) *
uint128ByteCount])
let u64 = reduceModulus.reduce(u128)
self[offset + index] = T(u64)
Expand Down Expand Up @@ -94,7 +94,7 @@ extension PolyRq {
// consumed for each coefficient.
let u64: UInt64 = rng.next()
let u32: UInt32 = rng.next()
let u128 = DWUInt128(u64) &<< 32 | DWUInt128(u32)
let u128 = UInt128(u64) &<< 32 | UInt128(u32)

let val = T(reductionModulus.reduce(u128))
for (index, modulus) in zip(rnsIndices(coeffIndex: coeffIndex), moduli) {
Expand Down
10 changes: 8 additions & 2 deletions Sources/HomomorphicEncryption/Random/NistCtrDrbg.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,23 @@ import Foundation
@usableFromInline
package struct NistCtrDrbg {
@usableFromInline static let ReseedInterval: Int64 = 1 << 48

@usableFromInline static let MaxByteCountPerRequest: Int = 1 << 16

/// Size of AES block.
@usableFromInline static let BlockCount: Int = 16

/// Size of AES key.
@usableFromInline static let KeyCount: Int = 16

/// Size of the seed.
@usableFromInline static let SeedCount: Int = KeyCount + BlockCount

@usableFromInline var key: SymmetricKey

/// This is called `V` in the NIST specification.
@usableFromInline var nonce: DWUInt128
@usableFromInline var nonce: UInt128

@usableFromInline var reseedCounter: Int64

@usableFromInline var nonceBytes: [UInt8] {
Expand Down Expand Up @@ -70,7 +76,7 @@ package struct NistCtrDrbg {

let zeroes = [UInt8](repeating: 0, count: requestedByteCount)
let output = try AES._CTR.encrypt(zeroes, using: key, nonce: .init(nonceBytes: nonceBytes))
nonce &+= DWUInt128(requestedByteCount.dividingCeil(Self.BlockCount, variableTime: true))
nonce &+= UInt128(requestedByteCount.dividingCeil(Self.BlockCount, variableTime: true))

let additionalInput = [UInt8](repeating: 0, count: Self.SeedCount)
try ctrDrbgUpdate(providedData: additionalInput)
Expand Down
27 changes: 2 additions & 25 deletions Sources/HomomorphicEncryption/Scalar.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,31 +22,8 @@ public protocol SignedScalarType: ModularArithmetic.CoreSignedScalarType, Codabl
extension UInt32: ScalarType {}
extension Int32: SignedScalarType {}

extension Int64: CoreSignedScalarType {}
extension Int64: SignedScalarType {
public typealias UnsignedScalar = UInt64
}

extension UInt64: CoreScalarType {}
extension UInt64: ScalarType {
public typealias DoubleWidth = DoubleWidthUInt<UInt64>
public typealias SignedScalar = Int64

public static var rnsCorrectionFactor: UInt64 {
// ~1000'th largest prime less than 2**62,
// but also NTT-unfriendly for all N
(Self(1) << 62) - 40797
}

public static var mTilde: UInt64 {
Self(1) << 32
}
}

extension DWUInt128: DoubleWidthType {
/// Single-width scalar, with bit-width half that of the ``DoubleWidthType``.
public typealias Scalar = UInt64
}
extension Int64: SignedScalarType {}
extension UInt64: ScalarType {}

extension FixedWidthInteger {
/// Big endian byte representation of this value.
Expand Down
15 changes: 0 additions & 15 deletions Sources/HomomorphicEncryption/Util.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,6 @@ extension Sequence where Element: Hashable {
}
}

// https://github.com/swiftlang/swift-evolution/blob/main/proposals/0220-count-where.md
// introduced in swift 6
#if swift(<6.0)
extension Sequence {
@inlinable
package func count(where predicate: (Element) throws -> Bool) rethrows -> Int {
var count = 0
for element in self where try predicate(element) {
count += 1
}
return count
}
}
#endif

extension FixedWidthInteger {
// not a constant time operation
@inlinable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ extension Message {
/// - Throws: Error upon failure to initialize message.
public init(from path: String) throws {
if path.hasSuffix(".txtpb") {
try self.init(textFormatString: String(contentsOfFile: path))
try self.init(textFormatString: String(contentsOfFile: path, encoding: .utf8))
} else {
let serializedData = try Data(contentsOf: URL(fileURLWithPath: path))
try self.init(serializedBytes: serializedData)
Expand Down
76 changes: 50 additions & 26 deletions Sources/ModularArithmetic/Scalar.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

/// Scalar type for ``PolyRq`` polynomial coefficients.
/// Scalar type.
public protocol CoreScalarType: FixedWidthInteger, UnsignedInteger, Sendable
where Self.Magnitude: Sendable
{
Expand Down Expand Up @@ -93,31 +93,7 @@ extension CoreSignedScalarType {
}
}

extension Int32: CoreSignedScalarType {
public typealias UnsignedScalar = UInt32
}

extension UInt64: DoubleWidthType {
/// Single-width scalar, with bit-width half that of the ``DoubleWidthType``.
public typealias Scalar = UInt32
}

extension UInt32: CoreScalarType {
public typealias DoubleWidth = UInt64
public typealias SignedScalar = Int32

public static var rnsCorrectionFactor: UInt32 {
// ~1000'th largest prime less than 2**30,
// but also NTT-unfriendly for N > 8
(Self(1) << 30) - 20405
}

public static var mTilde: UInt32 {
Self(1) << 16
}
}

/// Double-width scalar type which can hold a product of two ``ScalarType`` multiplicands.
/// Double-width scalar type which can hold a product of two ``CoreScalarType`` multiplicands.
public protocol DoubleWidthType: FixedWidthInteger, UnsignedInteger {
/// Single-width scalar, with bit-width half that of the ``DoubleWidthType``.
associatedtype Scalar: CoreScalarType
Expand Down Expand Up @@ -499,3 +475,51 @@ extension FixedWidthInteger {
return result
}
}

// MARK: Conformances

extension Int32: CoreSignedScalarType {
public typealias UnsignedScalar = UInt32
}

extension Int64: CoreSignedScalarType {
public typealias UnsignedScalar = UInt64
}

extension UInt64: DoubleWidthType {
public typealias Scalar = UInt32
}

extension UInt128: DoubleWidthType {
public typealias Scalar = UInt64
}

extension UInt32: CoreScalarType {
public typealias DoubleWidth = UInt64
public typealias SignedScalar = Int32

public static var rnsCorrectionFactor: UInt32 {
// ~1000'th largest prime less than 2**30,
// but also NTT-unfriendly for N > 8
(Self(1) << 30) - 20405
}

public static var mTilde: UInt32 {
Self(1) << 16
}
}

extension UInt64: CoreScalarType {
public typealias DoubleWidth = UInt128
public typealias SignedScalar = Int64

public static var rnsCorrectionFactor: UInt64 {
// ~1000'th largest prime less than 2**62,
// but also NTT-unfriendly for all N
(Self(1) << 62) - 40797
}

public static var mTilde: UInt64 {
Self(1) << 32
}
}
4 changes: 2 additions & 2 deletions Tests/HomomorphicEncryptionTests/Array2dTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class Array2dTests: XCTestCase {
runTest(Int32.self)
runTest(Int64.self)
runTest(UInt64.self)
runTest(DWUInt128.self)
runTest(UInt128.self)
}

func testZeroAndZeroize() {
Expand All @@ -54,7 +54,7 @@ class Array2dTests: XCTestCase {
runTest(Int32.self)
runTest(Int64.self)
runTest(UInt64.self)
runTest(DWUInt128.self)
runTest(UInt128.self)
}

func testShape() {
Expand Down

0 comments on commit 2c0df72

Please sign in to comment.