1 use bitcoin::hashes::{Hash, HashEngine};
2 use bitcoin::hashes::hmac::{Hmac, HmacEngine};
3 use bitcoin::hashes::sha256::Hash as Sha256;
4 use bitcoin::secp256k1::{Message, Secp256k1, SecretKey, ecdsa::Signature, Signing};
6 use crate::sign::EntropySource;
10 macro_rules! hkdf_extract_expand {
11 ($salt: expr, $ikm: expr) => {{
12 let mut hmac = HmacEngine::<Sha256>::new($salt);
14 let prk = Hmac::from_engine(hmac).into_inner();
15 let mut hmac = HmacEngine::<Sha256>::new(&prk[..]);
17 let t1 = Hmac::from_engine(hmac).into_inner();
18 let mut hmac = HmacEngine::<Sha256>::new(&prk[..]);
21 (t1, Hmac::from_engine(hmac).into_inner(), prk)
23 ($salt: expr, $ikm: expr, 2) => {{
24 let (k1, k2, _) = hkdf_extract_expand!($salt, $ikm);
27 ($salt: expr, $ikm: expr, 5) => {{
28 let (k1, k2, prk) = hkdf_extract_expand!($salt, $ikm);
30 let mut hmac = HmacEngine::<Sha256>::new(&prk[..]);
33 let k3 = Hmac::from_engine(hmac).into_inner();
35 let mut hmac = HmacEngine::<Sha256>::new(&prk[..]);
38 let k4 = Hmac::from_engine(hmac).into_inner();
40 let mut hmac = HmacEngine::<Sha256>::new(&prk[..]);
43 let k5 = Hmac::from_engine(hmac).into_inner();
49 pub fn hkdf_extract_expand_twice(salt: &[u8], ikm: &[u8]) -> ([u8; 32], [u8; 32]) {
50 hkdf_extract_expand!(salt, ikm, 2)
53 pub fn hkdf_extract_expand_5x(salt: &[u8], ikm: &[u8]) -> ([u8; 32], [u8; 32], [u8; 32], [u8; 32], [u8; 32]) {
54 hkdf_extract_expand!(salt, ikm, 5)
58 pub fn sign<C: Signing>(ctx: &Secp256k1<C>, msg: &Message, sk: &SecretKey) -> Signature {
59 #[cfg(feature = "grind_signatures")]
60 let sig = ctx.sign_ecdsa_low_r(msg, sk);
61 #[cfg(not(feature = "grind_signatures"))]
62 let sig = ctx.sign_ecdsa(msg, sk);
67 pub fn sign_with_aux_rand<C: Signing, ES: Deref>(
68 ctx: &Secp256k1<C>, msg: &Message, sk: &SecretKey, entropy_source: &ES
69 ) -> Signature where ES::Target: EntropySource {
70 #[cfg(feature = "grind_signatures")]
72 let sig = ctx.sign_ecdsa_with_noncedata(msg, sk, &entropy_source.get_secure_random_bytes());
73 if sig.serialize_compact()[0] < 0x80 {
77 #[cfg(all(not(feature = "grind_signatures"), not(feature = "_test_vectors")))]
78 let sig = ctx.sign_ecdsa_with_noncedata(msg, sk, &entropy_source.get_secure_random_bytes());
79 #[cfg(all(not(feature = "grind_signatures"), feature = "_test_vectors"))]
80 let sig = sign(ctx, msg, sk);