Skip to content

Commit

Permalink
Fix point at infinity verification in signature and public key
Browse files Browse the repository at this point in the history
  • Loading branch information
massaru-stark committed Nov 10, 2021
1 parent cd9d70f commit b75aac4
Show file tree
Hide file tree
Showing 6 changed files with 45 additions and 8 deletions.
11 changes: 10 additions & 1 deletion Sources/starkbank-ecdsa/Curve.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,16 @@ public class CurveFp {
- Returns: boolean
*/
func contains(p: Point) -> Bool {
return (p.y.power(2) - (p.x.power(3) + self.A * p.x + self.B)) % self.P == 0
if (p.x < 0 || p.x >= self.P) {
return false
}
if (p.y < 0 || p.y >= self.P) {
return false
}
if ((p.y.power(2) - (p.x.power(3) + self.A * p.x + self.B)) % self.P != 0) {
return false
}
return true
}

func length() -> Int {
Expand Down
8 changes: 5 additions & 3 deletions Sources/starkbank-ecdsa/Ecdsa.swift
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,10 @@ public class Ecdsa {
let inv = Math.inv(s, curve.N)
let u1 = Math.multiply(curve.G, (numberMessage * inv).modulus(curve.N), curve.N, curve.A, curve.P)
let u2 = Math.multiply(publicKey.point, (r * inv).modulus(curve.N), curve.N, curve.A, curve.P)
let add = Math.add(u1, u2, curve.A, curve.P)
let modX = add.x.modulus(curve.N)
return r == modX
let v = Math.add(u1, u2, curve.A, curve.P)
if (v.isAtInfinity()) {
return false
}
return v.x.modulus(curve.N) == r
}
}
4 changes: 4 additions & 0 deletions Sources/starkbank-ecdsa/Point.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,8 @@ public class Point {
self.y = y
self.z = z
}

func isAtInfinity() -> Bool {
return self.y == BigInt(0)
}
}
21 changes: 17 additions & 4 deletions Sources/starkbank-ecdsa/PublicKey.swift
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,26 @@ public class PublicKey {

let point = Point(BinaryAscii.intFromHex(xs), BinaryAscii.intFromHex(ys))

if (validatePoint && !curve.contains(p: point)) {
let publicKey = PublicKey(point: point, curve: curve)
if (!validatePoint) {
return publicKey
}
if (point.isAtInfinity()) {
throw Error.infinityError("Public Key point is at infinity")
}
if (!curve.contains(p: point)) {
throw Error.pointError("Point ({x},{y}) is not valid for curve {name}"
.replacingOccurrences(of: "{x}", with: String(point.x))
.replacingOccurrences(of:"{y}", with: String(point.y))
.replacingOccurrences(of:"{name}", with: curve.name))
.replacingOccurrences(of: "{y}", with: String(point.y))
.replacingOccurrences(of: "{name}", with: curve.name))
}
if (!Math.multiply(point, curve.N, curve.N, curve.A, curve.P).isAtInfinity()) {
throw Error.pointError("Point ({x},{y}) * {name}.N is not at infinity"
.replacingOccurrences(of: "{x}", with: String(point.x))
.replacingOccurrences(of: "{y}", with: String(point.y))
.replacingOccurrences(of: "{name}", with: curve.name))
}
return PublicKey(point: point, curve: curve)
return publicKey
}
}

Expand Down
1 change: 1 addition & 0 deletions Sources/starkbank-ecdsa/Utils/Error.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@ enum Error: Swift.Error {
case pointError(String)
case generationError(String)
case invalidPath(String)
case infinityError(String)
}
8 changes: 8 additions & 0 deletions Tests/starkbank-ecdsaTests/EcdsaTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,12 @@ class EcdsaTests: XCTestCase {

XCTAssertFalse(Ecdsa.verify(message: message2, signature: signature, publicKey: publicKey))
}

func testSignatureZero() throws {
let privateKey = try PrivateKey()
let publicKey = privateKey.publicKey()
let message = "This is a text message"

XCTAssertFalse(Ecdsa.verify(message: message, signature: Signature(0, 0), publicKey: publicKey))
}
}

0 comments on commit b75aac4

Please sign in to comment.