wip: sts. vincent and anastasius ii

This commit is contained in:
Matthew LeVan 2024-01-22 21:10:35 -05:00
commit 43d145ac72
15 changed files with 2168 additions and 343 deletions

603
rust/ares/Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -12,13 +12,14 @@ edition = "2018"
# Please keep these alphabetized
[dependencies]
ares_guard = { path = "../ares_guard" }
ares_crypto = { path = "../ares_crypto" }
ares_macros = { path = "../ares_macros" }
# Use this when debugging requires the debug printfs in the PMA
# ares_pma = { path = "../ares_pma", features=["debug_prints"] }
ares_pma = { path = "../ares_pma" }
assert_no_alloc = { path = "../rust-assert-no-alloc" }
# use this when debugging requires allocation (e.g. eprintln)
# assert_no_alloc = { path = "../rust-assert-no-alloc", features=["warn_debug"] }
assert_no_alloc = { path = "../rust-assert-no-alloc", features=["warn_debug"] }
# assert_no_alloc = { path = "../rust-assert-no-alloc" }
bitvec = "1.0.0"
criterion = "0.4"
either = "1.9.0"
@ -33,7 +34,6 @@ num-derive = "0.3"
num-traits = "0.2"
signal-hook = "0.3"
static_assertions = "1.1.0"
urcrypt-sys = "0.1.1"
[build-dependencies]
autotools = "0.2.6"

View File

@ -19,7 +19,6 @@ use ares_guard::{guard, guard_err};
use ares_macros::tas;
use assert_no_alloc::{assert_no_alloc, ensure_alloc_counters};
use bitvec::prelude::{BitSlice, Lsb0};
use bitvec::ptr::null_mut;
use either::Either::*;
use std::ffi::c_void;
use std::result;
@ -380,6 +379,7 @@ pub fn call_with_guard<F: FnMut() -> Result>(
alloc: *mut *mut c_void,
ret: *mut *mut c_void,
) -> Result {
eprintln!("call_with_guard");
let boxed_f = Box::new(f);
unsafe {

View File

@ -2,13 +2,12 @@ use crate::interpreter::Context;
use crate::jets::bits::util::met;
use crate::jets::util::slot;
use crate::jets::{JetErr, Result};
use crate::noun::{IndirectAtom, Noun};
use urcrypt_sys::*;
use crate::noun::Noun;
crate::gdb!();
// Note: The Hoon code for these functions doesn't explicitly check key
// sizes. However, the implementations of these functions in urcrypt
// sizes. However, the implementations of these functions in ares_crypto
// have fixed maximum key sizes, therefore we must punt if the key is
// too large.
@ -16,17 +15,15 @@ pub fn jet_siva_en(context: &mut Context, subject: Noun) -> Result {
let stack = &mut context.stack;
let txt = slot(subject, 6)?.as_atom()?;
let key = slot(subject, 60)?.as_atom()?;
let atoms = slot(subject, 61)?;
let ads = slot(subject, 61)?;
if met(3, key) > 32 {
Err(JetErr::Punt)
} else {
unsafe {
let (mut _key_ida, key_bytes) = IndirectAtom::new_raw_mut_bytes(stack, 32);
key_bytes[0..key.as_bytes().len()].copy_from_slice(key.as_bytes());
let key_bytes = &mut [0u8; 32];
key_bytes[0..key.as_bytes().len()].copy_from_slice(key.as_bytes());
util::_siv_en(stack, key_bytes, atoms, txt, urcrypt_aes_siva_en)
}
util::_siv_en::<32>(stack, key_bytes, ads, txt)
}
}
@ -41,12 +38,10 @@ pub fn jet_siva_de(context: &mut Context, subject: Noun) -> Result {
if met(3, key) > 32 {
Err(JetErr::Punt)
} else {
unsafe {
let (mut _key_ida, key_bytes) = IndirectAtom::new_raw_mut_bytes(stack, 32);
key_bytes[0..key.as_bytes().len()].copy_from_slice(key.as_bytes());
let key_bytes = &mut [0u8; 32];
key_bytes[0..key.as_bytes().len()].copy_from_slice(key.as_bytes());
util::_siv_de(stack, key_bytes, ads, iv, len, txt, urcrypt_aes_siva_de)
}
util::_siv_de::<32>(stack, key_bytes, ads, iv, len, txt)
}
}
@ -54,17 +49,15 @@ pub fn jet_sivb_en(context: &mut Context, subject: Noun) -> Result {
let stack = &mut context.stack;
let txt = slot(subject, 6)?.as_atom()?;
let key = slot(subject, 60)?.as_atom()?;
let atoms = slot(subject, 61)?;
let ads = slot(subject, 61)?;
if met(3, key) > 48 {
Err(JetErr::Punt)
} else {
unsafe {
let (mut _key_ida, key_bytes) = IndirectAtom::new_raw_mut_bytes(stack, 48);
key_bytes[0..key.as_bytes().len()].copy_from_slice(key.as_bytes());
let key_bytes = &mut [0u8; 48];
key_bytes[0..key.as_bytes().len()].copy_from_slice(key.as_bytes());
util::_siv_en(stack, key_bytes, atoms, txt, urcrypt_aes_sivb_en)
}
util::_siv_en::<48>(stack, key_bytes, ads, txt)
}
}
@ -79,12 +72,10 @@ pub fn jet_sivb_de(context: &mut Context, subject: Noun) -> Result {
if met(3, key) > 48 {
Err(JetErr::Punt)
} else {
unsafe {
let (mut _key_ida, key_bytes) = IndirectAtom::new_raw_mut_bytes(stack, 48);
key_bytes[0..key.as_bytes().len()].copy_from_slice(key.as_bytes());
let key_bytes = &mut [0u8; 48];
key_bytes[0..key.as_bytes().len()].copy_from_slice(key.as_bytes());
util::_siv_de(stack, key_bytes, ads, iv, len, txt, urcrypt_aes_sivb_de)
}
util::_siv_de::<48>(stack, key_bytes, ads, iv, len, txt)
}
}
@ -92,17 +83,15 @@ pub fn jet_sivc_en(context: &mut Context, subject: Noun) -> Result {
let stack = &mut context.stack;
let txt = slot(subject, 6)?.as_atom()?;
let key = slot(subject, 60)?.as_atom()?;
let atoms = slot(subject, 61)?;
let ads = slot(subject, 61)?;
if met(3, key) > 64 {
Err(JetErr::Punt)
} else {
unsafe {
let (mut _key_ida, key_bytes) = IndirectAtom::new_raw_mut_bytes(stack, 64);
key_bytes[0..key.as_bytes().len()].copy_from_slice(key.as_bytes());
let key_bytes = &mut [0u8; 64];
key_bytes[0..key.as_bytes().len()].copy_from_slice(key.as_bytes());
util::_siv_en(stack, key_bytes, atoms, txt, urcrypt_aes_sivc_en)
}
util::_siv_en::<64>(stack, key_bytes, ads, txt)
}
}
@ -117,12 +106,10 @@ pub fn jet_sivc_de(context: &mut Context, subject: Noun) -> Result {
if met(3, key) > 64 {
Err(JetErr::Punt)
} else {
unsafe {
let (mut _key_ida, key_bytes) = IndirectAtom::new_raw_mut_bytes(stack, 64);
key_bytes[0..key.as_bytes().len()].copy_from_slice(key.as_bytes());
let key_bytes = &mut [0u8; 64];
key_bytes[0..key.as_bytes().len()].copy_from_slice(key.as_bytes());
util::_siv_de(stack, key_bytes, ads, iv, len, txt, urcrypt_aes_sivc_de)
}
util::_siv_de::<64>(stack, key_bytes, ads, iv, len, txt)
}
}
@ -133,48 +120,35 @@ mod util {
use crate::jets::{JetErr, Result};
use crate::mem::NockStack;
use crate::noun::{Atom, IndirectAtom, Noun, D, T};
use std::ptr::null_mut;
use ares_crypto::aes_siv::{ac_aes_siv_de, ac_aes_siv_en};
use std::result;
use urcrypt_sys::urcrypt_aes_siv_data;
type UrcryptSiv = unsafe extern "C" fn(
*mut u8,
usize,
*mut urcrypt_aes_siv_data,
usize,
*mut u8,
*mut u8,
*mut u8,
) -> i32;
/// Associated data for AES-SIV functions.
struct AcAesSivData {
bytes: *mut u8,
length: usize,
}
/// Encodes the list of atoms.
///
/// # Arguments
///
/// * `stack` - the active NockStack
/// * `atoms` - the list of atoms to allocate
///
fn _allocate_atoms(
/// Allocates a noun list as an array of AesSivData structs on the NockStack
/// for use as associated data in AES-SIV functions.
fn _allocate_ads(
stack: &mut NockStack,
mut atoms: Noun,
) -> result::Result<&'static mut [urcrypt_aes_siv_data], JetErr> {
if unsafe { atoms.raw_equals(D(0)) } {
mut ads: Noun,
) -> result::Result<&'static mut [AcAesSivData], JetErr> {
if unsafe { ads.raw_equals(D(0)) } {
return Ok(&mut []);
}
// measure
let length = list::util::lent(atoms)?;
let length = list::util::lent(ads)?;
// allocate
let siv_data: &mut [urcrypt_aes_siv_data] = unsafe {
let ptr = stack.struct_alloc::<urcrypt_aes_siv_data>(length);
let siv_data: &mut [AcAesSivData] = unsafe {
let ptr = stack.struct_alloc::<AcAesSivData>(length);
std::slice::from_raw_parts_mut(ptr, length)
};
// encode
unsafe {
for item in siv_data.iter_mut().take(length) {
let cell = atoms.as_cell()?;
let cell = ads.as_cell()?;
let head = cell.head().as_atom()?;
let bytes = head.as_bytes();
let len = met(3, head);
@ -185,59 +159,42 @@ mod util {
item.length = bytes.len();
item.bytes = atom.data_pointer_mut() as *mut u8;
atoms = cell.tail();
ads = cell.tail();
}
}
Ok(siv_data)
}
pub fn _siv_en(
pub fn _siv_en<const N: usize>(
stack: &mut NockStack,
key: &mut [u8],
key: &mut [u8; N],
ads: Noun,
txt: Atom,
fun: UrcryptSiv,
) -> Result {
unsafe {
let siv_data = _allocate_atoms(stack, ads)?;
let ac_siv_data = _allocate_ads(stack, ads)?;
let siv_data: &mut [&mut [u8]] = std::slice::from_raw_parts_mut(
ac_siv_data.as_mut_ptr() as *mut &mut [u8],
ac_siv_data.len(),
);
let txt_len = met(3, txt);
let txt_ptr = match txt_len {
0 => null_mut::<u8>(),
_ => {
let (_, txt_bytes) = IndirectAtom::new_raw_mut_bytes(stack, txt_len);
txt_bytes[0..txt_len].copy_from_slice(&(txt.as_bytes()[0..txt_len]));
txt_bytes.as_mut_ptr()
}
};
let (mut iv, iv_bytes) = IndirectAtom::new_raw_mut_bytes(stack, 16);
let (mut iv, iv_bytes) = IndirectAtom::new_raw_mut_bytearray::<16, NockStack>(stack);
// We match on length here and elsewhere where a similar pattern is followed
// to avoid panicking when a zero length is passed to IndirectAtom::new_raw_mut_bytes.
match txt_len {
0 => {
fun(
txt_ptr,
txt_len,
siv_data.as_mut_ptr(),
siv_data.len(),
key.as_mut_ptr(),
iv_bytes.as_mut_ptr(),
null_mut::<u8>(),
);
ac_aes_siv_en::<N>(key, &mut [], siv_data, iv_bytes, &mut [0u8; 0]).unwrap();
Ok(T(stack, &[iv.normalize_as_atom().as_noun(), D(0), D(0)]))
}
_ => {
let (_txt_ida, txt_bytes) = IndirectAtom::new_raw_mut_bytes(stack, txt_len);
txt_bytes.copy_from_slice(&txt.as_bytes()[0..txt_len]);
let (mut out_atom, out_bytes) = IndirectAtom::new_raw_mut_bytes(stack, txt_len);
fun(
txt_ptr,
txt_len,
siv_data.as_mut_ptr(),
siv_data.len(),
key.as_mut_ptr(),
iv_bytes.as_mut_ptr(),
out_bytes.as_mut_ptr(),
);
ac_aes_siv_en::<N>(key, txt_bytes, siv_data, iv_bytes, out_bytes).unwrap();
Ok(T(
stack,
&[
@ -251,42 +208,42 @@ mod util {
}
}
pub fn _siv_de(
pub fn _siv_de<const N: usize>(
stack: &mut NockStack,
key: &mut [u8],
key: &mut [u8; N],
ads: Noun,
iv: Atom,
len: Atom,
txt: Atom,
fun: UrcryptSiv,
) -> Result {
unsafe {
let txt_len = match len.as_direct() {
Ok(direct) => direct.data() as usize,
Err(_) => return Err(JetErr::Fail(Error::NonDeterministic(D(0)))),
};
let (_, txt_bytes) = IndirectAtom::new_raw_mut_bytes(stack, txt_len);
txt_bytes[0..txt_len].copy_from_slice(&(txt.as_bytes()[0..txt_len]));
let (_iv_ida, iv_bytes) = IndirectAtom::new_raw_mut_bytes(stack, 16);
iv_bytes[0..16].copy_from_slice(&(iv.as_bytes()[0..16]));
let iv_bytes = &mut [0u8; 16];
iv_bytes.copy_from_slice(&iv.as_bytes()[0..16]);
let siv_data = _allocate_atoms(stack, ads)?;
let ac_siv_data = _allocate_ads(stack, ads)?;
let siv_data: &mut [&mut [u8]] = std::slice::from_raw_parts_mut(
ac_siv_data.as_mut_ptr() as *mut &mut [u8],
ac_siv_data.len(),
);
let (mut out_atom, out_bytes) = IndirectAtom::new_raw_mut_bytes(stack, txt_len);
fun(
if txt_len == 0 {
null_mut::<u8>()
} else {
txt_bytes.as_mut_ptr()
},
txt_len,
siv_data.as_mut_ptr(),
siv_data.len(),
key.as_mut_ptr(),
iv_bytes.as_mut_ptr(),
out_bytes.as_mut_ptr(),
);
match txt_len {
0 => {
ac_aes_siv_de::<N>(key, &mut [], siv_data, iv_bytes, &mut [0u8; 0]).unwrap();
}
_ => {
let (_txt_ida, txt_bytes) = IndirectAtom::new_raw_mut_bytes(stack, txt_len);
txt_bytes.copy_from_slice(&txt.as_bytes()[0..txt_len]);
ac_aes_siv_de::<N>(key, txt_bytes, siv_data, iv_bytes, out_bytes).unwrap();
}
}
Ok(T(stack, &[D(0), out_atom.normalize_as_atom().as_noun()]))
}
}
@ -377,6 +334,22 @@ mod tests {
pub fn test_sivb_en() {
let c = &mut init_context();
/*
> (~(en sivb:aes:crypto [key=0x0 vec=~]) txt=0x0)
[p=0x8fb.4085.a9b9.3662.ab44.f911.e47e.9ccd q=0 r=0x0]
*/
fn sample(_s: &mut NockStack) -> Noun {
D(0)
}
fn context(s: &mut NockStack) -> Noun {
let sample = T(s, &[D(0), D(0)]);
T(s, &[D(0), sample, D(0)])
}
let siv = A(&mut c.stack, &ubig!(0x8fb4085a9b93662ab44f911e47e9ccd));
let res = T(&mut c.stack, &[siv, D(0), D(0x0)]);
assert_jet_in_door(c, jet_sivb_en, &[sample], &[context], res);
/* RFC 5297
* https://datatracker.ietf.org/doc/html/rfc5297#appendix-A
*/
@ -404,6 +377,22 @@ mod tests {
pub fn test_sivc_en() {
let c = &mut init_context();
/*
> (~(en sivc:aes:crypto [key=0x0 vec=~]) txt=0x0)
[p=0x2c6a.abc5.bb25.1140.e221.d70b.fb31.c519 q=0 r=0x0]
*/
fn sample(_s: &mut NockStack) -> Noun {
D(0)
}
fn context(s: &mut NockStack) -> Noun {
let sample = T(s, &[D(0), D(0)]);
T(s, &[D(0), sample, D(0)])
}
let siv = A(&mut c.stack, &ubig!(0x2c6aabc5bb251140e221d70bfb31c519));
let res = T(&mut c.stack, &[siv, D(0), D(0x0)]);
assert_jet_in_door(c, jet_sivc_en, &[sample], &[context], res);
/* RFC 5297
* https://datatracker.ietf.org/doc/html/rfc5297#appendix-A
*/

View File

@ -2,8 +2,9 @@ use crate::interpreter::{Context, Error};
use crate::jets::bits::util::met;
use crate::jets::util::slot;
use crate::jets::{JetErr, Result};
use crate::mem::NockStack;
use crate::noun::{IndirectAtom, Noun, D, NO, YES};
use urcrypt_sys::*;
use ares_crypto::ed25519::{ac_ed_puck, ac_ed_shar, ac_ed_sign, ac_ed_veri};
crate::gdb!();
@ -11,21 +12,17 @@ pub fn jet_puck(context: &mut Context, subject: Noun) -> Result {
let stack = &mut context.stack;
let sed = slot(subject, 6)?.as_atom()?;
if met(3, sed) > 32 {
let sed_len = met(3, sed);
if sed_len > 32 {
return Err(JetErr::Fail(Error::Deterministic(D(0))));
}
unsafe {
// allocate 32 byte buffer on
let sed_buffer = &mut [0u8; 32] as *mut u8;
let sed_bytes = sed.as_bytes();
let sed_bytes = &mut [0u8; 32];
sed_bytes[0..sed_len].copy_from_slice(&(sed.as_bytes())[0..sed_len]);
// we need to copy because the atom might be less than 32 bytes and urcrypt expects a
// 32-byte buffer
std::ptr::copy_nonoverlapping(sed_bytes.as_ptr(), sed_buffer, sed_bytes.len());
let (mut pub_ida, pub_key) = IndirectAtom::new_raw_mut_bytes(stack, 32);
urcrypt_ed_puck(sed_buffer as *const u8, pub_key.as_mut_ptr());
let (mut pub_ida, pub_key) = IndirectAtom::new_raw_mut_bytearray::<32, NockStack>(stack);
ac_ed_puck(sed_bytes, pub_key);
Ok(pub_ida.normalize_as_atom().as_noun())
}
@ -47,17 +44,17 @@ pub fn jet_shar(context: &mut Context, subject: Noun) -> Result {
}
unsafe {
let (_, public) = IndirectAtom::new_raw_mut_bytes(stack, 32);
let (_, secret) = IndirectAtom::new_raw_mut_bytes(stack, 32);
let public = &mut [0u8; 32];
let secret = &mut [0u8; 32];
let pub_bytes = pub_key.as_bytes();
let sec_bytes = sec_key.as_bytes();
public[0..pub_bytes.len()].copy_from_slice(pub_bytes);
secret[0..sec_bytes.len()].copy_from_slice(sec_bytes);
secret[0..pub_bytes.len()].copy_from_slice(sec_bytes);
let (mut shar_ida, shar) = IndirectAtom::new_raw_mut_bytes(stack, 32);
urcrypt_ed_shar(public.as_ptr(), secret.as_ptr(), shar.as_mut_ptr());
let (mut shar_ida, shar) = IndirectAtom::new_raw_mut_bytearray::<32, NockStack>(stack);
ac_ed_shar(public, secret, shar);
Ok(shar_ida.normalize_as_atom().as_noun())
}
@ -70,62 +67,55 @@ pub fn jet_sign(context: &mut Context, subject: Noun) -> Result {
unsafe {
let sed_bytes = sed.as_bytes();
if sed_bytes.len() > 32 {
let sed_len = sed_bytes.len();
if sed_len > 32 {
return Err(JetErr::Fail(Error::Deterministic(D(0))));
};
let seed = &mut [0u8; 32];
seed[0..sed_len].copy_from_slice(sed_bytes);
let msg_bytes = &(msg.as_bytes())[0..met(3, msg)]; // drop trailing zeros
let (mut sig_ida, sig) = IndirectAtom::new_raw_mut_bytearray::<64, NockStack>(stack);
let (mut _seed_ida, seed) = IndirectAtom::new_raw_mut_bytes(stack, 32);
seed.copy_from_slice(sed_bytes);
let (mut sig_ida, sig) = IndirectAtom::new_raw_mut_bytes(stack, 64);
urcrypt_ed_sign(
msg_bytes.as_ptr(),
msg_bytes.len(),
seed.as_ptr(),
sig.as_mut_ptr(),
);
sig.reverse(); // LSB first
let msg_len = met(3, msg);
if msg_len > 0 {
let (_msg_ida, message) = IndirectAtom::new_raw_mut_bytes(stack, msg_len);
message.copy_from_slice(&msg.as_bytes()[0..msg_len]);
ac_ed_sign(message, seed, sig);
}
else {
ac_ed_sign(&[0u8; 0], seed, sig);
}
sig.reverse();
Ok(sig_ida.normalize_as_atom().as_noun())
}
}
pub fn jet_veri(context: &mut Context, subject: Noun) -> Result {
let stack = &mut context.stack;
pub fn jet_veri(_context: &mut Context, subject: Noun) -> Result {
let sig = slot(subject, 12)?.as_atom()?;
let msg = slot(subject, 26)?.as_atom()?;
let puk = slot(subject, 27)?.as_atom()?;
unsafe {
// Both are size checked by Hoon, but without crashing
let sig_bytes = sig.as_bytes();
if sig_bytes.len() > 64 {
return Ok(NO);
};
// Both are size checked by Hoon, but without crashing
let sig_bytes = sig.as_bytes();
if sig_bytes.len() > 64 {
return Ok(NO);
};
let signature = &mut [0u8; 64];
signature[0..sig_bytes.len()].copy_from_slice(sig_bytes);
let pub_bytes = puk.as_bytes();
if pub_bytes.len() > 32 {
return Ok(NO);
};
let pub_bytes = puk.as_bytes();
if pub_bytes.len() > 32 {
return Ok(NO);
};
let public_key = &mut [0u8; 32];
public_key[0..pub_bytes.len()].copy_from_slice(pub_bytes);
let (mut _sig_ida, signature) = IndirectAtom::new_raw_mut_bytes(stack, 64);
signature.copy_from_slice(sig_bytes);
let (mut _pub_ida, public_key) = IndirectAtom::new_raw_mut_bytes(stack, 32);
public_key.copy_from_slice(pub_bytes);
let message = &(msg.as_bytes())[0..met(3, msg)]; // drop trailing zeros
let message = &(msg.as_bytes())[0..met(3, msg)]; // drop trailing zeros
let valid = ac_ed_veri(message, public_key, signature);
let valid = urcrypt_ed_veri(
message.as_ptr(),
message.len(),
public_key.as_ptr(),
signature.as_ptr(),
);
Ok(if valid { YES } else { NO })
}
Ok(if valid { YES } else { NO })
}
#[cfg(test)]
@ -142,6 +132,16 @@ mod tests {
fn test_puck() {
let c = &mut init_context();
let sam = A(
&mut c.stack,
&ubig!(_0x0),
);
let ret = A(
&mut c.stack,
&ubig!(_0x29da598ba148c03aa643e21d77153265730d6f2ad0a8a3622da4b6cebc276a3b),
);
assert_jet(c, jet_puck, sam, ret);
let sam = A(
&mut c.stack,
&ubig!(_0x607fae1c03ac3b701969327b69c54944c42cec92f44a84ba605afdef9db1619d),
@ -157,6 +157,13 @@ mod tests {
fn test_shar() {
let c = &mut init_context();
let sam = T(&mut c.stack, &[D(0), D(0)]);
let ret = A(
&mut c.stack,
&ubig!(_0x0),
);
assert_jet(c, jet_shar, sam, ret);
let sam = T(&mut c.stack, &[D(234), D(234)]);
let ret = A(
&mut c.stack,
@ -176,6 +183,10 @@ mod tests {
let c = &mut init_context();
unsafe {
let sam = T(&mut c.stack, &[D(0), D(0)]);
let ret = A(&mut c.stack, &ubig!(_0x8f895b3cafe2c9506039d0e2a66382568004674fe8d237785092e40d6aaf483e4fc60168705f31f101596138ce21aa357c0d32a064f423dc3ee4aa3abf53f803));
assert_jet(c, jet_sign, sam, ret);
let message = D(0x72);
let sed_ubig =
@ -213,6 +224,9 @@ mod tests {
let c = &mut init_context();
unsafe {
let sam = T(&mut c.stack, &[D(0), D(0), D(0)]);
assert_jet(c, jet_veri, sam, NO);
let sig_ubig = ubig!(_0x92a009a9f0d4cab8720e820b5f642540a2b27b5416503f8fb3762223ebdb69da085ac1e43e15996e458f3613d0f11d8c387b2eaeb4302aeeb00d291612bb0c00);
let sig_bytes = sig_ubig.to_be_bytes();
let signature =

View File

@ -3,7 +3,7 @@ use crate::jets::bits::util::met;
use crate::jets::util::slot;
use crate::jets::{JetErr, Result};
use crate::noun::{IndirectAtom, Noun, D};
use urcrypt_sys::*;
use ares_crypto::sha::{ac_sha1, ac_shal, ac_shas, ac_shay};
crate::gdb!();
@ -17,19 +17,22 @@ pub fn jet_shas(context: &mut Context, subject: Noun) -> Result {
let (mut _salt_ida, salt) = unsafe { IndirectAtom::new_raw_mut_bytes(stack, sal_bytes.len()) };
salt.copy_from_slice(sal_bytes);
let message = &(ruz.as_bytes())[0..met(3, ruz)]; // drop trailing zeros
unsafe {
let (mut out_ida, out) = IndirectAtom::new_raw_mut_bytes(stack, 32);
urcrypt_shas(
salt.as_mut_ptr(),
salt.len(),
message.as_ptr(),
message.len(),
out.as_mut_ptr(),
);
let msg_len = met(3, ruz);
if msg_len > 0 {
let (_msg_ida, message) = IndirectAtom::new_raw_mut_bytes(stack, msg_len);
message.copy_from_slice(&ruz.as_bytes()[0..msg_len]);
ac_shas(message, salt, out);
}
else {
ac_shas(&mut [], salt, out);
}
Ok(out_ida.normalize_as_atom().as_noun())
}
}
pub fn jet_shax(context: &mut Context, subject: Noun) -> Result {
@ -40,7 +43,16 @@ pub fn jet_shax(context: &mut Context, subject: Noun) -> Result {
unsafe {
let (mut ida, out) = IndirectAtom::new_raw_mut_bytes(stack, 32);
urcrypt_shay(msg.as_bytes().as_ptr(), len, out.as_mut_ptr());
if len > 0 {
let (mut _msg_ida, msg_copy) = IndirectAtom::new_raw_mut_bytes(stack, len);
msg_copy.copy_from_slice(&msg.as_bytes()[0..len]);
ac_shay(&mut (msg_copy)[0..len], out);
}
else {
ac_shay(&mut [], out);
}
Ok(ida.normalize_as_atom().as_noun())
}
}
@ -56,11 +68,16 @@ pub fn jet_shay(context: &mut Context, subject: Noun) -> Result {
Err(_) => return Err(JetErr::Fail(Error::NonDeterministic(D(0)))),
};
let message = dat.as_bytes();
unsafe {
let (mut out_ida, out) = IndirectAtom::new_raw_mut_bytes(stack, 32);
urcrypt_shay(message.as_ptr(), width, out.as_mut_ptr());
if width > 0 {
let (mut _msg_ida, msg) = IndirectAtom::new_raw_mut_bytes(stack, width);
msg.copy_from_slice(&dat.as_bytes()[0..width]);
ac_shay(msg, out);
}
else {
ac_shay(&mut [], out);
}
Ok(out_ida.normalize_as_atom().as_noun())
}
}
@ -71,16 +88,23 @@ pub fn jet_shal(context: &mut Context, subject: Noun) -> Result {
let wid = slot(sam, 2)?.as_atom()?;
let dat = slot(sam, 3)?.as_atom()?;
let width = match wid.as_direct() {
let _width = match wid.as_direct() {
Ok(direct) => direct.data() as usize,
Err(_) => return Err(JetErr::Fail(Error::NonDeterministic(D(0)))),
};
let message = &(dat.as_bytes())[0..met(3, dat)]; // drop trailing zeros
let msg_len = met(3, dat);
unsafe {
let (mut ida, out) = IndirectAtom::new_raw_mut_bytes(stack, 64);
urcrypt_shal(message.as_ptr(), width, out.as_mut_ptr());
if msg_len > 0 {
let (mut _msg_ida, msg) = IndirectAtom::new_raw_mut_bytes(stack, msg_len);
msg.copy_from_slice(&dat.as_bytes()[0..msg_len]);
ac_shal(msg, out);
}
else {
ac_shal(&mut [], out);
}
Ok(ida.normalize_as_atom().as_noun())
}
}
@ -97,12 +121,12 @@ pub fn jet_sha1(context: &mut Context, subject: Noun) -> Result {
};
unsafe {
let msg_bytes = dat.as_bytes();
let msg_bytes = &(dat.as_bytes())[0..width];
let (mut _msg_ida, msg) = IndirectAtom::new_raw_mut_bytes(stack, msg_bytes.len());
msg.copy_from_slice(msg_bytes);
let (mut out_ida, out) = IndirectAtom::new_raw_mut_bytes(stack, 20);
urcrypt_sha1(msg.as_mut_ptr(), width, out.as_mut_ptr());
ac_sha1(msg, out);
Ok(out_ida.normalize_as_atom().as_noun())
}
}
@ -119,6 +143,14 @@ mod tests {
fn test_shas() {
let c = &mut init_context();
let sam = T(&mut c.stack, &[D(1), D(0)]);
assert_jet_ubig(
c,
jet_shas,
sam,
ubig!(_0x4abac214e1e95fe0c60df79d09cbd05454a4cb958683e02318aa147f2a5e6d60),
);
let sam = T(&mut c.stack, &[D(1), D(1)]);
assert_jet_ubig(
c,
@ -156,6 +188,13 @@ mod tests {
fn test_shax() {
let c = &mut init_context();
assert_jet_ubig(
c,
jet_shax,
D(0), // ''
ubig!(_0x55b852781b9995a44c939b64e441ae2724b96f99c8f4fb9a141cfc9842c4b0e3),
);
assert_jet_ubig(
c,
jet_shax,
@ -197,6 +236,13 @@ mod tests {
fn test_shay() {
let c = &mut init_context();
let sam = T(&mut c.stack, &[D(0), D(0)]);
let ret = A(
&mut c.stack,
&ubig!(_0x55b852781b9995a44c939b64e441ae2724b96f99c8f4fb9a141cfc9842c4b0e3),
);
assert_jet(c, jet_shay, sam, ret);
let sam = T(&mut c.stack, &[D(1), D(0)]);
let ret = A(
&mut c.stack,
@ -254,6 +300,14 @@ mod tests {
fn test_shal() {
let c = &mut init_context();
let sam = T(&mut c.stack, &[D(0), D(0)]);
assert_jet_ubig(
c,
jet_shal,
sam,
ubig!(_0x3eda27f97a3238a5817a4147bd31b9632fec7e87d21883ffb0f2855d3cd1d047cee96cd321a9f483dc15570b05e420d607806dd6502854f1bdb8ef7e35e183cf)
);
let sam = T(&mut c.stack, &[D(1), D(1)]);
assert_jet_ubig(
c,

View File

@ -436,6 +436,15 @@ impl IndirectAtom {
(noun, from_raw_parts_mut(ptr as *mut u8, size))
}
/// Create an indirect atom backed by a fixed-size array
pub unsafe fn new_raw_mut_bytearray<'a, const N: usize, A: NounAllocator>(
allocator: &mut A,
) -> (Self, &'a mut [u8; N]) {
let word_size = (std::mem::size_of::<[u8; N]>() + 7) << 3;
let (noun, ptr) = Self::new_raw_mut_zeroed(allocator, word_size);
(noun, &mut *(ptr as *mut [u8; N]))
}
/** Size of an indirect atom in 64-bit words */
pub fn size(&self) -> usize {
unsafe { *(self.to_raw_pointer().add(1)) as usize }

794
rust/ares_crypto/Cargo.lock generated Normal file
View File

@ -0,0 +1,794 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "aead"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0"
dependencies = [
"crypto-common",
"generic-array",
]
[[package]]
name = "aes"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac1f845298e95f983ff1944b728ae08b8cebab80d684f0a832ed0fc74dfa27e2"
dependencies = [
"cfg-if",
"cipher",
"cpufeatures",
]
[[package]]
name = "aes-siv"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7e08d0cdb774acd1e4dac11478b1a0c0d203134b2aab0ba25eb430de9b18f8b9"
dependencies = [
"aead",
"aes",
"cipher",
"cmac",
"ctr",
"dbl",
"digest",
"zeroize",
]
[[package]]
name = "aho-corasick"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0"
dependencies = [
"memchr",
]
[[package]]
name = "ares_crypto"
version = "0.1.0"
dependencies = [
"aes",
"aes-siv",
"assert_no_alloc",
"curve25519-dalek",
"ed25519-dalek",
"ibig",
"rand",
"sha1",
"sha2",
"urcrypt-sys",
"x25519-dalek",
]
[[package]]
name = "assert_no_alloc"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55ca83137a482d61d916ceb1eba52a684f98004f18e0cafea230fe5579c178a3"
[[package]]
name = "autocfg"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]]
name = "bindgen"
version = "0.68.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "726e4313eb6ec35d2730258ad4e15b547ee75d6afaa1361a922e78e59b7d8078"
dependencies = [
"bitflags",
"cexpr",
"clang-sys",
"lazy_static",
"lazycell",
"log",
"peeking_take_while",
"prettyplease",
"proc-macro2",
"quote",
"regex",
"rustc-hash",
"shlex",
"syn",
"which",
]
[[package]]
name = "bitflags"
version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07"
[[package]]
name = "block-buffer"
version = "0.10.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
dependencies = [
"generic-array",
]
[[package]]
name = "cexpr"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766"
dependencies = [
"nom",
]
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "cipher"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad"
dependencies = [
"crypto-common",
"inout",
]
[[package]]
name = "clang-sys"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67523a3b4be3ce1989d607a828d036249522dd9c1c8de7f4dd2dae43a37369d1"
dependencies = [
"glob",
"libc",
"libloading",
]
[[package]]
name = "cmac"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8543454e3c3f5126effff9cd44d562af4e31fb8ce1cc0d3dcd8f084515dbc1aa"
dependencies = [
"cipher",
"dbl",
"digest",
]
[[package]]
name = "cpufeatures"
version = "0.2.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504"
dependencies = [
"libc",
]
[[package]]
name = "crypto-common"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
dependencies = [
"generic-array",
"rand_core",
"typenum",
]
[[package]]
name = "ctr"
version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835"
dependencies = [
"cipher",
]
[[package]]
name = "curve25519-dalek"
version = "4.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e89b8c6a2e4b1f45971ad09761aafb85514a84744b67a95e32c3cc1352d1f65c"
dependencies = [
"cfg-if",
"cpufeatures",
"curve25519-dalek-derive",
"digest",
"fiat-crypto",
"platforms",
"rustc_version",
"subtle",
]
[[package]]
name = "curve25519-dalek-derive"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "dbl"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd2735a791158376708f9347fe8faba9667589d82427ef3aed6794a8981de3d9"
dependencies = [
"generic-array",
]
[[package]]
name = "digest"
version = "0.10.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
dependencies = [
"block-buffer",
"crypto-common",
"subtle",
]
[[package]]
name = "ed25519"
version = "2.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53"
dependencies = [
"signature",
]
[[package]]
name = "ed25519-dalek"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1f628eaec48bfd21b865dc2950cfa014450c01d2fa2b69a86c2fd5844ec523c0"
dependencies = [
"curve25519-dalek",
"ed25519",
"sha2",
"subtle",
]
[[package]]
name = "either"
version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07"
[[package]]
name = "errno"
version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245"
dependencies = [
"libc",
"windows-sys 0.52.0",
]
[[package]]
name = "fiat-crypto"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "27573eac26f4dd11e2b1916c3fe1baa56407c83c71a773a8ba17ec0bca03b6b7"
[[package]]
name = "generic-array"
version = "0.14.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
dependencies = [
"typenum",
"version_check",
]
[[package]]
name = "getrandom"
version = "0.2.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]]
name = "glob"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
[[package]]
name = "home"
version = "0.5.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5"
dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "ibig"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d1fcc7f316b2c079dde77564a1360639c1a956a23fa96122732e416cb10717bb"
dependencies = [
"cfg-if",
"num-traits",
"rand",
"static_assertions",
]
[[package]]
name = "inout"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5"
dependencies = [
"generic-array",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "lazycell"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
[[package]]
name = "libc"
version = "0.2.152"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7"
[[package]]
name = "libloading"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c571b676ddfc9a8c12f1f3d3085a7b163966a8fd8098a90640953ce5f6170161"
dependencies = [
"cfg-if",
"windows-sys 0.48.0",
]
[[package]]
name = "linux-raw-sys"
version = "0.4.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456"
[[package]]
name = "log"
version = "0.4.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
[[package]]
name = "memchr"
version = "2.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149"
[[package]]
name = "minimal-lexical"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
[[package]]
name = "nom"
version = "7.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
dependencies = [
"memchr",
"minimal-lexical",
]
[[package]]
name = "num-traits"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c"
dependencies = [
"autocfg",
]
[[package]]
name = "once_cell"
version = "1.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
[[package]]
name = "peeking_take_while"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
[[package]]
name = "pkg-config"
version = "0.3.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69d3587f8a9e599cc7ec2c00e331f71c4e69a5f9a4b8a6efd5b07466b9736f9a"
[[package]]
name = "platforms"
version = "3.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "626dec3cac7cc0e1577a2ec3fc496277ec2baa084bebad95bb6fdbfae235f84c"
[[package]]
name = "prettyplease"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a41cf62165e97c7f814d2221421dbb9afcbcdb0a88068e5ea206e19951c2cbb5"
dependencies = [
"proc-macro2",
"syn",
]
[[package]]
name = "proc-macro2"
version = "1.0.76"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
dependencies = [
"proc-macro2",
]
[[package]]
name = "rand"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
dependencies = [
"rand_core",
]
[[package]]
name = "rand_core"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
dependencies = [
"getrandom",
]
[[package]]
name = "regex"
version = "1.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343"
dependencies = [
"aho-corasick",
"memchr",
"regex-automata",
"regex-syntax",
]
[[package]]
name = "regex-automata"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
[[package]]
name = "rustc-hash"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
[[package]]
name = "rustc_version"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
dependencies = [
"semver",
]
[[package]]
name = "rustix"
version = "0.38.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72e572a5e8ca657d7366229cdde4bd14c4eb5499a9573d4d366fe1b599daa316"
dependencies = [
"bitflags",
"errno",
"libc",
"linux-raw-sys",
"windows-sys 0.52.0",
]
[[package]]
name = "semver"
version = "1.0.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0"
[[package]]
name = "sha1"
version = "0.10.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba"
dependencies = [
"cfg-if",
"cpufeatures",
"digest",
]
[[package]]
name = "sha2"
version = "0.10.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8"
dependencies = [
"cfg-if",
"cpufeatures",
"digest",
]
[[package]]
name = "shlex"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7cee0529a6d40f580e7a5e6c495c8fbfe21b7b52795ed4bb5e62cdf92bc6380"
[[package]]
name = "signature"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de"
[[package]]
name = "static_assertions"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]]
name = "subtle"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc"
[[package]]
name = "syn"
version = "2.0.48"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "typenum"
version = "1.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
[[package]]
name = "unicode-ident"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
name = "urcrypt-sys"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ced751f95a527a3458eb67c75e4ae7093d41585edaa7565f5769101502473019"
dependencies = [
"bindgen",
"pkg-config",
]
[[package]]
name = "version_check"
version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
name = "wasi"
version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "which"
version = "4.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7"
dependencies = [
"either",
"home",
"once_cell",
"rustix",
]
[[package]]
name = "windows-sys"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
dependencies = [
"windows-targets 0.48.5",
]
[[package]]
name = "windows-sys"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
dependencies = [
"windows-targets 0.52.0",
]
[[package]]
name = "windows-targets"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
dependencies = [
"windows_aarch64_gnullvm 0.48.5",
"windows_aarch64_msvc 0.48.5",
"windows_i686_gnu 0.48.5",
"windows_i686_msvc 0.48.5",
"windows_x86_64_gnu 0.48.5",
"windows_x86_64_gnullvm 0.48.5",
"windows_x86_64_msvc 0.48.5",
]
[[package]]
name = "windows-targets"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd"
dependencies = [
"windows_aarch64_gnullvm 0.52.0",
"windows_aarch64_msvc 0.52.0",
"windows_i686_gnu 0.52.0",
"windows_i686_msvc 0.52.0",
"windows_x86_64_gnu 0.52.0",
"windows_x86_64_gnullvm 0.52.0",
"windows_x86_64_msvc 0.52.0",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea"
[[package]]
name = "windows_aarch64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef"
[[package]]
name = "windows_i686_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
[[package]]
name = "windows_i686_gnu"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313"
[[package]]
name = "windows_i686_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
[[package]]
name = "windows_i686_msvc"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a"
[[package]]
name = "windows_x86_64_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e"
[[package]]
name = "windows_x86_64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04"
[[package]]
name = "x25519-dalek"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fb66477291e7e8d2b0ff1bcb900bf29489a9692816d79874bea351e7a8b6de96"
dependencies = [
"curve25519-dalek",
"rand_core",
]
[[package]]
name = "zeroize"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d"

View File

@ -0,0 +1,37 @@
[package]
name = "ares_crypto"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
assert_no_alloc = "1.1.2"
# use this when debugging requires allocation (e.g. eprintln)
# assert_no_alloc = {version="1.1.2", features=["warn_debug"]}
ibig = "0.3.6"
# ed25519
curve25519-dalek = {version = "4.1.1", default-features = false, optional = true }
ed25519-dalek = { version = "2.1.0", default-features = false, optional = true }
x25519-dalek = { version = "2.0.0", features = ["static_secrets"], default-features = false, optional = true}
# aes_siv
aes = { version = "0.8.3", default-features = false, optional = true }
aes-siv = { version = "0.7.0", default-features = false, optional = true }
# sha
sha1 = { version = "0.10.6", default-features = false, optional = true }
sha2 = { version = "0.10.8", default-features = false, optional = true }
# test_vs_urcrypt
rand = { version = "0.8.4", default-features = false, features = ["getrandom"], optional = true }
urcrypt-sys = { version = "0.1.1", optional = true }
[features]
# XX turn off test_vs_urcrypt after development
default = ["aes_siv", "ed25519", "sha"]
aes_siv = ["aes", "aes-siv"]
ed25519 = ["curve25519-dalek", "ed25519-dalek", "x25519-dalek"]
sha = ["sha1", "sha2"]
test_vs_urcrypt = ["urcrypt-sys", "rand"]

View File

@ -0,0 +1,277 @@
use aes_siv::aead::{generic_array::GenericArray, KeyInit};
use aes_siv::siv::{Aes128Siv, Aes256Siv, CmacSiv};
use aes::Aes192;
type Aes192Siv = CmacSiv<Aes192>;
#[derive(Debug)]
pub enum Error {
InvalidKeyLength,
InvalidOutputLength,
InvalidHeadersLength,
CipherNotAuthentic,
}
/// AES-SIV encryption function.
pub fn ac_aes_siv_en<const N: usize>(
key: &mut [u8; N],
message: &mut [u8],
data: &mut [&mut [u8]],
iv: &mut [u8; 16],
out: &mut [u8],
) -> Result<(), Error> {
key.reverse();
message.reverse();
for item in data.iter_mut() {
item.reverse();
}
let iv_tag;
if N == 32 {
if let Ok(mut cipher) = Aes128Siv::new_from_slice(key) {
match cipher.encrypt_in_place_detached(data, message) {
Ok(tag) => iv_tag = tag,
Err(_) => return Err(Error::InvalidOutputLength),
}
} else {
return Err(Error::InvalidKeyLength);
}
} else if N == 48 {
if let Ok(mut cipher) = Aes192Siv::new_from_slice(key) {
match cipher.encrypt_in_place_detached(data, message) {
Ok(tag) => iv_tag = tag,
Err(_) => return Err(Error::InvalidOutputLength),
}
} else {
return Err(Error::InvalidKeyLength);
}
} else if N == 64 {
if let Ok(mut cipher) = Aes256Siv::new_from_slice(key) {
match cipher.encrypt_in_place_detached(data, message) {
Ok(tag) => iv_tag = tag,
Err(_) => return Err(Error::InvalidOutputLength),
}
} else {
return Err(Error::InvalidKeyLength);
}
} else {
return Err(Error::InvalidKeyLength);
}
let mut iv_slice = iv_tag.as_slice().to_owned();
iv_slice.reverse();
iv.copy_from_slice(&iv_slice);
key.reverse();
message.reverse();
out[0..message.len()].copy_from_slice(message);
Ok(())
}
/// AES-SIV decryption function.
pub fn ac_aes_siv_de<const N: usize>(
key: &mut [u8; N],
message: &mut [u8],
data: &mut [&mut [u8]],
iv: &mut [u8; 16],
out: &mut [u8],
) -> Result<(), Error> {
key.reverse();
message.reverse();
iv.reverse();
for item in data.iter_mut() {
item.reverse();
}
let iv_array = GenericArray::from_slice(iv);
if N == 32 {
if let Ok(mut cipher) = Aes128Siv::new_from_slice(key) {
match cipher.decrypt_in_place_detached(data, message, iv_array) {
Ok(_) => (),
Err(_) => return Err(Error::CipherNotAuthentic),
}
} else {
return Err(Error::InvalidKeyLength);
}
} else if N == 48 {
if let Ok(mut cipher) = Aes192Siv::new_from_slice(key) {
match cipher.decrypt_in_place_detached(data, message, iv_array) {
Ok(_) => (),
Err(_) => return Err(Error::CipherNotAuthentic),
}
} else {
return Err(Error::InvalidKeyLength);
}
} else if N == 64 {
if let Ok(mut cipher) = Aes256Siv::new_from_slice(key) {
match cipher.decrypt_in_place_detached(data, message, iv_array) {
Ok(_) => (),
Err(_) => return Err(Error::CipherNotAuthentic),
}
} else {
return Err(Error::InvalidKeyLength);
}
} else {
return Err(Error::InvalidKeyLength);
}
key.reverse();
message.reverse();
out.copy_from_slice(message);
Ok(())
}
#[cfg(test)]
#[cfg(feature = "test_vs_urcrypt")]
/// Compare the results of the ares_crypto functions with the corresponding
/// urcrypt functions. To run, use `cargo test --features test_vs_urcrypt`
/// from the `ares/rust/ares_crypto` directory.
mod urcrypt_tests {
use super::ac_aes_siv_en;
use aes_siv::aead::rand_core::CryptoRngCore;
use rand::rngs::OsRng;
use urcrypt_sys::{
urcrypt_aes_siv_data, urcrypt_aes_siva_en, urcrypt_aes_sivb_en, urcrypt_aes_sivc_en,
};
#[test]
fn test_aes_siva_en() {
let mut uc_key = [0u8; 32];
let mut uc_message = [0u8; 56];
let mut uc_iv = [0u8; 16];
let mut uc_bytes = [0u8; 32];
let mut osrng = OsRng;
let csprng = osrng.as_rngcore();
csprng.fill_bytes(&mut uc_key);
csprng.fill_bytes(&mut uc_message);
csprng.fill_bytes(&mut uc_bytes);
let mut uc_data: [urcrypt_aes_siv_data; 1] = [urcrypt_aes_siv_data {
bytes: uc_bytes.as_mut_ptr(),
length: uc_bytes.len(),
}];
let mut uc_out = [0u8; 56];
let mut ac_key = uc_key;
let mut ac_message = uc_message;
let mut ac_iv = [0u8; 16];
let mut ac_bytes = uc_bytes;
let ac_data: &mut [&mut [u8]] = &mut [&mut ac_bytes];
let mut ac_out = [0u8; 56];
unsafe {
urcrypt_aes_siva_en(
uc_message.as_mut_ptr(),
uc_message.len(),
uc_data.as_mut_ptr(),
uc_data.len(),
uc_key.as_mut_ptr(),
uc_iv.as_mut_ptr(),
uc_out.as_mut_ptr(),
)
};
ac_aes_siv_en::<32>(
&mut ac_key,
&mut ac_message,
ac_data,
&mut ac_iv,
&mut ac_out,
)
.unwrap();
assert_eq!(ac_out, uc_out);
}
#[test]
fn test_aes_sivb_en() {
let mut uc_key = [0u8; 48];
let mut uc_message = [0u8; 56];
let mut uc_iv = [0u8; 16];
let mut uc_bytes = [0u8; 32];
let mut osrng = OsRng;
let csprng = osrng.as_rngcore();
csprng.fill_bytes(&mut uc_key);
csprng.fill_bytes(&mut uc_message);
csprng.fill_bytes(&mut uc_bytes);
let mut uc_data: [urcrypt_aes_siv_data; 1] = [urcrypt_aes_siv_data {
bytes: uc_bytes.as_mut_ptr(),
length: uc_bytes.len(),
}];
let mut uc_out = [0u8; 56];
let mut ac_key = uc_key;
let mut ac_message = uc_message;
let mut ac_iv = [0u8; 16];
let mut ac_bytes = uc_bytes;
let ac_data: &mut [&mut [u8]] = &mut [&mut ac_bytes];
let mut ac_out = [0u8; 56];
unsafe {
urcrypt_aes_sivb_en(
uc_message.as_mut_ptr(),
uc_message.len(),
uc_data.as_mut_ptr(),
uc_data.len(),
uc_key.as_mut_ptr(),
uc_iv.as_mut_ptr(),
uc_out.as_mut_ptr(),
)
};
ac_aes_siv_en::<48>(
&mut ac_key,
&mut ac_message,
ac_data,
&mut ac_iv,
&mut ac_out,
)
.unwrap();
assert_eq!(ac_out, uc_out);
}
#[test]
fn test_aes_sivc_en() {
let mut uc_key = [0u8; 64];
let mut uc_message = [0u8; 56];
let mut uc_iv = [0u8; 16];
let mut uc_bytes = [0u8; 32];
let mut osrng = OsRng;
let csprng = osrng.as_rngcore();
csprng.fill_bytes(&mut uc_key);
csprng.fill_bytes(&mut uc_message);
csprng.fill_bytes(&mut uc_bytes);
let mut uc_data: [urcrypt_aes_siv_data; 1] = [urcrypt_aes_siv_data {
bytes: uc_bytes.as_mut_ptr(),
length: uc_bytes.len(),
}];
let mut uc_out = [0u8; 56];
let mut ac_key = uc_key;
let mut ac_message = uc_message;
let mut ac_iv = [0u8; 16];
let mut ac_bytes = uc_bytes;
let ac_data: &mut [&mut [u8]] = &mut [&mut ac_bytes];
let mut ac_out = [0u8; 56];
unsafe {
urcrypt_aes_sivc_en(
uc_message.as_mut_ptr(),
uc_message.len(),
uc_data.as_mut_ptr(),
uc_data.len(),
uc_key.as_mut_ptr(),
uc_iv.as_mut_ptr(),
uc_out.as_mut_ptr(),
)
};
ac_aes_siv_en::<64>(
&mut ac_key,
&mut ac_message,
ac_data,
&mut ac_iv,
&mut ac_out,
)
.unwrap();
assert_eq!(ac_out, uc_out);
}
}

View File

@ -0,0 +1,212 @@
use curve25519_dalek::edwards::CompressedEdwardsY;
use ed25519_dalek::{Signature, Signer, SigningKey, Verifier, VerifyingKey};
use x25519_dalek::{PublicKey, StaticSecret};
/// Generate a public key from the given seed and write it to the given output slice.
pub fn ac_ed_puck(seed: &mut [u8; 32], out: &mut [u8; 32]) {
let signing_key = SigningKey::from_bytes(seed);
let verifying_key = signing_key.verifying_key();
*out = verifying_key.to_bytes();
}
/// Perform a key exchange between the given public key and the private key of
/// the keypair generate from the given seed, writing the resulting shared key
/// to the given output slice.
pub fn ac_ed_shar(public: &[u8; 32], seed: &[u8; 32], out: &mut [u8; 32]) {
let self_key = SigningKey::from_bytes(seed);
let self_secret = StaticSecret::from(self_key.to_scalar_bytes());
if let Ok(compressed_ed_pt) = CompressedEdwardsY::from_slice(public) {
if let Some(ed_pt) = compressed_ed_pt.decompress() {
let public_key = PublicKey::from(ed_pt.to_montgomery().to_bytes());
let shared_secret = self_secret.diffie_hellman(&public_key);
*out = shared_secret.to_bytes();
}
}
}
/// Sign a message with the given seed and write the resulting signature to the
/// given output slice.
pub fn ac_ed_sign(msg: &[u8], seed: &[u8; 32], out: &mut [u8; 64]) {
let signing_key = SigningKey::from_bytes(seed);
let signature = signing_key.sign(msg);
*out = signature.to_bytes();
}
/// Verify a signature of the given message with the given public key.
pub fn ac_ed_veri(msg: &[u8], public: &[u8; 32], signature: &[u8; 64]) -> bool {
if let Ok(verifying_key) = VerifyingKey::from_bytes(public) {
verifying_key
.verify(msg, &Signature::from_bytes(signature))
.is_ok()
} else {
false
}
}
#[cfg(test)]
mod tests {
use ibig::ubig;
use super::{ac_ed_puck, ac_ed_sign, ac_ed_veri};
#[test]
fn test_ed_puck() {
let mut seed: [u8; 32] = [0; 32];
let mut public_key: [u8; 32] = [0; 32];
ac_ed_puck(&mut seed, &mut public_key);
assert_eq!(
public_key,
[
59, 106, 39, 188, 206, 182, 164, 45, 98, 163, 168, 208, 42, 111, 13, 115, 101, 50,
21, 119, 29, 226, 67, 166, 58, 192, 72, 161, 139, 89, 218, 41
]
);
}
// #[test]
// fn test_ed_shar() {
// }
#[test]
fn test_ed_sign() {
// from https://datatracker.ietf.org/doc/html/rfc8032#section-7.1
// let msg: [u8; 0] = [];
// let seed_src = &ubig!(_0x9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60)
// .to_le_bytes();
// let mut seed: [u8; 32] = [0; 32];
// seed.copy_from_slice(seed_src);
// let mut signature: [u8; 64] = [0; 64];
// ac_ed_sign(&msg, &seed, &mut signature);
// let signature_src = &ubig!(_0xe5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b).to_le_bytes();
// let mut test_signature: [u8; 64] = [0; 64];
// test_signature.copy_from_slice(signature_src);
// assert_eq!(signature, test_signature);
//
let msg = b"Ares has long exerted a pull on the human imagination.";
let seed_src = &ubig!(_0x4ccd089b28ff96da9db6c346ec114e0f5b8a319f35aba624da8cf6ed4fb8a6fb)
.to_le_bytes();
let mut seed: [u8; 32] = [0; 32];
seed.copy_from_slice(seed_src);
let mut signature: [u8; 64] = [0; 64];
ac_ed_sign(msg, &seed, &mut signature);
let constant_signature = [
112, 132, 235, 218, 21, 180, 5, 48, 145, 211, 212, 153, 255, 229, 198, 165, 64, 140,
246, 27, 0, 97, 185, 143, 180, 10, 38, 68, 200, 71, 231, 108, 141, 26, 97, 207, 199,
204, 0, 123, 250, 161, 182, 92, 48, 116, 144, 42, 204, 6, 199, 162, 10, 66, 173, 185,
155, 96, 240, 56, 224, 187, 160, 1,
];
assert_eq!(signature, constant_signature);
}
#[test]
fn test_ed_veri() {
let msg = b"The erratically moving red star in the sky was seen as sinister or violent by the ancients.";
let mut seed = [42; 32];
let mut public_key: [u8; 32] = [0; 32];
ac_ed_puck(&mut seed, &mut public_key);
let mut signature: [u8; 64] = [0; 64];
ac_ed_sign(msg, &seed, &mut signature);
let valid = ac_ed_veri(msg, &public_key, &signature);
assert!(valid);
}
}
#[cfg(test)]
#[cfg(feature = "test_vs_urcrypt")]
/// Compare the results of the ares_crypto functions with the corresponding
/// urcrypt functions. To run, use `cargo test --features test_vs_urcrypt`
/// from the `ares/rust/ares_crypto` directory.
mod urcrypt_tests {
use super::{ac_ed_puck, ac_ed_shar, ac_ed_sign, ac_ed_veri};
use ibig::ubig;
use urcrypt_sys::{urcrypt_ed_puck, urcrypt_ed_shar, urcrypt_ed_sign, urcrypt_ed_veri};
#[test]
fn test_ed_puck() {
let mut seed: [u8; 32] = [42; 32];
let mut uc_out: [u8; 32] = [0; 32];
unsafe { urcrypt_ed_puck(seed.as_ptr(), uc_out.as_mut_ptr()) };
let mut ac_out: [u8; 32] = [0; 32];
ac_ed_puck(&mut seed, &mut ac_out);
assert_eq!(ac_out, uc_out);
}
#[test]
fn test_ed_shar() {
let public_key_src =
&ubig!(_0xd75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a)
.to_le_bytes();
let mut public_key: [u8; 32] = [0; 32];
public_key.copy_from_slice(public_key_src);
let seed_src = &ubig!(_0x4ccd089b28ff96da9db6c346ec114e0f5b8a319f35aba624da8cf6ed4fb8a6fb)
.to_le_bytes();
let mut seed: [u8; 32] = [0; 32];
seed.copy_from_slice(seed_src);
let mut uc_out: [u8; 32] = [0; 32];
unsafe { urcrypt_ed_shar(public_key.as_ptr(), seed.as_ptr(), uc_out.as_mut_ptr()) };
let mut ac_out: [u8; 32] = [0; 32];
ac_ed_shar(&public_key, &seed, &mut ac_out);
assert_eq!(ac_out, uc_out);
}
#[test]
fn test_ed_sign() {
let msg = b"The Greeks identified it with Ares, the god of war.";
let seed_src = &ubig!(_0x4ccd089b28ff96da9db6c346ec114e0f5b8a319f35aba624da8cf6ed4fb8a6fb)
.to_le_bytes();
let mut seed: [u8; 32] = [0; 32];
seed.copy_from_slice(seed_src);
let mut uc_out: [u8; 64] = [0; 64];
unsafe { urcrypt_ed_sign(msg.as_ptr(), msg.len(), seed.as_ptr(), uc_out.as_mut_ptr()) };
let mut ac_out: [u8; 64] = [0; 64];
ac_ed_sign(msg, &seed, &mut ac_out);
assert_eq!(ac_out, uc_out);
}
#[test]
fn test_ed_veri() {
let msg = b"The Babylonians named it after Nergal, god of the underworld.";
let seed_src = &ubig!(_0x4ccd089b28ff96da9db6c346ec114e0f5b8a319f35aba624da8cf6ed4fb8a6fb)
.to_le_bytes();
let mut seed: [u8; 32] = [0; 32];
seed.copy_from_slice(seed_src);
let mut public_key: [u8; 32] = [0; 32];
ac_ed_puck(&mut seed, &mut public_key);
let mut signature: [u8; 64] = [0; 64];
ac_ed_sign(msg, &seed, &mut signature);
let uc_out = unsafe {
urcrypt_ed_veri(
msg.as_ptr(),
msg.len(),
public_key.as_ptr(),
signature.as_ptr(),
)
};
let ac_out = ac_ed_veri(msg, &public_key, &signature);
assert_eq!(ac_out, uc_out);
}
}

View File

@ -0,0 +1,8 @@
#[cfg(feature = "aes_siv")]
pub mod aes_siv;
#[cfg(feature = "ed25519")]
pub mod ed25519;
#[cfg(feature = "sha")]
pub mod sha;

118
rust/ares_crypto/src/sha.rs Normal file
View File

@ -0,0 +1,118 @@
use sha1::{Digest, Sha1};
use sha2::{Sha256, Sha512};
/// Hashes a message using SHA-1.
pub fn ac_sha1(message: &mut [u8], out: &mut [u8]) {
message.reverse();
let mut hasher = Sha1::new();
hasher.update(message);
let mut result = hasher.finalize();
result.reverse();
out.copy_from_slice(&result);
}
/// Hashes a message using SHA-256.
pub fn ac_shay(message: &mut [u8], out: &mut [u8]) {
let mut hasher = Sha256::new();
hasher.update(message);
let result = hasher.finalize();
out.copy_from_slice(&result);
}
/// Hashes a message using SHA-512.
pub fn ac_shal(message: &mut [u8], out: &mut [u8]) {
let mut hasher = Sha512::new();
hasher.update(message);
let result = hasher.finalize();
out.copy_from_slice(&result);
}
/// Hashes a message and salt using SHA-256.
pub fn ac_shas(message: &mut [u8], salt: &mut [u8], out: &mut [u8]) {
let mut mid: [u8; 32] = [0; 32];
ac_shay(message, &mut mid);
if salt.len() > 32 {
for i in 0..32 {
salt[i] ^= mid[i];
}
ac_shay(salt, out);
} else {
for i in 0..salt.len() {
mid[i] ^= salt[i];
}
ac_shay(&mut mid, out);
}
}
#[cfg(test)]
#[cfg(feature = "test_vs_urcrypt")]
/// Compare the results of the ares_crypto functions with the corresponding
/// urcrypt functions. To run, use `cargo test --features test_vs_urcrypt`
/// from the `ares/rust/ares_crypto` directory.
mod urcrypt_tests {
use super::{ac_sha1, ac_shal, ac_shas, ac_shay};
use urcrypt_sys::{urcrypt_sha1, urcrypt_shal, urcrypt_shas, urcrypt_shay};
#[test]
fn test_sha1() {
let mut message: [u8; 32] = [42; 32];
let mut uc_out: [u8; 20] = [0; 20];
unsafe { urcrypt_sha1(message.as_mut_ptr(), message.len(), uc_out.as_mut_ptr()) };
let mut ac_out: [u8; 20] = [0; 20];
ac_sha1(&mut message, &mut ac_out);
assert_eq!(ac_out, uc_out);
}
#[test]
fn test_shay() {
let mut message: [u8; 32] = [42; 32];
let mut uc_out: [u8; 32] = [0; 32];
unsafe { urcrypt_shay(message.as_mut_ptr(), message.len(), uc_out.as_mut_ptr()) };
let mut ac_out: [u8; 32] = [0; 32];
ac_shay(&mut message, &mut ac_out);
assert_eq!(ac_out, uc_out);
}
#[test]
fn test_shal() {
let mut message: [u8; 32] = [42; 32];
let mut uc_out: [u8; 64] = [0; 64];
unsafe { urcrypt_shal(message.as_mut_ptr(), message.len(), uc_out.as_mut_ptr()) };
let mut ac_out: [u8; 64] = [0; 64];
ac_shal(&mut message, &mut ac_out);
assert_eq!(ac_out, uc_out);
}
#[test]
fn test_shas() {
let mut message: [u8; 32] = [42; 32];
let mut uc_salt: [u8; 32] = [43; 32];
let mut uc_out: [u8; 32] = [0; 32];
unsafe {
urcrypt_shas(
uc_salt.as_mut_ptr(),
uc_salt.len(),
message.as_ptr(),
message.len(),
uc_out.as_mut_ptr(),
)
};
let mut ac_salt: [u8; 32] = [43; 32];
let mut ac_out: [u8; 32] = [0; 32];
ac_shas(&mut message, &mut ac_salt, &mut ac_out);
assert_eq!(ac_out, uc_out);
}
}

View File

@ -65,9 +65,11 @@ guard_err _slash_guard(void *si_addr) {
void _signal_handler(int sig, siginfo_t *si, void *unused) {
switch (sig) {
case SIGSEGV:
fprintf(stderr, "guard: caught sigsegv\r\n");
err = _slash_guard(si->si_addr);
break;
case SIGINT:
fprintf(stderr, "guard: caught sigint\r\n");
err = guard_erupt;
break;
default:
@ -98,6 +100,7 @@ void guard(void *(*f)(void *), void *arg, void *const *const stack, void *const
goto fail;
}
fprintf(stderr, "guard: installing guard page\r\n");
if (guard_p == NULL && (err = _focus_guard()) != guard_sound) {
goto fail;
}

View File

@ -35,6 +35,7 @@
pkgs.llvmPackages.clang
pkgs.pkg-config
pkgs.urcrypt
pkgs.glibc.static
] ++
(nixpkgs.lib.lists.optional (parsedSystem.kernel.name != "darwin") pkgs.gdb); # nixpkgs won't build gdb for darwin
};