Compare commits
No commits in common. "main" and "feat_gcm_crack" have entirely different histories.
main
...
feat_gcm_c
12 changed files with 196 additions and 19 deletions
|
|
@ -179,7 +179,7 @@ pub fn task_deploy(testcase: &Testcase) -> Result<Value> {
|
||||||
}
|
}
|
||||||
"gcm_crack" => {
|
"gcm_crack" => {
|
||||||
let result = gcm_crack(args)?;
|
let result = gcm_crack(args)?;
|
||||||
let json = json!(result);
|
let json = json!({"factors" : result});
|
||||||
|
|
||||||
Ok(json)
|
Ok(json)
|
||||||
}
|
}
|
||||||
|
|
@ -241,7 +241,7 @@ pub fn task_distribute_st(testcases: &Testcases) -> Result<Responses> {
|
||||||
|
|
||||||
pub fn task_distribute(testcases: &Testcases) -> Result<Responses> {
|
pub fn task_distribute(testcases: &Testcases) -> Result<Responses> {
|
||||||
let cpus = num_cpus::get();
|
let cpus = num_cpus::get();
|
||||||
if cpus > 1 {
|
if cpus > 1000000 {
|
||||||
task_distribute_mt(testcases)
|
task_distribute_mt(testcases)
|
||||||
} else {
|
} else {
|
||||||
task_distribute_st(testcases)
|
task_distribute_st(testcases)
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ pub fn block2poly(val: &Value) -> Result<Vec<u8>> {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
// Note this useful idiom: importing names from outer (for mod tests) scope.
|
// Note this useful idiom: importing names from outer (for mod tests) scope.
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,13 @@
|
||||||
|
use std::{env::args, fs::canonicalize, slice::Chunks};
|
||||||
|
|
||||||
use anyhow::{Ok, Result};
|
use anyhow::{Ok, Result};
|
||||||
use base64::{prelude::BASE64_STANDARD, Engine};
|
use base64::{prelude::BASE64_STANDARD, Engine};
|
||||||
|
use openssl::derive;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde_json::Value;
|
use serde_json::{map, Value};
|
||||||
|
|
||||||
use crate::utils::{
|
use crate::utils::{
|
||||||
|
self,
|
||||||
ciphers::ghash,
|
ciphers::ghash,
|
||||||
dff::ddf,
|
dff::ddf,
|
||||||
edf::edf,
|
edf::edf,
|
||||||
|
|
@ -32,12 +35,9 @@ struct Message {
|
||||||
fn parse_message(val: &Value) -> Result<(Message, Polynomial)> {
|
fn parse_message(val: &Value) -> Result<(Message, Polynomial)> {
|
||||||
let ciphertext_text: String = serde_json::from_value(val["ciphertext"].clone())?;
|
let ciphertext_text: String = serde_json::from_value(val["ciphertext"].clone())?;
|
||||||
let mut ciphertext_bytes: Vec<u8> = BASE64_STANDARD.decode(ciphertext_text)?;
|
let mut ciphertext_bytes: Vec<u8> = BASE64_STANDARD.decode(ciphertext_text)?;
|
||||||
let mut c_len: Vec<u8> = ((ciphertext_bytes.len() * 8) as u64).to_be_bytes().to_vec();
|
|
||||||
|
|
||||||
if ciphertext_bytes.len() % 16 != 0 {
|
if ciphertext_bytes.len() % 16 != 0 {
|
||||||
ciphertext_bytes.append(vec![0u8; 16 - (ciphertext_bytes.len() % 16)].as_mut());
|
ciphertext_bytes.append(vec![0u8; 16 - (ciphertext_bytes.len() % 16)].as_mut());
|
||||||
}
|
}
|
||||||
|
|
||||||
let ciphertext_chunks: Vec<FieldElement> = ciphertext_bytes
|
let ciphertext_chunks: Vec<FieldElement> = ciphertext_bytes
|
||||||
.chunks(16)
|
.chunks(16)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
|
@ -51,7 +51,6 @@ fn parse_message(val: &Value) -> Result<(Message, Polynomial)> {
|
||||||
if ad_bytes.len() % 16 != 0 || ad_bytes.is_empty() {
|
if ad_bytes.len() % 16 != 0 || ad_bytes.is_empty() {
|
||||||
ad_bytes.append(vec![0u8; 16 - (ad_bytes.len() % 16)].as_mut());
|
ad_bytes.append(vec![0u8; 16 - (ad_bytes.len() % 16)].as_mut());
|
||||||
}
|
}
|
||||||
|
|
||||||
let ad_chunks: Vec<FieldElement> = ad_bytes
|
let ad_chunks: Vec<FieldElement> = ad_bytes
|
||||||
.chunks(16)
|
.chunks(16)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
|
@ -62,6 +61,7 @@ fn parse_message(val: &Value) -> Result<(Message, Polynomial)> {
|
||||||
let tag_bytes: Vec<u8> = BASE64_STANDARD.decode(tag_text)?;
|
let tag_bytes: Vec<u8> = BASE64_STANDARD.decode(tag_text)?;
|
||||||
let tag_field: FieldElement = FieldElement::new(tag_bytes.clone());
|
let tag_field: FieldElement = FieldElement::new(tag_bytes.clone());
|
||||||
|
|
||||||
|
let mut c_len: Vec<u8> = ((ciphertext_bytes.len() * 8) as u64).to_be_bytes().to_vec();
|
||||||
l_field.append(c_len.as_mut());
|
l_field.append(c_len.as_mut());
|
||||||
|
|
||||||
// Combine all data
|
// Combine all data
|
||||||
|
|
@ -95,8 +95,13 @@ pub fn gcm_crack(args: &Value) -> Result<CrackAnswer> {
|
||||||
|
|
||||||
let (m3_data, _) = parse_message(&args["m3"])?;
|
let (m3_data, _) = parse_message(&args["m3"])?;
|
||||||
|
|
||||||
|
eprintln!("m1 poly: {:?}", m1_h_poly.clone().to_c_array());
|
||||||
|
eprintln!("m2 poly: {:?}", m2_h_poly.clone().to_c_array());
|
||||||
|
|
||||||
let combine_poly = m1_h_poly + m2_h_poly;
|
let combine_poly = m1_h_poly + m2_h_poly;
|
||||||
|
|
||||||
|
eprintln!("combine poly: {:?}", combine_poly.clone().to_c_array());
|
||||||
|
|
||||||
let combine_sff = sff(combine_poly.monic());
|
let combine_sff = sff(combine_poly.monic());
|
||||||
|
|
||||||
let mut combine_ddf: Vec<(Polynomial, u128)> = vec![];
|
let mut combine_ddf: Vec<(Polynomial, u128)> = vec![];
|
||||||
|
|
@ -104,6 +109,8 @@ pub fn gcm_crack(args: &Value) -> Result<CrackAnswer> {
|
||||||
combine_ddf.extend(ddf(factor));
|
combine_ddf.extend(ddf(factor));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
eprintln!("combine_ddf: {:?}", combine_ddf);
|
||||||
|
|
||||||
let mut combine_edf: Vec<Polynomial> = vec![];
|
let mut combine_edf: Vec<Polynomial> = vec![];
|
||||||
for (factor, degree) in combine_ddf {
|
for (factor, degree) in combine_ddf {
|
||||||
if degree == 1 {
|
if degree == 1 {
|
||||||
|
|
@ -111,12 +118,15 @@ pub fn gcm_crack(args: &Value) -> Result<CrackAnswer> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
eprintln!("combine_edf: {:?}", combine_edf);
|
||||||
|
|
||||||
let mut m3_auth_tag: Vec<u8> = vec![];
|
let mut m3_auth_tag: Vec<u8> = vec![];
|
||||||
let mut h_candidate: FieldElement = FieldElement::zero();
|
let mut h_candidate: FieldElement = FieldElement::zero();
|
||||||
let mut eky0: Vec<u8> = vec![];
|
let mut eky0: Vec<u8> = vec![];
|
||||||
for candidate in combine_edf {
|
for candidate in combine_edf {
|
||||||
if candidate.degree() == 1 {
|
if candidate.degree() == 1 {
|
||||||
h_candidate = candidate.extract_component(0);
|
h_candidate = candidate.extract_component(0);
|
||||||
|
eprintln!("H candidate: {:02X?}", h_candidate.to_b64());
|
||||||
let m1_ghash = ghash(
|
let m1_ghash = ghash(
|
||||||
reverse_bits_in_bytevec(h_candidate.to_vec()),
|
reverse_bits_in_bytevec(h_candidate.to_vec()),
|
||||||
m1_data.ad.clone(),
|
m1_data.ad.clone(),
|
||||||
|
|
@ -143,6 +153,8 @@ pub fn gcm_crack(args: &Value) -> Result<CrackAnswer> {
|
||||||
);
|
);
|
||||||
|
|
||||||
if m3_auth_tag == m3_data.tag {
|
if m3_auth_tag == m3_data.tag {
|
||||||
|
eprintln!("Candidate valid");
|
||||||
|
eprintln!("{:02X?}", m3_auth_tag);
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
eprintln!("H candidate not valid");
|
eprintln!("H candidate not valid");
|
||||||
|
|
@ -150,6 +162,15 @@ pub fn gcm_crack(args: &Value) -> Result<CrackAnswer> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
eprintln!(
|
||||||
|
"M3 Authentication TAG {:02X?}",
|
||||||
|
BASE64_STANDARD.encode(&m3_auth_tag)
|
||||||
|
);
|
||||||
|
|
||||||
|
if m3_auth_tag.is_empty() {
|
||||||
|
eprintln!("No valid candidate found");
|
||||||
|
}
|
||||||
|
|
||||||
let (forgery_data, _) = parse_message(&args["forgery"])?;
|
let (forgery_data, _) = parse_message(&args["forgery"])?;
|
||||||
|
|
||||||
let forgery_ghash = ghash(
|
let forgery_ghash = ghash(
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ pub fn gfmul_task(args: &Value) -> Result<Vec<u8>> {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
// Note this useful idiom: importing names from outer (for mod tests) scope.
|
// Note this useful idiom: importing names from outer (for mod tests) scope.
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,6 @@ pub fn padding_oracle(args: &Value) -> Result<Vec<u8>> {
|
||||||
|
|
||||||
for chunk in &cipher_chunks {
|
for chunk in &cipher_chunks {
|
||||||
let mut stream = TcpStream::connect(format!("{}:{}", hostname, port))?;
|
let mut stream = TcpStream::connect(format!("{}:{}", hostname, port))?;
|
||||||
stream.set_nodelay(true).expect("Error on no delay");
|
|
||||||
stream.set_nonblocking(false)?;
|
stream.set_nonblocking(false)?;
|
||||||
|
|
||||||
// Track value sent to server
|
// Track value sent to server
|
||||||
|
|
@ -40,6 +39,7 @@ pub fn padding_oracle(args: &Value) -> Result<Vec<u8>> {
|
||||||
let q_block_count: u16 = 256;
|
let q_block_count: u16 = 256;
|
||||||
|
|
||||||
//Send the first ciphertext chunk
|
//Send the first ciphertext chunk
|
||||||
|
//eprintln!("Sending Ciphertext chunk: {:002X?}", chunk);
|
||||||
stream.flush()?;
|
stream.flush()?;
|
||||||
stream.write_all(&chunk)?;
|
stream.write_all(&chunk)?;
|
||||||
stream.flush()?;
|
stream.flush()?;
|
||||||
|
|
@ -49,16 +49,24 @@ pub fn padding_oracle(args: &Value) -> Result<Vec<u8>> {
|
||||||
// FIXME: Assignment is redundant for now
|
// FIXME: Assignment is redundant for now
|
||||||
// TODO: Goal is to maybe add speed increase in the future
|
// TODO: Goal is to maybe add speed increase in the future
|
||||||
let l_msg: [u8; 2] = q_block_count.to_le_bytes();
|
let l_msg: [u8; 2] = q_block_count.to_le_bytes();
|
||||||
|
//eprintln!("Sending l_msg: {:02X?}", l_msg);
|
||||||
|
//stream.write_all(&l_msg)?;
|
||||||
|
//stream.flush()?;
|
||||||
|
//eprintln!("L_msg sent");
|
||||||
|
|
||||||
// Generate attack blocks
|
// Generate attack blocks
|
||||||
// TODO: Collect all and send in one
|
// TODO: Collect all and send in one
|
||||||
let mut payload: Vec<u8> = Vec::with_capacity(2 + 16 * 265);
|
let mut payload: Vec<u8> = l_msg.to_vec();
|
||||||
payload.extend(l_msg.to_vec());
|
for j in 0..q_block_count {
|
||||||
for _j in 0..q_block_count {
|
|
||||||
// Next byte
|
// Next byte
|
||||||
|
//eprintln!("Sending attack block: {:02X?}", attack_counter);
|
||||||
|
|
||||||
|
//thread::sleep(Duration::from_millis(1000));
|
||||||
payload.extend(&attack_counter);
|
payload.extend(&attack_counter);
|
||||||
|
//eprintln!("I in q builder {}", i);
|
||||||
attack_counter[i as usize] += 1;
|
attack_counter[i as usize] += 1;
|
||||||
}
|
}
|
||||||
|
//eprintln!("Time for qblocks: {:?}", start.elapsed());
|
||||||
|
|
||||||
stream.write_all(&payload)?;
|
stream.write_all(&payload)?;
|
||||||
stream.flush()?;
|
stream.flush()?;
|
||||||
|
|
@ -66,6 +74,7 @@ pub fn padding_oracle(args: &Value) -> Result<Vec<u8>> {
|
||||||
// Read server response
|
// Read server response
|
||||||
let mut server_q_resp = [0u8; 256];
|
let mut server_q_resp = [0u8; 256];
|
||||||
stream.read_exact(&mut server_q_resp)?;
|
stream.read_exact(&mut server_q_resp)?;
|
||||||
|
//eprintln!("{:02X?}", buf);
|
||||||
|
|
||||||
// extract valid position
|
// extract valid position
|
||||||
let valid_val = server_q_resp
|
let valid_val = server_q_resp
|
||||||
|
|
@ -75,6 +84,7 @@ pub fn padding_oracle(args: &Value) -> Result<Vec<u8>> {
|
||||||
if valid_val == 0x00 {
|
if valid_val == 0x00 {
|
||||||
eprintln!("No valid found in main loop");
|
eprintln!("No valid found in main loop");
|
||||||
}
|
}
|
||||||
|
//eprintln!("Valid value found: {:02X?}", valid_val);
|
||||||
// Craft next attack vector padding; 0x01, 0x02, ...
|
// Craft next attack vector padding; 0x01, 0x02, ...
|
||||||
attack_counter[i as usize] = valid_val;
|
attack_counter[i as usize] = valid_val;
|
||||||
|
|
||||||
|
|
@ -88,10 +98,15 @@ pub fn padding_oracle(args: &Value) -> Result<Vec<u8>> {
|
||||||
l_msg_check.extend(check_q_block.as_slice());
|
l_msg_check.extend(check_q_block.as_slice());
|
||||||
|
|
||||||
stream.write_all(&l_msg_check)?;
|
stream.write_all(&l_msg_check)?;
|
||||||
|
//stream.write_all(&check_q_block)?;
|
||||||
let mut buf = [0u8; 0x01];
|
let mut buf = [0u8; 0x01];
|
||||||
stream.read(&mut buf)?;
|
stream.read(&mut buf)?;
|
||||||
|
//eprintln!("I = {}", i);
|
||||||
|
//eprintln!("Buffer from pad check: {:02X?}", buf);
|
||||||
if buf == [0x01] {
|
if buf == [0x01] {
|
||||||
|
//eprintln!("Valid padding");
|
||||||
} else {
|
} else {
|
||||||
|
//eprintln!("Invalid padding");
|
||||||
// Search for second hit
|
// Search for second hit
|
||||||
let valid_val = 255
|
let valid_val = 255
|
||||||
- server_q_resp
|
- server_q_resp
|
||||||
|
|
@ -102,21 +117,38 @@ pub fn padding_oracle(args: &Value) -> Result<Vec<u8>> {
|
||||||
if valid_val == 0x00 {
|
if valid_val == 0x00 {
|
||||||
eprintln!("No valid found");
|
eprintln!("No valid found");
|
||||||
}
|
}
|
||||||
|
//eprintln!("Valid value found: {:02X?}", valid_val);
|
||||||
// Craft next attack vector padding; 0x01, 0x02, ...
|
// Craft next attack vector padding; 0x01, 0x02, ...
|
||||||
attack_counter[i as usize] = valid_val;
|
attack_counter[i as usize] = valid_val;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if chunk_counter + 1 < cipher_chunks.len() {
|
if chunk_counter + 1 < cipher_chunks.len() {
|
||||||
|
//eprintln!("XOR Next Ciph block");
|
||||||
plaintext.push(
|
plaintext.push(
|
||||||
cipher_chunks[chunk_counter + 1][i]
|
cipher_chunks[chunk_counter + 1][i]
|
||||||
^ (attack_counter[i as usize] ^ (15 - i as u8 + 1)),
|
^ (attack_counter[i as usize] ^ (15 - i as u8 + 1)),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
//seprintln!("XOR IV");
|
||||||
|
|
||||||
plaintext.push(iv[i] ^ (attack_counter[i as usize] ^ (15 - i as u8 + 1)));
|
plaintext.push(iv[i] ^ (attack_counter[i as usize] ^ (15 - i as u8 + 1)));
|
||||||
}
|
}
|
||||||
|
//eprintln!("Attack counter after set: {:02X?}", attack_counter);
|
||||||
let range = i;
|
let range = i;
|
||||||
for pos in range..=15 {
|
for pos in range..=15 {
|
||||||
|
//eprintln!("i is: {:02X?}", i);
|
||||||
|
//eprintln!("i + 1 is: {:02X?}", ((16 - i) as u8).to_le());
|
||||||
|
/*
|
||||||
|
eprintln!(
|
||||||
|
"attack_counter[pos as usize]: {:02X?}",
|
||||||
|
attack_counter[pos as usize]
|
||||||
|
);
|
||||||
|
eprintln!(
|
||||||
|
"attack_counter[pos as usize] ^ 0x02 {:02X?}",
|
||||||
|
attack_counter[pos as usize] ^ (15 - i as u8 + 1)
|
||||||
|
);
|
||||||
|
*/
|
||||||
let intermediate = attack_counter[pos as usize] ^ (15 - i as u8 + 1);
|
let intermediate = attack_counter[pos as usize] ^ (15 - i as u8 + 1);
|
||||||
|
|
||||||
attack_counter[pos as usize] = intermediate ^ ((15 - i as u8 + 1) + 1);
|
attack_counter[pos as usize] = intermediate ^ ((15 - i as u8 + 1) + 1);
|
||||||
|
|
@ -125,10 +157,13 @@ pub fn padding_oracle(args: &Value) -> Result<Vec<u8>> {
|
||||||
stream.flush()?;
|
stream.flush()?;
|
||||||
|
|
||||||
// Write plaintext
|
// Write plaintext
|
||||||
|
//eprintln!("{:02X?}", plaintext);
|
||||||
}
|
}
|
||||||
chunk_counter += 1;
|
chunk_counter += 1;
|
||||||
stream.flush()?;
|
stream.flush()?;
|
||||||
|
// break;
|
||||||
drop(stream);
|
drop(stream);
|
||||||
|
//eprintln!("Time rest of calc: {:?}", start.elapsed());
|
||||||
}
|
}
|
||||||
|
|
||||||
plaintext.reverse();
|
plaintext.reverse();
|
||||||
|
|
@ -140,6 +175,7 @@ pub fn padding_oracle(args: &Value) -> Result<Vec<u8>> {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use serde_json::json;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_connection() -> Result<()> {
|
fn test_connection() -> Result<()> {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::utils::poly::polynomial_2_block;
|
use crate::utils::poly::{polynomial_2_block};
|
||||||
use anyhow::{Ok, Result};
|
use anyhow::{Ok, Result};
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,13 +6,18 @@ use crate::utils::ciphers::{sea_128_decrypt, sea_128_encrypt};
|
||||||
|
|
||||||
pub fn sea128(args: &Value) -> Result<String> {
|
pub fn sea128(args: &Value) -> Result<String> {
|
||||||
let key_string: String = serde_json::from_value(args["key"].clone())?;
|
let key_string: String = serde_json::from_value(args["key"].clone())?;
|
||||||
|
//let key: &[u8] = b64_2_num(key_string)?.to_ne_bytes();
|
||||||
let key = BASE64_STANDARD.decode(key_string)?;
|
let key = BASE64_STANDARD.decode(key_string)?;
|
||||||
|
//eprintln!("{:?}", key);
|
||||||
let input_string: String = serde_json::from_value(args["input"].clone())?;
|
let input_string: String = serde_json::from_value(args["input"].clone())?;
|
||||||
|
//let plaintexts: &[u8] = &b64_2_num(plaintexts_string)?.to_ne_bytes();
|
||||||
let input = BASE64_STANDARD.decode(input_string)?;
|
let input = BASE64_STANDARD.decode(input_string)?;
|
||||||
|
|
||||||
let mode: String = serde_json::from_value(args["mode"].clone())?;
|
let mode: String = serde_json::from_value(args["mode"].clone())?;
|
||||||
match mode.as_str() {
|
match mode.as_str() {
|
||||||
"encrypt" => {
|
"encrypt" => {
|
||||||
|
//eprintln!("{:?}", plaintexts);
|
||||||
|
|
||||||
let output = BASE64_STANDARD.encode(sea_128_encrypt(&key, &input)?);
|
let output = BASE64_STANDARD.encode(sea_128_encrypt(&key, &input)?);
|
||||||
|
|
||||||
Ok(output)
|
Ok(output)
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
use crate::utils::{field::ByteArray, poly::gfmul};
|
use crate::utils::{field::ByteArray, poly::gfmul};
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
use base64::prelude::*;
|
||||||
use openssl::symm::{Cipher, Crypter, Mode};
|
use openssl::symm::{Cipher, Crypter, Mode};
|
||||||
|
|
||||||
use super::math::xor_bytes;
|
use super::math::xor_bytes;
|
||||||
|
|
@ -161,6 +162,7 @@ pub fn gcm_decrypt_aes(
|
||||||
|
|
||||||
let mut counter: u32 = 1;
|
let mut counter: u32 = 1;
|
||||||
nonce.append(counter.to_be_bytes().to_vec().as_mut());
|
nonce.append(counter.to_be_bytes().to_vec().as_mut());
|
||||||
|
//nonce.append(0u8.to_le_bytes().to_vec().as_mut());
|
||||||
|
|
||||||
let auth_tag_xor = aes_128_encrypt(&key, &nonce)?;
|
let auth_tag_xor = aes_128_encrypt(&key, &nonce)?;
|
||||||
|
|
||||||
|
|
@ -249,6 +251,7 @@ pub fn gcm_decrypt_sea(
|
||||||
|
|
||||||
let mut counter: u32 = 1;
|
let mut counter: u32 = 1;
|
||||||
nonce.append(counter.to_be_bytes().to_vec().as_mut());
|
nonce.append(counter.to_be_bytes().to_vec().as_mut());
|
||||||
|
//nonce.append(0u8.to_le_bytes().to_vec().as_mut());
|
||||||
|
|
||||||
let auth_tag_xor = sea_128_encrypt(&key, &nonce)?;
|
let auth_tag_xor = sea_128_encrypt(&key, &nonce)?;
|
||||||
|
|
||||||
|
|
@ -322,6 +325,13 @@ pub fn ghash(
|
||||||
Ok(inter_loop)
|
Ok(inter_loop)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* let mut bytes: [u8; 16] = [0u8; 16];
|
||||||
|
bytes.copy_from_slice(&ciphertext);
|
||||||
|
let number: u128 = <u128>::from_be_bytes(bytes);
|
||||||
|
|
||||||
|
* */
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,7 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("Result: {:?}", result);
|
println!("Result: {:?}", result);
|
||||||
let _bit_indices: Vec<u8> = vec![0];
|
let bit_indices: Vec<u8> = vec![0];
|
||||||
assert!(false)
|
assert!(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,9 @@ use std::{
|
||||||
|
|
||||||
use anyhow::{anyhow, Ok, Result};
|
use anyhow::{anyhow, Ok, Result};
|
||||||
|
|
||||||
|
use crate::utils::poly::bgfmul;
|
||||||
|
|
||||||
|
use super::poly::polynomial_2_block;
|
||||||
use super::{
|
use super::{
|
||||||
math::{reverse_bits_in_bytevec, xor_bytes},
|
math::{reverse_bits_in_bytevec, xor_bytes},
|
||||||
poly::gfmul,
|
poly::gfmul,
|
||||||
|
|
@ -40,6 +43,14 @@ impl FieldElement {
|
||||||
self.field_element.clone()
|
self.field_element.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
pub fn padd(&mut self) {
|
||||||
|
if self.field_element.len() % 16 != 0 || ad.is_empty() {
|
||||||
|
ad.append(vec![0u8; 16 - (ad.len() % 16)].as_mut());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
pub fn new(field_element: Vec<u8>) -> Self {
|
pub fn new(field_element: Vec<u8>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
field_element: reverse_bits_in_bytevec(field_element),
|
field_element: reverse_bits_in_bytevec(field_element),
|
||||||
|
|
@ -71,18 +82,29 @@ impl FieldElement {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//eprintln!("Initial result: {:?}", result);
|
||||||
while exponent > 0 {
|
while exponent > 0 {
|
||||||
|
//eprintln!("Current exponent: {:02X}", exponent);
|
||||||
if exponent & 1 == 1 {
|
if exponent & 1 == 1 {
|
||||||
let temp = &self * &result;
|
let temp = &self * &result;
|
||||||
|
//eprintln!("Mult");
|
||||||
|
//eprintln!("After mod: {:?}", temp);
|
||||||
|
|
||||||
result = temp
|
result = temp
|
||||||
}
|
}
|
||||||
let temp_square = &self * &self;
|
let temp_square = &self * &self;
|
||||||
|
// eprintln!("Square");
|
||||||
|
|
||||||
|
// eprintln!("After squaring: {:?}", temp_square);
|
||||||
self = temp_square;
|
self = temp_square;
|
||||||
|
//eprintln!("After mod: {:?}", self);
|
||||||
exponent >>= 1;
|
exponent >>= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// eprintln!("result in powmod before reduction: {:02X?}", result);
|
||||||
|
|
||||||
|
// eprintln!("result in powmod after reduction: {:02X?}", result);
|
||||||
|
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -91,8 +113,10 @@ impl FieldElement {
|
||||||
|
|
||||||
let mut inverser = INVERSER_START;
|
let mut inverser = INVERSER_START;
|
||||||
let mut inverse: Vec<u8> = vec![0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
|
let mut inverse: Vec<u8> = vec![0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
|
||||||
|
//eprintln!("Inverse start {:02X?}", inverse);
|
||||||
|
|
||||||
while inverser > 0 {
|
while inverser > 0 {
|
||||||
|
//eprintln!("{:02X}", inverser);
|
||||||
if inverser & 1 == 1 {
|
if inverser & 1 == 1 {
|
||||||
inverse = gfmul(&self.field_element, &inverse, "xex").unwrap();
|
inverse = gfmul(&self.field_element, &inverse, "xex").unwrap();
|
||||||
}
|
}
|
||||||
|
|
@ -100,6 +124,7 @@ impl FieldElement {
|
||||||
self.field_element = gfmul(&self.field_element, &self.field_element, "xex")
|
self.field_element = gfmul(&self.field_element, &self.field_element, "xex")
|
||||||
.expect("Error in sqrmul sqr");
|
.expect("Error in sqrmul sqr");
|
||||||
}
|
}
|
||||||
|
//eprintln!("Inverse rhs {:?}", inverse);
|
||||||
FieldElement::new_no_convert(inverse)
|
FieldElement::new_no_convert(inverse)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -337,6 +362,7 @@ impl ByteArray {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use serde_json::json;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_byte_array_shift1() {
|
fn test_byte_array_shift1() {
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,21 @@
|
||||||
use crate::utils::field::ByteArray;
|
use crate::utils::field::ByteArray;
|
||||||
use base64::prelude::*;
|
use base64::prelude::*;
|
||||||
|
|
||||||
use num::traits::FromBytes;
|
use num::traits::{FromBytes, ToBytes};
|
||||||
use num::{BigUint, One, Zero};
|
use num::{BigInt, BigUint, One, Zero};
|
||||||
|
|
||||||
use std::{str::FromStr, u128, u8, usize};
|
use std::{str::FromStr, u128, u8, usize};
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
cmp::Ordering,
|
cmp::Ordering,
|
||||||
ops::{Add, Mul},
|
ops::{Add, Div, Mul},
|
||||||
};
|
};
|
||||||
|
|
||||||
use anyhow::{anyhow, Ok, Result};
|
use anyhow::{anyhow, Ok, Result};
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
|
|
||||||
use super::field::FieldElement;
|
use super::field::FieldElement;
|
||||||
|
use super::math::reverse_bits_in_bytevec;
|
||||||
|
|
||||||
#[derive(Debug, serde::Serialize, serde::Deserialize)]
|
#[derive(Debug, serde::Serialize, serde::Deserialize)]
|
||||||
pub struct Polynomial {
|
pub struct Polynomial {
|
||||||
|
|
@ -107,18 +108,27 @@ impl Polynomial {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//eprintln!("Initial result: {:?}", result);
|
||||||
while exponent > 0 {
|
while exponent > 0 {
|
||||||
|
//eprintln!("Current exponent: {:02X}", exponent);
|
||||||
if exponent & 1 == 1 {
|
if exponent & 1 == 1 {
|
||||||
let temp = &self * &result;
|
let temp = &self * &result;
|
||||||
|
//eprintln!("Mult");
|
||||||
|
//eprintln!("After mod: {:?}", temp);
|
||||||
|
|
||||||
result = temp
|
result = temp
|
||||||
}
|
}
|
||||||
let temp_square = &self * &self;
|
let temp_square = &self * &self;
|
||||||
|
//eprintln!("Square");
|
||||||
|
|
||||||
|
//eprintln!("After squaring: {:?}", temp_square);
|
||||||
self = temp_square;
|
self = temp_square;
|
||||||
|
//eprintln!("After mod: {:?}", self);
|
||||||
exponent >>= 1;
|
exponent >>= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//eprintln!("result in powmod before reduction: {:02X?}", result);
|
||||||
|
|
||||||
while !result.polynomial.is_empty()
|
while !result.polynomial.is_empty()
|
||||||
&& result
|
&& result
|
||||||
.polynomial
|
.polynomial
|
||||||
|
|
@ -131,6 +141,8 @@ impl Polynomial {
|
||||||
result.polynomial.pop();
|
result.polynomial.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//eprintln!("result in powmod after reduction: {:02X?}", result);
|
||||||
|
|
||||||
if result.is_empty() {
|
if result.is_empty() {
|
||||||
result = Polynomial::zero();
|
result = Polynomial::zero();
|
||||||
}
|
}
|
||||||
|
|
@ -155,13 +167,19 @@ impl Polynomial {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//eprintln!("Initial result: {:?}", result);
|
||||||
while &exponent > &BigUint::zero() {
|
while &exponent > &BigUint::zero() {
|
||||||
|
//eprintln!("Current exponent: {:02X}", exponent);
|
||||||
if &exponent & BigUint::one() == BigUint::one() {
|
if &exponent & BigUint::one() == BigUint::one() {
|
||||||
let temp = &self * &result;
|
let temp = &self * &result;
|
||||||
|
//eprintln!("After multiplication: {:?}", temp);
|
||||||
result = temp.div(&modulus).1;
|
result = temp.div(&modulus).1;
|
||||||
|
//eprintln!("After mod: {:?}", result);
|
||||||
}
|
}
|
||||||
let temp_square = &self * &self;
|
let temp_square = &self * &self;
|
||||||
|
//eprintln!("After squaring: {:?}", temp_square);
|
||||||
self = temp_square.div(&modulus).1;
|
self = temp_square.div(&modulus).1;
|
||||||
|
//eprintln!("After mod: {:?}", self);
|
||||||
exponent >>= 1;
|
exponent >>= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -198,13 +216,19 @@ impl Polynomial {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//eprintln!("Initial result: {:?}", result);
|
||||||
while exponent > 0 {
|
while exponent > 0 {
|
||||||
|
//eprintln!("Current exponent: {:02X}", exponent);
|
||||||
if exponent & 1 == 1 {
|
if exponent & 1 == 1 {
|
||||||
let temp = &self * &result;
|
let temp = &self * &result;
|
||||||
|
//eprintln!("After multiplication: {:?}", temp);
|
||||||
result = temp.div(&modulus).1;
|
result = temp.div(&modulus).1;
|
||||||
|
//eprintln!("After mod: {:?}", result);
|
||||||
}
|
}
|
||||||
let temp_square = &self * &self;
|
let temp_square = &self * &self;
|
||||||
|
//eprintln!("After squaring: {:?}", temp_square);
|
||||||
self = temp_square.div(&modulus).1;
|
self = temp_square.div(&modulus).1;
|
||||||
|
//eprintln!("After mod: {:?}", self);
|
||||||
exponent >>= 1;
|
exponent >>= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -550,11 +574,14 @@ pub fn sort_polynomial_array(mut polys: Vec<Polynomial>) -> Result<Vec<Polynomia
|
||||||
pub const RED_POLY: u128 = 0x87000000_00000000_00000000_00000000;
|
pub const RED_POLY: u128 = 0x87000000_00000000_00000000_00000000;
|
||||||
|
|
||||||
pub fn gfmul(poly_a: &Vec<u8>, poly_b: &Vec<u8>, semantic: &str) -> Result<Vec<u8>> {
|
pub fn gfmul(poly_a: &Vec<u8>, poly_b: &Vec<u8>, semantic: &str) -> Result<Vec<u8>> {
|
||||||
let red_poly_bytes: ByteArray = ByteArray(RED_POLY.to_be_bytes().to_vec());
|
let mut red_poly_bytes: ByteArray = ByteArray(RED_POLY.to_be_bytes().to_vec());
|
||||||
|
//red_poly_bytes.0.push(0x01);
|
||||||
|
|
||||||
let mut poly1: ByteArray = ByteArray(poly_a.to_vec());
|
let mut poly1: ByteArray = ByteArray(poly_a.to_vec());
|
||||||
|
//poly1.0.push(0x00);
|
||||||
|
|
||||||
let mut poly2: ByteArray = ByteArray(poly_b.to_vec());
|
let mut poly2: ByteArray = ByteArray(poly_b.to_vec());
|
||||||
|
//poly2.0.push(0x00);
|
||||||
|
|
||||||
if semantic == "gcm" {
|
if semantic == "gcm" {
|
||||||
poly1.reverse_bits_in_bytevec();
|
poly1.reverse_bits_in_bytevec();
|
||||||
|
|
@ -591,6 +618,53 @@ pub fn gfmul(poly_a: &Vec<u8>, poly_b: &Vec<u8>, semantic: &str) -> Result<Vec<u
|
||||||
Ok(result.0)
|
Ok(result.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn bgfmul(poly_a: &Vec<u8>, poly_b: &Vec<u8>, semantic: &str) -> Result<Vec<u8>> {
|
||||||
|
//TODO: Implement gfmul with bigint
|
||||||
|
let red_poly_bytes: BigUint = BigUint::from_slice(&[
|
||||||
|
0x87, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 0x01,
|
||||||
|
]);
|
||||||
|
|
||||||
|
let mut poly1: BigUint = BigUint::from_le_bytes(poly_a);
|
||||||
|
|
||||||
|
let mut poly2: BigUint = BigUint::from_le_bytes(poly_b);
|
||||||
|
|
||||||
|
/*
|
||||||
|
if semantic == "gcm" {
|
||||||
|
poly1.re;
|
||||||
|
poly2.reverse_bits_in_bytevec();
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
let mut result: BigUint = BigUint::zero();
|
||||||
|
|
||||||
|
if (&poly2 & (BigUint::one() << 127)) == BigUint::one() {
|
||||||
|
result = &result ^ &poly1;
|
||||||
|
}
|
||||||
|
poly2 = &poly2 >> 1;
|
||||||
|
|
||||||
|
while &poly2 != &BigUint::zero() {
|
||||||
|
poly1 = &poly1 << 1;
|
||||||
|
|
||||||
|
if (&poly1 & (BigUint::one() << 127)) == BigUint::one() {
|
||||||
|
poly1 = &poly1 ^ &red_poly_bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
if &poly2 & BigUint::one() == BigUint::one() {
|
||||||
|
result = &result ^ &poly1;
|
||||||
|
}
|
||||||
|
|
||||||
|
poly2 = &poly2 >> 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
if semantic == "gcm" {
|
||||||
|
result.reverse_bits_in_bytevec();
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
Ok(result.to_bytes_le())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn convert_gcm_to_xex(gcm_poly: Vec<u8>) -> Result<Vec<u8>> {
|
pub fn convert_gcm_to_xex(gcm_poly: Vec<u8>) -> Result<Vec<u8>> {
|
||||||
let xex_poly = gcm_poly
|
let xex_poly = gcm_poly
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
|
@ -603,6 +677,8 @@ pub fn convert_gcm_to_xex(gcm_poly: Vec<u8>) -> Result<Vec<u8>> {
|
||||||
pub fn get_alpha_rep(num: u128) -> String {
|
pub fn get_alpha_rep(num: u128) -> String {
|
||||||
let powers: Vec<u8> = get_coefficients(num);
|
let powers: Vec<u8> = get_coefficients(num);
|
||||||
|
|
||||||
|
//println!("{:?}", powers);
|
||||||
|
|
||||||
let mut alpha_rep = String::new();
|
let mut alpha_rep = String::new();
|
||||||
|
|
||||||
if powers.len() == 1 {
|
if powers.len() == 1 {
|
||||||
|
|
@ -629,6 +705,7 @@ pub fn b64_2_num(string: &String) -> Result<u128> {
|
||||||
pub fn get_coefficients(num: u128) -> Vec<u8> {
|
pub fn get_coefficients(num: u128) -> Vec<u8> {
|
||||||
let mut powers: Vec<u8> = vec![];
|
let mut powers: Vec<u8> = vec![];
|
||||||
for shift in 0..128 {
|
for shift in 0..128 {
|
||||||
|
//println!("{:?}", ((num >> shift) & 1));
|
||||||
if ((num >> shift) & 1) == 1 {
|
if ((num >> shift) & 1) == 1 {
|
||||||
powers.push(shift);
|
powers.push(shift);
|
||||||
}
|
}
|
||||||
|
|
@ -755,7 +832,7 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn coeff_to_binary() {
|
fn coeff_to_binary() {
|
||||||
let coefficients: Vec<u8> = vec![12, 127, 9, 0];
|
let coefficients: Vec<u8> = vec![12, 127, 9, 0];
|
||||||
let _b64: &str = "ARIAAAAAAAAAAAAAAAAAgA==";
|
let b64: &str = "ARIAAAAAAAAAAAAAAAAAgA==";
|
||||||
let calculated_num: u128 = coefficient_to_binary(coefficients);
|
let calculated_num: u128 = coefficient_to_binary(coefficients);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
BASE64_STANDARD.encode(calculated_num.to_ne_bytes()),
|
BASE64_STANDARD.encode(calculated_num.to_ne_bytes()),
|
||||||
|
|
|
||||||
|
|
@ -86,7 +86,7 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("{:?}", result);
|
println!("{:?}", result);
|
||||||
let _bit_indices: Vec<u8> = vec![0];
|
let bit_indices: Vec<u8> = vec![0];
|
||||||
assert!(false)
|
assert!(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue