[kgm/ncm/kwm] refactor: improve performance for large file
This commit is contained in:
parent
fd73e8b9a3
commit
da806d7ad4
@ -15,9 +15,8 @@ impl DecipherV2 {
|
|||||||
|
|
||||||
impl Decipher for DecipherV2 {
|
impl Decipher for DecipherV2 {
|
||||||
fn decrypt(&self, buffer: &mut [u8], offset: usize) {
|
fn decrypt(&self, buffer: &mut [u8], offset: usize) {
|
||||||
let key_stream = self.key.iter().cycle().skip(offset % self.key.len());
|
for (datum, offset) in buffer.iter_mut().zip(offset..) {
|
||||||
for (datum, &k) in buffer.iter_mut().zip(key_stream) {
|
*datum ^= self.key[offset % self.key.len()];
|
||||||
*datum ^= k;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,34 +25,27 @@ impl DecipherV3 {
|
|||||||
|
|
||||||
Ok(Self { slot_key, file_key })
|
Ok(Self { slot_key, file_key })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn offset_key(offset: usize) -> u8 {
|
||||||
|
let offset_key = (offset as u32).to_ne_bytes();
|
||||||
|
offset_key[0] ^ offset_key[1] ^ offset_key[2] ^ offset_key[3]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Decipher for DecipherV3 {
|
impl Decipher for DecipherV3 {
|
||||||
fn decrypt(&self, buffer: &mut [u8], offset: usize) {
|
fn decrypt(&self, buffer: &mut [u8], offset: usize) {
|
||||||
let slot_key_stream = self
|
for (datum, offset) in buffer.iter_mut().zip(offset..) {
|
||||||
.slot_key
|
let offset_key = Self::offset_key(offset);
|
||||||
.iter()
|
|
||||||
.cycle()
|
|
||||||
.skip(offset % self.slot_key.len());
|
|
||||||
let file_key_stream = self
|
|
||||||
.file_key
|
|
||||||
.iter()
|
|
||||||
.cycle()
|
|
||||||
.skip(offset % self.file_key.len());
|
|
||||||
|
|
||||||
let mut offset = offset as u32;
|
let file_key = self.file_key[offset % self.file_key.len()];
|
||||||
let key_stream = slot_key_stream.zip(file_key_stream);
|
let slot_key = self.slot_key[offset % self.slot_key.len()];
|
||||||
for (datum, (&slot_key, &file_key)) in buffer.iter_mut().zip(key_stream) {
|
|
||||||
let offset_key = offset.to_ne_bytes().iter().fold(0, |acc, &x| acc ^ x);
|
|
||||||
|
|
||||||
let mut temp = *datum;
|
let mut temp = *datum;
|
||||||
temp ^= file_key;
|
temp ^= file_key;
|
||||||
temp ^= temp.wrapping_shl(4);
|
temp ^= temp << 4;
|
||||||
temp ^= slot_key;
|
temp ^= slot_key;
|
||||||
temp ^= offset_key;
|
temp ^= offset_key;
|
||||||
*datum = temp;
|
*datum = temp;
|
||||||
|
|
||||||
offset = offset.wrapping_add(1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,10 +11,8 @@ const KEY: [u8; 0x20] = [
|
|||||||
impl CipherV1 {
|
impl CipherV1 {
|
||||||
pub fn new(resource_id: u32) -> Self {
|
pub fn new(resource_id: u32) -> Self {
|
||||||
let mut key = KEY;
|
let mut key = KEY;
|
||||||
for (k, r) in key
|
let resource_id = resource_id.to_string();
|
||||||
.iter_mut()
|
for (k, &r) in key.iter_mut().zip(resource_id.as_bytes().iter().cycle()) {
|
||||||
.zip(resource_id.to_string().as_bytes().iter().cycle())
|
|
||||||
{
|
|
||||||
*k ^= r;
|
*k ^= r;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -26,10 +24,9 @@ impl CipherV1 {
|
|||||||
T: AsMut<[u8]> + ?Sized,
|
T: AsMut<[u8]> + ?Sized,
|
||||||
{
|
{
|
||||||
let data = data.as_mut();
|
let data = data.as_mut();
|
||||||
let key_stream = self.key.iter().cycle().skip(offset % self.key.len());
|
|
||||||
|
|
||||||
for (datum, key) in data.iter_mut().zip(key_stream) {
|
for (datum, offset) in data.iter_mut().zip(offset..) {
|
||||||
*datum ^= *key;
|
*datum ^= self.key[offset % self.key.len()];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -182,9 +182,8 @@ impl NCMFile {
|
|||||||
where
|
where
|
||||||
T: AsMut<[u8]> + ?Sized,
|
T: AsMut<[u8]> + ?Sized,
|
||||||
{
|
{
|
||||||
let key_stream = self.audio_rc4_key_stream.iter().cycle().skip(offset & 0xff);
|
for (datum, offset) in data.as_mut().iter_mut().zip(offset..) {
|
||||||
for (datum, &key) in data.as_mut().iter_mut().zip(key_stream) {
|
*datum ^= self.audio_rc4_key_stream[offset % self.audio_rc4_key_stream.len()];
|
||||||
*datum ^= key;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user