use crate::{
asymmetric::{
asymmetric::{AsymmetricRandState, qrc_asymmetric_secrand_generate},
cipher::mceliecebody::mceliecebase::{
qrc_mceliece_ref_decapsulate, qrc_mceliece_ref_encapsulate,
qrc_mceliece_ref_generate_keypair,
},
},
common::common::{
QRC_MCELIECE_S3N4608T96, QRC_MCELIECE_S5N6688T128, QRC_MCELIECE_S5N6960T119,
QRC_MCELIECE_S5N8192T128,
},
prng::secrand::{qrc_secrand_destroy, qrc_secrand_initialize},
};
#[cfg(feature = "no_std")]
use alloc::vec::Vec;
pub const QRC_MCELIECE_CIPHERTEXT_SIZE: usize = if QRC_MCELIECE_S3N4608T96 {
188
} else if QRC_MCELIECE_S5N6688T128 {
240
} else if QRC_MCELIECE_S5N6960T119 {
226
} else if QRC_MCELIECE_S5N8192T128 {
240
} else {
0
};
pub const QRC_MCELIECE_PRIVATEKEY_SIZE: usize = if QRC_MCELIECE_S3N4608T96 {
13608
} else if QRC_MCELIECE_S5N6688T128 {
13932
} else if QRC_MCELIECE_S5N6960T119 {
13948
} else if QRC_MCELIECE_S5N8192T128 {
14120
} else {
0
};
pub const QRC_MCELIECE_PUBLICKEY_SIZE: usize = if QRC_MCELIECE_S3N4608T96 {
524160
} else if QRC_MCELIECE_S5N6688T128 {
1044992
} else if QRC_MCELIECE_S5N6960T119 {
1047319
} else if QRC_MCELIECE_S5N8192T128 {
1357824
} else {
0
};
pub const QRC_MCELIECE_SEED_SIZE: usize = 32;
pub const QRC_MCELIECE_SHAREDSECRET_SIZE: usize = 32;
pub const QRC_MCELIECE_ALGNAME: &str = "MCELIECE";
pub fn qrc_mceliece_decapsulate(
secret: &mut [u8; QRC_MCELIECE_SHAREDSECRET_SIZE],
ciphertext: &[u8; QRC_MCELIECE_CIPHERTEXT_SIZE],
privatekey: &[u8],
) -> bool {
if privatekey.len() == QRC_MCELIECE_PRIVATEKEY_SIZE {
return qrc_mceliece_ref_decapsulate(secret, ciphertext, privatekey) == 0;
} else {
return false;
}
}
pub fn qrc_mceliece_decrypt(
secret: &mut [u8; QRC_MCELIECE_SHAREDSECRET_SIZE],
ciphertext: &[u8; QRC_MCELIECE_CIPHERTEXT_SIZE],
privatekey: &[u8],
) -> bool {
return qrc_mceliece_decapsulate(secret, ciphertext, privatekey);
}
pub fn qrc_mceliece_encapsulate(
asymmetric_state: &mut AsymmetricRandState,
secret: &mut [u8; QRC_MCELIECE_SHAREDSECRET_SIZE],
ciphertext: &mut [u8; QRC_MCELIECE_CIPHERTEXT_SIZE],
publickey: &[u8],
rng_generate: fn(&mut AsymmetricRandState, &mut [u8], usize) -> bool,
) {
if publickey.len() == QRC_MCELIECE_PUBLICKEY_SIZE {
qrc_mceliece_ref_encapsulate(
asymmetric_state,
ciphertext,
secret,
publickey,
rng_generate,
);
}
}
pub fn qrc_mceliece_encrypt(
secret: &mut [u8; QRC_MCELIECE_SHAREDSECRET_SIZE],
ciphertext: &mut [u8; QRC_MCELIECE_CIPHERTEXT_SIZE],
publickey: &[u8],
seed: [u8; QRC_MCELIECE_SEED_SIZE],
) {
if publickey.len() == QRC_MCELIECE_PUBLICKEY_SIZE {
let asymmetric_state = &mut AsymmetricRandState::default();
qrc_secrand_initialize(
&mut asymmetric_state.secrand_state,
&seed,
QRC_MCELIECE_SEED_SIZE,
&[],
0,
);
qrc_mceliece_encapsulate(
asymmetric_state,
secret,
ciphertext,
publickey,
qrc_asymmetric_secrand_generate,
);
qrc_secrand_destroy(&mut asymmetric_state.secrand_state);
}
}
pub fn qrc_mceliece_generate_keypair(
publickey: &mut [u8],
privatekey: &mut Vec<u8>,
seed: [u8; QRC_MCELIECE_SEED_SIZE],
) {
if privatekey.len() == QRC_MCELIECE_PRIVATEKEY_SIZE
&& publickey.len() == QRC_MCELIECE_PUBLICKEY_SIZE
{
let asymmetric_state = &mut AsymmetricRandState::default();
qrc_secrand_initialize(
&mut asymmetric_state.secrand_state,
&seed,
QRC_MCELIECE_SEED_SIZE,
&[],
0,
);
qrc_mceliece_gen_keypair(
asymmetric_state,
publickey,
privatekey,
qrc_asymmetric_secrand_generate,
);
qrc_secrand_destroy(&mut asymmetric_state.secrand_state);
}
}
pub fn qrc_mceliece_gen_keypair(
asymmetric_state: &mut AsymmetricRandState,
publickey: &mut [u8],
privatekey: &mut [u8],
rng_generate: fn(&mut AsymmetricRandState, &mut [u8], usize) -> bool,
) {
if privatekey.len() == QRC_MCELIECE_PRIVATEKEY_SIZE
&& publickey.len() == QRC_MCELIECE_PUBLICKEY_SIZE
{
qrc_mceliece_ref_gen_keypair(asymmetric_state, publickey, privatekey, rng_generate);
}
}
fn qrc_mceliece_ref_gen_keypair(
asymmetric_state: &mut AsymmetricRandState,
publickey: &mut [u8],
privatekey: &mut [u8],
rng_generate: fn(&mut AsymmetricRandState, &mut [u8], usize) -> bool,
) {
if privatekey.len() == QRC_MCELIECE_PRIVATEKEY_SIZE
&& publickey.len() == QRC_MCELIECE_PUBLICKEY_SIZE
{
qrc_mceliece_ref_generate_keypair(asymmetric_state, publickey, privatekey, rng_generate);
}
}