Skip to content

Commit

Permalink
Update project for Swift 4
Browse files Browse the repository at this point in the history
  • Loading branch information
FabioTacke committed Nov 8, 2017
1 parent a5e3e6d commit 0c52fd3
Show file tree
Hide file tree
Showing 14 changed files with 67 additions and 42 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ playground.xcworkspace
# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
Packages/
Package.pins
Package.resolved
.build/

# CocoaPods
Expand Down
1 change: 1 addition & 0 deletions .swift-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
4.0.2
5 changes: 3 additions & 2 deletions PVSS.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'PVSS'
s.version = '2.0.0'
s.version = '2.1.0'
s.summary = 'An implementation of Publicly Verifiably Secret Sharing (PVSS) in Swift.'
s.description = <<-DESC
The library implements a PVSS scheme in Swift. The algorithm is based on "A Simple Publicly Verifiable Secret Sharing Scheme and its Application to Electronic Voting" by Berry Schoenmakers.
Expand All @@ -12,7 +12,8 @@ The library implements a PVSS scheme in Swift. The algorithm is based on "A Simp
s.source = { :git => 'https://github.com/FabioTacke/PubliclyVerifiableSecretSharing.git', :tag => 'v' + String(s.version) }
s.social_media_url = 'https://twitter.com/FabioTacke'

s.source_files = 'Sources/*.swift'
s.source_files = 'Sources/PVSS/*.swift'

s.dependency 'BigInt'
s.dependency 'CryptoSwift'

Expand Down
21 changes: 17 additions & 4 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -1,12 +1,25 @@
// swift-tools-version:3.1
// swift-tools-version:4.0

import PackageDescription

let package = Package(
name: "PVSS",
products: [
.library(
name: "PVSS",
targets: ["PVSS"]),
],
dependencies: [
.Package(url: "https://github.com/lorentey/BigInt.git", majorVersion: 2, minor: 1),
.Package(url: "https://github.com/krzyzanowskim/CryptoSwift.git", majorVersion: 0),
.Package(url: "https://github.com/mdaxter/BignumGMP.git", majorVersion: 1),
.package(url: "https://github.com/attaswift/BigInt.git", .branch("master")),
.package(url: "https://github.com/krzyzanowskim/CryptoSwift.git", .branch("master")),
.package(url: "https://github.com/mdaxter/BignumGMP.git", .branch("master")),
],
targets: [
.target(
name: "PVSS",
dependencies: ["BigInt", "Bignum", "CryptoSwift"]),
.testTarget(
name: "PVSSTests",
dependencies: ["PVSS"]),
]
)
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Thus PVSS can be used to share a secret among a group of participants so that ei
## Build settings
Since version 2.0.0 PVSS uses GMP for speeding up the calculations. If you don't have GMP installed there's a compiled GMP library version 6.1.2 included. However you need to provide the compiler and the linker with the information where to find the GMP header file and the library. Example:

`swift [build | test] -Xcc -Lgmp/include -Xlinker -Lgmp/lib`
`swift [build | test] -Xcc -Igmp/include -Xlinker -Lgmp/lib`

You can replace those paths if you already have GMP installed.

Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
39 changes: 20 additions & 19 deletions Sources/PVSSInstance.swift → Sources/PVSS/PVSSInstance.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ public struct PVSSInstance {
repeat {
q -= 2
} while !q.isPrime()
sophieGermainCandidate = (q-1).divided(by: 2).quotient
sophieGermainCandidate = (q-1).quotientAndRemainder(dividingBy: 2).quotient
// sophieGermainCandidate = (q-1).divided(by: 2).quotient
} while !sophieGermainCandidate.isPrime()

let qConverted = Bignum(q.description)
Expand All @@ -55,7 +56,7 @@ public struct PVSSInstance {
/// Initializes a PVSSInstance with default parameters. `q` is a safe prime of length 2048 bit (RFC3526). `2` and the corresponding sophie germain prime are generators.
public init() {
let q = BigUInt(stringLiteral: "32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559")
let g = Bignum((q-1).divided(by: 2).quotient.description)
let g = Bignum((q-1).quotientAndRemainder(dividingBy: 2).quotient.description)
let G = Bignum(2)
let length = 2048

Expand All @@ -66,11 +67,11 @@ public struct PVSSInstance {

public func generatePrivateKey() -> Bignum {
let q = BigUInt(self.q.description)!
var key = BigUInt.randomIntegerLessThan(q)
var key = BigUInt.randomInteger(lessThan: q)

// We need the private key and q-1 to be coprime so that we can calculate 1/key mod (q-1) during secret reconstruction.
while BigUInt.gcd(key, q - 1) != 1 {
key = BigUInt.randomIntegerLessThan(q)
while key.greatestCommonDivisor(with: q - 1) != 1 {
key = BigUInt.randomInteger(lessThan: q)
}
return Bignum(key.description)
}
Expand Down Expand Up @@ -106,10 +107,10 @@ public struct PVSSInstance {
let a2 = (mod_exp(key, response, q) * mod_exp(share, distributionBundle.challenge, q)) % q

// Update hash
let _ = try! digest.update(withBytes: x.description.data(using: .utf8)!)
let _ = try! digest.update(withBytes: share.description.data(using: .utf8)!)
let _ = try! digest.update(withBytes: a1.description.data(using: .utf8)!)
let _ = try! digest.update(withBytes: a2.description.data(using: .utf8)!)
let _ = try! digest.update(withBytes: Array(x.description.data(using: .utf8)!))
let _ = try! digest.update(withBytes: Array(share.description.data(using: .utf8)!))
let _ = try! digest.update(withBytes: Array(a1.description.data(using: .utf8)!))
let _ = try! digest.update(withBytes: Array(a2.description.data(using: .utf8)!))
}

// Calculate challenge
Expand Down Expand Up @@ -146,10 +147,10 @@ public struct PVSSInstance {
let a1 = (mod_exp(G, shareBundle.response, q) * mod_exp(shareBundle.publicKey, shareBundle.challenge, q)) % q
let a2 = (mod_exp(shareBundle.share, shareBundle.response, q) * mod_exp(encryptedShare, shareBundle.challenge, q)) % q

let _ = try! digest.update(withBytes: shareBundle.publicKey.description.data(using: .utf8)!)
let _ = try! digest.update(withBytes: encryptedShare.description.data(using: .utf8)!)
let _ = try! digest.update(withBytes: a1.description.data(using: .utf8)!)
let _ = try! digest.update(withBytes: a2.description.data(using: .utf8)!)
let _ = try! digest.update(withBytes: Array(shareBundle.publicKey.description.data(using: .utf8)!))
let _ = try! digest.update(withBytes: Array(encryptedShare.description.data(using: .utf8)!))
let _ = try! digest.update(withBytes: Array(a1.description.data(using: .utf8)!))
let _ = try! digest.update(withBytes: Array(a2.description.data(using: .utf8)!))

let challengeHash = try! digest.finish().toHexString()
let challengeInt = Bignum(hex: challengeHash) % (q-1)
Expand Down Expand Up @@ -200,9 +201,9 @@ public struct PVSSInstance {
// Cancel fraction if possible
var numerator = BigUInt(lagrangeCoefficient.numerator.description)!
var denominator = BigUInt(lagrangeCoefficient.denominator.abs.description)!
let gcd = BigUInt.gcd(numerator, denominator)
numerator = numerator.divided(by: gcd).quotient
denominator = denominator.divided(by: gcd).quotient
let gcd = numerator.greatestCommonDivisor(with: denominator)
numerator = numerator.quotientAndRemainder(dividingBy: gcd).quotient
denominator = denominator.quotientAndRemainder(dividingBy: gcd).quotient

let q1 = BigUInt((self.q - 1).description)!
if let inverseDenominator = denominator.inverse(q1) {
Expand Down Expand Up @@ -271,9 +272,9 @@ public struct PVSSInstance {
// Cancel fraction if possible
var numerator = BigUInt(lagrangeCoefficient.numerator.description)!
var denominator = BigUInt(lagrangeCoefficient.denominator.abs.description)!
let gcd = BigUInt.gcd(numerator, denominator)
numerator = numerator.divided(by: gcd).quotient
denominator = denominator.divided(by: gcd).quotient
let gcd = numerator.greatestCommonDivisor(with: denominator)
numerator = numerator.quotientAndRemainder(dividingBy: gcd).quotient
denominator = denominator.quotientAndRemainder(dividingBy: gcd).quotient

let q1 = BigUInt((self.q - 1).description)!
if let inverseDenominator = denominator.inverse(q1) {
Expand Down
18 changes: 9 additions & 9 deletions Sources/Participant.swift → Sources/PVSS/Participant.swift
Original file line number Diff line number Diff line change
Expand Up @@ -93,10 +93,10 @@ public class Participant {
a[key] = (dleq.a1, dleq.a2)

// Update challenge hash
let _ = try! challenge.update(withBytes: x.description.data(using: .utf8)!)
let _ = try! challenge.update(withBytes: share.description.data(using: .utf8)!)
let _ = try! challenge.update(withBytes: dleq.a1.description.data(using: .utf8)!)
let _ = try! challenge.update(withBytes: dleq.a2.description.data(using: .utf8)!)
let _ = try! challenge.update(withBytes: Array(x.description.data(using: .utf8)!))
let _ = try! challenge.update(withBytes: Array(share.description.data(using: .utf8)!))
let _ = try! challenge.update(withBytes: Array(dleq.a1.description.data(using: .utf8)!))
let _ = try! challenge.update(withBytes: Array(dleq.a2.description.data(using: .utf8)!))

position += 1
}
Expand Down Expand Up @@ -134,7 +134,7 @@ public class Participant {
/// - Returns: The distribution bundle that is published so everyone (especially but not only the participants) can check the shares' integrity. Furthermore the participants extract their shares from it.
public func distribute(secret: Bignum, publicKeys: [Bignum], threshold: Int) -> DistributionBundle {
let polynomial = Polynomial(degree: threshold - 1, bitLength: pvssInstance.length, q: pvssInstance.q)
let w = Bignum((BigUInt.randomIntegerLessThan(BigUInt((pvssInstance.q).description)!)).description)
let w = Bignum((BigUInt.randomInteger(lessThan: BigUInt((pvssInstance.q).description)!)).description)
return distribute(secret: secret, publicKeys: publicKeys, threshold: threshold, polynomial: polynomial, w: w)
}

Expand All @@ -155,10 +155,10 @@ public class Participant {

var dleq = DLEQ(g1: pvssInstance.G, h1: publicKey, g2: share, h2: encryptedShare, length: pvssInstance.length, q: pvssInstance.q, alpha: privateKey, w: w)
var digest = SHA2(variant: .sha256)
let _ = try! digest.update(withBytes: publicKey.description.data(using: .utf8)!)
let _ = try! digest.update(withBytes: encryptedShare.description.data(using: .utf8)!)
let _ = try! digest.update(withBytes: dleq.a1.description.data(using: .utf8)!)
let _ = try! digest.update(withBytes: dleq.a2.description.data(using: .utf8)!)
let _ = try! digest.update(withBytes: Array(publicKey.description.data(using: .utf8)!))
let _ = try! digest.update(withBytes: Array(encryptedShare.description.data(using: .utf8)!))
let _ = try! digest.update(withBytes: Array(dleq.a1.description.data(using: .utf8)!))
let _ = try! digest.update(withBytes: Array(dleq.a2.description.data(using: .utf8)!))
let challengeHash = try! digest.finish().toHexString()
let challengeInt = Bignum(hex: challengeHash) % (pvssInstance.q - 1)

Expand Down
2 changes: 1 addition & 1 deletion Sources/Polynomial.swift → Sources/PVSS/Polynomial.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public struct Polynomial {

for _ in 0...degree {
let threshold = BigUInt(q.description)!
coefficientList.append(Bignum(BigUInt.randomIntegerLessThan(threshold).description))
coefficientList.append(Bignum(BigUInt.randomInteger(lessThan: threshold).description))
}

self.init(coefficients: coefficientList)
Expand Down
4 changes: 2 additions & 2 deletions Tests/PVSSTests/MathFunctionsTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,8 @@ class MathFunctionsTest: XCTestCase {
let value2: Bignum = Bignum("14735247304952934566")

var digest = SHA2(variant: .sha256)
let _ = try! digest.update(withBytes: value1.description.data(using: .utf8)!)
let _ = try! digest.update(withBytes: value2.description.data(using: .utf8)!)
let _ = try! digest.update(withBytes: Array(value1.description.data(using: .utf8)!))
let _ = try! digest.update(withBytes: Array(value2.description.data(using: .utf8)!))
let result = try! digest.finish()

XCTAssertEqual(result.toHexString(), "e25e5b7edf4ea66e5238393fb4f183e0fc1593c69a522f9255a51bd0bc2b7ba7")
Expand Down
16 changes: 12 additions & 4 deletions Tests/PVSSTests/PVSSTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ public class PVSSTest: XCTestCase {

XCTAssert(BigUInt((pvss.q).description)!.isPrime())
XCTAssert(BigUInt((pvss.g).description)!.isPrime())
XCTAssertEqual(pvss.g, Bignum((BigUInt((pvss.q-1).description)!.divided(by: 2).quotient).description))
XCTAssertEqual(pvss.g, Bignum((BigUInt((pvss.q-1).description)!.quotientAndRemainder(dividingBy: 2).quotient).description))
}

public func testDistribution() {
Expand Down Expand Up @@ -147,7 +147,8 @@ public class PVSSTest: XCTestCase {
public func testParallelReconstructionPerformance() {
let pvss = PVSSInstance()
let dealer = Participant(pvssInstance: pvss)
let keyCount = 20
let keyCount = 75
let threshold = keyCount / 2
let keyPairs: [(privateKey: Bignum, publicKey: Bignum)] = pvssKeyPairs.reduce([]) { (previouskeyPairs, keyPair) in
var keyPairs = previouskeyPairs
if keyPairs.count < keyCount {
Expand All @@ -156,11 +157,18 @@ public class PVSSTest: XCTestCase {
return keyPairs
}
let secret = Bignum(BigUInt.randomInteger(withExactWidth: 512).description)
let distributionBundle = dealer.distribute(secret: secret, publicKeys: keyPairs.map {$0.publicKey} , threshold: keyCount)
let distributionBundle = dealer.distribute(secret: secret, publicKeys: keyPairs.map {$0.publicKey} , threshold: threshold)
let participants: [Participant] = keyPairs.map { Participant(pvssInstance: pvss, privateKey: $0.privateKey, publicKey: $0.publicKey) }
let shareBundles = participants.map { $0.extractShare(distributionBundle: distributionBundle, privateKey: $0.privateKey)! }
let reconstructionShareBundles: [ShareBundle] = shareBundles.reduce([]) { (previousShareBundles, shareBundle) in
var shareBundles = previousShareBundles
if shareBundles.count < threshold {
shareBundles.append(shareBundle)
}
return shareBundles
}
measure {
let _ = pvss.reconstructParallelized(shareBundles: shareBundles, distributionBundle: distributionBundle)
let _ = pvss.reconstructParallelized(shareBundles: reconstructionShareBundles, distributionBundle: distributionBundle, threads: 2)
}
}

Expand Down

0 comments on commit 0c52fd3

Please sign in to comment.