Skip to content

Commit

Permalink
[API BREAK] Remove recoverPublicKey from `K1.ECDSA.NonRecoverable.Sig…
Browse files Browse the repository at this point in the history
…nature` and remove an init from `K1.ECDSA.Recoverable.Signature` (#36)
  • Loading branch information
Sajjon committed Mar 29, 2023
1 parent 605923c commit a54a100
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 40 deletions.
24 changes: 0 additions & 24 deletions Sources/K1/K1/ECDSA/ECDSASignatureNonRecoverable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -85,30 +85,6 @@ extension K1.ECDSA.NonRecoverable.Signature {
}
}

// MARK: Recover
extension K1.ECDSA.NonRecoverable.Signature {
/// Recovers a public key from a `secp256k1` ECDSA signature, the message signed
/// and a `recoveryID`.
///
/// - Parameters:
/// - recoveryID: The recoveryID produced when a recoverable signature was produced.
/// - message: The message that was signed to produce this ECDSA signature.
/// - Returns: The public key which corresponds to the private key which used to produce this
/// signature by signing the `message`.
public func recoverPublicKey(
recoveryID: K1.ECDSA.Recoverable.Signature.RecoveryID,
message: some DataProtocol
) throws -> K1.ECDSA.NonRecoverable.PublicKey {
let wrapped = try FFI.ECDSA.NonRecoverable.recoverPublicKey(
self.wrapped,
recoveryID: recoveryID.recid,
message: [UInt8](message)
)
let impl = K1._PublicKeyImplementation(wrapped: wrapped)
return K1.ECDSA.NonRecoverable.PublicKey(impl: impl)
}
}

extension K1.ECDSA.NonRecoverable.Signature {
internal static let byteCount = FFI.ECDSA.Recoverable.byteCount
}
Expand Down
29 changes: 20 additions & 9 deletions Sources/K1/K1/ECDSA/ECDSASignatureRecoverable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,6 @@ extension K1.ECDSA.Recoverable.Signature {
)
}

/// Compact aka `IEEE P1363` aka `R||S`.
public init(compact: Data, recoveryID: RecoveryID) throws {
try self.init(compact: .init(compact: compact, recoveryID: recoveryID))
}

init(
internalRepresentation: some DataProtocol
) throws {
Expand All @@ -63,7 +58,7 @@ extension K1.ECDSA.Recoverable.Signature {
Data(wrapped.bytes)
}

/// Compact aka `IEEE P1363` aka `R||S` with `RecoveryID`
/// Compact aka `IEEE P1363` aka `R||S` and `V` (`RecoveryID`).
public func compact() throws -> Compact {
let (rs, recid) = try FFI.ECDSA.Recoverable.serializeCompact(
wrapped
Expand All @@ -74,7 +69,9 @@ extension K1.ECDSA.Recoverable.Signature {
)
}

/// A tuple of `R||S` and `recoveryID` from a recoverable ECDSA signature.
/// A tuple of `R||S` and `V` (`RecoveryID`) from a recoverable ECDSA signature.
///
/// Can be serialized into data using `serialize:format` method.
public struct Compact: Sendable, Hashable {
/// Compact aka `IEEE P1363` aka `R||S`.
public let compact: Data
Expand All @@ -99,7 +96,10 @@ extension K1.ECDSA.Recoverable.Signature.Compact {
public static let byteCountRS = 2 * Curve.Field.byteCount
public static let byteCount = Self.byteCountRS + 1

/// Takes either `R || S || V` data or `V || R || S` data, as per specification of `format`.
/// Creates a compact recoverable ECDSA signature from a `rawRepresentation` on `format`,
/// either `R || S || V` or `V || R || S`.
///
/// You can initialize a `K1.ECDSA.Recoverable.Signature` by using the `init:compact` initializer.
public init(
rawRepresentation: some DataProtocol,
format: SerializationFormat
Expand All @@ -121,6 +121,11 @@ extension K1.ECDSA.Recoverable.Signature.Compact {
}
}

/// A serialization format of a `K1.ECDSA.Recoverable.Signature.Compact`, use to
/// deserialize data into such a type, or used to serialize from that type into data.
///
/// Controls the order of the three components `R`, `S` and `V` (`RecoveryID`), specifyin
/// either `R || S || V` called `.rsv` or `V || R || S` called `vrs`.
public enum SerializationFormat {
/// `R || S || V` - the format `libsecp256k1` v0.3.0 uses as internal representation
/// This is the default value of this library.
Expand All @@ -141,7 +146,13 @@ extension K1.ECDSA.Recoverable.Signature.Compact {
compact
}

func serialize(format: SerializationFormat) -> Data {
/// Serializes this compact recoverable ECDSA signature to Data on either `rsv` or `vsr` according to `format`
///
/// Returns 65 bytes on either format `R || S || V` or `V || R || S`.
///
/// - Parameter format: Specified of order of `R`, `S` and `RecoveryID` (`V`), either `R || S || V` or `V || R || S`.
/// - Returns: Serialized data representation of the signature.
public func serialize(format: SerializationFormat) -> Data {
switch format {
case .rsv:
return rs + v
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ final class ECDASignaturePublicKeyRecoveryTests: XCTestCase {
XCTAssertEqual(compactRecoverableSig.recoveryID, recid)

let compactRecoverableSigRS = try Data(hex: compactRecoverableSigRSHex)
try XCTAssertEqual(K1.ECDSA.Recoverable.Signature(compact: compactRecoverableSigRS, recoveryID: recid), K1.ECDSA.Recoverable.Signature(compact: compactRecoverableSig))
try XCTAssertEqual(K1.ECDSA.Recoverable.Signature(compact: .init(compact: compactRecoverableSigRS, recoveryID: recid)), K1.ECDSA.Recoverable.Signature(compact: compactRecoverableSig))
try XCTAssertEqual(K1.ECDSA.Recoverable.Signature.Compact(compact: compactRecoverableSigRS, recoveryID: recid), compactRecoverableSig)

let nonRecoverable = try K1.ECDSA.NonRecoverable.Signature(rawRepresentation: compactRecoverableSig.compact)
Expand Down Expand Up @@ -89,12 +89,6 @@ private extension ECDASignaturePublicKeyRecoveryTests {

XCTAssertTrue(recoveredPublicKey.isValidSignature(recoverableSig, hashed: hashedMessage))

let recoveredWithID = try recoverableSig.nonRecoverable().recoverPublicKey(
recoveryID: vector.recoveryID,
message: hashedMessage
)
try XCTAssertEqual(expectedPublicKey, .init(x963Representation: recoveredWithID.x963Representation))

numberOfTestsRun += 1
}
return .init(numberOfTestsRun: numberOfTestsRun, idsOmittedTests: [])
Expand Down

0 comments on commit a54a100

Please sign in to comment.