Skip to content

Commit

Permalink
Cleanup of API of errors (#29)
Browse files Browse the repository at this point in the history
  • Loading branch information
Sajjon committed Mar 26, 2023
1 parent 4305158 commit aaa0ae0
Show file tree
Hide file tree
Showing 22 changed files with 227 additions and 130 deletions.
2 changes: 1 addition & 1 deletion Sources/K1/K1/ECDSA/ECDSA.swift
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ extension K1.ECDSA.SigningOptions.NonceFunction {
public static let byteCount = Curve.Field.byteCount
public init(arbitraryData: [UInt8]) throws {
guard arbitraryData.count == Self.byteCount else {
throw K1.Error.incorrectByteCountOfArbitraryDataForNonceFunction
throw K1.Error.incorrectParameterSize
}
self.arbitraryData = arbitraryData
}
Expand Down
7 changes: 2 additions & 5 deletions Sources/K1/K1/ECDSA/ECDSASignatureRecoverable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,7 @@ extension K1.ECDSA.Recoverable.Signature {
recoveryID: RecoveryID
) throws {
guard compact.count == Self.byteCountRS else {
throw K1.Error.failedToDeserializeCompactRSRecoverableSignatureInvalidByteCount(
got: compact.count,
expected: Self.byteCountRS
)
throw K1.Error.incorrectKeySize
}
self.compact = compact
self.recoveryID = recoveryID
Expand All @@ -108,7 +105,7 @@ extension K1.ECDSA.Recoverable.Signature.Compact {
format: SerializationFormat
) throws {
guard rawRepresentation.count == Self.byteCount else {
throw K1.Error.failedToDeserializeCompactRecoverableSignatureInvalidByteCount(got: rawRepresentation.count, expected: Self.byteCount)
throw K1.Error.incorrectKeySize
}
switch format {
case .vrs:
Expand Down
4 changes: 2 additions & 2 deletions Sources/K1/K1/ECDSA/RecoveryID.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@ extension K1.ECDSA.Recoverable.Signature {
extension K1.ECDSA.Recoverable.Signature.RecoveryID {
public init(byte: UInt8) throws {
guard let self_ = Self(rawValue: byte) else {
throw K1.Error.invalidRecoveryID(got: Int(byte))
throw K1.Error.invalidParameter
}
self = self_
}

public init(recid: Int32) throws {
guard recid <= 3, recid >= 0 else {
throw K1.Error.invalidRecoveryID(got: Int(recid))
throw K1.Error.invalidParameter
}
try self.init(byte: UInt8(recid))
}
Expand Down
6 changes: 3 additions & 3 deletions Sources/K1/K1/Keys/PrivateKeyImplementation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ extension K1._PrivateKeyImplementation {
let parsed = try ASN1.PKCS8PrivateKey(asn1Encoded: Array(pem.derBytes))
self = try .init(rawRepresentation: parsed.privateKey.privateKey)
default:
throw K1.Error.invalidPEMDocument
throw K1.ASN1Error.invalidPEMDocument
}
}

Expand All @@ -73,15 +73,15 @@ extension K1._PrivateKeyImplementation {
) throws {
let length = x963Representation.withUnsafeBytes { $0.count }
guard length == Self.x963ByteCount else {
throw K1.Error.incorrectByteCountOfX963PrivateKey(got: length, expected: Self.x963ByteCount)
throw K1.Error.incorrectKeySize
}

let publicKeyX963 = x963Representation.bytes.prefix(K1._PublicKeyImplementation.x963ByteCount)
let publicKeyFromX963 = try K1._PublicKeyImplementation(x963Representation: publicKeyX963)
let privateKeyRaw = x963Representation.bytes.suffix(Self.rawByteCount)
try self.init(rawRepresentation: privateKeyRaw)
guard self.publicKey == publicKeyFromX963 else {
throw K1.Error.invalidPrivateX963RepresentationPublicKeyDiscrepancy
throw K1.Error.invalidKey
}
// All good
}
Expand Down
2 changes: 1 addition & 1 deletion Sources/K1/K1/Keys/PublicKeyImplementation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ extension K1._PublicKeyImplementation {
init(pemRepresentation: String) throws {
let pem = try ASN1.PEMDocument(pemString: pemRepresentation)
guard pem.type == Self.pemType else {
throw K1.Error.invalidPEMDocument
throw K1.ASN1Error.invalidPEMDocument
}
self = try .init(derRepresentation: pem.derBytes)
}
Expand Down
2 changes: 1 addition & 1 deletion Sources/K1/K1/Schnorr/Schnorr.swift
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ extension K1.Schnorr.SigningOptions.AuxiliaryRandomData {
public static let byteCount = Curve.Field.byteCount
public init(aux: some DataProtocol) throws {
guard aux.count == Self.byteCount else {
throw K1.Error.failedToSchnorrSignDigestProvidedRandomnessInvalidLength
throw K1.Error.incorrectParameterSize
}
self.aux = [UInt8](aux)
}
Expand Down
2 changes: 1 addition & 1 deletion Sources/K1/Support/FFI/API/ECDH/FFI+ECDH.swift
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ extension FFI.ECDH {
}()
var publicKeyRaw = publicKey.raw
try FFI.call(
ifFailThrow: .failedToPerformDiffieHellmanKeyExchange
ifFailThrow: .ecdh
) { context in
secp256k1_ecdh(
context,
Expand Down
7 changes: 2 additions & 5 deletions Sources/K1/Support/FFI/API/ECDSA/FFI+ECDSA.swift
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,13 @@ extension FFI.ECDSA {
options: K1.ECDSA.SigningOptions = .default
) throws -> WrappedSignature where WrappedSignature: WrappedECDSASignature {
guard message.count == Curve.Field.byteCount else {
throw K1.Error.unableToSignMessageHasInvalidLength(
got: message.count,
expected: Curve.Field.byteCount
)
throw K1.Error.incorrectParameterSize
}

var raw = WrappedSignature.Raw()

try FFI.call(
ifFailThrow: .failedToECDSASignDigest
ifFailThrow: .ecdsaSign
) { context in
WrappedSignature.sign()(
context,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,12 @@ extension FFI.ECDSA.NonRecoverable {
static func compact(_ wrapped: Wrapped) throws -> Data {
var out = [UInt8](repeating: 0, count: Self.byteCount)
var rawSignature = wrapped.raw
try FFI.call(ifFailThrow: .failedToSerializeSignature) { context in
secp256k1_ecdsa_signature_serialize_compact(context, &out, &rawSignature)
try FFI.call(ifFailThrow: .ecdsaSignatureSerializeCompact) { context in
secp256k1_ecdsa_signature_serialize_compact(
context,
&out,
&rawSignature
)
}
return Data(out)
}
Expand All @@ -40,7 +44,7 @@ extension FFI.ECDSA.NonRecoverable {
var derMaxLength = 75 // in fact max is 73, but we can have some margin.
var derSignature = [UInt8](repeating: 0, count: derMaxLength)
var rawSignature = wrapped.raw
try FFI.call(ifFailThrow: .failedToSerializeDERSignature) { context in
try FFI.call(ifFailThrow: .ecdsaSignatureSerializeDER) { context in
secp256k1_ecdsa_signature_serialize_der(
context,
&derSignature,
Expand All @@ -60,7 +64,7 @@ extension FFI.ECDSA.NonRecoverable {
message: [UInt8]
) throws -> FFI.PublicKey.Wrapped {
guard message.count == Curve.Field.byteCount else {
throw K1.Error.unableToRecoverMessageHasInvalidLength(got: message.count, expected: Curve.Field.byteCount)
throw K1.Error.incorrectParameterSize
}
let nonRecoverableCompact = try FFI.ECDSA.NonRecoverable.compact(wrapped)
return try Self.recoverPublicKey(
Expand All @@ -76,14 +80,11 @@ extension FFI.ECDSA.NonRecoverable {
message: [UInt8]
) throws -> FFI.PublicKey.Wrapped {
guard message.count == Curve.Field.byteCount else {
throw K1.Error.unableToRecoverMessageHasInvalidLength(
got: message.count,
expected: Curve.Field.byteCount
)
throw K1.Error.incorrectParameterSize
}
var compact = [UInt8](nonRecoverableCompact)
var recoverable = secp256k1_ecdsa_recoverable_signature()
try FFI.call(ifFailThrow: .failedToParseRecoverableSignatureFromCompact) { context in
try FFI.call(ifFailThrow: .recoverableSignatureParseCompact) { context in
secp256k1_ecdsa_recoverable_signature_parse_compact(
context,
&recoverable,
Expand All @@ -92,7 +93,7 @@ extension FFI.ECDSA.NonRecoverable {
)
}
var publicKeyRaw = secp256k1_pubkey()
try FFI.call(ifFailThrow: .failedToRecoverPublicKey) { context in
try FFI.call(ifFailThrow: .recover) { context in
secp256k1_ecdsa_recover(
context,
&publicKeyRaw,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ extension FFI.ECDSA.Recoverable {
) throws -> Wrapped {
var raw = Wrapped.Raw()
try FFI.call(
ifFailThrow: .failedSignatureToConvertRecoverableSignatureToCompact
ifFailThrow: .recoverableSignatureParseCompact
) { context in
secp256k1_ecdsa_recoverable_signature_parse_compact(
context,
Expand All @@ -40,7 +40,7 @@ extension FFI.ECDSA.Recoverable {
var recoveryID: Int32 = 0
var rawSignature = wrapped.raw
try FFI.call(
ifFailThrow: .failedSignatureToConvertRecoverableSignatureToCompact
ifFailThrow: .recoverableSignatureSerializeCompact
) { context in
secp256k1_ecdsa_recoverable_signature_serialize_compact(
context,
Expand All @@ -62,7 +62,7 @@ extension FFI.ECDSA.Recoverable {
var recoverable = wrapped.raw

try FFI.call(
ifFailThrow: .failedToConvertRecoverableSignatureToNonRecoverable
ifFailThrow: .recoverableSignatureConvert
) { context in
secp256k1_ecdsa_recoverable_signature_convert(
context,
Expand All @@ -82,12 +82,12 @@ extension FFI.ECDSA.Recoverable {
message: [UInt8]
) throws -> FFI.PublicKey.Wrapped {
guard message.count == Curve.Field.byteCount else {
throw K1.Error.unableToRecoverMessageHasInvalidLength(got: message.count, expected: Curve.Field.byteCount)
throw K1.Error.incorrectParameterSize
}
var rawSignature = wrapped.raw
var rawPublicKey = secp256k1_pubkey()
try FFI.call(
ifFailThrow: .failedToRecoverPublicKey
ifFailThrow: .recover
) { context in
secp256k1_ecdsa_recover(
context,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,24 @@ extension FFI {

fileprivate init(secureBytes: SecureBytes) throws {
guard secureBytes.count == Curve.Field.byteCount else {
throw K1.Error.failedToInitializePrivateKeyIncorrectByteCount(
got: secureBytes.count,
expected: Curve.Field.byteCount
)
throw K1.Error.incorrectKeySize
}

if secureBytes.allSatisfy({ $0 == .zero }) {
throw K1.Error.invalidPrivateKeyMustNotBeZero
throw K1.Error.invalidKey
}

self.secureBytes = secureBytes
var secureBytes = secureBytes
self.publicKey = try secureBytes.withUnsafeMutableBytes { seckey in
var raw = secp256k1_pubkey()

try FFI.call(ifFailThrow: .invalidPrivateKeyMustBeSmallerThanOrder) { context in
secp256k1_ec_pubkey_create(context, &raw, seckey.baseAddress!)
try FFI.call(ifFailThrow: .publicKeyCreate) { context in
secp256k1_ec_pubkey_create(
context,
&raw,
seckey.baseAddress!
)
}

return FFI.PublicKey.Wrapped(raw: raw)
Expand Down
17 changes: 6 additions & 11 deletions Sources/K1/Support/FFI/API/Keys/PublicKey/FFI+PublicKey.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ extension FFI.PublicKey {
try contiguousBytes.withUnsafeBytes { bufferPointer throws -> Wrapped in
let expected = Self.x963ByteCount
guard bufferPointer.count == expected else {
throw K1.Error.incorrectByteCountOfX963PublicKey(got: bufferPointer.count, expected: expected)
throw K1.Error.incorrectKeySize
}
return try Self._deserialize(bytes: [UInt8](bufferPointer))
}
Expand All @@ -32,14 +32,9 @@ extension FFI.PublicKey {
try contiguousBytes.withUnsafeBytes { bufferPointer throws -> Wrapped in
let expected = Self.rawByteCount
guard bufferPointer.count == expected else {
throw K1.Error.incorrectByteCountOfRawPublicKey(got: bufferPointer.count, expected: expected)
}
// We can simply prepend `04` and parse as x963Representation
do {
return try Self.deserialize(x963Representation: [0x04] + [UInt8](bufferPointer))
} catch {
throw K1.Error.unableToDeserializePublicKeyFromRawRepresentation
throw K1.Error.incorrectKeySize
}
return try Self.deserialize(x963Representation: [0x04] + [UInt8](bufferPointer))
}
}

Expand All @@ -50,7 +45,7 @@ extension FFI.PublicKey {
try contiguousBytes.withUnsafeBytes { bufferPointer throws -> Wrapped in
let expected = Self.compressedByteCount
guard bufferPointer.count == expected else {
throw K1.Error.incorrectByteCountOfCompressedPublicKey(got: bufferPointer.count, expected: expected)
throw K1.Error.incorrectKeySize
}
return try Self._deserialize(bytes: [UInt8](bufferPointer))
}
Expand All @@ -59,7 +54,7 @@ extension FFI.PublicKey {
private static func _deserialize(bytes: [UInt8]) throws -> Wrapped {
var raw = secp256k1_pubkey()
try FFI.call(
ifFailThrow: .failedToDeserializePublicKey
ifFailThrow: .publicKeyParse
) { context in
secp256k1_ec_pubkey_parse(
context,
Expand All @@ -81,7 +76,7 @@ extension FFI.PublicKey {
var byteCount = format.length
var out = [UInt8](repeating: 0x00, count: byteCount)
var publicKeyRaw = wrapped.raw
try FFI.call(ifFailThrow: .failedToSerializePublicKey) { context in
try FFI.call(ifFailThrow: .publicKeySerialize) { context in
secp256k1_ec_pubkey_serialize(
context,
&out,
Expand Down
11 changes: 4 additions & 7 deletions Sources/K1/Support/FFI/API/Schnorr/FFI+Schnorr.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ extension FFI.Schnorr {
try FFI.toC { ffi -> Bool in
var publicKeyX = secp256k1_xonly_pubkey()
var publicKeyRaw = publicKey.raw
try FFI.call(ifFailThrow: .failedToSchnorrVerifyGettingXFromPubKey) { context in
try FFI.call(ifFailThrow: .xonlyPublicKeyFromPublicKey) { context in
secp256k1_xonly_pubkey_from_pubkey(
context,
&publicKeyX,
Expand Down Expand Up @@ -48,18 +48,15 @@ extension FFI.Schnorr {
guard
message.count == Curve.Field.byteCount
else {
throw K1.Error.unableToSignMessageHasInvalidLength(
got: message.count,
expected: Curve.Field.byteCount
)
throw K1.Error.incorrectParameterSize
}

var signatureOut = [UInt8](repeating: 0, count: FFI.Schnorr.Wrapped.byteCount)

var keyPair = secp256k1_keypair()

try FFI.call(
ifFailThrow: .failedToInitializeKeyPairForSchnorrSigning
ifFailThrow: .keypairCreate
) { context in
secp256k1_keypair_create(
context,
Expand All @@ -69,7 +66,7 @@ extension FFI.Schnorr {
}

try FFI.call(
ifFailThrow: .failedToSchnorrSignDigest
ifFailThrow: .schnorrSign
) { context in
secp256k1_schnorrsig_sign32(
context,
Expand Down
5 changes: 1 addition & 4 deletions Sources/K1/Support/FFI/API/Schnorr/Schnorr+Wrapped.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,7 @@ extension FFI.Schnorr {

init(bytes: [UInt8]) throws {
guard bytes.count == Self.byteCount else {
throw K1.Error.failedToInitSchnorrSignatureInvalidByteCount(
got: bytes.count,
expected: Self.byteCount
)
throw K1.Error.incorrectParameterSize
}
self.bytes = bytes
}
Expand Down
8 changes: 4 additions & 4 deletions Sources/K1/Support/FFI/Internals/FFI+Call.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ final class FFI {
/* "Create a secp256k1 context object." */
let context = secp256k1_context_create(Context.sign.rawValue | Context.verify.rawValue)
else {
throw K1.Error.failedToCreateContextForSecp256k1
throw K1.Error.underlyingLibsecp256k1Error(.failedToCreateContextForSecp256k1)
}

self.context = context
Expand Down Expand Up @@ -43,18 +43,18 @@ extension FFI {
}

func call(
ifFailThrow error: K1.Error,
ifFailThrow error: FFI.Error,
_ method: (OpaquePointer) -> Int32
) throws {
let result = callWithResultCode(method)
let successCode = 1
guard result == successCode else {
throw error
throw K1.Error.underlyingLibsecp256k1Error(error)
}
}

static func call(
ifFailThrow error: K1.Error,
ifFailThrow error: FFI.Error,
_ method: (OpaquePointer) -> Int32
) throws {
try toC { ffi in
Expand Down
Loading

0 comments on commit aaa0ae0

Please sign in to comment.