bouncycastle_factory/
xof_factory.rs1use crate::{AlgorithmFactory, FactoryError};
37use bouncycastle_core::errors::HashError;
38use bouncycastle_core::traits::{KDF, SecurityStrength, XOF};
39use bouncycastle_sha3 as sha3;
40use bouncycastle_sha3::{SHAKE128_NAME, SHAKE256_NAME};
41
42pub const DEFAULT_XOF_NAME: &str = SHAKE128_NAME;
45pub const DEFAULT_128BIT_XOF_NAME: &str = SHAKE128_NAME;
47pub const DEFAULT_256BIT_XOF_NAME: &str = SHAKE256_NAME;
49
50pub enum XOFFactory {
52 SHAKE128(sha3::SHAKE128),
54 SHAKE256(sha3::SHAKE256),
56}
57
58impl Default for XOFFactory {
59 fn default() -> Self {
60 Self::new(DEFAULT_XOF_NAME).unwrap()
61 }
62}
63
64impl AlgorithmFactory for XOFFactory {
65 fn default_128_bit() -> Self {
66 Self::new(DEFAULT_128BIT_XOF_NAME).unwrap()
67 }
68
69 fn default_256_bit() -> Self {
70 Self::new(DEFAULT_256BIT_XOF_NAME).unwrap()
71 }
72
73 fn new(alg_name: &str) -> Result<Self, FactoryError> {
74 match alg_name {
75 SHAKE128_NAME => Ok(Self::SHAKE128(sha3::SHAKE128::new())),
76 SHAKE256_NAME => Ok(Self::SHAKE256(sha3::SHAKE256::new())),
77 _ => Err(FactoryError::UnsupportedAlgorithm(format!(
78 "The algorithm: \"{}\" is not a known XOF",
79 alg_name
80 ))),
81 }
82 }
83}
84impl XOF for XOFFactory {
85 fn hash_xof(self, data: &[u8], result_len: usize) -> Vec<u8> {
86 match self {
87 Self::SHAKE128(h) => h.hash_xof(data, result_len),
88 Self::SHAKE256(h) => h.hash_xof(data, result_len),
89 }
90 }
91
92 fn hash_xof_out(self, data: &[u8], output: &mut [u8]) -> usize {
93 output.fill(0);
94
95 match self {
96 Self::SHAKE128(h) => h.hash_xof_out(data, output),
97 Self::SHAKE256(h) => h.hash_xof_out(data, output),
98 }
99 }
100
101 fn absorb(&mut self, data: &[u8]) -> Result<(), HashError> {
102 match self {
103 Self::SHAKE128(h) => h.absorb(data),
104 Self::SHAKE256(h) => h.absorb(data),
105 }
106 }
107
108 fn absorb_last_partial_byte(
109 &mut self,
110 partial_byte: u8,
111 num_partial_bits: usize,
112 ) -> Result<(), HashError> {
113 match self {
114 Self::SHAKE128(h) => h.absorb_last_partial_byte(partial_byte, num_partial_bits),
115 Self::SHAKE256(h) => h.absorb_last_partial_byte(partial_byte, num_partial_bits),
116 }
117 }
118
119 fn squeeze(&mut self, num_bytes: usize) -> Vec<u8> {
120 match self {
121 Self::SHAKE128(h) => h.squeeze(num_bytes),
122 Self::SHAKE256(h) => h.squeeze(num_bytes),
123 }
124 }
125
126 fn squeeze_out(&mut self, output: &mut [u8]) -> usize {
127 output.fill(0);
128
129 match self {
130 Self::SHAKE128(h) => h.squeeze_out(output),
131 Self::SHAKE256(h) => h.squeeze_out(output),
132 }
133 }
134
135 fn squeeze_partial_byte_final(self, num_bits: usize) -> Result<u8, HashError> {
136 match self {
137 Self::SHAKE128(h) => h.squeeze_partial_byte_final(num_bits),
138 Self::SHAKE256(h) => h.squeeze_partial_byte_final(num_bits),
139 }
140 }
141
142 fn squeeze_partial_byte_final_out(
143 self,
144 num_bits: usize,
145 output: &mut u8,
146 ) -> Result<(), HashError> {
147 *output = 0;
148
149 match self {
150 Self::SHAKE128(h) => h.squeeze_partial_byte_final_out(num_bits, output),
151 Self::SHAKE256(h) => h.squeeze_partial_byte_final_out(num_bits, output),
152 }
153 }
154
155 fn max_security_strength(&self) -> SecurityStrength {
156 match self {
157 Self::SHAKE128(h) => KDF::max_security_strength(h),
158 Self::SHAKE256(h) => XOF::max_security_strength(h),
159 }
160 }
161}