Skip to content

Commit e012e68

Browse files
authored
Merge pull request #33 from wvanlint/wvanlint/parent_key
Provide hardened parent key as argument to LnurlAuthToJwtProvider
2 parents 1e2b840 + 8f3395a commit e012e68

File tree

2 files changed

+14
-18
lines changed

2 files changed

+14
-18
lines changed

src/headers/lnurl_auth_jwt.rs

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,13 @@ use bitcoin::hashes::hex::FromHex;
77
use bitcoin::hashes::sha256;
88
use bitcoin::hashes::{Hash, HashEngine, Hmac, HmacEngine};
99
use bitcoin::secp256k1::{Message, Secp256k1, SignOnly};
10-
use bitcoin::Network;
1110
use bitcoin::PrivateKey;
1211
use serde::Deserialize;
1312
use std::collections::HashMap;
1413
use std::sync::RwLock;
1514
use std::time::{Duration, SystemTime};
1615
use url::Url;
1716

18-
// Derivation index of the parent extended private key as defined by LUD-05.
19-
const PARENT_DERIVATION_INDEX: u32 = 138;
2017
// Derivation index of the hashing private key as defined by LUD-05.
2118
const HASHING_DERIVATION_INDEX: u32 = 0;
2219
// The JWT token will be refreshed by the given amount before its expiry.
@@ -61,24 +58,20 @@ pub struct LnurlAuthToJwtProvider {
6158
impl LnurlAuthToJwtProvider {
6259
/// Creates a new JWT provider based on LNURL Auth.
6360
///
64-
/// The LNURL Auth keys are derived from a seed according to LUD-05.
65-
/// The user is free to choose a consistent seed, such as a hardened derivation from the wallet
66-
/// master key or otherwise for compatibility reasons.
61+
/// The LNURL Auth keys are derived as children from a hardened parent key,
62+
/// following [LUD-05](https://github.com/lnurl/luds/blob/luds/05.md).
63+
/// The hardened parent extended key is given here as an argument, and is suggested to be the
64+
/// `m/138'` derivation from the wallet master key as in the specification.
65+
/// However, users are free to choose a consistent hardened derivation path.
66+
///
6767
/// The LNURL with the challenge will be retrieved by making a request to the given URL.
6868
/// The JWT token will be returned in response to the signed LNURL request under a token field.
6969
/// The given set of headers will be used for LNURL requests, and will also be returned together
7070
/// with the JWT authorization header for VSS requests.
7171
pub fn new(
72-
seed: &[u8], url: String, default_headers: HashMap<String, String>,
72+
parent_key: Xpriv, url: String, default_headers: HashMap<String, String>,
7373
) -> Result<LnurlAuthToJwtProvider, VssHeaderProviderError> {
7474
let engine = Secp256k1::signing_only();
75-
let master =
76-
Xpriv::new_master(Network::Testnet, seed).map_err(VssHeaderProviderError::from)?;
77-
let child_number = ChildNumber::from_hardened_idx(PARENT_DERIVATION_INDEX)
78-
.map_err(VssHeaderProviderError::from)?;
79-
let parent_key = master
80-
.derive_priv(&engine, &vec![child_number])
81-
.map_err(VssHeaderProviderError::from)?;
8275
let default_headermap = get_headermap(&default_headers)?;
8376
let client = reqwest::Client::builder()
8477
.default_headers(default_headermap)
@@ -297,13 +290,13 @@ mod test {
297290
#[test]
298291
fn test_sign_lnurl() {
299292
let engine = Secp256k1::signing_only();
300-
let seed: [u8; 32] =
293+
let parent_key_bytes: [u8; 32] =
301294
FromHex::from_hex("abababababababababababababababababababababababababababababababab")
302295
.unwrap();
303-
let master = Xpriv::new_master(Network::Testnet, &seed).unwrap();
296+
let parent_key = Xpriv::new_master(Network::Testnet, &parent_key_bytes).unwrap();
304297
let signed = sign_lnurl(
305298
&engine,
306-
&master,
299+
&parent_key,
307300
"https://example.com/path?tag=login&k1=e2af6254a8df433264fa23f67eb8188635d15ce883e8fc020989d5f82ae6f11e",
308301
)
309302
.unwrap();

tests/lnurl_auth_jwt_tests.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
mod lnurl_auth_jwt_tests {
33
use base64::engine::general_purpose::URL_SAFE_NO_PAD;
44
use base64::Engine;
5+
use bitcoin::bip32::Xpriv;
6+
use bitcoin::Network;
57
use mockito::Matcher;
68
use serde_json::json;
79
use std::collections::HashMap;
@@ -34,8 +36,9 @@ mod lnurl_auth_jwt_tests {
3436
// Initialize LNURL Auth JWT provider connecting to the mock server.
3537
let addr = mockito::server_address();
3638
let base_url = format!("http://localhost:{}", addr.port());
39+
let parent_key = Xpriv::new_master(Network::Testnet, &[0; 32]).unwrap();
3740
let lnurl_auth_jwt =
38-
LnurlAuthToJwtProvider::new(&[0; 32], base_url.clone(), HashMap::new()).unwrap();
41+
LnurlAuthToJwtProvider::new(parent_key, base_url.clone(), HashMap::new()).unwrap();
3942
{
4043
// First request will be provided with an expired JWT token.
4144
let k1 = "0000000000000000000000000000000000000000000000000000000000000000";

0 commit comments

Comments
 (0)