Romove big files. Wrapping things up.
This commit is contained in:
@@ -0,0 +1,344 @@
|
||||
use std::time::Duration;
|
||||
|
||||
use tokio;
|
||||
use tonic;
|
||||
use tonic::transport::Channel;
|
||||
//use tonic::{Request, Response, Status};
|
||||
pub mod nyash_proto {
|
||||
tonic::include_proto!("nyash_proto"); // The string specified here must match the proto package name
|
||||
}
|
||||
|
||||
use nyash_proto::nyash_luks_client::NyashLuksClient;
|
||||
use nyash_proto::{
|
||||
CommitReply, KeyData, ProgressReply, ProgressRequest, WorkCommit, WorkReply,
|
||||
WorkRequest, work_commit, work_reply,
|
||||
};
|
||||
|
||||
use std::sync::{Arc};
|
||||
use tokio::sync::RwLock as AsyncRwLock;
|
||||
|
||||
use crate::ocl_utils::ExecData;
|
||||
|
||||
pub mod client_config;
|
||||
pub mod num_utils;
|
||||
pub mod ocl_utils;
|
||||
mod search_params;
|
||||
//mod test_cl;
|
||||
|
||||
const S_ADDR: &str = "http://127.0.0.1:37939";
|
||||
// const SRC_PATH: &str = "src/open_cl/nyash_aes_xts256_plain.cl";
|
||||
// const OCL_COMP_OPT: &str = "-I src/open_cl";
|
||||
const CONF_RILE_NAME: &str = "nyash_conf.json";
|
||||
|
||||
|
||||
async fn shutdown_signal() {
|
||||
let ctrl_c = async {
|
||||
tokio::signal::ctrl_c()
|
||||
.await
|
||||
.expect("Failed to install Ctrl+C handler");
|
||||
};
|
||||
|
||||
#[cfg(unix)]
|
||||
let terminate = async {
|
||||
tokio::signal::unix::signal(tokio::signal::unix::SignalKind::terminate())
|
||||
.expect("Failed to install SIGTERM handler")
|
||||
.recv()
|
||||
.await;
|
||||
};
|
||||
|
||||
#[cfg(not(unix))]
|
||||
let terminate = std::future::pending::<()>();
|
||||
|
||||
tokio::select! {
|
||||
_ = ctrl_c => println!("Received Ctrl+C, initiating shutdown"),
|
||||
_ = terminate => println!("Received SIGTERM, initiating shutdown"),
|
||||
}
|
||||
}
|
||||
|
||||
fn key_dat_from_exec_dat(ex_dat: &ExecData) -> KeyData {
|
||||
let t_k = num_utils::u128_to_u64arr(num_utils::u32arr_to_u128(num_utils::vec_to_u32_4arr(
|
||||
&ex_dat.tweak_key,
|
||||
0,
|
||||
)));
|
||||
let e_k = num_utils::u128_to_u64arr(ex_dat.get_found_key());
|
||||
|
||||
KeyData {
|
||||
start_key0: e_k[0],
|
||||
start_key1: e_k[1],
|
||||
tweak_key0: t_k[0],
|
||||
tweak_key1: t_k[1],
|
||||
}
|
||||
}
|
||||
|
||||
async fn get_progress(chanel: Channel) -> Result<ProgressReply, tonic::Status> {
|
||||
let mut client = NyashLuksClient::new(chanel);
|
||||
|
||||
let request = tonic::Request::new(ProgressRequest {});
|
||||
let response = client.request_progress(request).await?;
|
||||
return Ok(response.into_inner());
|
||||
}
|
||||
|
||||
async fn get_work(chanel: Channel, work_size: u64) -> Result<WorkReply, tonic::Status> {
|
||||
let mut client = NyashLuksClient::new(chanel);
|
||||
|
||||
println!("Requesting work {} keys...", work_size);
|
||||
let request = tonic::Request::new(WorkRequest {
|
||||
pref_work_size: work_size,
|
||||
});
|
||||
let response = client.request_work(request).await?;
|
||||
return Ok(response.into_inner());
|
||||
}
|
||||
|
||||
async fn commit_work(
|
||||
chanel: Channel,
|
||||
commit_data: WorkCommit,
|
||||
) -> Result<CommitReply, tonic::Status> {
|
||||
let mut client = NyashLuksClient::new(chanel);
|
||||
|
||||
let request = tonic::Request::new(commit_data);
|
||||
let response = client.commit_work(request).await?;
|
||||
return Ok(response.into_inner());
|
||||
}
|
||||
|
||||
fn benchmark(exec_context: &mut ocl_utils::ExecContext) -> (u64, usize) {
|
||||
let mut nyan_exec_dat = ocl_utils::ExecData {
|
||||
start_key: vec![1u32; 4],
|
||||
tweak_key: vec![2u32; 4],
|
||||
uenc_data: vec![0u32; 4],
|
||||
target_data: vec![0u32; 4],
|
||||
tweak_i: 0,
|
||||
tweak_j: 0,
|
||||
key_found: vec![0u32; 5],
|
||||
batch_size: 10000000,
|
||||
work_size: 128,
|
||||
};
|
||||
|
||||
let total_work: u64 = 1280000000;
|
||||
let work_sizes: [usize; 8] = [128, 256, 512, 1024, 2048, 4096, 8192, 16384];
|
||||
let mut work_time = [0f64; 8];
|
||||
|
||||
ocl_utils::set_target_data(exec_context, &mut nyan_exec_dat).expect("Error set target data!");
|
||||
|
||||
let mut preffered_work_size: usize = work_sizes[0];
|
||||
let mut preffered_batch_size: u64 = 0;
|
||||
for i in 0..8 {
|
||||
let test_work_s = work_sizes[i];
|
||||
let batch_size: u64 = total_work / test_work_s as u64;
|
||||
nyan_exec_dat.work_size = test_work_s;
|
||||
nyan_exec_dat.batch_size = batch_size;
|
||||
println!("Benchmarking work size {}", test_work_s);
|
||||
for _j in 0..3 {
|
||||
let (_, exec_time) =
|
||||
ocl_utils::do_work(exec_context, &mut nyan_exec_dat).expect("Error running tests!");
|
||||
work_time[i] += exec_time;
|
||||
}
|
||||
work_time[i] = work_time[i] / 3.0;
|
||||
println!("Average time {}", work_time[i]);
|
||||
if i > 0 {
|
||||
//giving 5% error for speed mesure
|
||||
if (work_time[i]*1.05) > work_time[i - 1] {
|
||||
break;
|
||||
}
|
||||
}
|
||||
preffered_work_size = work_sizes[i];
|
||||
// calculate batch size so it correspond to 30 sec job
|
||||
preffered_batch_size = (batch_size as f64 * (20.0 / work_time[i])) as u64;
|
||||
println!("batch_size {}, work_time {}, preffered_batch_size {}, preffered_work_size {}",
|
||||
batch_size,
|
||||
work_time[i],
|
||||
preffered_batch_size,
|
||||
preffered_work_size);
|
||||
}
|
||||
|
||||
return (preffered_batch_size, preffered_work_size);
|
||||
}
|
||||
|
||||
#[tokio::main(flavor = "current_thread")]
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
const OCL_NYAS_GZ_SRC: &[u8] =
|
||||
include_bytes!(concat!(env!("OUT_DIR"), "/nyash_aes_full.cl.gz"));
|
||||
|
||||
println!("OCL bin src lenght {}", OCL_NYAS_GZ_SRC.len());
|
||||
println!("Hello, world nya!");
|
||||
//use ocl::{Buffer, Context, Device, Kernel, Platform, Program, Queue, flags};
|
||||
let (devices, mut app_conf) =
|
||||
client_config::get_devices_conf(CONF_RILE_NAME).expect("Error loading config!");
|
||||
|
||||
let nyash_dev = devices[0].0;
|
||||
let nyash_plt = devices[0].1;
|
||||
//
|
||||
println!(
|
||||
"Platform: {:?}, Device: {:?}",
|
||||
nyash_plt.name().unwrap(),
|
||||
nyash_dev.name().unwrap()
|
||||
);
|
||||
|
||||
// reading ocl program sources
|
||||
//let prog_src = std::fs::read_to_string(SRC_PATH).expect("Error reading program sources!");
|
||||
|
||||
let mut exec_context: ocl_utils::ExecContext = ocl_utils::ExecContext::new(
|
||||
nyash_dev,
|
||||
nyash_plt,
|
||||
OCL_NYAS_GZ_SRC,
|
||||
1024
|
||||
)
|
||||
.expect("Error creating exec context!");
|
||||
|
||||
// need to train in order to learn optimal params
|
||||
|
||||
// need to train in order to learn optimal params
|
||||
if (app_conf.devices[0].batch_size == 0) || (app_conf.devices[0].work_size == 0) {
|
||||
println!("Performing banchmark to determine optimal GPU parameters...");
|
||||
let (batch_size, work_size) = benchmark(&mut exec_context);
|
||||
println!("batch_size {}, work_size {}", batch_size, work_size);
|
||||
app_conf.devices[0].batch_size = batch_size;
|
||||
app_conf.devices[0].work_size = work_size;
|
||||
client_config::save_config(CONF_RILE_NAME, &app_conf).expect("Error saving config!");
|
||||
}
|
||||
|
||||
let nyash_dev_cfg = &app_conf.devices[0];
|
||||
println!(
|
||||
"Preffered Work size: {}, Batch size {}",
|
||||
nyash_dev_cfg.work_size, nyash_dev_cfg.batch_size
|
||||
);
|
||||
|
||||
let (_, _, encrypted_data) = search_params::get_params();
|
||||
//setting data
|
||||
let mut nyan_exec_dat = ocl_utils::ExecData {
|
||||
start_key: Vec::new(),
|
||||
tweak_key: Vec::new(),
|
||||
uenc_data: vec![0u32; 4],
|
||||
target_data: encrypted_data.to_vec(),
|
||||
tweak_i: 0,
|
||||
tweak_j: 0,
|
||||
key_found: vec![0u32; 5],
|
||||
batch_size: nyash_dev_cfg.batch_size,
|
||||
work_size: nyash_dev_cfg.work_size,
|
||||
};
|
||||
println!(
|
||||
"nyan_exec_dat Work size: {}, Batch size {}",
|
||||
nyan_exec_dat.work_size, nyan_exec_dat.batch_size
|
||||
);
|
||||
|
||||
|
||||
ocl_utils::set_target_data(&mut exec_context, &mut nyan_exec_dat)
|
||||
.expect("Error setting target data!");
|
||||
|
||||
// Don't keep connection alive when idle
|
||||
let nya_channel: tonic::transport::Channel = tonic::transport::Endpoint::from_static(S_ADDR)
|
||||
.keep_alive_while_idle(false)
|
||||
.keep_alive_timeout(Duration::from_secs(10))
|
||||
.connect_timeout(Duration::from_secs(10))
|
||||
.connect()
|
||||
.await
|
||||
.expect("Error connecting to server!");
|
||||
|
||||
let key_found = match get_progress(nya_channel.clone()).await {
|
||||
Err(_) => {
|
||||
println!("Error getting progress!");
|
||||
false
|
||||
}
|
||||
Ok(p_r) => {
|
||||
println!("Current progress {:.8}%", p_r.progress * 100.0);
|
||||
p_r.key_found
|
||||
}
|
||||
};
|
||||
|
||||
let mut giga_keys_per_second: f64 = 0f64;
|
||||
let req_work_size: u64 = nyash_dev_cfg.batch_size as u64 * nyash_dev_cfg.work_size as u64;
|
||||
|
||||
|
||||
let shared_key_found = Arc::new(AsyncRwLock::new(key_found));
|
||||
// handling program termination
|
||||
let sh_k_f_clone = shared_key_found.clone();
|
||||
tokio::spawn(async move {
|
||||
shutdown_signal().await;
|
||||
//signaling that we should stop
|
||||
let mut guard = sh_k_f_clone.write().await;
|
||||
*guard = true;
|
||||
});
|
||||
|
||||
while *shared_key_found.read().await == false {
|
||||
let mut work = get_work(nya_channel.clone(), req_work_size).await;
|
||||
while work.is_err() {
|
||||
println!("Error getting work, waiting 10 seconds and trying again...");
|
||||
tokio::time::sleep(Duration::from_secs(10)).await;
|
||||
work = get_work(nya_channel.clone(), req_work_size).await;
|
||||
}
|
||||
let work = work.expect("Error getting work!");
|
||||
|
||||
let work_data = match work.result.expect("Error! Expected WorkResult!") {
|
||||
work_reply::Result::NoWork(_) => {
|
||||
println!("No work right now, try again later...");
|
||||
continue;
|
||||
}
|
||||
work_reply::Result::Error(ex) => {
|
||||
println!("Erro getting work: {}", ex);
|
||||
continue;
|
||||
}
|
||||
work_reply::Result::WorkData(wd) => wd,
|
||||
};
|
||||
println!("Got work, {} keys...", work_data.work_size);
|
||||
nyan_exec_dat.start_key = num_utils::u128_to_u32arr(num_utils::u64arr_to_u128([
|
||||
work_data.start_key0,
|
||||
work_data.start_key1,
|
||||
]))
|
||||
.to_vec();
|
||||
nyan_exec_dat.tweak_key = num_utils::u128_to_u32arr(num_utils::u64arr_to_u128([
|
||||
work_data.tweak_key0,
|
||||
work_data.tweak_key1,
|
||||
]))
|
||||
.to_vec();
|
||||
|
||||
let mut batch_size = work_data.work_size / nyan_exec_dat.work_size as u64;
|
||||
if (work_data.work_size % nyan_exec_dat.work_size as u64) != 0 {
|
||||
batch_size += 1;
|
||||
}
|
||||
println!("Setting batch size to {}", batch_size);
|
||||
nyan_exec_dat.batch_size = batch_size;
|
||||
|
||||
println!("Crunching numbers...");
|
||||
match ocl_utils::do_work(&mut exec_context, &mut nyan_exec_dat) {
|
||||
Err(_) => println!("Error doing work!"),
|
||||
Ok((k_f, work_time)) => {
|
||||
let mut w_k = WorkCommit {
|
||||
work_id: work_data.work_id,
|
||||
result: Some(work_commit::Result::NoKey(true)),
|
||||
};
|
||||
|
||||
let g_k_p_s = (work_data.work_size as f64 / work_time) / 1000000000.0;
|
||||
if giga_keys_per_second != 0f64 {
|
||||
giga_keys_per_second -= giga_keys_per_second / 10.0;
|
||||
giga_keys_per_second += g_k_p_s / 10.0;
|
||||
} else {
|
||||
giga_keys_per_second = g_k_p_s;
|
||||
}
|
||||
println!("Average speed: {:.3}GigaKeys/Sec", giga_keys_per_second);
|
||||
if k_f == true {
|
||||
println!(
|
||||
"We found the key! {:?} {:?}",
|
||||
nyan_exec_dat.key_found, nyan_exec_dat.tweak_key
|
||||
);
|
||||
|
||||
//signaling that key found
|
||||
let mut guard = shared_key_found.write().await;
|
||||
*guard = true;
|
||||
|
||||
w_k.result = Some(work_commit::Result::FoundKey(key_dat_from_exec_dat(
|
||||
&nyan_exec_dat,
|
||||
)));
|
||||
}
|
||||
|
||||
let resp = commit_work(nya_channel.clone(), w_k).await;
|
||||
match resp {
|
||||
Ok(c_r) => println!("Work commited. Progress: {:.8}%", c_r.progress * 100.0),
|
||||
Err(_) => println!("Error commiting work..."),
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
println!("Exiting!");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -1,7 +1,8 @@
|
||||
use ocl::{Device, Platform};
|
||||
use ocl::{Device, Platform, DeviceType, flags};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json;
|
||||
use std::error::Error;
|
||||
use std::{io};
|
||||
|
||||
#[derive(Clone, Deserialize, Serialize, Debug)]
|
||||
pub struct DevConf {
|
||||
@@ -9,7 +10,7 @@ pub struct DevConf {
|
||||
pub platform_name: String,
|
||||
pub id: usize,
|
||||
pub work_size: usize,
|
||||
pub batch_size: u32,
|
||||
pub batch_size: u64,
|
||||
}
|
||||
|
||||
impl DevConf {
|
||||
@@ -68,7 +69,130 @@ pub fn load_config(file_name: &str) -> Result<AppConfig, Box<dyn Error>> {
|
||||
}
|
||||
|
||||
pub fn save_config(file_name: &str, app_conf: &AppConfig) -> Result<(), Box<dyn Error>> {
|
||||
let conf_str = serde_json::to_string(app_conf)?;
|
||||
let conf_str = serde_json::to_string_pretty(app_conf)?;
|
||||
std::fs::write(file_name, conf_str)?;
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
fn dev_type_from_str(s: &str) -> Result<flags::DeviceType, ()> {
|
||||
match s {
|
||||
"CPU" => Ok(flags::DeviceType::CPU),
|
||||
"GPU" => Ok(flags::DeviceType::GPU),
|
||||
"ALL" => Ok(flags::DeviceType::ALL),
|
||||
"CUSTOM" => Ok(flags::DeviceType::CUSTOM),
|
||||
"ACCELERATOR" => Ok(flags::DeviceType::ACCELERATOR),
|
||||
"DEFAULT" => Ok(flags::DeviceType::DEFAULT),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
|
||||
fn str_or_empty(r: ocl::error::Result<String>) -> String {
|
||||
match r {
|
||||
Ok(s) => s,
|
||||
Err(_) => "".to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
fn print_devices(dev_list: &Vec<(Device, Platform)>) {
|
||||
let mut i = 0;
|
||||
for (dev, plt) in dev_list.iter() {
|
||||
let dev_name = str_or_empty(dev.name());
|
||||
let plt_name = str_or_empty(plt.name());
|
||||
println!("({i}) device: \"{dev_name}\" ----- platorm: \"{plt_name}\"");
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
|
||||
fn choose_devices(devices_num: usize) -> Result<Vec<usize>, String> {
|
||||
println!("Please input desired device to use as a number and press Enter.");
|
||||
let mut result: Vec<usize> = Vec::new();
|
||||
|
||||
let mut s_devs_nums = String::new();
|
||||
|
||||
io::stdin()
|
||||
.read_line(&mut s_devs_nums)
|
||||
.expect("Failed to read line");
|
||||
|
||||
for s_dev_num in s_devs_nums.split(' ') {
|
||||
let dev_num: usize = match s_dev_num.trim().parse() {
|
||||
Ok(num) => num,
|
||||
Err(_) => return Err("You must input a number from device list.".to_string()),
|
||||
};
|
||||
if dev_num >= devices_num {
|
||||
return Err("You must input a number from device list.".to_string());
|
||||
};
|
||||
result.push(dev_num);
|
||||
}
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
fn list_devices(dev_type: DeviceType) -> Vec<(Device, Platform)> {
|
||||
let platforms = Platform::list();
|
||||
let mut devices: Vec<(Device, Platform)> = Vec::new();
|
||||
for plt in platforms.iter() {
|
||||
//let plat_name = str_or_empty(plt.name());
|
||||
let list_res = Device::list(plt, Some(dev_type));
|
||||
match list_res {
|
||||
Ok(dev_l) => devices.extend(dev_l.iter().map(|dev| (*dev, plt.clone()))),
|
||||
Err(_) => {}
|
||||
}
|
||||
}
|
||||
return devices;
|
||||
}
|
||||
|
||||
|
||||
fn dev_sel_dialog(all_devices: &Vec<(Device, Platform)>) -> Vec<usize> {
|
||||
let devs_nums = loop {
|
||||
print_devices(&all_devices);
|
||||
match choose_devices(all_devices.len()) {
|
||||
Ok(value) => break value,
|
||||
Err(exc) => {
|
||||
println!("Error! {exc}\n")
|
||||
}
|
||||
}
|
||||
};
|
||||
return devs_nums;
|
||||
}
|
||||
|
||||
pub fn get_devices_conf(file_name: &str) -> Result<(Vec<(Device, Platform)>, AppConfig), String> {
|
||||
let dev_type = dev_type_from_str("GPU").expect("Unexpected device type!");
|
||||
|
||||
// Get devices to be used for key search
|
||||
let all_devices: Vec<(Device, Platform)> = list_devices(dev_type);
|
||||
if all_devices.len() == 0 {
|
||||
return Err("Cannot find any usable devices.".to_string());
|
||||
};
|
||||
|
||||
let app_conf = match load_config(file_name) {
|
||||
Ok(readed_config) => {
|
||||
let dev_found = all_devices
|
||||
.iter()
|
||||
.filter(|dp| readed_config.device_exist(&dp.0))
|
||||
.count();
|
||||
if dev_found < readed_config.devices.len() {
|
||||
println!("Devices from config not found in the system!");
|
||||
let devs_nums = dev_sel_dialog(&all_devices);
|
||||
let res = AppConfig::from_dev_list(&all_devices, devs_nums);
|
||||
save_config(file_name, &res).expect("Error saving config!");
|
||||
res
|
||||
} else {
|
||||
readed_config
|
||||
}
|
||||
}
|
||||
Err(_) => {
|
||||
println!("Cannot find config file {}", file_name);
|
||||
let devs_nums = dev_sel_dialog(&all_devices);
|
||||
let res = AppConfig::from_dev_list(&all_devices, devs_nums);
|
||||
save_config(file_name, &res).expect("Error saving config!");
|
||||
res
|
||||
}
|
||||
};
|
||||
|
||||
let selected_devs = all_devices
|
||||
.iter()
|
||||
.filter(|dp| app_conf.device_exist(&dp.0))
|
||||
.cloned()
|
||||
.collect();
|
||||
|
||||
return Ok((selected_devs, app_conf));
|
||||
}
|
||||
+320
-251
@@ -3,265 +3,334 @@
|
||||
// i: [u32; 2],
|
||||
// }
|
||||
|
||||
fn add_u32_to_u256(a: &[u32; 8], b: u32) -> ([u32; 8], bool) {
|
||||
let mut res: [u32; 8] = [0; 8];
|
||||
let mut carry = false;
|
||||
(res[0], carry) = a[0].carrying_add(b, carry);
|
||||
|
||||
for idx in 1..8 {
|
||||
(res[idx], carry) = a[idx].carrying_add(0, carry);
|
||||
pub fn vec_to_u32_4arr(in_v: &Vec<u32>, start_idx: usize) -> [u32; 4] {
|
||||
let mut u32_arr_k = [0u32; 4];
|
||||
for i in 0..4 {
|
||||
u32_arr_k[0] = in_v[start_idx + i];
|
||||
}
|
||||
|
||||
return (res, carry);
|
||||
return u32_arr_k;
|
||||
}
|
||||
|
||||
fn add_u32_to_u256_(a: &mut [u32; 8], b: u32) -> bool {
|
||||
let mut carry = false;
|
||||
(a[0], carry) = a[0].carrying_add(b, carry);
|
||||
|
||||
for idx in 1..8 {
|
||||
(a[idx], carry) = a[idx].carrying_add(0, carry);
|
||||
pub fn u128_to_u64arr(a: u128) -> [u64; 2] {
|
||||
let mut res = [0u64; 2];
|
||||
let a_bytes = a.to_le_bytes();
|
||||
let chunks = a_bytes.as_chunks::<8>().0;
|
||||
for i in 0..2 {
|
||||
res[i] = u64::from_le_bytes(chunks[i]);
|
||||
}
|
||||
|
||||
return carry;
|
||||
}
|
||||
|
||||
fn bytes_from_chars(chars_chunk: &[char]) -> [u8; 4] {
|
||||
let mut res: [u8; 4] = [0; 4];
|
||||
let mut idx: usize = 0;
|
||||
chars_chunk.chunks_exact(2).for_each(|b_c| {
|
||||
if idx < 4 {
|
||||
match u8::from_str_radix(&b_c.iter().collect::<String>(), 16) {
|
||||
Ok(n) => res[idx] = n,
|
||||
Err(_) => (),
|
||||
}
|
||||
idx += 1;
|
||||
}
|
||||
});
|
||||
return res;
|
||||
}
|
||||
|
||||
fn bignum_from_hex(hex: &str) -> [u32; 8] {
|
||||
let mut res: [u32; 8] = [0; 8];
|
||||
let mut idx: usize = 0;
|
||||
let chars_hex = hex.chars().collect::<Vec<char>>();
|
||||
chars_hex
|
||||
.chunks_exact(8)
|
||||
.rev()
|
||||
.map(|chunk| bytes_from_chars(chunk))
|
||||
.for_each(|b_arr| {
|
||||
if idx < 8 {
|
||||
res[idx] = u32::from_be_bytes(b_arr);
|
||||
idx += 1;
|
||||
}
|
||||
});
|
||||
return res;
|
||||
pub fn u64arr_to_u128(a: [u64; 2]) -> u128 {
|
||||
let mut bytes_data: [u8; 16] = [0u8; 16];
|
||||
bytes_data[0..8].copy_from_slice(a[0].to_le_bytes().as_slice());
|
||||
bytes_data[8..].copy_from_slice(a[1].to_le_bytes().as_slice());
|
||||
|
||||
return u128::from_le_bytes(bytes_data);
|
||||
}
|
||||
|
||||
fn hex_fmt_byte(n: u32) -> String {
|
||||
let res: String = n
|
||||
.to_be_bytes()
|
||||
.iter()
|
||||
.map(|b| format!("{:02x}", b))
|
||||
.collect();
|
||||
return res;
|
||||
}
|
||||
|
||||
fn bignum_to_hex(a: &[u32; 8]) -> String {
|
||||
let res: String = a
|
||||
.iter()
|
||||
.rev()
|
||||
.map(|n| hex_fmt_byte(*n))
|
||||
.collect::<Vec<String>>()
|
||||
.join("");
|
||||
return res;
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod num_utils_tests {
|
||||
use std::io::Read;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_add() {
|
||||
use std::io::{BufRead, BufReader};
|
||||
use std::process::{Command, Stdio};
|
||||
|
||||
let test_gen_cmd = "/home/kira/Development/Rust/nyash-aes-xts256-plain64/nyash_client/src/tests/gen_test_data.py";
|
||||
let mut child = Command::new(test_gen_cmd)
|
||||
.stdout(Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap();
|
||||
|
||||
let gen_stdout = child
|
||||
.stdout
|
||||
.take()
|
||||
.ok_or("Failed to capture stdout")
|
||||
.unwrap();
|
||||
let gen_reader = BufReader::new(gen_stdout);
|
||||
|
||||
for r_line in gen_reader.lines() {
|
||||
let test_line: String = r_line.unwrap(); // Handle any I/O errors
|
||||
let test_data_line = test_line.split(' ').collect::<Vec<&str>>();
|
||||
let num_to_add = u32::from_str_radix(test_data_line[0], 10).unwrap();
|
||||
let t0 = bignum_from_hex(test_data_line[1]);
|
||||
|
||||
let t1_test = add_u32_to_u256(&t0, 1).0;
|
||||
let t2_test = add_u32_to_u256(&t0, num_to_add).0;
|
||||
|
||||
let res_actual = format!(
|
||||
"{} {} {} {}",
|
||||
num_to_add,
|
||||
bignum_to_hex(&t0),
|
||||
bignum_to_hex(&t1_test),
|
||||
bignum_to_hex(&t2_test)
|
||||
);
|
||||
assert_eq!(test_line, res_actual);
|
||||
}
|
||||
|
||||
let _ = child.wait().unwrap();
|
||||
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cl_add() {
|
||||
extern crate ocl;
|
||||
use ocl::{
|
||||
Buffer, Context, Device, DeviceType, Kernel, Platform, Program, Queue, SpatialDims,
|
||||
flags,
|
||||
};
|
||||
use std::fs::File;
|
||||
use std::io::{BufRead, BufReader};
|
||||
use std::process::{Command, Stdio};
|
||||
|
||||
let cl_test_path = "/home/kira/Development/Rust/nyash-aes-xts256-plain64/nyash_client/src/open_cl/test_num_utils.cl";
|
||||
let cl_include_opt =
|
||||
"-I /home/kira/Development/Rust/nyash-aes-xts256-plain64/nyash_client/src/open_cl";
|
||||
let mut cl_src = String::new();
|
||||
// read ocl source
|
||||
BufReader::new(File::open(cl_test_path).unwrap()).read_to_string(&mut cl_src);
|
||||
|
||||
const G_WORK_SIZE: usize = 4096;
|
||||
|
||||
let cl_platform = Platform::default();
|
||||
let cl_device = Device::first(cl_platform).unwrap();
|
||||
let cl_context = Context::builder()
|
||||
.platform(cl_platform)
|
||||
.devices(cl_device.clone())
|
||||
.build()
|
||||
.unwrap();
|
||||
let cl_program = Program::builder()
|
||||
.devices(cl_device)
|
||||
.src(cl_src)
|
||||
.cmplr_opt(cl_include_opt)
|
||||
.build(&cl_context)
|
||||
.unwrap();
|
||||
let cl_queue = Queue::new(&cl_context, cl_device, None).unwrap();
|
||||
|
||||
let cl_buffer_num = Buffer::<u32>::builder()
|
||||
.queue(cl_queue.clone())
|
||||
.flags(flags::MEM_READ_ONLY)
|
||||
.len(G_WORK_SIZE)
|
||||
.fill_val(0u32)
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
let cl_buffer_t0 = Buffer::<u32>::builder()
|
||||
.queue(cl_queue.clone())
|
||||
.flags(flags::MEM_READ_ONLY)
|
||||
.len(G_WORK_SIZE * 8)
|
||||
.fill_val(0u32)
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
let cl_buffer_t1 = Buffer::<u32>::builder()
|
||||
.queue(cl_queue.clone())
|
||||
.flags(flags::MEM_WRITE_ONLY)
|
||||
.len(G_WORK_SIZE * 8)
|
||||
.fill_val(0u32)
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
let cl_buffer_t2 = Buffer::<u32>::builder()
|
||||
.queue(cl_queue.clone())
|
||||
.flags(flags::MEM_WRITE_ONLY)
|
||||
.len(G_WORK_SIZE * 8)
|
||||
.fill_val(0u32)
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
// (3) Create a kernel with arguments matching those in the source above:
|
||||
let kernel = Kernel::builder()
|
||||
.program(&cl_program)
|
||||
.name("test_add")
|
||||
.queue(cl_queue.clone())
|
||||
.global_work_size(G_WORK_SIZE)
|
||||
.arg(&cl_buffer_num)
|
||||
.arg(&cl_buffer_t0)
|
||||
.arg(&cl_buffer_t1)
|
||||
.arg(&cl_buffer_t2)
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
let test_gen_cmd = "/home/kira/Development/Rust/nyash-aes-xts256-plain64/nyash_client/src/tests/gen_test_data.py";
|
||||
let mut child = Command::new(test_gen_cmd)
|
||||
.stdout(Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap();
|
||||
|
||||
let gen_stdout = child
|
||||
.stdout
|
||||
.take()
|
||||
.ok_or("Failed to capture stdout")
|
||||
.unwrap();
|
||||
let gen_reader = BufReader::new(gen_stdout);
|
||||
|
||||
|
||||
let mut buffer_num: Vec<u32> = vec![0u32; G_WORK_SIZE];
|
||||
let mut buffer_t0: Vec<u32> = vec![0u32; G_WORK_SIZE*8];
|
||||
let mut exp_buffer_t1: Vec<u32> = vec![0u32; G_WORK_SIZE*8];
|
||||
let mut exp_buffer_t2: Vec<u32> = vec![0u32; G_WORK_SIZE*8];
|
||||
|
||||
let mut act_buffer_t1: Vec<u32> = vec![0u32; G_WORK_SIZE*8];
|
||||
let mut act_buffer_t2: Vec<u32> = vec![0u32; G_WORK_SIZE*8];
|
||||
|
||||
let mut w_id: usize = 0;
|
||||
|
||||
for r_line in gen_reader.lines() {
|
||||
let test_line: String = r_line.unwrap(); // Handle any I/O errors
|
||||
let test_data_line = test_line.split(' ').collect::<Vec<&str>>();
|
||||
let num_to_add = u32::from_str_radix(test_data_line[0], 10).unwrap();
|
||||
buffer_num[w_id] = num_to_add;
|
||||
let slise_id = w_id*8;
|
||||
buffer_t0[slise_id..slise_id+8].copy_from_slice(&bignum_from_hex(test_data_line[1]));
|
||||
exp_buffer_t1[slise_id..slise_id+8].copy_from_slice(&bignum_from_hex(test_data_line[2]));
|
||||
exp_buffer_t2[slise_id..slise_id+8].copy_from_slice(&bignum_from_hex(test_data_line[3]));
|
||||
|
||||
w_id += 1;
|
||||
if w_id >= G_WORK_SIZE {
|
||||
w_id = 0; // reset counter
|
||||
cl_buffer_num.cmd().queue(&cl_queue).offset(0).write(&buffer_num).enq().unwrap();
|
||||
cl_buffer_t0.cmd().queue(&cl_queue).offset(0).write(&buffer_t0).enq().unwrap();
|
||||
|
||||
// (4) Run the kernel
|
||||
unsafe {
|
||||
kernel
|
||||
.cmd()
|
||||
.queue(&cl_queue)
|
||||
.global_work_size(G_WORK_SIZE)
|
||||
.enq().unwrap();
|
||||
}
|
||||
|
||||
cl_buffer_t1.cmd().queue(&cl_queue).offset(0).read(&mut act_buffer_t1).enq().unwrap();
|
||||
cl_buffer_t2.cmd().queue(&cl_queue).offset(0).read(&mut act_buffer_t2).enq().unwrap();
|
||||
|
||||
assert_eq!(exp_buffer_t1, act_buffer_t1);
|
||||
assert_eq!(exp_buffer_t2, act_buffer_t2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
let _ = child.wait().unwrap();
|
||||
pub fn u128_to_u32arr(a: u128) -> [u32; 4] {
|
||||
let mut res = [0u32; 4];
|
||||
let a_bytes = a.to_le_bytes();
|
||||
let chunks = a_bytes.as_chunks::<4>().0;
|
||||
for i in 0..4 {
|
||||
res[i] = u32::from_le_bytes(chunks[i]);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
pub fn u32arr_to_u128(a: [u32; 4]) -> u128 {
|
||||
let mut bytes_data: [u8; 16] = [0u8; 16];
|
||||
bytes_data[0..4].copy_from_slice(a[0].to_le_bytes().as_slice());
|
||||
bytes_data[4..8].copy_from_slice(a[1].to_le_bytes().as_slice());
|
||||
bytes_data[8..12].copy_from_slice(a[2].to_le_bytes().as_slice());
|
||||
bytes_data[12..16].copy_from_slice(a[3].to_le_bytes().as_slice());
|
||||
|
||||
return u128::from_le_bytes(bytes_data);
|
||||
}
|
||||
|
||||
// fn add_u32_to_u256(a: &[u32; 8], b: u32) -> ([u32; 8], bool) {
|
||||
// let mut res: [u32; 8] = [0; 8];
|
||||
// let mut carry = false;
|
||||
// (res[0], carry) = a[0].carrying_add(b, carry);
|
||||
|
||||
// for idx in 1..8 {
|
||||
// (res[idx], carry) = a[idx].carrying_add(0, carry);
|
||||
// }
|
||||
|
||||
// return (res, carry);
|
||||
// }
|
||||
|
||||
// fn add_u32_to_u256_(a: &mut [u32; 8], b: u32) -> bool {
|
||||
// let mut carry = false;
|
||||
// (a[0], carry) = a[0].carrying_add(b, carry);
|
||||
|
||||
// for idx in 1..8 {
|
||||
// (a[idx], carry) = a[idx].carrying_add(0, carry);
|
||||
// }
|
||||
|
||||
// return carry;
|
||||
// }
|
||||
|
||||
// fn bytes_from_chars(chars_chunk: &[char]) -> [u8; 4] {
|
||||
// let mut res: [u8; 4] = [0; 4];
|
||||
// let mut idx: usize = 0;
|
||||
// chars_chunk.chunks_exact(2).for_each(|b_c| {
|
||||
// if idx < 4 {
|
||||
// match u8::from_str_radix(&b_c.iter().collect::<String>(), 16) {
|
||||
// Ok(n) => res[idx] = n,
|
||||
// Err(_) => (),
|
||||
// }
|
||||
// idx += 1;
|
||||
// }
|
||||
// });
|
||||
// return res;
|
||||
// }
|
||||
|
||||
// fn bignum_from_hex(hex: &str) -> [u32; 8] {
|
||||
// let mut res: [u32; 8] = [0; 8];
|
||||
// let mut idx: usize = 0;
|
||||
// let chars_hex = hex.chars().collect::<Vec<char>>();
|
||||
// chars_hex
|
||||
// .chunks_exact(8)
|
||||
// .rev()
|
||||
// .map(|chunk| bytes_from_chars(chunk))
|
||||
// .for_each(|b_arr| {
|
||||
// if idx < 8 {
|
||||
// res[idx] = u32::from_be_bytes(b_arr);
|
||||
// idx += 1;
|
||||
// }
|
||||
// });
|
||||
// return res;
|
||||
// }
|
||||
|
||||
// fn hex_fmt_byte(n: u32) -> String {
|
||||
// let res: String = n
|
||||
// .to_be_bytes()
|
||||
// .iter()
|
||||
// .map(|b| format!("{:02x}", b))
|
||||
// .collect();
|
||||
// return res;
|
||||
// }
|
||||
|
||||
// fn bignum_to_hex(a: &[u32; 8]) -> String {
|
||||
// let res: String = a
|
||||
// .iter()
|
||||
// .rev()
|
||||
// .map(|n| hex_fmt_byte(*n))
|
||||
// .collect::<Vec<String>>()
|
||||
// .join("");
|
||||
// return res;
|
||||
// }
|
||||
|
||||
// #[cfg(test)]
|
||||
// mod num_utils_tests {
|
||||
// use std::io::Read;
|
||||
|
||||
// use super::*;
|
||||
|
||||
// #[test]
|
||||
// fn test_add() {
|
||||
// use std::io::{BufRead, BufReader};
|
||||
// use std::process::{Command, Stdio};
|
||||
|
||||
// let test_gen_cmd = "/home/kira/Development/Rust/nyash-aes-xts256-plain64/nyash_client/src/tests/gen_test_data.py";
|
||||
// let mut child = Command::new(test_gen_cmd)
|
||||
// .stdout(Stdio::piped())
|
||||
// .spawn()
|
||||
// .unwrap();
|
||||
|
||||
// let gen_stdout = child
|
||||
// .stdout
|
||||
// .take()
|
||||
// .ok_or("Failed to capture stdout")
|
||||
// .unwrap();
|
||||
// let gen_reader = BufReader::new(gen_stdout);
|
||||
|
||||
// for r_line in gen_reader.lines() {
|
||||
// let test_line: String = r_line.unwrap(); // Handle any I/O errors
|
||||
// let test_data_line = test_line.split(' ').collect::<Vec<&str>>();
|
||||
// let num_to_add = u32::from_str_radix(test_data_line[0], 10).unwrap();
|
||||
// let t0 = bignum_from_hex(test_data_line[1]);
|
||||
|
||||
// let t1_test = add_u32_to_u256(&t0, 1).0;
|
||||
// let t2_test = add_u32_to_u256(&t0, num_to_add).0;
|
||||
|
||||
// let res_actual = format!(
|
||||
// "{} {} {} {}",
|
||||
// num_to_add,
|
||||
// bignum_to_hex(&t0),
|
||||
// bignum_to_hex(&t1_test),
|
||||
// bignum_to_hex(&t2_test)
|
||||
// );
|
||||
// assert_eq!(test_line, res_actual);
|
||||
// }
|
||||
|
||||
// let _ = child.wait().unwrap();
|
||||
// }
|
||||
|
||||
// #[test]
|
||||
// fn test_cl_add() {
|
||||
// extern crate ocl;
|
||||
// use ocl::{Buffer, Context, Device, Kernel, Platform, Program, Queue, flags};
|
||||
// use std::fs::File;
|
||||
// use std::io::{BufRead, BufReader};
|
||||
// use std::process::{Command, Stdio};
|
||||
|
||||
// let cl_test_path = "/home/kira/Development/Rust/nyash-aes-xts256-plain64/nyash_client/src/open_cl/test_num_utils.cl";
|
||||
// let cl_include_opt =
|
||||
// "-I /home/kira/Development/Rust/nyash-aes-xts256-plain64/nyash_client/src/open_cl";
|
||||
// let mut cl_src = String::new();
|
||||
// // read ocl source
|
||||
// BufReader::new(File::open(cl_test_path).unwrap())
|
||||
// .read_to_string(&mut cl_src)
|
||||
// .expect("Error reading cl_src!");
|
||||
|
||||
// const G_WORK_SIZE: usize = 4096;
|
||||
|
||||
// let cl_platform = Platform::default();
|
||||
// let cl_device = Device::first(cl_platform).unwrap();
|
||||
// let cl_context = Context::builder()
|
||||
// .platform(cl_platform)
|
||||
// .devices(cl_device.clone())
|
||||
// .build()
|
||||
// .unwrap();
|
||||
// let cl_program = Program::builder()
|
||||
// .devices(cl_device)
|
||||
// .src(cl_src)
|
||||
// .cmplr_opt(cl_include_opt)
|
||||
// .build(&cl_context)
|
||||
// .unwrap();
|
||||
// let cl_queue = Queue::new(&cl_context, cl_device, None).unwrap();
|
||||
|
||||
// let cl_buffer_num = Buffer::<u32>::builder()
|
||||
// .queue(cl_queue.clone())
|
||||
// .flags(flags::MEM_READ_ONLY)
|
||||
// .len(G_WORK_SIZE)
|
||||
// .fill_val(0u32)
|
||||
// .build()
|
||||
// .unwrap();
|
||||
|
||||
// let cl_buffer_t0 = Buffer::<u32>::builder()
|
||||
// .queue(cl_queue.clone())
|
||||
// .flags(flags::MEM_READ_ONLY)
|
||||
// .len(G_WORK_SIZE * 8)
|
||||
// .fill_val(0u32)
|
||||
// .build()
|
||||
// .unwrap();
|
||||
|
||||
// let cl_buffer_t1 = Buffer::<u32>::builder()
|
||||
// .queue(cl_queue.clone())
|
||||
// .flags(flags::MEM_WRITE_ONLY)
|
||||
// .len(G_WORK_SIZE * 8)
|
||||
// .fill_val(0u32)
|
||||
// .build()
|
||||
// .unwrap();
|
||||
|
||||
// let cl_buffer_t2 = Buffer::<u32>::builder()
|
||||
// .queue(cl_queue.clone())
|
||||
// .flags(flags::MEM_WRITE_ONLY)
|
||||
// .len(G_WORK_SIZE * 8)
|
||||
// .fill_val(0u32)
|
||||
// .build()
|
||||
// .unwrap();
|
||||
|
||||
// // (3) Create a kernel with arguments matching those in the source above:
|
||||
// let kernel = Kernel::builder()
|
||||
// .program(&cl_program)
|
||||
// .name("test_add")
|
||||
// .queue(cl_queue.clone())
|
||||
// .global_work_size(G_WORK_SIZE)
|
||||
// .arg(&cl_buffer_num)
|
||||
// .arg(&cl_buffer_t0)
|
||||
// .arg(&cl_buffer_t1)
|
||||
// .arg(&cl_buffer_t2)
|
||||
// .build()
|
||||
// .unwrap();
|
||||
|
||||
// let test_gen_cmd = "/home/kira/Development/Rust/nyash-aes-xts256-plain64/nyash_client/src/tests/gen_test_data.py";
|
||||
// let mut child = Command::new(test_gen_cmd)
|
||||
// .stdout(Stdio::piped())
|
||||
// .spawn()
|
||||
// .unwrap();
|
||||
|
||||
// let gen_stdout = child
|
||||
// .stdout
|
||||
// .take()
|
||||
// .ok_or("Failed to capture stdout")
|
||||
// .unwrap();
|
||||
// let gen_reader = BufReader::new(gen_stdout);
|
||||
|
||||
// let mut buffer_num: Vec<u32> = vec![0u32; G_WORK_SIZE];
|
||||
// let mut buffer_t0: Vec<u32> = vec![0u32; G_WORK_SIZE * 8];
|
||||
// let mut exp_buffer_t1: Vec<u32> = vec![0u32; G_WORK_SIZE * 8];
|
||||
// let mut exp_buffer_t2: Vec<u32> = vec![0u32; G_WORK_SIZE * 8];
|
||||
|
||||
// let mut act_buffer_t1: Vec<u32> = vec![0u32; G_WORK_SIZE * 8];
|
||||
// let mut act_buffer_t2: Vec<u32> = vec![0u32; G_WORK_SIZE * 8];
|
||||
|
||||
// let mut w_id: usize = 0;
|
||||
|
||||
// for r_line in gen_reader.lines() {
|
||||
// let test_line: String = r_line.unwrap(); // Handle any I/O errors
|
||||
// let test_data_line = test_line.split(' ').collect::<Vec<&str>>();
|
||||
// let num_to_add = u32::from_str_radix(test_data_line[0], 10).unwrap();
|
||||
// buffer_num[w_id] = num_to_add;
|
||||
// let slise_id = w_id * 8;
|
||||
// buffer_t0[slise_id..slise_id + 8].copy_from_slice(&bignum_from_hex(test_data_line[1]));
|
||||
// exp_buffer_t1[slise_id..slise_id + 8]
|
||||
// .copy_from_slice(&bignum_from_hex(test_data_line[2]));
|
||||
// exp_buffer_t2[slise_id..slise_id + 8]
|
||||
// .copy_from_slice(&bignum_from_hex(test_data_line[3]));
|
||||
|
||||
// w_id += 1;
|
||||
// if w_id >= G_WORK_SIZE {
|
||||
// w_id = 0; // reset counter
|
||||
// cl_buffer_num
|
||||
// .cmd()
|
||||
// .queue(&cl_queue)
|
||||
// .offset(0)
|
||||
// .write(&buffer_num)
|
||||
// .enq()
|
||||
// .unwrap();
|
||||
// cl_buffer_t0
|
||||
// .cmd()
|
||||
// .queue(&cl_queue)
|
||||
// .offset(0)
|
||||
// .write(&buffer_t0)
|
||||
// .enq()
|
||||
// .unwrap();
|
||||
|
||||
// // (4) Run the kernel
|
||||
// unsafe {
|
||||
// kernel
|
||||
// .cmd()
|
||||
// .queue(&cl_queue)
|
||||
// .global_work_size(G_WORK_SIZE)
|
||||
// .enq()
|
||||
// .unwrap();
|
||||
// }
|
||||
|
||||
// cl_buffer_t1
|
||||
// .cmd()
|
||||
// .queue(&cl_queue)
|
||||
// .offset(0)
|
||||
// .read(&mut act_buffer_t1)
|
||||
// .enq()
|
||||
// .unwrap();
|
||||
// cl_buffer_t2
|
||||
// .cmd()
|
||||
// .queue(&cl_queue)
|
||||
// .offset(0)
|
||||
// .read(&mut act_buffer_t2)
|
||||
// .enq()
|
||||
// .unwrap();
|
||||
|
||||
// assert_eq!(exp_buffer_t1, act_buffer_t1);
|
||||
// assert_eq!(exp_buffer_t2, act_buffer_t2);
|
||||
// }
|
||||
// }
|
||||
|
||||
// let _ = child.wait().unwrap();
|
||||
// }
|
||||
// }
|
||||
|
||||
@@ -0,0 +1,320 @@
|
||||
|
||||
use std::io::Read;
|
||||
|
||||
use ocl::{Buffer, Context, Device, Kernel, Platform, Program, Queue, flags};
|
||||
|
||||
use crate::num_utils;
|
||||
|
||||
pub struct CtxBuffers {
|
||||
tweak_params: Buffer<u32>,
|
||||
batch_size: Buffer<u64>,
|
||||
start_key: Buffer<u32>,
|
||||
tweak_key: Buffer<u32>,
|
||||
uenc_data: Buffer<u32>,
|
||||
target_data: Buffer<u32>,
|
||||
key_found: Buffer<u32>,
|
||||
}
|
||||
|
||||
pub struct ExecData {
|
||||
pub start_key: Vec<u32>,
|
||||
pub tweak_key: Vec<u32>,
|
||||
pub uenc_data: Vec<u32>,
|
||||
pub target_data: Vec<u32>,
|
||||
pub tweak_i: u64,
|
||||
pub tweak_j: u32,
|
||||
pub key_found: Vec<u32>,
|
||||
pub batch_size: u64,
|
||||
pub work_size: usize,
|
||||
}
|
||||
impl ExecData {
|
||||
// g_params[uint4]
|
||||
// g_params[0-1] - ulog g_Ti
|
||||
// g_params[2] - g_Tj
|
||||
pub fn tweak_params(&self) -> Vec<u32> {
|
||||
let mut res: Vec<u32> = Vec::with_capacity(4);
|
||||
|
||||
// the sector number (S) is first converted into a little-endian byte array
|
||||
// before being encrypted using the second AES key (K₂)
|
||||
let tweak_i_b: [u8;8] = self.tweak_i.to_le_bytes();
|
||||
let (tweak_i_cnk,_) = tweak_i_b.as_chunks::<4>();
|
||||
res.push(u32::from_le_bytes(tweak_i_cnk[0]));
|
||||
res.push(u32::from_le_bytes(tweak_i_cnk[1]));
|
||||
|
||||
//last enc block number (tweak_j)
|
||||
res.push(self.tweak_j);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
pub fn get_found_key(&self) -> u128 {
|
||||
let mut u32_arr_k = [0u32;4];
|
||||
u32_arr_k[0] = self.key_found[1];
|
||||
u32_arr_k[1] = self.key_found[2];
|
||||
u32_arr_k[2] = self.key_found[3];
|
||||
u32_arr_k[3] = self.key_found[4];
|
||||
return num_utils::u32arr_to_u128(u32_arr_k);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
pub struct ExecContext {
|
||||
_ctx: Context,
|
||||
kernel: Kernel,
|
||||
_prog: Program,
|
||||
queue: Queue,
|
||||
buffers: CtxBuffers,
|
||||
}
|
||||
|
||||
pub fn init_program(
|
||||
cl_device: Device,
|
||||
cl_platform: Platform,
|
||||
cl_src_gz_bytes: &[u8],
|
||||
) -> Result<(Context, Program, Queue), ocl::Error> {
|
||||
use flate2::read::GzDecoder;
|
||||
let mut gz_decoder = GzDecoder::new(cl_src_gz_bytes);
|
||||
let mut decompressed_src = String::new();
|
||||
gz_decoder.read_to_string(&mut decompressed_src).expect("Error decompressing OCL sources!");
|
||||
|
||||
let cl_context = Context::builder()
|
||||
.platform(cl_platform)
|
||||
.devices(cl_device.clone())
|
||||
.build()?;
|
||||
|
||||
let cl_program = Program::builder()
|
||||
.devices(cl_device)
|
||||
.src(decompressed_src)
|
||||
.build(&cl_context)
|
||||
.unwrap();
|
||||
|
||||
let cl_queue: Queue = Queue::new(&cl_context, cl_device, None)?;
|
||||
|
||||
return Ok((cl_context, cl_program, cl_queue));
|
||||
}
|
||||
|
||||
pub fn init_buffers(cl_queue: &Queue) -> Result<CtxBuffers, ocl::Error> {
|
||||
let cl_buffer_tweak_params = Buffer::<u32>::builder()
|
||||
.queue(cl_queue.clone())
|
||||
.flags(flags::MEM_READ_ONLY)
|
||||
.len(3)
|
||||
.fill_val(0u32)
|
||||
.build()?;
|
||||
|
||||
let cl_buffer_batch_size = Buffer::<u64>::builder()
|
||||
.queue(cl_queue.clone())
|
||||
.flags(flags::MEM_READ_ONLY)
|
||||
.len(1)
|
||||
.fill_val(0u64)
|
||||
.build()?;
|
||||
|
||||
let cl_buffer_start_key = Buffer::<u32>::builder()
|
||||
.queue(cl_queue.clone())
|
||||
.flags(flags::MEM_READ_ONLY)
|
||||
.len(4)
|
||||
.fill_val(0u32)
|
||||
.build()?;
|
||||
|
||||
let cl_buffer_tweak_key = Buffer::<u32>::builder()
|
||||
.queue(cl_queue.clone())
|
||||
.flags(flags::MEM_READ_ONLY)
|
||||
.len(4)
|
||||
.fill_val(0u32)
|
||||
.build()?;
|
||||
|
||||
let cl_buffer_uenc_data = Buffer::<u32>::builder()
|
||||
.queue(cl_queue.clone())
|
||||
.flags(flags::MEM_READ_ONLY)
|
||||
.len(4)
|
||||
.fill_val(0u32)
|
||||
.build()?;
|
||||
|
||||
let cl_buffer_target_data = Buffer::<u32>::builder()
|
||||
.queue(cl_queue.clone())
|
||||
.flags(flags::MEM_READ_ONLY)
|
||||
.len(4)
|
||||
.fill_val(0u32)
|
||||
.build()?;
|
||||
|
||||
let cl_buffer_key_found = Buffer::<u32>::builder()
|
||||
.queue(cl_queue.clone())
|
||||
.flags(flags::MEM_WRITE_ONLY)
|
||||
.len(5)
|
||||
.fill_val(0u32)
|
||||
.build()?;
|
||||
|
||||
|
||||
Ok(CtxBuffers {
|
||||
tweak_params: cl_buffer_tweak_params,
|
||||
batch_size: cl_buffer_batch_size,
|
||||
start_key: cl_buffer_start_key,
|
||||
tweak_key: cl_buffer_tweak_key,
|
||||
uenc_data: cl_buffer_uenc_data,
|
||||
target_data: cl_buffer_target_data,
|
||||
key_found: cl_buffer_key_found,
|
||||
})
|
||||
}
|
||||
|
||||
fn init_kernel(
|
||||
work_size: usize,
|
||||
cl_program: &Program,
|
||||
cl_queue: &Queue,
|
||||
buffs: &CtxBuffers,
|
||||
) -> Result<Kernel, ocl::Error> {
|
||||
Kernel::builder()
|
||||
.program(cl_program)
|
||||
.name("search_key")
|
||||
.queue(cl_queue.clone())
|
||||
.global_work_size(work_size)
|
||||
.arg(&buffs.tweak_params)
|
||||
.arg(&buffs.batch_size)
|
||||
.arg(&buffs.start_key)
|
||||
.arg(&buffs.tweak_key)
|
||||
.arg(&buffs.uenc_data)
|
||||
.arg(&buffs.target_data)
|
||||
.arg(&buffs.key_found)
|
||||
.build()
|
||||
}
|
||||
|
||||
impl ExecContext {
|
||||
// Constructor with parameters
|
||||
pub fn new(
|
||||
cl_device: Device,
|
||||
cl_platform: Platform,
|
||||
cl_src_gz_bytes: &[u8],
|
||||
global_work_size: usize,
|
||||
) -> Result<Self, ocl::Error> {
|
||||
let (nya_cl_context, nya_cl_program, nya_cl_queue) =
|
||||
init_program(cl_device, cl_platform, cl_src_gz_bytes)?;
|
||||
|
||||
let nya_cl_buffers = init_buffers(&nya_cl_queue)?;
|
||||
|
||||
let nya_cl_kernel = init_kernel(
|
||||
global_work_size,
|
||||
&nya_cl_program,
|
||||
&nya_cl_queue,
|
||||
&nya_cl_buffers,
|
||||
)?;
|
||||
Ok(Self {
|
||||
_ctx: nya_cl_context,
|
||||
kernel: nya_cl_kernel,
|
||||
_prog: nya_cl_program,
|
||||
queue: nya_cl_queue,
|
||||
buffers: nya_cl_buffers,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_target_data(ex_ctx: &mut ExecContext, ex_data: &mut ExecData) -> Result<(), ocl::Error> {
|
||||
// transfer tweaks
|
||||
let t_p = ex_data.tweak_params();
|
||||
ex_ctx
|
||||
.buffers
|
||||
.tweak_params
|
||||
.cmd()
|
||||
.queue(&ex_ctx.queue)
|
||||
.offset(0)
|
||||
.write(&t_p)
|
||||
.enq()?;
|
||||
|
||||
// transfen unencrypted data to device
|
||||
ex_ctx
|
||||
.buffers
|
||||
.uenc_data
|
||||
.cmd()
|
||||
.queue(&ex_ctx.queue)
|
||||
.offset(0)
|
||||
.write(&ex_data.uenc_data)
|
||||
.enq()?;
|
||||
|
||||
// transfet target data
|
||||
ex_ctx
|
||||
.buffers
|
||||
.target_data
|
||||
.cmd()
|
||||
.queue(&ex_ctx.queue)
|
||||
.offset(0)
|
||||
.write(&ex_data.target_data)
|
||||
.enq()?;
|
||||
|
||||
ex_ctx.queue.finish()?;
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
pub fn do_work(ex_ctx: &mut ExecContext, ex_data: &mut ExecData) -> Result<(bool, f64), ocl::Error> {
|
||||
|
||||
let b_s = vec![ex_data.batch_size];
|
||||
|
||||
let start_time = std::time::Instant::now();
|
||||
|
||||
// tranfer batch_size
|
||||
ex_ctx
|
||||
.buffers
|
||||
.batch_size
|
||||
.cmd()
|
||||
.queue(&ex_ctx.queue)
|
||||
.offset(0)
|
||||
.write(&b_s)
|
||||
.enq()?;
|
||||
|
||||
|
||||
// transfer start key to device
|
||||
ex_ctx
|
||||
.buffers
|
||||
.start_key
|
||||
.cmd()
|
||||
.queue(&ex_ctx.queue)
|
||||
.offset(0)
|
||||
.write(&ex_data.start_key)
|
||||
.enq()?;
|
||||
|
||||
// transfet tweak key
|
||||
ex_ctx
|
||||
.buffers
|
||||
.tweak_key
|
||||
.cmd()
|
||||
.queue(&ex_ctx.queue)
|
||||
.offset(0)
|
||||
.write(&ex_data.tweak_key)
|
||||
.enq()?;
|
||||
|
||||
// zero out key_found buffer
|
||||
// ex_ctx
|
||||
// .buffers
|
||||
// .key_found
|
||||
// .cmd()
|
||||
// .queue(&ex_ctx.queue)
|
||||
// .offset(0)
|
||||
// .fill(0u32, None)
|
||||
// .enq()?;
|
||||
|
||||
|
||||
// (4) Run the kernel
|
||||
unsafe {
|
||||
ex_ctx
|
||||
.kernel
|
||||
.cmd()
|
||||
.queue(&ex_ctx.queue)
|
||||
.global_work_size(ex_data.work_size)
|
||||
.enq()?;
|
||||
}
|
||||
|
||||
// read key_foun buffer
|
||||
ex_ctx
|
||||
.buffers
|
||||
.key_found
|
||||
.cmd()
|
||||
.queue(&ex_ctx.queue)
|
||||
.offset(0)
|
||||
.read(&mut ex_data.key_found)
|
||||
.enq()?;
|
||||
|
||||
let exec_duration = start_time.elapsed().as_secs_f64();
|
||||
|
||||
//ex_ctx.queue.finish()?;
|
||||
|
||||
if ex_data.key_found[0] == 0 {
|
||||
Ok((false, exec_duration))
|
||||
} else {
|
||||
Ok((true, exec_duration))
|
||||
}
|
||||
}
|
||||
@@ -12,32 +12,7 @@ use crate::client_config::{AppConfig, DevConf};
|
||||
|
||||
mod client_config;
|
||||
mod num_utils;
|
||||
/// Exploded version. Boom!
|
||||
///
|
||||
/// The functions above use `ProQue` and other abstractions to greatly reduce
|
||||
/// the amount of boilerplate and configuration necessary to do basic work.
|
||||
/// Many tasks, however, will require more configuration and will necessitate
|
||||
/// doing away with `ProQue` altogether. Enqueuing kernels and reading/writing
|
||||
/// from buffers and images usually requires a more explicit interface.
|
||||
///
|
||||
/// The following function performs the exact same steps that the above
|
||||
/// functions did, with many of the convenience abstractions peeled away.
|
||||
///
|
||||
/// See the function below this to take things a step deeper...
|
||||
///
|
||||
// trait FromStr {
|
||||
// fn from_str(&self);
|
||||
// }
|
||||
// // Define a trait with a constructor method
|
||||
// trait NewFile {
|
||||
// fn new<P: AsRef<Path>>(path: P) -> std::io::Result<Self> where Self: Sized;
|
||||
// }
|
||||
|
||||
// impl Foo for ocl::flags::DeviceType {
|
||||
// fn foo(&self) {
|
||||
// println!("foo");
|
||||
// }
|
||||
// }
|
||||
|
||||
fn dev_type_from_str(s: &str) -> Result<flags::DeviceType, ()> {
|
||||
match s {
|
||||
Executable
+8
@@ -0,0 +1,8 @@
|
||||
#!/bin/sh
|
||||
|
||||
out_file="$1"
|
||||
|
||||
clang -c -target spir64 -O0 -finclude-default-header -I ./ -emit-llvm -o nyash_aes_xts256_plain.bc nyash_aes_xts256_plain.cl
|
||||
|
||||
#llc -march=spir64 nyash_aes_xts256_plain.bc -filetype=obj -o $out_file
|
||||
llvm-spirv -o $out_file nyash_aes_xts256_plain.bc
|
||||
@@ -32,15 +32,25 @@
|
||||
// g_key_found uint[9] - 0 element - flag that sets to 1 if key found.
|
||||
// Other 8 elements is found key
|
||||
|
||||
__kernel void search_key(const uint batch_size, const ulong g_Ti, const uint g_Tj,
|
||||
__global const uint8* g_start_enc_key,
|
||||
|
||||
// in current implementation tweak key is not changing by kernel
|
||||
// So changing it a bit
|
||||
|
||||
// g_params[uint4]
|
||||
// g_params[0] - batch_size
|
||||
// g_params[1-2] - ulong g_Ti
|
||||
// g_params[3] - g_Tj
|
||||
__kernel void search_key(__global const uint* g_tweak_params,
|
||||
__global const ulong* g_batch_size,
|
||||
__global const uint4* g_start_enc_key,
|
||||
__global const uint4* g_tweak_key,
|
||||
__global const uint4* g_uenc_data,
|
||||
__global const uint4* g_target_data,
|
||||
__global uint* g_key_found)
|
||||
{
|
||||
const uint g_id = get_global_id(0);
|
||||
|
||||
uint enc_key[8];
|
||||
uint enc_key[4];
|
||||
uint tweak[4];
|
||||
uint uenc_data[4];
|
||||
uint4 target_data = *g_target_data;
|
||||
@@ -48,32 +58,34 @@ __kernel void search_key(const uint batch_size, const ulong g_Ti, const uint g_T
|
||||
uint d_ks[44]; // data expanded key
|
||||
uint t_ks[44]; // tweak expanded key
|
||||
|
||||
//set batch_size
|
||||
ulong batch_size = g_batch_size[0];
|
||||
|
||||
// set disk sector number
|
||||
uint sec_n[4] = {0};
|
||||
sec_n[0] = ((uint*)&g_Ti)[0];
|
||||
sec_n[1] = ((uint*)&g_Ti)[1];
|
||||
sec_n[0] = g_tweak_params[0];
|
||||
sec_n[1] = g_tweak_params[1];
|
||||
|
||||
uint Tj = g_Tj; // AES block number
|
||||
uint Tj = g_tweak_params[2]; // AES block number
|
||||
|
||||
vstore4(*g_uenc_data, 0, uenc_data);
|
||||
vstore8(*g_start_enc_key, 0, enc_key);
|
||||
|
||||
vstore4(*g_start_enc_key, 0, enc_key);
|
||||
vstore4(*g_tweak_key, 0, tweak);
|
||||
|
||||
// Set initial start key for every work thread
|
||||
uint k_data_carry = add_uint_to_bigint4_ (enc_key, (g_id*batch_size));
|
||||
// uint k_tweak_carry = add_uint_to_bigint4_ (&enc_key[4], k_data_carry);
|
||||
// No need to store tweak carry
|
||||
if (add_uint_to_bigint4_ (&enc_key[4], k_data_carry) != 0u) return; // if reached max key value exit thread
|
||||
if (k_data_carry != 0u) return; // if reached max key value exit thread
|
||||
|
||||
// Generate tweak
|
||||
aes128_set_encrypt_key (t_ks, &enc_key[4]);
|
||||
aes128_set_encrypt_key (t_ks, tweak);
|
||||
aes_xts256_gen_tweak (t_ks, sec_n, Tj, tweak);
|
||||
//if (g_id == 0) g_key_found[1] = 1;
|
||||
|
||||
for (uint batch_id = 0u; (batch_id < batch_size); batch_id++)
|
||||
for (ulong batch_id = 0ul; batch_id < batch_size; batch_id++)
|
||||
{
|
||||
// Data encrypt key always changing because we increment from 0 index to 8
|
||||
//if (g_id == 0) g_key_found[1] = 2;
|
||||
// Set encrypt key
|
||||
aes128_set_encrypt_key (d_ks, enc_key);
|
||||
|
||||
// encrypt data
|
||||
aes_xts256_enc_block (d_ks, tweak, uenc_data, (uint*)&enc_data);
|
||||
|
||||
@@ -81,29 +93,17 @@ __kernel void search_key(const uint batch_size, const ulong g_Ti, const uint g_T
|
||||
if (all(enc_data==target_data))
|
||||
{
|
||||
g_key_found[0] = 1;
|
||||
vstore8(vload8(0, enc_key), 0, &g_key_found[1]);
|
||||
g_key_found[1] = enc_key[0];
|
||||
g_key_found[2] = enc_key[1];
|
||||
g_key_found[3] = enc_key[2];
|
||||
g_key_found[4] = enc_key[3];
|
||||
return;
|
||||
}
|
||||
|
||||
// Increment data key part by 1.
|
||||
// Increment data key by 1.
|
||||
k_data_carry = add_one_to_bigint4_ (enc_key);
|
||||
|
||||
// Tweak changes only once in 2^128 times
|
||||
if (k_data_carry != 0u) {
|
||||
|
||||
// Increment tweak part
|
||||
// k_tweak_carry = add_one_to_bigint4_ (&enc_key[4]);
|
||||
add_one_to_bigint4_ (&enc_key[4]); // no need to store tweak carry
|
||||
|
||||
// *** I commented next line because, its a really!! lol! rare event,
|
||||
// *** and in a worse case we just do a bit of noneed work.
|
||||
// *** But additional check on every itaration actually mesurable cost.
|
||||
// if (k_tweak_carry != 0u) return; // if reached max key value exit thread
|
||||
|
||||
// Gen new tweak
|
||||
aes128_set_encrypt_key (t_ks, &enc_key[4]);
|
||||
aes_xts256_gen_tweak (t_ks, sec_n, Tj, tweak);
|
||||
}
|
||||
// if reached max key value exit thread
|
||||
if (k_data_carry != 0u) return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
|
||||
|
||||
pub fn get_params() ->([u32; 4],[u32; 4],[u32; 4]) {
|
||||
use crate::num_utils;
|
||||
|
||||
const ENCRYPTED_DATA: [u8; 16] = [
|
||||
198, 255, 55, 185, 15, 226, 223, 174, 119, 8, 36, 239, 242, 89, 126, 230
|
||||
];
|
||||
|
||||
const KEY_DATA: [u8; 32] = [
|
||||
206, 193, 83, 54, 46, 234, 185, 41, 146, 244, 130, 6, 212, 68, 106, 162, 165, 97, 188,
|
||||
218, 39, 111, 141, 236, 67, 159, 157, 157, 166, 79, 89, 134
|
||||
];
|
||||
|
||||
// let key_bytes_reversed: Vec<u8> = KEY_DATA.iter().rev().map(|e| *e).collect();
|
||||
// let data_bytes_reversed: Vec<u8> = ENCRYPTED_DATA.iter().rev().map(|e| *e).collect();
|
||||
|
||||
let mut tweak_key_b: [u8;16] = [0u8;16];
|
||||
let mut data_key_b: [u8;16] = [0u8;16];
|
||||
|
||||
data_key_b.copy_from_slice(&KEY_DATA[0..16]);
|
||||
tweak_key_b.copy_from_slice(&KEY_DATA[16..32]);
|
||||
|
||||
// getting keys
|
||||
let data_key = u128::from_le_bytes(data_key_b);
|
||||
let tweak_key = u128::from_le_bytes(tweak_key_b);
|
||||
let data_key = num_utils::u128_to_u32arr(data_key);
|
||||
let tweak_key = num_utils::u128_to_u32arr(tweak_key);
|
||||
|
||||
// converting bytes raw data to u32 arr
|
||||
let mut encrypted_data: [u32; 4] = [0u32; 4];
|
||||
let (enc_dat_bytes_chunks, _) = ENCRYPTED_DATA.as_chunks::<4>();
|
||||
for i in 0..4 {
|
||||
encrypted_data[i] = u32::from_le_bytes(enc_dat_bytes_chunks[i]);
|
||||
}
|
||||
|
||||
return (data_key, tweak_key, encrypted_data);
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
|
||||
#[cfg(test)]
|
||||
mod test_cl {
|
||||
#[test]
|
||||
fn test_encryption() {
|
||||
use ocl::{Device, Platform};
|
||||
use crate::ocl_utils;
|
||||
use crate::num_utils;
|
||||
|
||||
|
||||
const SRC_PATH: &str = "src/open_cl/nyash_aes_xts256_plain.cl";
|
||||
const OCL_COMP_OPT: &str = "-I src/open_cl";
|
||||
const ENCRYPTED_DATA: [u8; 16] = [
|
||||
198, 255, 55, 185, 15, 226, 223, 174, 119, 8, 36, 239, 242, 89, 126, 230
|
||||
];
|
||||
const KEY_DATA: [u8; 32] = [
|
||||
206, 193, 83, 54, 46, 234, 185, 41, 146, 244, 130, 6, 212, 68, 106, 162, 165, 97, 188,
|
||||
218, 39, 111, 141, 236, 67, 159, 157, 157, 166, 79, 89, 134
|
||||
];
|
||||
|
||||
// let key_bytes_reversed: Vec<u8> = KEY_DATA.iter().rev().map(|e| *e).collect();
|
||||
// let data_bytes_reversed: Vec<u8> = ENCRYPTED_DATA.iter().rev().map(|e| *e).collect();
|
||||
|
||||
let mut tweak_key_b: [u8;16] = [0u8;16];
|
||||
let mut data_key_b: [u8;16] = [0u8;16];
|
||||
|
||||
data_key_b.copy_from_slice(&KEY_DATA[0..16]);
|
||||
tweak_key_b.copy_from_slice(&KEY_DATA[16..32]);
|
||||
|
||||
// getting keys
|
||||
let data_key = u128::from_le_bytes(data_key_b);
|
||||
let tweak_key = u128::from_le_bytes(tweak_key_b);
|
||||
let data_key = num_utils::u128_to_u32arr(data_key);
|
||||
let tweak_key = num_utils::u128_to_u32arr(tweak_key);
|
||||
|
||||
|
||||
// converting bytes raw data to u32 arr
|
||||
let mut encrypted_data: [u32; 4] = [0u32; 4];
|
||||
let (enc_dat_bytes_chunks, _) = ENCRYPTED_DATA.as_chunks::<4>();
|
||||
for i in 0..4 {
|
||||
encrypted_data[i] = u32::from_le_bytes(enc_dat_bytes_chunks[i]);
|
||||
}
|
||||
|
||||
// init devices
|
||||
let platform = Platform::first().expect("Error getting platform!");
|
||||
let device = Device::first(platform).expect("Error getting device!");
|
||||
|
||||
println!("Platform: {:?}, Device: {:?}", platform.name().unwrap(), device.name().unwrap());
|
||||
|
||||
// reading ocl program sources
|
||||
let prog_src = std::fs::read_to_string(SRC_PATH).expect("Error reading program sources!");
|
||||
|
||||
let mut nyan_context =
|
||||
ocl_utils::ExecContext::new(device, platform, prog_src.as_str(), OCL_COMP_OPT, 256)
|
||||
.expect("Error creating execution nyan context!");
|
||||
|
||||
|
||||
//setting data
|
||||
let mut nyan_exec_dat = ocl_utils::ExecData {
|
||||
start_key: data_key.to_vec(),
|
||||
tweak_key: tweak_key.to_vec(),
|
||||
uenc_data: vec![0u32;4],
|
||||
target_data: encrypted_data.to_vec(),
|
||||
tweak_i: 0,
|
||||
tweak_j: 0,
|
||||
key_found: vec![0u32;5],
|
||||
batch_size: 1000000,
|
||||
work_size: 256,
|
||||
};
|
||||
|
||||
println!("Set target data");
|
||||
ocl_utils::set_target_data(&mut nyan_context, &mut nyan_exec_dat).expect("Error set target data!");
|
||||
|
||||
let found_flag = ocl_utils::do_work(&mut nyan_context, &mut nyan_exec_dat).expect("Error do work!");
|
||||
println!("Found?: {}", found_flag);
|
||||
println!("Key found: {:?}", nyan_exec_dat.key_found);
|
||||
assert_eq!(true, found_flag);
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,16 @@
|
||||
#!/bin/bash
|
||||
|
||||
truncate -s 255M test_btrfs.img
|
||||
dd if=/dev/urandom of=master.key bs=32 count=1
|
||||
|
||||
cryptsetup luksFormat --type=luks2 --sector-size 512 --pbkdf=pbkdf2 --pbkdf-force-iterations=1000 --hash=sha256 --key-size=256 --cipher=aes-xts-plain64 --master-key-file ./test_master.key ./test.img
|
||||
|
||||
cryptsetup luksFormat --type=luks2 --pbkdf=pbkdf2 --pbkdf-force-iterations=1000 --hash=sha256 --key-size=256 --cipher=aes-xts-plain64 ./luks-container.img
|
||||
|
||||
sudo cryptsetup luksOpen ./test.img luks-container-crypt
|
||||
|
||||
sudo mkfs.btrfs /dev/mapper/luks-container-crypt
|
||||
|
||||
sudo dd if=/dev/mapper/luks-container-crypt of=./test_btrfs_luks_unencrypt.img bs=1M count=255
|
||||
|
||||
sudo cryptsetup close luks-container-crypt
|
||||
@@ -0,0 +1,44 @@
|
||||
from utils import read_metadata
|
||||
|
||||
|
||||
# Init logger
|
||||
|
||||
LUKS_FILE_NAME = "test.img"
|
||||
KEY_FILE_NAME = "master.key"
|
||||
|
||||
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
metadat = read_metadata(LUKS_FILE_NAME)
|
||||
print(f"metadata:\n{metadat}")
|
||||
|
||||
|
||||
segments_offset_bytes = int(metadat["segments"]["0"]["offset"])
|
||||
superblock_start_bytes = 0x00010000
|
||||
superblock_start_sector = superblock_start_bytes//512
|
||||
magic_offset = 0x40
|
||||
superblock_lenght_bytes = 0x1000
|
||||
sector_size = 512
|
||||
|
||||
with open(LUKS_FILE_NAME, 'rb') as luks_file:
|
||||
luks_file.seek(segments_offset_bytes)
|
||||
enc_data = luks_file.read(16)
|
||||
|
||||
|
||||
print("ENC DATA:")
|
||||
print("[" + ",".join([format(a, 'd') for a in enc_data])+"]")
|
||||
|
||||
print()
|
||||
print("KEY DATA:")
|
||||
with open(KEY_FILE_NAME, 'rb') as key_file:
|
||||
key_data = key_file.read(32)
|
||||
print("[" + ",".join([format(a, 'd') for a in key_data])+"]")
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -0,0 +1,25 @@
|
||||
import subprocess
|
||||
import json
|
||||
|
||||
def read_metadata(file_name: str) -> dict:
|
||||
#cryptsetup luksDump --dump-json-metadata /dev/loop0
|
||||
luks_cmd: list[str] = ["cryptsetup", "luksDump", "--dump-json-metadata", file_name]
|
||||
|
||||
result = subprocess.run(luks_cmd, capture_output=True, encoding="UTF-8")
|
||||
if result.returncode == 0 and result.stdout is not None:
|
||||
metadata = json.loads(result.stdout)
|
||||
return metadata
|
||||
else:
|
||||
raise Exception(f"Error executing 'cryptsetup' binary! {result.stderr}")
|
||||
|
||||
|
||||
def read_encrypted_key(f_name: str, metadata: dict, keyslot: int) -> bytes:
|
||||
stripes = metadata["keyslots"][str(keyslot)]["af"]["stripes"]
|
||||
offset = int(metadata["keyslots"][str(keyslot)]["area"]["offset"])
|
||||
# size = int(metadata["keyslots"][str(keyslot)]["area"]["size"])
|
||||
key_size = metadata["keyslots"][str(keyslot)]["area"]["key_size"]
|
||||
with open(f_name, 'rb') as luks_file:
|
||||
luks_file.seek(offset)
|
||||
data = luks_file.read(key_size*stripes)
|
||||
return data
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod cl_num_utils_tests {
|
||||
use super::*;
|
||||
|
||||
Reference in New Issue
Block a user