essential_sign/
encode.rs

1//! Functions for encoding signatures and public keys.
2
3use essential_types::{
4    convert::{bytes_from_word, word_4_from_u8_32, word_8_from_u8_64, word_from_bytes},
5    Word,
6};
7use secp256k1::{ecdsa::RecoverableSignature, PublicKey};
8
9/// Encode a secp256k1 public key into 5 words.
10pub fn public_key(pk: &PublicKey) -> [Word; 5] {
11    let [start @ .., end] = pk.serialize();
12    let start = word_4_from_u8_32(start);
13    let mut end_word = [0u8; 8];
14    end_word[7] = end;
15    let end_word = word_from_bytes(end_word);
16    let mut out = [0; 5];
17    out[..4].copy_from_slice(&start);
18    out[4] = end_word;
19    out
20}
21
22/// Encode a secp256k1 public key into 40 bytes.
23/// This is word aligned.
24pub fn public_key_as_bytes(pk: &PublicKey) -> [u8; 40] {
25    let mut out = [0; 40];
26    let words = public_key(pk);
27    for (word, out) in words.iter().zip(out.chunks_exact_mut(8)) {
28        let bytes = bytes_from_word(*word);
29        out.copy_from_slice(&bytes);
30    }
31    out
32}
33
34/// Encode a secp256k1 recoverable signature into 9 words.
35pub fn signature(sig: &RecoverableSignature) -> [Word; 9] {
36    let (rec_id, sig) = sig.serialize_compact();
37    let rec_id: i32 = rec_id.into();
38    let rec_id = Word::from(rec_id);
39    let sig = word_8_from_u8_64(sig);
40    let mut out = [0; 9];
41    out[..8].copy_from_slice(&sig);
42    out[8] = rec_id;
43    out
44}
45
46/// Encode a secp256k1 recoverable signature into 72 bytes.
47pub fn signature_as_bytes(sig: &RecoverableSignature) -> [u8; 72] {
48    let mut out = [0; 72];
49    let words = signature(sig);
50    for (word, out) in words.iter().zip(out.chunks_exact_mut(8)) {
51        let bytes = bytes_from_word(*word);
52        out.copy_from_slice(&bytes);
53    }
54    out
55}