Looking into msgpack serialization and multibase32z encoding a bit, just noting some trivia and observations, there is no certainty yet if this is what will end up being used.
Using
multibase = “0.6.0”
rmp-serde = “0.14.4”
Secret Key
The current way in safe-api is bincode serialization and hex encoding which gives 64 characters
eg 281dbd717e63ae1845c66851977ea64223e5740c9e3b2637b84f0f8ea33d1a0a
The (maybe) new way in safe-api might be rmp-serde serialization and multibase32z encoding which gives 61 characters
eg hbfgxfkhyqabept7r9u9whqqdrjqxte6c6dw1sge9noum1z8ohfrupcdnnwxg
This would have a public key of 78 characters (sort of like the equivalent of a bitcoin address):
hmo1hqgurec6yhuas8edpb6w7b3nwqc7nrr5gs5ptmmmyowms9ntbe6yqsd75t6my7yupa5kszdbg7
So a slight decrease in the total characters when using msgpack and multibase32z.
To give an equivalent point of comparison, a bitcoin WIF encoded private key (base58) is 52 characters.
// Serialize using msgpack (ie rmp-serde crate)
let secret_key_vec = rmp_serde::to_vec(&SerdeSecret(&secret_key)).unwrap();
// Encode using multibase32z (ie multibase crate)
let mb32z_bytes = encode(Base::Base32z, secret_key_vec).into_bytes();
msgpack-to-json works as expected. Using toolslick.com messagepack-to-json the msgpack bytes (see below) can be decoded into a set of u64 values which represents the underlying 256 bit secret key finite field. Cool!
converting from multibase32z above into raw msgpack bytes
[148, 207, 42, 184, 7, 96, 40, 108, 122, 79, 207, 244, 227, 156, 50, 37, 207, 138, 60, 207, 14, 146, 177, 145, 241, 66, 107, 149, 207, 14, 20, 147, 107, 6, 33, 81, 230]
then into json using toolslick
[
13837213670986298635,
12811103515824107464,
18046157036817630463,
2492927070659696894
]
Poly with threshold 2
The current way in safe-api would be bincode serialization and hex encoding which gives 208 characters (although safe-api does not use or expose Poly it’s a larger and more interesting bit of data to use than the secret key and imo is inevitable when multisig wallets are implemented).
eg 0300000000000000b09167a4c8915eeb5c5e98b29a5bde0a6fd369375fedbaef3ddce4ec6ba9932557ca2d774b63f0d886dd200d442011162c47d33de5dbb2e2d99e3823e38e623b0979bde07259ba7f687f1e766bde4c7f72f6294f821836ef675108d76eca4603
The (maybe) new way in safe-api might be rmp-serde serialization and multibase32z encoding which gives 182 characters.
eg h1gj3juhjrg54nxzhsh9h9nnqqd1e37stjz8ibwzkzrudkb4m37u6ep48uu9r9tcw3her854rghbm7esxm9o1y8gkdtog9u6phiu4os4dh41h6gyrg5mhzfijyqkc98ja37sugesaed8st1p1ppo83cwk395u67frz68473qxmrbs54fiancnk
msgpack to json for poly-with-threshold-2
[
[
[
8917136771447855699,
10181468347128250025,
16032800147641816965,
1259811719774385146
],
[
4155445286346159596,
8104559542406594117,
2603743878687488964,
1442636379315754736
],
[
922117657886018339,
14657046883067931162,
18344042788901578676,
568681510477232256
]
]
]
u64 numbers
This way of encoding secret key / poly is sorta interesting, it uses rust u64 as the ‘base’ number (I guess due to how ff crate represents finite fields behind the scenes, presumably 4 x u64 which gives 256 bits?)
The thing is if this json were to be called in javascript like JSON.parse(my_list_of_u64s)
it would be incorrect (with no indication of error!), since javascript works on f64 (max 253 integer) as the largest integers.
Taking the first poly u64 value and comparing to one less, 8917136771447855699 === 8917136771447855698
is true in javascript.
Or consider JSON.stringify([8917136771447855699])
gives "[8917136771447856000]"
and
JSON.parse("[13837213670986298635]")
gives
[13837213670986300000]
This u64 thing is not a problem per se but it might be worth considering places where rust u64 is used it might be better converted to 8 bytes for maximum cross-language compatibility? Dunno, just dumping my brain on this, need to think about it more.