1

A small bit of Rust code:

let secret_key = SecretKey::from_slice(&rand::thread_rng().gen::<[u8; 32]>()).expect("32 bytes, within curve order");
let public_key = PublicKey::from_secret_key(&secp, &secret_key);
let pk : [u8; 33] = public_key.serialize();
println!("secret_key {:?}", secret_key);
println!("public_key {:?}", public_key);
println!("pk {:x?}", &pk[0..32]);

produces output of the form:

secret_key SecretKey(03697e6c2168bd5f99f4df7086adf0598f9ae97cced61b072dded9f77a1e837f)
public_key PublicKey(b53c8b4a40a9512037199f4047376905cbe8008be1612e166cb01fa35a60b0c9cd17d5ef86f9c92590fe1125f0fa9b478ca5966eb4be1454b0171adaebe35cfd)
pk [3, c9, b0, 60, 5a, a3, 1f, b0, 6c, 16, 2e, 61, e1, 8b, 0, e8, cb, 5, 69, 37, 47, 40, 9f, 19, 37, 20, 51, a9, 40, 4a, 8b, 3c]
secret_key SecretKey(6d8b97d7bfc4240589d5b523dd5d87096dcbd5b14ea5f780912ab713f6fcfbb3)
public_key PublicKey(3484567baaa84424ceeb76456b6f4ec54efac4c4aa5a06215733aa5d5b2f0d06120a5d05f68dfb5a8b6c204b5efa37201350cfb7905014d239e5fd71e1e23775)
pk [2, 6, d, 2f, 5b, 5d, aa, 33, 57, 21, 6, 5a, aa, c4, c4, fa, 4e, c5, 4e, 6f, 6b, 45, 76, eb, ce, 24, 44, a8, aa, 7b, 56, 84]
secret_key SecretKey(60778385b0110ea8b780f27ca96fce19dfe37d8ad94d2492a0c5595261e9fa49)
public_key PublicKey(db1f88690d138e88544d6a47ed7718cf048abd969cfb79684a3dc19053661bc9c3341094dc84aef237832c993bc16df4b5cf0df27eaa4508ea6f7b67f4062ed7)
pk [3, c9, 1b, 66, 53, 90, c1, 3d, 4a, 68, 79, fb, 9c, 96, bd, 8a, 4, cf, 18, 77, ed, 47, 6a, 4d, 54, 88, 8e, 13, d, 69, 88, 1f]

The serialised public key looks as expected, 33 bytes, beginning with 0x02 or 0x03 to denote the sign of the missing Y component.

The X component is present in the uncompressed public key db1f8869... but it is offset by one byte and reversed. This leaves only 31 bytes for the Y component, which does not seem sufficient.

What is the endianess of the uncompressed and compressed public keys?

What have I not understood?

4

2 回答 2

1

crate 中还有另一种方法secp256k1,您可以调用公钥来获取未压缩的密钥serialize_uncompressed()。(然后您需要删除第一个字节以获得 64 字节的密钥)。

于 2021-03-11T18:52:13.673 回答
0

“偏移一个字节”问题是因为您的切片索引错误。第二个值是包含的最后一个索引的一个,所以不是&pk[0..32]你想要的&pk[0..33],或者因为那是整个数组&pk[..]

颠倒的字节是因为公钥的调试输出只是转储了密钥的内部表示。在内部,密钥作为int64s 数组保存,直接复制到 char 数组中,因此在小端系统上,这看起来像字节反转*。使用serialize(或{}格式说明符)时,密钥的格式正确,首先是最高有效字节。

*实际上比这更复杂一些,计算是在一个使用 52 位的整数数组上完成的,然后被打包成一个使用所有 64 位的更密集的“存储”形式。

于 2020-07-01T03:07:18.600 回答