-
Notifications
You must be signed in to change notification settings - Fork 250
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
Implement a single type to provide different forms of encryption keys #4273
Comments
I think that this approach will encapsulate a solution for each use case we have for public keys. |
just in case, here's the code I used to collect different formats: func TestMessengerKeys(t *testing.T) {
suite.Run(t, new(MessengerKeysTestSuite))
}
type MessengerKeysTestSuite struct {
suite.Suite
}
func (s *MessengerKeysTestSuite) Test_1() {
privateKey, err := gethcrypto.GenerateKey()
s.Require().NoError(err)
publicKey := privateKey.PublicKey
// 1. X/Y
fmt.Println(fmt.Sprintf("raw curve point: X = %s, Y = %s", publicKey.X.String(), publicKey.Y.String()))
// 2. 33-bytes compressed
compressed := crypto.CompressPubkey(&publicKey)
fmt.Println("compressed bytes:", hex.EncodeToString(compressed))
// 3. 64-bytes uncompressed
uncompressed := elliptic.Marshal(secp256k1.S256(), publicKey.X, publicKey.Y)
fmt.Println("uncompressed bytes", hex.EncodeToString(uncompressed))
// 4. hex-encoded 64-bytes uncompressed
hexEncodedCompressed := types.EncodeHex(compressed)
fmt.Println("compressed hex-encoded", hexEncodedCompressed)
// 5. hex-encoded 64-bytes uncompressed
hexEncodedUncompressed := types.EncodeHex(uncompressed)
fmt.Println("uncompressed hex-encoded", hexEncodedUncompressed)
// 6. serialised: compressed + multibase-identified + base58-encoded
serialized, err := multiformat.SerializeLegacyKey(hexEncodedUncompressed)
s.Require().NoError(err)
fmt.Println("serialized", serialized)
// 5. deserialized: decompressed + multibase-identified + hex-encoded
deserialized, err := multiformat.DeserializePublicKey(serialized, "f")
s.Require().NoError(err)
fmt.Println("deserialized", deserialized)
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Problem
NOTE: It might be that I'm just stupid, but it seems to me from the codebase that we do have a lot of confusion about the topic.
This is all the same public key:
ecdsa.PublicKey
curve = secp256k1.S256()
X = 65048851631837384047378089819319437426496905877495594931948125317595069084841
Y = 54855369826654862910415609527800597498500226949009120841462260707132436223130
02 8f d0 58 65 ad fd 5d f7 00 be f8 16 09 a5 ed 38 89 ee 4c 82 c4 5a 74 b1 05 ca ca 8c 3a 62 f4 a9
04 8f d0 58 65 ad fd 5d f7 00 be f8 16 09 a5 ed 38 89 ee 4c 82 c4 5a 74 b1 05 ca ca 8c 3a 62 f4 a9 79 47 09 ff 97 b5 8e 0d 38 4a 11 90 57 b7 f5 b4 70 a2 df 9f 13 37 ed 54 73 c1 58 fc c5 5d 94 9a
hex-encoded
0x028fd05865adfd5df700bef81609a5ed3889ee4c82c45a74b105caca8c3a62f4a9
hex-encoded
0x048fd05865adfd5df700bef81609a5ed3889ee4c82c45a74b105caca8c3a62f4a9794709ff97b58e0d384a119057b7f5b470a2df9f1337ed5473c158fcc55d949a
zQ3shX6BKTi1CpWcqEiQLTLRmvGSzktyg14eMcfjYZfHzFzVE
fe701048fd05865adfd5df700bef81609a5ed3889ee4c82c45a74b105caca8c3a62f4a9794709ff97b58e0d384a119057b7f5b470a2df9f1337ed5473c158fcc55d949a
Proposals
COMPRESSED
should only be used for "using the X coordinate of ECDSA Public Key".It has (almost) nothing to do with
zQ3sh...
base58-encoding.E.g. in status-desktop we have
decompressPk
function that wrapsdeserializePublicKey
call.SERIALIZED
== base58-encoded multibase-identified uncompressed public keyDESERIALIZED
== hex-encoded multibase-identified compressed public keycommunities_communities
table use "33-bytes compressed public key" as BLOB type,while
contacts
table use "full uncompressed public key" as STRING.0x0701
z
,f
encoding identifiers0x
.Though we have special
types.EncodeHex
andtypes
DecodeHex` functions, there're still so many places that do this manually. And actually, should we even use this form of the public key? Even if we don't want to migrate the database, we could convert it to smth right after scanning the database.One of the confusion reasons is that currently we use a bunch of modules for converting purposes:
hex
,types
,utils
,secp256k1
,ecdsa
,elliptic
,crypto
,gethcrypto
,multiformat
,multibase
Bad code references
decompressPk
https://github.com/status-im/status-desktop/blob/94953bb925a3a3cbac1508eb6baf7aec053eeae3/src/backend/accounts.nim#L148-L163
Problems here:
- at first check it the input is not uncompressed already, this seems correct
- then mistake: "decompress" wraps "deserialize" procedure and actually return it as result
- and in case of
JsonParsingError
it simply does the things manually in nim 😄SerializePublicKey
andDeserializePublicKey
custom wrappers:This is a very good example of confusion and lack of convenient functions.
It's really not obvious how to convert
zQ3sh...
string to33-bytes compressed
bytes. So we end up with such functions in the codebase:status-go/services/utils/utils.go
Lines 28 to 60 in b65eda3
Implementation
I also came up with an idea that could help us.
This has it's pros and cons, it to be discussed ofc, but I'm sharing it here anyway.
The idea is to implement a "smart class" for keys.
We could pass it around within status-go and each consumer can take the key in whatever format is needed. We can also cache some popular values inside, e.g. compressed/uncompressed versions,
z
andf
string encodings andecdsa.PublicKey
. And I suppose that with due implementation it can even be used for maps indexing.The text was updated successfully, but these errors were encountered: