Comments (11)
Right, that makes sense. At some point it may be worth creating something like Bip137Signature(dataRepresentation:)
just to make this easier for users so they don't have to manually take the header apart like I'm doing. Either way, I've got a working solution so all good my end. Thanks for your help it's much appreciated 🙏
from secp256k1.swift.
Right, that makes sense. At some point it may be worth creating something like
Bip137Signature(dataRepresentation:)
just to make this easier for users so they don't have to manually take the header apart like I'm doing. Either way, I've got a working solution so all good my end. Thanks for your help it's much appreciated 🙏I like the idea and if you're interested in contributing, I'd gladly review the changes for acceptance. 😁
Yep for sure man! If/when I get the time to go back and refactor this into a class, I'll create a PR :)
from secp256k1.swift.
Hey @mikekelly 👋
Something seems off with the sigHex
, while the number of bytes is correct, the recID
returns 73 which is expected to be invalid.
Here is the code I used to check:
let sigHex = "283f5723bc367993c7492f8d79087b499e776012e0d744426e1be8e12d57264ab765f52dad6dac7df61d2209e875b037390c181b8c205ad47443c5bfea2f08c149"
let dataHex = "03a69666f5863ecc3b35ac143ef843f2a07ef98a76c09fba6bbd23ea36c7839602"
let sigData = Data(try! sigHex.bytes)
let data = Data(try! dataHex.bytes)
let sig = try! secp256k1.Recovery.ECDSASignature(dataRepresentation: sigData)
print(sig.dataRepresentation.base64EncodedString())
print(try! sig.compactRepresentation.recoveryId)
let expectedSignature = "rPnhleCU8vQOthm5h4gX/5UbmxH6w3zw1ykAmLvvtXT4YGKBoiMaP8eBBF8upN8IaTYmO7+o0Vyhf+cODD1uVgE="
let expectedDerSignature = Data(base64Encoded: expectedSignature, options: .ignoreUnknownCharacters)!
let expectedSig = try! secp256k1.Recovery.ECDSASignature(expectedDerSignature)
print(expectedSig.dataRepresentation.base64EncodedString())
print(try! expectedSig.compactRepresentation.recoveryId)
And here is the output:
KD9XI7w2eZPHSS+NeQh7SZ53YBLg10RCbhvo4S1XJkq3ZfUtrW2sffYdIgnodbA3OQwYG4wgWtR0Q8W/6i8IwUk=
73
rPnhleCU8vQOthm5h4gX/5UbmxH6w3zw1ykAmLvvtXT4YGKBoiMaP8eBBF8upN8IaTYmO7+o0Vyhf+cODD1uVgE=
1
from secp256k1.swift.
Hi @csjones thanks for having a look. To me, isn't the the rec id of sigHex
in range?
let sigHex = "283f5723bc367993c7492f8d79087b499e776012e0d744426e1be8e12d57264ab765f52dad6dac7df61d2209e875b037390c181b8c205ad47443c5bfea2f08c149"
let sigData = Data(try! sigHex.bytes)
print(String(sigData.map { String($0) }.joined(separator: " ")))
outputs
40 63 87 35 188 54 121 147 199 73 47 141 121 8 123 73 158 119 96 18 224 215 68 66 110 27 232 225 45 87 38 74 183 101 245 45 173 109 172 125 246 29 34 9 232 117 176 55 57 12 24 27 140 32 90 212 116 67 197 191 234 47 8 193 73
ie. the rec id is 40 according to the format?
from secp256k1.swift.
sorry, I meant the header is 40 - the rec id is 1
from secp256k1.swift.
sorry, I meant the header is 40 - the rec id is 1
I'm not sure how you're getting a recID
of 1. Given a header byte value of 40 (in decimal format which corresponds to the hexadecimal value 28), the least significant 2 bits are "00" meaning the recID
is 0.
How is the signature being created?
from secp256k1.swift.
The signature comes from a closed source hardware wallet, doesn't 40 resolve to 1 according to this BIP?
from secp256k1.swift.
I can get around all of it by manually picking off the header, deriving the rec id, and then constructing the sig:
let header = UInt8(sigData.first!)
let recId = recIdFromHeader(header)
let compact = sigData.dropFirst()
let sig = try! secp256k1.Recovery.ECDSASignature(compactRepresentation: compact, recoveryId: recId)
where recIdFromHeader
looks like this (implementation lifted from the BIP referenced above) :
func recIdFromHeader(_ header: UInt8) -> Int32 {
var adjustedValue = header
if(adjustedValue >= 39) // this is a bech32 signature
{
adjustedValue -= 12;
} // this is a segwit p2sh signature
else if(adjustedValue >= 35)
{
adjustedValue -= 8;
} // this is a compressed key signature
else if (adjustedValue >= 31) {
adjustedValue -= 4;
}
return Int32(adjustedValue - 27);
}
from secp256k1.swift.
Thanks for the information. Yes, I see how the recID
is 1 because of BIP137 (i.e. 40-39=1); I'll need to investigate more though. Stepping through, secp256k1_ecdsa_recover(
returns 0
which raises the error, secp256k1.secp256k1Error.underlyingCryptoError
.
Might be helpful to use the bindings directly to recreate the issue. Additionally, I think this comment might be related: bitcoin-core/secp256k1#1024 (comment)
from secp256k1.swift.
Hey @mikekelly,
Investigating this more, it seems we're mixing types,ECDSASignature
and ECDSACompactSignature
, which are not equivalent.
This line, secp256k1.Recovery.ECDSASignature(dataRepresentation:)
, is using libsecp256k1's internal signature representation which includes the note "The exact representation of data inside is implementation defined and not guaranteed to be portable between different platforms or versions."
The line that worked for you after dropping the header, secp256k1.Recovery.ECDSASignature(compactRepresentation:recoveryId:)
is using the compact signature representation which is expected to be used with BIP-0137.
from secp256k1.swift.
Right, that makes sense. At some point it may be worth creating something like
Bip137Signature(dataRepresentation:)
just to make this easier for users so they don't have to manually take the header apart like I'm doing. Either way, I've got a working solution so all good my end. Thanks for your help it's much appreciated 🙏
I like the idea and if you're interested in contributing, I'd gladly review the changes for acceptance. 😁
from secp256k1.swift.
Related Issues (20)
- nvm I need the podspec for this, i'm so sorry... HOT 2
- Contructing a PublicKey with rawRepresentation fails with incorrect size HOT 3
- value of type `secp256k1_surjectionproof` has no member `data` HOT 13
- Differenct signature result with other libraries HOT 2
- Do you have any examples of how you would sign a taproot input using this library? HOT 1
- Did library already support sign a taproot input? HOT 4
- Taproot address format HOT 9
- Cannot install package via SPM when importing it from another package HOT 3
- Is it possible to generate an invalid PrivateKey when no secret it passed? HOT 9
- How to use secp256k1_ec_pubkey_combine HOT 10
- How to create PrivateKey by importing pem private key? HOT 7
- Test/Example for `sharedSecretFromKeyAgreement` with `handler`? HOT 8
- xcodebuild fails for 0.13.0 HOT 1
- secp256k1/ECDH.swift:180:20 Value of type 'UnsafeMutablePointer<UInt8>' has no member 'update' HOT 1
- #include "./secp256k1.h" Report an error './secp256k1.h' file not found HOT 6
- Is there really a random k injected when calculating an ECDSA signature ? HOT 2
- Please use semver for release tags HOT 1
- Add support for VisionOS HOT 4
- BitcoinSign Transaction HOT 4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from secp256k1.swift.