Skip to content

Commit 4732484

Browse files
committed
Add a ChaCha20 utility for encrypting a block
This hides an encryption implementation detail from callers.
1 parent 4fafae0 commit 4732484

File tree

2 files changed

+50
-8
lines changed

2 files changed

+50
-8
lines changed

lightning/src/ln/inbound_payment.rs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -277,10 +277,9 @@ fn construct_payment_secret(iv_bytes: &[u8; IV_LEN], metadata_bytes: &[u8; METAD
277277
let (iv_slice, encrypted_metadata_slice) = payment_secret_bytes.split_at_mut(IV_LEN);
278278
iv_slice.copy_from_slice(iv_bytes);
279279

280-
let chacha_block = ChaCha20::get_single_block(metadata_key, iv_bytes);
281-
for i in 0..METADATA_LEN {
282-
encrypted_metadata_slice[i] = chacha_block[i] ^ metadata_bytes[i];
283-
}
280+
ChaCha20::encrypt_single_block(
281+
metadata_key, iv_bytes, encrypted_metadata_slice, metadata_bytes
282+
);
284283
PaymentSecret(payment_secret_bytes)
285284
}
286285

@@ -412,11 +411,10 @@ fn decrypt_metadata(payment_secret: PaymentSecret, keys: &ExpandedKey) -> ([u8;
412411
let (iv_slice, encrypted_metadata_bytes) = payment_secret.0.split_at(IV_LEN);
413412
iv_bytes.copy_from_slice(iv_slice);
414413

415-
let chacha_block = ChaCha20::get_single_block(&keys.metadata_key, &iv_bytes);
416414
let mut metadata_bytes: [u8; METADATA_LEN] = [0; METADATA_LEN];
417-
for i in 0..METADATA_LEN {
418-
metadata_bytes[i] = chacha_block[i] ^ encrypted_metadata_bytes[i];
419-
}
415+
ChaCha20::encrypt_single_block(
416+
&keys.metadata_key, &iv_bytes, &mut metadata_bytes, encrypted_metadata_bytes
417+
);
420418

421419
(iv_bytes, metadata_bytes)
422420
}

lightning/src/util/chacha20.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,20 @@ mod real_chacha {
159159
chacha_bytes
160160
}
161161

162+
/// Encrypts `src` into `dest` using a single block from a ChaCha stream. Passing `dest` as
163+
/// `src` in a second call will decrypt it.
164+
pub fn encrypt_single_block(
165+
key: &[u8; 32], nonce: &[u8; 16], dest: &mut [u8], src: &[u8]
166+
) {
167+
debug_assert_eq!(dest.len(), src.len());
168+
debug_assert!(dest.len() <= 32);
169+
170+
let block = ChaCha20::get_single_block(key, nonce);
171+
for i in 0..dest.len() {
172+
dest[i] = block[i] ^ src[i];
173+
}
174+
}
175+
162176
fn expand(key: &[u8], nonce: &[u8]) -> ChaChaState {
163177
let constant = match key.len() {
164178
16 => b"expand 16-byte k",
@@ -290,6 +304,13 @@ mod fuzzy_chacha {
290304
[0; 32]
291305
}
292306

307+
pub fn encrypt_single_block(
308+
_key: &[u8; 32], _nonce: &[u8; 16], dest: &mut [u8], src: &[u8]
309+
) {
310+
debug_assert_eq!(dest.len(), src.len());
311+
debug_assert!(dest.len() <= 32);
312+
}
313+
293314
pub fn process(&mut self, input: &[u8], output: &mut [u8]) {
294315
output.copy_from_slice(input);
295316
}
@@ -618,4 +639,27 @@ mod test {
618639

619640
assert_eq!(ChaCha20::get_single_block(&key, &nonce_16bytes), block_bytes);
620641
}
642+
643+
#[test]
644+
fn encrypt_single_block() {
645+
let key = [
646+
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
647+
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
648+
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
649+
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
650+
];
651+
let nonce = [
652+
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
653+
0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
654+
];
655+
let bytes = [1; 32];
656+
657+
let mut encrypted_bytes = [0; 32];
658+
ChaCha20::encrypt_single_block(&key, &nonce, &mut encrypted_bytes, &bytes);
659+
660+
let mut decrypted_bytes = [0; 32];
661+
ChaCha20::encrypt_single_block(&key, &nonce, &mut decrypted_bytes, &encrypted_bytes);
662+
663+
assert_eq!(bytes, decrypted_bytes);
664+
}
621665
}

0 commit comments

Comments
 (0)