1

I need to interact with Hyperledger Fabric in an iOS application, and I've run into a problem when creating the proposal signature. Fabric requires low-s ECDSA, but I can't find a way to specify that in Apple's crypto functions. Without specifying low-s, my calls fail about %50 of the time, when S is higher than R.

My signing code is pretty simple:

  static func sign(data:Data, withPrivateKey:SecKey) throws -> Data {
    var error: Unmanaged<CFError>?
    guard
      let signature = SecKeyCreateSignature(
        withPrivateKey,
        .ecdsaSignatureMessageX962SHA256,
        data as CFData,
        &error
      ) as Data?
    else {
      throw error!.takeRetainedValue()
    }
    return signature
  }
Michael
  • 145
  • 6

1 Answers1

0

According to this comment in Hyperledger Fabric code, the "low-S" form of the ECDSA signature is the one described in BIP-146, that is, s < n/2, where n is the order of your curve. Having just s < r is not enough.

You can transform a signature into "low-S" form yourself: parse the signature into (r, s), flip it if needed (s' = min(s, -s % n)), and encode the result (r, s') back into bytes. The X9.62 point encoding is not hard to parse, and since signatures are public, you need not worry about leaking secrets through side channels.

De117
  • 351
  • 2
  • 11