Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
08d7a7e
add belt-dwp
makavity May 18, 2024
35c591d
cargo fmt
makavity May 18, 2024
f91b95c
rm cargo.lock
makavity May 18, 2024
d005883
fix features
makavity May 18, 2024
9197ed7
add beltdwp bench
makavity May 18, 2024
f3453d4
fix dwp
makavity May 18, 2024
893fcd7
make ghash public
makavity May 19, 2024
0f8ecb4
fix belt-dwp tests
makavity May 19, 2024
6bb004d
fix belt-dwp tests
makavity May 19, 2024
d783635
fix belt-dwp tests
makavity May 19, 2024
a3c7434
update belt-dwp to prerelease
makavity Mar 5, 2025
c0ac13a
add belt-dwp to benches
makavity Mar 5, 2025
5b771fc
fix tests
makavity Mar 5, 2025
6a955f7
fixes for belt-dwp + rebase
makavity Mar 26, 2025
d1d3e6f
Fix tests
makavity Mar 26, 2025
854d183
Fix tests
makavity Mar 26, 2025
c806f30
Add zeroize + edition to 2024 + msrv 1.85
makavity Mar 26, 2025
54b3208
cargo fmt
makavity Mar 27, 2025
547f19a
Fixes for review
makavity Mar 28, 2025
b8c8c00
fix cargo.toml
makavity Mar 28, 2025
360216f
More readable
makavity Mar 28, 2025
669aee7
Store BetlBlock instead of raw key
makavity Mar 28, 2025
8fe1573
Fix zeroize
makavity Mar 28, 2025
1bb3d47
fix get_sizes_block
makavity Mar 28, 2025
989ca57
Move initialization to trait implementation
makavity Mar 28, 2025
32ac38a
BeltDwp is generic now
makavity Mar 28, 2025
46e01d3
cargo fmt
makavity Mar 28, 2025
2e5a142
Remove type alias from examples
makavity Mar 28, 2025
a198446
Impl InnerInit instead of KeySizeUser
makavity Mar 28, 2025
f95b3f6
Fixes for generic, type alias
makavity Mar 28, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 40 additions & 23 deletions belt-dwp/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@
#![cfg_attr(not(all(feature = "os_rng", feature = "heapless")), doc = "```ignore")]
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
//! use belt_dwp::{
//! aead::{Aead, AeadCore, KeyInit},
//! BeltDwp, Nonce
//! aead::{Aead, AeadCore, KeyInit}, Nonce, BeltBlock
//! };
//! type BeltDwp = belt_dwp::BeltDwp::<BeltBlock>;
//!
//! let key = BeltDwp::generate_key().unwrap();
//! let cipher = BeltDwp::new(&key);
Expand Down Expand Up @@ -49,8 +49,9 @@
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
//! use belt_dwp::{
//! aead::{AeadInPlace, AeadInPlaceDetached, KeyInit, heapless::Vec},
//! BeltDwp, Nonce
//! Nonce, BeltBlock
//! };
//! type BeltDwp = belt_dwp::BeltDwp::<BeltBlock>;
//!
//! let key = BeltDwp::generate_key().unwrap();
//! let cipher = BeltDwp::new(&key);
Expand All @@ -76,13 +77,14 @@
//! [`aead::Buffer`] for `arrayvec::ArrayVec` (re-exported from the [`aead`] crate as
//! [`aead::arrayvec::ArrayVec`]).

use aead::consts::{U8, U16, U32};
use aead::consts::{U16, U8};
pub use aead::{self, AeadCore, AeadInPlace, Error, Key, KeyInit, KeySizeUser};
use aead::{AeadInPlaceDetached, PostfixTagged};
use belt_block::BeltBlock;
use belt_block::cipher::{Block, BlockCipherEncrypt, StreamCipher};
pub use belt_block::BeltBlock;
use belt_ctr::cipher::InnerIvInit;
use belt_ctr::{BeltCtr, BeltCtrCore};
use universal_hash::crypto_common::BlockSizeUser;
use universal_hash::UniversalHash;

use crate::ghash::GHash;
Expand All @@ -101,15 +103,24 @@ const T: u128 = 0xE45D_4A58_8E00_6D36_3BF5_080A_C8BA_94B1;

/// Belt-DWP authenticated encryption with associated data (AEAD) cipher, defined in
/// STB 34.101.31-2020
pub struct BeltDwp {
backend: BeltBlock,
pub struct BeltDwp<C = BeltBlock>
where
C: BlockCipherEncrypt + BlockSizeUser<BlockSize = U16>,
{
cipher: C,
}

impl KeySizeUser for BeltDwp {
type KeySize = U32;
impl<C> KeySizeUser for BeltDwp<C>
where
C: BlockCipherEncrypt + BlockSizeUser<BlockSize = U16> + KeySizeUser,
{
type KeySize = C::KeySize;
}

impl AeadInPlaceDetached for BeltDwp {
impl<C> AeadInPlaceDetached for BeltDwp<C>
where
C: BlockCipherEncrypt + BlockSizeUser<BlockSize = U16>,
{
fn encrypt_in_place_detached(
&self,
nonce: &Nonce,
Expand All @@ -120,11 +131,11 @@ impl AeadInPlaceDetached for BeltDwp {

// 2.1. 𝑠 ← belt-block(𝑆, 𝐾);
let mut s = *nonce;
self.backend.encrypt_block(&mut s);
self.cipher.encrypt_block(&mut s);

// 2.2. 𝑟 ← belt-block(𝑠, 𝐾);
let mut r = s;
self.backend.encrypt_block(&mut r);
self.cipher.encrypt_block(&mut r);

// Initialize GHash
let mut ghash = GHash::new_with_init_block(
Expand All @@ -133,7 +144,7 @@ impl AeadInPlaceDetached for BeltDwp {
);

// Initialize CTR mode
let core = BeltCtrCore::inner_iv_init(&self.backend, nonce);
let core = BeltCtrCore::inner_iv_init(&self.cipher, nonce);
let mut enc_cipher = BeltCtr::from_core(core);

// 3. For 𝑖 = 1, 2, . . . , 𝑚 do:
Expand All @@ -156,7 +167,7 @@ impl AeadInPlaceDetached for BeltDwp {

// 6. 𝑡 ← belt-block(𝑡 * 𝑟, 𝐾).
let mut tag = ghash.finalize_reset();
self.backend.encrypt_block(&mut tag);
self.cipher.encrypt_block(&mut tag);

Ok(Tag::try_from(&tag[..8]).expect("Tag is always 8 bytes"))
}
Expand All @@ -172,11 +183,11 @@ impl AeadInPlaceDetached for BeltDwp {

// 2.1. 𝑠 ← belt-block(𝑆, 𝐾);
let mut s = *nonce;
self.backend.encrypt_block(&mut s);
self.cipher.encrypt_block(&mut s);

// 2.2. 𝑟 ← belt-block(𝑠, 𝐾);
let mut r = s;
self.backend.encrypt_block(&mut r);
self.cipher.encrypt_block(&mut r);

// Initialize GHash
let mut ghash = GHash::new_with_init_block(
Expand All @@ -199,15 +210,15 @@ impl AeadInPlaceDetached for BeltDwp {

// 6. 𝑡 ← belt-block(𝑡 * 𝑟, 𝐾).
let mut tag_exact = ghash.finalize_reset();
self.backend.encrypt_block(&mut tag_exact);
self.cipher.encrypt_block(&mut tag_exact);

use subtle::ConstantTimeEq;
// 7. If 𝑇 != Lo(𝑡, 64), return ⊥
if tag_exact[..8].ct_eq(tag).into() {
// 8. For 𝑖 = 1,2,...,𝑛 do:
// 8.1. 𝑠 ← 𝑠 ⊞ ⟨1⟩128;
// 8.2. 𝑋𝑖 ← 𝑌𝑖 ⊕ Lo(belt-block(𝑠, 𝐾), |𝑌𝑖|)
let core = BeltCtrCore::inner_iv_init(&self.backend, nonce);
let core = BeltCtrCore::inner_iv_init(&self.cipher, nonce);
let mut enc_cipher = BeltCtr::from_core(core);
enc_cipher.apply_keystream(buffer);
Ok(())
Expand All @@ -217,18 +228,24 @@ impl AeadInPlaceDetached for BeltDwp {
}
}

impl PostfixTagged for BeltDwp {}
impl<C> PostfixTagged for BeltDwp<C> where C: BlockCipherEncrypt + BlockSizeUser<BlockSize = U16> {}

impl KeyInit for BeltDwp {
impl<C> KeyInit for BeltDwp<C>
where
C: BlockCipherEncrypt + BlockSizeUser<BlockSize = U16> + KeyInit,
{
fn new(key: &Key<Self>) -> Self {
Self {
backend: BeltBlock::new(key),
cipher: C::new(key),
}
}
}

impl AeadCore for BeltDwp {
type NonceSize = U16;
impl<C> AeadCore for BeltDwp<C>
where
C: BlockCipherEncrypt + BlockSizeUser<BlockSize = U16>,
{
type NonceSize = C::BlockSize;
type TagSize = U8;
}

Expand Down
11 changes: 7 additions & 4 deletions belt-dwp/tests/belt.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
use aead::AeadInPlaceDetached;
use belt_dwp::{BeltDwp, KeyInit};
use belt_block::BeltBlock;
use belt_dwp::KeyInit;
use hex_literal::hex;

type BeltDwp = belt_dwp::BeltDwp<BeltBlock>;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, just use BeltDwp with the default type parameter.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

   Compiling belt-dwp v0.1.0 (/Users/makavity/dev/crypto/AEADs/belt-dwp)
error[E0283]: type annotations needed for `BeltDwp<_>`
   --> belt-dwp/tests/belt.rs:39:13
    |
39  |         let belt_dwp = BeltDwp::new_from_slice(&vec.k).unwrap();
    |             ^^^^^^^^   ------- type must be known at this point
    |
    = note: cannot satisfy `_: cipher::block::BlockCipherEncrypt`
    = help: the following types implement trait `cipher::block::BlockCipherEncrypt`:
              &Alg
              BeltBlock
              cipher::tweak::zero::ZeroTweak<C>
note: required by a bound in `BeltDwp`
   --> /Users/makavity/dev/crypto/AEADs/belt-dwp/src/lib.rs:106:8
    |
104 | pub struct BeltDwp<C = BeltBlock>
    |            ------- required by a bound in this struct
105 | where
106 |     C: BlockCipherEncrypt + BlockSizeUser<BlockSize = U16>,
    |        ^^^^^^^^^^^^^^^^^^ required by this bound in `BeltDwp`
help: consider giving `belt_dwp` an explicit type, where the type for type parameter `C` is specified
    |
39  |         let belt_dwp: BeltDwp<C> = BeltDwp::new_from_slice(&vec.k).unwrap();
    |                     ++++++++++++

For more information about this error, try `rustc --explain E0283`.
error: could not compile `belt-dwp` (test "belt") due to 1 previous error

Should I use

let dwp: BeltDwp = BeltDwp::new_from_slice(&vec.k).unwrap();

?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Huh... weird. I guess one way to work around this issue is to write this:

pub struct Dwp<C> {
    cipher: C,
}

pub type BeltDwp = Dwp<BeltBlock>;

Though I am interested in learning why the default type parameter does not work here as expected.

Copy link
Contributor Author

@makavity makavity Mar 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The same problem is also in belt-ctr crate. Should I commit same fix for that?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, it's probably worth to define a generic Ctr type and BeltCtr = Ctr<BeltBlock> type alias on top of it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, thank you.
Fixed generic default by type alias, as you suggest.


/// Test from Appendix A, tables 19-20 of STB 34.101.31-2020:
/// https://apmi.bsu.by/assets/files/std/belt-spec372.pdf
#[test]
Expand Down Expand Up @@ -36,11 +39,11 @@ fn test_belt_dwp() {

for vec in test_vectors {
let mut x = vec.x;
let beltdwp = BeltDwp::new_from_slice(&vec.k).unwrap();
let tag = beltdwp.encrypt_in_place_detached(&vec.s.into(), &vec.i, &mut x);
let belt_dwp = BeltDwp::new_from_slice(&vec.k).unwrap();
let tag = belt_dwp.encrypt_in_place_detached(&vec.s.into(), &vec.i, &mut x);
assert_eq!(vec.t, *tag.unwrap());
assert_eq!(vec.y, x);
beltdwp
belt_dwp
.decrypt_in_place_detached(&vec.s.into(), &vec.i, &mut x, &tag.unwrap())
.unwrap();
assert_eq!(x, vec.x);
Expand Down
Loading