-
Notifications
You must be signed in to change notification settings - Fork 10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Get PublicKey<Secp256k1> from Data #22
Comments
One more thing I noticed. I create an AffinePoint with the raw Data like shown in my message above (first hex value) like this
I wanted to check the x and y values. I tried to recreate the original hex value like above. Therfore I didn't use the as256bitLongData as it doesn't correctly interpret signed values. I did it like that
which gave me following result 04000af135a4889436cee52b5c73a33ec5ad0be0952f57f4f0ed0c80b0beda7ca601789393a5947e9faa3f6795c9aa09a96325dfe850bfc3f1db62a50abfb0fff7 The reason for this is that it uses following calls internally in init function of AffinePoint
which is calling the BigInt extension method in Data Conversion.swift from Károly Lőrentey which accordingly to the documentation always drops the first byte
Which means my AffinePoint will actually never represent the raw data I pass via the init function... Edit: it actually works when I create a PublicKey from my uncompressed raw Data public key like this
This workaround works for me at the moment but I think the stuff above I mentioned before is not as it should be. Sorry for spamming, waiting for your feedback about this @Sajjon :) |
@grill2010 thx for reporting this issue, I'm making a fix now, stay tuned. |
@grill2010 Hmm I was unable to reproduce, which version of EllipticCurveKit are you usign? on import Foundation
import XCTest
@testable import EllipticCurveKit
final class PublicKeyFromDataTests: XCTestCase {
func testPubKeyFromData() throws {
let pubKeyUncompressedHex = "04f40af135a4889436cee52b5c73a33ec5ad0be0952f57f4f0ed0c80b0beda7ca643789393a5947e9faa3f6795c9aa09a96325dfe850bfc3f1db62a50abfb0fff7"
let pubKeyUncompressedData = Data(hex: pubKeyUncompressedHex)
XCTAssertEqual(pubKeyUncompressedHex, pubKeyUncompressedData.toHexString())
let affinePoint = try AffinePoint<Secp256k1>(data: pubKeyUncompressedData)
let expectedY = "43789393a5947e9faa3f6795c9aa09a96325dfe850bfc3f1db62a50abfb0fff7"
let expectedX = "f40af135a4889436cee52b5c73a33ec5ad0be0952f57f4f0ed0c80b0beda7ca6"
XCTAssertEqual(affinePoint.y.asHexString(uppercased: false), expectedY)
XCTAssertEqual(affinePoint.x.asHexString(uppercased: false), expectedX)
let publickey = PublicKey<Secp256k1>.init(point: affinePoint)
XCTAssertEqual(publickey.y.asHexString(uppercased: false), expectedY)
XCTAssertEqual(publickey.x.asHexString(uppercased: false), expectedX)
}
} Which works just fine. But I did notice the issue with leading minus sign when converting BigInt to hexstring. Wonder if it might be safe to just drop that minus sign. Will have to investigate the implications of this. |
I use the main branch of EllipticCurveKit. Just dropping the minus sign is probably not safe as the reason for this problem is in AffinePoint. E.g.
In the constructor of AffinePoint it uses following BigInt init functions to generate x and y
and the BigInt from Károly Lőrentey assumes the first byte represents the sign (0 for positive, 1 for negative). So this leads to following problems, it always drops the first byte for the BigInt value which is bad because it doesn't represent then the correct value in AffinePoint and second when the first byte is not 0 but any other value the BigInt is treated as negative BigInt which then leads to the problem in PublicKey as the values should never be negative for BigInt. Edit: I copied your test and it give me the exact same error ^^ Don't know why this doesn't happen on your side, it's strange. |
@Sajjon any news in regards this topic? |
I encountered the same issue as yours. Could you tell me how you fixed it?? |
Hey! Did you guys try decoding an AffinePoint from data and pass that to PublicKey init? Otherwise can you pass me the test PrivateKey, expected public key and I can add a test and have a look if it fails. |
@EunJuJang sorry for the late reply, I use the workaround mentioned in the this comment above @Sajjon the tests I posted above fail for me every time if I don't use the workaround mentioned above. |
Hi,
I'm currently porting my Android app to iOS and I stumbled across your library which seems to perfectly meet my requirements. I'm not sure if I do something wrong but I'm not able to create a public key from Data. I have created a Unit test to check if the output of some crypto functions is the same as in my Android app. Therefore I use following uncompressed public key. Below the uncompressed public key in hex representation
04F40AF135A4889436CEE52B5C73A33EC5AD0BE0952F57F4F0ED0C80B0BEDA7CA643789393A5947E9FAA3F6795C9AA09A96325DFE850BFC3F1DB62A50ABFB0FFF7
Once converted the hex string to Data I use following function calls
let decodedFromUncompressed = try AffinePoint<Secp256k1>.init(data: publicKeyBytes)
return PublicKey<Secp256k1>.init(point: decodedFromUncompressed)
This leads to an error here
EllipticCurveKit/Sources/EllipticCurveKit/EllipticCurve/Keys/PublicKey.swift
Line 37 in 7a01b9f
Upon further investigation I saw that the call
let yData = y.as256bitLongData()
returned 0 despite the value is not 0. It seems the as256bitLongData uses internally a function called asHexStringLength64 which returns following strange hex value
0-789393A5947E9FAA3F6795C9AA09A96325DFE850BFC3F1DB62A50ABFB0FFF7
The function fills up the missing values with 0 but seems to ignore the '-' sign. Is this the root cause of the error, did I misunderstand something or is there another way to get a PublicKey from uncompressed Data?
The text was updated successfully, but these errors were encountered: