1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#![no_std]
pub use block_padding::{PadError, Padding, UnpadError};
use core::convert::Infallible;
use core::marker::PhantomData;
use consts::{U1, U256};
pub use typenum::consts;
use typenum::marker_traits::{NonZero, PowerOfTwo, Unsigned};
use typenum::operator_aliases::{Gr, LeEq};
use typenum::type_operators::{IsGreater, IsLessOrEqual};
use rand::RngCore;
#[cfg(not(features = "thread_rng"))]
type DefaultRng = rand::rngs::OsRng;
#[cfg(features = "thread_rng")]
type DefaultRng = rand::ThreadRng;
#[derive(Clone, Copy, Debug)]
pub enum TxPadding<N> {
_Phantom(Infallible, PhantomData<N>),
}
impl<N> Padding for TxPadding<N>
where
N: PowerOfTwo + Unsigned + IsLessOrEqual<U256> + IsGreater<U1>,
LeEq<N, U256>: NonZero,
Gr<N, U1>: NonZero,
{
fn pad_block(_block: &mut [u8], _pos: usize) -> Result<(), PadError> {
Err(PadError)
}
fn unpad(data: &[u8]) -> Result<&[u8], UnpadError> {
if data.is_empty() {
Err(UnpadError)?
}
let l = data.len();
let block_size = N::to_usize();
let pad_zero = block_size - 1;
let pad_len = (data[0] & (pad_zero as u8)) as usize + 2;
if l < pad_len + block_size {
Err(UnpadError)?
}
if data[l - pad_zero..l].iter().any(|&v| v != 0) {
Err(UnpadError)?
}
Ok(&data[1 + pad_len..l - pad_zero])
}
fn pad(buf: &mut [u8], pos: usize, block_size: usize) -> Result<&mut [u8], PadError> {
if block_size != N::to_usize() {
Err(PadError)?
}
let block_size = N::to_usize();
let be = block_size * ((pos + 1) / block_size + 2);
if buf.len() < be {
Err(PadError)?
}
let pad_zero = block_size - 1;
let pad_len = ((-(pos as isize) - 2).rem_euclid(block_size as isize)) as usize + 2;
buf.copy_within(..pos, 1 + pad_len);
DefaultRng::default()
.try_fill_bytes(&mut buf[1..1 + pad_len])
.map_err(|_| PadError)?;
buf[0] = !((block_size - 1) as u8) | (pad_len - 2) as u8;
unsafe {
core::ptr::write_bytes(buf[be - pad_zero..be].as_mut_ptr(), 0, pad_zero);
}
Ok(&mut buf[..be])
}
}