Skip to content

Commit

Permalink
Bare (very bare) HKDF implementation
Browse files Browse the repository at this point in the history
* Dropping the sha2 and hkdf deps in favor of internal implemenation,
but this has a long way to go. The packet tests cover the *exact*
path for now though, so actually gives good coverage.
  • Loading branch information
nyonson committed Mar 1, 2024
1 parent 046cf93 commit 5ad0415
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 47 deletions.
58 changes: 15 additions & 43 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ rust-version = "1.56.1"
[dependencies]
secp256k1 = { version="0.28.2" }
rand = "0.8.4"
hkdf = "0.12.4"
sha2 = "0.10.8"
bitcoin_hashes = "0.13.0"
chacha20poly1305 = "0.10.1"
chacha20 = "0.9.1"

Expand Down
37 changes: 37 additions & 0 deletions src/hkdf.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
use bitcoin_hashes::{sha256, Hash, HashEngine, Hmac, HmacEngine};
use core::fmt;

/// Structure for InvalidLength, used for output error handling.
#[derive(Copy, Clone, Debug)]
pub struct InvalidLength;

impl fmt::Display for InvalidLength {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "invalid number of blocks, too large output")
}
}

// Hardcoding to SHA256 hash and hmac implemenation.
pub struct Hkdf {
prk: Hmac<sha256::Hash>,
}

impl Hkdf {
// TODO: make salt optional.
pub fn new(salt: &[u8], ikm: &[u8]) -> Self {
let mut hmac_engine: HmacEngine<sha256::Hash> = HmacEngine::new(salt);
hmac_engine.input(ikm);
Hkdf {
prk: Hmac::from_engine(hmac_engine),
}
}
pub fn expand(&self, info: &[u8], okm: &mut [u8]) -> Result<(), InvalidLength> {
// TODO: actually loop and do not assume exact 32 byte match.
let mut hmac_engine: HmacEngine<sha256::Hash> = HmacEngine::new(&self.prk.to_byte_array());
hmac_engine.input(info);
hmac_engine.input(&[1u8]);
let t = Hmac::from_engine(hmac_engine);
okm.copy_from_slice(&t.to_byte_array());
return Ok(());
}
}
5 changes: 3 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@
//! ```
mod error;
mod hkdf;
mod types;

use chacha20::cipher::{KeyIvInit, StreamCipher, StreamCipherSeek};
use chacha20::ChaCha20;
use chacha20poly1305::{AeadInPlace, ChaCha20Poly1305, KeyInit, Nonce};
Expand All @@ -49,7 +51,6 @@ use secp256k1::{
ellswift::{ElligatorSwift, ElligatorSwiftParty},
PublicKey, Secp256k1, SecretKey,
};
use sha2::Sha256;
pub use types::SessionKeyMaterial;
pub use types::{
CompleteHandshake, EcdhPoint, HandshakeRole, InitiatorHandshake, ReceivedMessage,
Expand Down Expand Up @@ -373,7 +374,7 @@ fn initialize_session_key_material(ikm: &[u8]) -> SessionKeyMaterial {
let ikm_salt = "bitcoin_v2_shared_secret".as_bytes();
let magic = NETWORK_MAGIC.as_slice();
let salt = [ikm_salt, magic].concat();
let (_, hk) = Hkdf::<Sha256>::extract(Some(salt.as_slice()), ikm);
let hk = Hkdf::new(salt.as_slice(), ikm);
let mut session_id = [0u8; 32];
let session_info = "session_id".as_bytes();
hk.expand(session_info, &mut session_id)
Expand Down

0 comments on commit 5ad0415

Please sign in to comment.