make crypto depending on ring optional

This commit is contained in:
Skgland
2026-04-25 21:17:48 +02:00
committed by Bennet Bleßmann
parent 61d94dceae
commit 938f588769
2 changed files with 362 additions and 245 deletions

View File

@@ -17,16 +17,25 @@ rust-version = "1.93.1"
crate-type = ["cdylib", "rlib"] crate-type = ["cdylib", "rlib"]
[features] [features]
default = ["ffi", "repl", "hostname", "tls", "http", "crypto-full"] default = ["all-simple-cross", "tls", "http"]
# activates all features that depend on no non pure-rust dependencies
#
# currently does not include
# ffi due to libffi
# tls, http due to openssl
# crypto-inpure due to ring
all-pure = ["repl", "hostname"]
# enables all features that are simple to get working for cross-compliation # enables all features that are simple to get working for cross-compliation
# currently all but tls, http as those depend on openssl # currently all but tls, http as those depend on openssl
all-simple-cross = ["ffi", "repl", "hostname", "crypto-full"] all-simple-cross = ["all-pure", "ffi", "crypto-full"]
ffi = ["dep:libffi"] ffi = ["dep:libffi"]
repl = ["dep:crossterm", "dep:ctrlc", "dep:rustyline"] repl = ["dep:crossterm", "dep:ctrlc", "dep:rustyline"]
hostname = ["dep:hostname"] hostname = ["dep:hostname"]
tls = ["dep:native-tls"] tls = ["dep:native-tls"]
http = ["dep:warp", "dep:reqwest"] http = ["dep:warp", "dep:reqwest"]
crypto-full = [] # crypto function that require non pure-rust dependencies
crypto-inpure = ["dep:ring"]
crypto-full = ["crypto-inpure"]
[lints.rust] [lints.rust]
unexpected_cfgs = { level = "deny", check-cfg = [ unexpected_cfgs = { level = "deny", check-cfg = [
@@ -73,7 +82,9 @@ ordered-float = "5.0.0"
phf = { version = "0.11", features = ["macros"] } phf = { version = "0.11", features = ["macros"] }
puruspe = "0.4.1" puruspe = "0.4.1"
rand = "0.8.5" rand = "0.8.5"
ring = { version = "0.17.8", features = ["wasm32_unknown_unknown_js"] } ring = { version = "0.17.8", features = [
"wasm32_unknown_unknown_js",
], optional = true }
ripemd = "0.1.3" ripemd = "0.1.3"
roxmltree = "0.20.0" roxmltree = "0.20.0"
ryu = "1.0.18" ryu = "1.0.18"

View File

@@ -53,7 +53,6 @@ use std::mem;
#[cfg(feature = "http")] #[cfg(feature = "http")]
use std::net::{SocketAddr, ToSocketAddrs}; use std::net::{SocketAddr, ToSocketAddrs};
use std::net::{TcpListener, TcpStream}; use std::net::{TcpListener, TcpStream};
use std::num::NonZeroU32;
use std::process; use std::process;
use std::process::Child; use std::process::Child;
use std::process::Stdio; use std::process::Stdio;
@@ -74,11 +73,15 @@ use crossterm::event::{read, Event, KeyCode, KeyEvent, KeyEventKind, KeyModifier
use crossterm::terminal::{disable_raw_mode, enable_raw_mode}; use crossterm::terminal::{disable_raw_mode, enable_raw_mode};
use blake2::{Blake2b512, Blake2s256}; use blake2::{Blake2b512, Blake2s256};
use ring::rand::{SecureRandom, SystemRandom};
use ring::{digest, hkdf, hmac, pbkdf2};
#[cfg(feature = "crypto-full")] #[cfg(feature = "crypto-full")]
use ring::aead; use ring::aead;
#[cfg(feature = "crypto-inpure")]
use ring::{
digest, hkdf, hmac, pbkdf2,
rand::{SecureRandom, SystemRandom},
};
use ripemd::{Digest, Ripemd160}; use ripemd::{Digest, Ripemd160};
use sha3::{Sha3_224, Sha3_256, Sha3_384, Sha3_512}; use sha3::{Sha3_224, Sha3_256, Sha3_384, Sha3_512};
@@ -96,8 +99,6 @@ use roxmltree;
use futures::future; use futures::future;
#[cfg(feature = "http")] #[cfg(feature = "http")]
use reqwest::Url; use reqwest::Url;
use tokio::runtime::Handle;
use tokio::task;
#[cfg(feature = "http")] #[cfg(feature = "http")]
use warp::hyper::header::{HeaderName, HeaderValue}; use warp::hyper::header::{HeaderName, HeaderValue};
#[cfg(feature = "http")] #[cfg(feature = "http")]
@@ -4403,6 +4404,8 @@ impl Machine {
#[cfg(feature = "http")] #[cfg(feature = "http")]
#[inline(always)] #[inline(always)]
pub(crate) fn http_open(&mut self) -> CallResult { pub(crate) fn http_open(&mut self) -> CallResult {
use tokio::task;
let address_sink = self.deref_register(1); let address_sink = self.deref_register(1);
let method = read_heap_cell!(self.deref_register(3), let method = read_heap_cell!(self.deref_register(3),
(HeapCellValueTag::Atom, (name, arity)) => { (HeapCellValueTag::Atom, (name, arity)) => {
@@ -4466,7 +4469,7 @@ impl Machine {
// do it! // do it!
task::block_in_place(move || { task::block_in_place(move || {
match Handle::current().block_on(req.send()) { match tokio::runtime::Handle::current().block_on(req.send()) {
Ok(resp) => { Ok(resp) => {
// status code // status code
let status = resp.status().as_u16(); let status = resp.status().as_u16();
@@ -7843,22 +7846,33 @@ impl Machine {
#[inline(always)] #[inline(always)]
pub(crate) fn crypto_random_byte(&mut self) { pub(crate) fn crypto_random_byte(&mut self) {
let arg = self.machine_st.registers[1]; #[cfg(feature = "crypto-inpure")]
let mut bytes: [u8; 1] = [0]; {
let arg = self.machine_st.registers[1];
let mut bytes: [u8; 1] = [0];
match rng().fill(&mut bytes) { match rng().fill(&mut bytes) {
Ok(()) => {} Ok(()) => {}
Err(_) => { Err(_) => {
// the error payload here is of type 'Unspecified', // the error payload here is of type 'Unspecified',
// which contains no information whatsoever. So, for now, // which contains no information whatsoever. So, for now,
// just fail. // just fail.
self.machine_st.fail = true; self.machine_st.fail = true;
return; return;
}
} }
let byte = Fixnum::build_with(bytes[0]);
self.machine_st.unify_fixnum(byte, arg);
} }
let byte = Fixnum::build_with(bytes[0]); #[cfg(not(feature = "crypto-inpure"))]
self.machine_st.unify_fixnum(byte, arg); {
let stub_gen = || functor_stub(atom!("crypto_random_byte"), 1);
let err = self.machine_st.missing_feature_error(atom!("crypto"));
let exception = self.machine_st.error_form(err, stub_gen());
self.machine_st.throw_exception(exception);
}
} }
#[inline(always)] #[inline(always)]
@@ -7990,29 +8004,40 @@ impl Machine {
) )
} }
_ => { _ => {
let ints = digest::digest( #[cfg(feature = "crypto-inpure")]
match algorithm { {
atom!("sha256") => &digest::SHA256, let ints = digest::digest(
atom!("sha384") => &digest::SHA384, match algorithm {
atom!("sha512") => &digest::SHA512, atom!("sha256") => &digest::SHA256,
atom!("sha512_256") => &digest::SHA512_256, atom!("sha384") => &digest::SHA384,
_ => { atom!("sha512") => &digest::SHA512,
unreachable!() atom!("sha512_256") => &digest::SHA512_256,
} _ => {
}, unreachable!()
&bytes, }
); },
&bytes,
);
step_or_resource_error!( step_or_resource_error!(
self.machine_st, self.machine_st,
sized_iter_to_heap_list( sized_iter_to_heap_list(
&mut self.machine_st.heap, &mut self.machine_st.heap,
ints.as_ref().len(), ints.as_ref().len(),
ints.as_ref() ints.as_ref()
.iter() .iter()
.map(|b| fixnum_as_cell!(Fixnum::build_with(*b))) .map(|b| fixnum_as_cell!(Fixnum::build_with(*b)))
)
) )
) }
#[cfg(not(feature = "crypto-inpure"))]
{
let stub_gen = || functor_stub(atom!("crypto_data_hash"), 1);
let err = self.machine_st.missing_feature_error(atom!("crypto"));
let exception = self.machine_st.error_form(err, stub_gen());
self.machine_st.throw_exception(exception);
return;
}
} }
}; };
@@ -8021,168 +8046,201 @@ impl Machine {
#[inline(always)] #[inline(always)]
pub(crate) fn crypto_hmac(&mut self) { pub(crate) fn crypto_hmac(&mut self) {
let encoding = cell_as_atom!(self.deref_register(2));
let data = self.string_encoding_bytes(self.machine_st.registers[1], encoding);
let stub_gen = || functor_stub(atom!("crypto_data_hash"), 3); let stub_gen = || functor_stub(atom!("crypto_data_hash"), 3);
let key = self #[cfg(feature = "crypto-inpure")]
.machine_st {
.integers_to_bytevec(self.machine_st.registers[3], stub_gen); let encoding = cell_as_atom!(self.deref_register(2));
let data = self.string_encoding_bytes(self.machine_st.registers[1], encoding);
let algorithm = cell_as_atom!(self.deref_register(5)); let key = self
let ralg = match algorithm { .machine_st
atom!("sha256") => hmac::HMAC_SHA256, .integers_to_bytevec(self.machine_st.registers[3], stub_gen);
atom!("sha384") => hmac::HMAC_SHA384,
atom!("sha512") => hmac::HMAC_SHA512,
_ => {
unreachable!()
}
};
let rkey = hmac::Key::new(ralg, key.as_ref()); let algorithm = cell_as_atom!(self.deref_register(5));
let tag = hmac::sign(&rkey, &data); let ralg = match algorithm {
atom!("sha256") => hmac::HMAC_SHA256,
atom!("sha384") => hmac::HMAC_SHA384,
atom!("sha512") => hmac::HMAC_SHA512,
_ => {
unreachable!()
}
};
let ints_list = step_or_resource_error!( let rkey = hmac::Key::new(ralg, key.as_ref());
self.machine_st, let tag = hmac::sign(&rkey, &data);
sized_iter_to_heap_list(
&mut self.machine_st.heap,
tag.as_ref().len(),
tag.as_ref()
.iter()
.map(|b| fixnum_as_cell!(Fixnum::build_with(*b)))
)
);
unify!(self.machine_st, self.machine_st.registers[4], ints_list); let ints_list = step_or_resource_error!(
self.machine_st,
sized_iter_to_heap_list(
&mut self.machine_st.heap,
tag.as_ref().len(),
tag.as_ref()
.iter()
.map(|b| fixnum_as_cell!(Fixnum::build_with(*b)))
)
);
unify!(self.machine_st, self.machine_st.registers[4], ints_list);
}
#[cfg(not(feature = "crypto-inpure"))]
{
let err = self.machine_st.missing_feature_error(atom!("crypto"));
let exception = self.machine_st.error_form(err, stub_gen());
self.machine_st.throw_exception(exception);
}
} }
#[inline(always)] #[inline(always)]
pub(crate) fn crypto_data_hkdf(&mut self) { pub(crate) fn crypto_data_hkdf(&mut self) {
let encoding = cell_as_atom!(self.deref_register(2));
let data = self.string_encoding_bytes(self.machine_st.registers[1], encoding);
let stub1_gen = || functor_stub(atom!("crypto_data_hkdf"), 4); let stub1_gen = || functor_stub(atom!("crypto_data_hkdf"), 4);
let salt = self
.machine_st
.integers_to_bytevec(self.machine_st.registers[3], stub1_gen);
let stub2_gen = || functor_stub(atom!("crypto_data_hkdf"), 4); #[cfg(feature = "crypto-inpure")]
let info = self {
.machine_st let encoding = cell_as_atom!(self.deref_register(2));
.integers_to_bytevec(self.machine_st.registers[4], stub2_gen); let data = self.string_encoding_bytes(self.machine_st.registers[1], encoding);
let algorithm = cell_as_atom!(self.deref_register(5)); let salt = self
.machine_st
.integers_to_bytevec(self.machine_st.registers[3], stub1_gen);
let length = self.deref_register(6); let stub2_gen = || functor_stub(atom!("crypto_data_hkdf"), 4);
let info = self
.machine_st
.integers_to_bytevec(self.machine_st.registers[4], stub2_gen);
let length = match Number::try_from((length, &self.machine_st.arena.f64_tbl)) { let algorithm = cell_as_atom!(self.deref_register(5));
Ok(Number::Fixnum(n)) => usize::try_from(n.get_num()).unwrap(),
Ok(Number::Integer(n)) => match (&*n).try_into() as Result<usize, _> { let length = self.deref_register(6);
Ok(u) => u,
let length = match Number::try_from((length, &self.machine_st.arena.f64_tbl)) {
Ok(Number::Fixnum(n)) => usize::try_from(n.get_num()).unwrap(),
Ok(Number::Integer(n)) => match (&*n).try_into() as Result<usize, _> {
Ok(u) => u,
_ => {
self.machine_st.fail = true;
return;
}
},
_ => { _ => {
self.machine_st.fail = true; unreachable!()
return;
}
},
_ => {
unreachable!()
}
};
let ints_list = {
let digest_alg = match algorithm {
atom!("sha256") => hkdf::HKDF_SHA256,
atom!("sha384") => hkdf::HKDF_SHA384,
atom!("sha512") => hkdf::HKDF_SHA512,
_ => {
self.machine_st.fail = true;
return;
} }
}; };
let salt = hkdf::Salt::new(digest_alg, &salt); let ints_list = {
let mut bytes: Vec<u8> = vec![0; length]; let digest_alg = match algorithm {
atom!("sha256") => hkdf::HKDF_SHA256,
atom!("sha384") => hkdf::HKDF_SHA384,
atom!("sha512") => hkdf::HKDF_SHA512,
_ => {
self.machine_st.fail = true;
return;
}
};
match salt.extract(&data).expand(&[&info[..]], MyKey(length)) { let salt = hkdf::Salt::new(digest_alg, &salt);
Ok(r) => { let mut bytes: Vec<u8> = vec![0; length];
r.fill(&mut bytes).unwrap();
}
_ => {
self.machine_st.fail = true;
return;
}
}
step_or_resource_error!( match salt.extract(&data).expand(&[&info[..]], MyKey(length)) {
self.machine_st, Ok(r) => {
sized_iter_to_heap_list( r.fill(&mut bytes).unwrap();
&mut self.machine_st.heap, }
bytes.len(),
bytes
.iter()
.map(|b| fixnum_as_cell!(Fixnum::build_with(*b)))
)
)
};
unify!(self.machine_st, self.machine_st.registers[7], ints_list);
}
#[inline(always)]
pub(crate) fn crypto_password_hash(&mut self) {
let stub1_gen = || functor_stub(atom!("crypto_password_hash"), 3);
let data = self
.machine_st
.integers_to_bytevec(self.machine_st.registers[1], stub1_gen);
let stub2_gen = || functor_stub(atom!("crypto_password_hash"), 3);
let salt = self
.machine_st
.integers_to_bytevec(self.machine_st.registers[2], stub2_gen);
let iterations = self.deref_register(3);
let iterations = match Number::try_from((iterations, &self.machine_st.arena.f64_tbl)) {
Ok(Number::Fixnum(n)) => u64::try_from(n.get_num()).unwrap(),
Ok(Number::Integer(n)) => {
let n: Result<u64, _> = (&*n).try_into();
match n {
Ok(i) => i,
_ => { _ => {
self.machine_st.fail = true; self.machine_st.fail = true;
return; return;
} }
} }
}
_ => {
unreachable!()
}
};
let ints_list = { step_or_resource_error!(
let mut bytes = [0u8; digest::SHA512_OUTPUT_LEN]; self.machine_st,
sized_iter_to_heap_list(
pbkdf2::derive( &mut self.machine_st.heap,
pbkdf2::PBKDF2_HMAC_SHA512, bytes.len(),
NonZeroU32::new(iterations as u32).unwrap(), bytes
&salt, .iter()
&data, .map(|b| fixnum_as_cell!(Fixnum::build_with(*b)))
&mut bytes, )
);
step_or_resource_error!(
self.machine_st,
sized_iter_to_heap_list(
&mut self.machine_st.heap,
bytes.len(),
bytes
.iter()
.map(|b| fixnum_as_cell!(Fixnum::build_with(*b)))
) )
) };
};
unify!(self.machine_st, self.machine_st.registers[4], ints_list); unify!(self.machine_st, self.machine_st.registers[7], ints_list);
}
#[cfg(not(feature = "crypto-inpure"))]
{
let err = self.machine_st.missing_feature_error(atom!("crypto"));
let exception = self.machine_st.error_form(err, stub1_gen());
self.machine_st.throw_exception(exception);
}
}
#[inline(always)]
pub(crate) fn crypto_password_hash(&mut self) {
let stub1_gen = || functor_stub(atom!("crypto_password_hash"), 3);
#[cfg(feature = "crypto-inpure")]
{
use std::num::NonZeroU32;
let data = self
.machine_st
.integers_to_bytevec(self.machine_st.registers[1], stub1_gen);
let stub2_gen = || functor_stub(atom!("crypto_password_hash"), 3);
let salt = self
.machine_st
.integers_to_bytevec(self.machine_st.registers[2], stub2_gen);
let iterations = self.deref_register(3);
let iterations = match Number::try_from((iterations, &self.machine_st.arena.f64_tbl)) {
Ok(Number::Fixnum(n)) => u64::try_from(n.get_num()).unwrap(),
Ok(Number::Integer(n)) => {
let n: Result<u64, _> = (&*n).try_into();
match n {
Ok(i) => i,
_ => {
self.machine_st.fail = true;
return;
}
}
}
_ => {
unreachable!()
}
};
let ints_list = {
let mut bytes = [0u8; digest::SHA512_OUTPUT_LEN];
pbkdf2::derive(
pbkdf2::PBKDF2_HMAC_SHA512,
NonZeroU32::new(iterations as u32).unwrap(),
&salt,
&data,
&mut bytes,
);
step_or_resource_error!(
self.machine_st,
sized_iter_to_heap_list(
&mut self.machine_st.heap,
bytes.len(),
bytes
.iter()
.map(|b| fixnum_as_cell!(Fixnum::build_with(*b)))
)
)
};
unify!(self.machine_st, self.machine_st.registers[4], ints_list);
}
#[cfg(not(feature = "crypto-inpure"))]
{
let err = self.machine_st.missing_feature_error(atom!("crypto"));
let exception = self.machine_st.error_form(err, stub1_gen());
self.machine_st.throw_exception(exception);
}
} }
#[cfg(feature = "crypto-full")] #[cfg(feature = "crypto-full")]
@@ -8304,109 +8362,153 @@ impl Machine {
#[inline(always)] #[inline(always)]
pub(crate) fn crypto_curve_scalar_mult(&mut self) { pub(crate) fn crypto_curve_scalar_mult(&mut self) {
let stub_gen = || functor_stub(atom!("crypto_curve_scalar_mult"), 4); let stub_gen = || functor_stub(atom!("crypto_curve_scalar_mult"), 4);
let scalar_bytes = self
.machine_st
.integers_to_bytevec(self.machine_st.registers[2], stub_gen);
let point_bytes = self
.machine_st
.integers_to_bytevec(self.machine_st.registers[3], stub_gen);
let mut point = secp256k1::Point::decode(&point_bytes).unwrap(); {
let scalar = secp256k1::Scalar::decode_reduce(&scalar_bytes); let scalar_bytes = self
point *= scalar; .machine_st
.integers_to_bytevec(self.machine_st.registers[2], stub_gen);
let point_bytes = self
.machine_st
.integers_to_bytevec(self.machine_st.registers[3], stub_gen);
let uncompressed = step_or_resource_error!( let mut point = secp256k1::Point::decode(&point_bytes).unwrap();
self.machine_st, let scalar = secp256k1::Scalar::decode_reduce(&scalar_bytes);
self.u8s_to_string(&point.encode_uncompressed()) point *= scalar;
);
unify!(self.machine_st, self.machine_st.registers[4], uncompressed); let uncompressed = step_or_resource_error!(
self.machine_st,
self.u8s_to_string(&point.encode_uncompressed())
);
unify!(self.machine_st, self.machine_st.registers[4], uncompressed);
}
{
let err = self.machine_st.missing_feature_error(atom!("crypto"));
let exception = self.machine_st.error_form(err, stub_gen());
self.machine_st.throw_exception(exception);
}
} }
#[inline(always)] #[inline(always)]
pub(crate) fn ed25519_seed_to_public_key(&mut self) { pub(crate) fn ed25519_seed_to_public_key(&mut self) {
let stub_gen = || functor_stub(atom!("ed25519_seed_keypair"), 2); let stub_gen = || functor_stub(atom!("ed25519_seed_keypair"), 2);
let seed_bytes = self
.machine_st
.integers_to_bytevec(self.machine_st.registers[1], stub_gen);
let skey = ed25519::PrivateKey::from_seed(&seed_bytes); {
let seed_bytes = self
.machine_st
.integers_to_bytevec(self.machine_st.registers[1], stub_gen);
let complete_string = step_or_resource_error!( let skey = ed25519::PrivateKey::from_seed(&seed_bytes);
self.machine_st,
self.u8s_to_string(skey.public_key.encoded.as_ref())
);
unify!( let complete_string = step_or_resource_error!(
self.machine_st, self.machine_st,
self.machine_st.registers[2], self.u8s_to_string(skey.public_key.encoded.as_ref())
complete_string );
);
unify!(
self.machine_st,
self.machine_st.registers[2],
complete_string
);
}
{
let err = self.machine_st.missing_feature_error(atom!("crypto"));
let exception = self.machine_st.error_form(err, stub_gen());
self.machine_st.throw_exception(exception);
}
} }
#[inline(always)] #[inline(always)]
pub(crate) fn ed25519_sign_raw(&mut self) { pub(crate) fn ed25519_sign_raw(&mut self) {
let stub_gen = || functor_stub(atom!("ed25519_sign"), 4); let stub_gen = || functor_stub(atom!("ed25519_sign"), 4);
let seed_bytes = self
.machine_st
.integers_to_bytevec(self.machine_st.registers[1], stub_gen);
let skey = ed25519::PrivateKey::from_seed(&seed_bytes); {
let seed_bytes = self
.machine_st
.integers_to_bytevec(self.machine_st.registers[1], stub_gen);
let encoding = cell_as_atom!(self.deref_register(3)); let skey = ed25519::PrivateKey::from_seed(&seed_bytes);
let data = self.string_encoding_bytes(self.machine_st.registers[2], encoding);
let sig = skey.sign_raw(&data); let encoding = cell_as_atom!(self.deref_register(3));
let sig_list = step_or_resource_error!( let data = self.string_encoding_bytes(self.machine_st.registers[2], encoding);
self.machine_st,
sized_iter_to_heap_list(
&mut self.machine_st.heap,
sig.as_ref().len(),
sig.as_ref()
.iter()
.map(|b| fixnum_as_cell!(Fixnum::build_with(*b)))
)
);
unify!(self.machine_st, self.machine_st.registers[4], sig_list); let sig = skey.sign_raw(&data);
let sig_list = step_or_resource_error!(
self.machine_st,
sized_iter_to_heap_list(
&mut self.machine_st.heap,
sig.as_ref().len(),
sig.as_ref()
.iter()
.map(|b| fixnum_as_cell!(Fixnum::build_with(*b)))
)
);
unify!(self.machine_st, self.machine_st.registers[4], sig_list);
}
{
let err = self.machine_st.missing_feature_error(atom!("crypto"));
let exception = self.machine_st.error_form(err, stub_gen());
self.machine_st.throw_exception(exception);
}
} }
#[inline(always)] #[inline(always)]
pub(crate) fn ed25519_verify_raw(&mut self) { pub(crate) fn ed25519_verify_raw(&mut self) {
let key_bytes = self.string_encoding_bytes(self.machine_st.registers[1], atom!("octet"));
let pkey = ed25519::PublicKey::decode(&key_bytes).unwrap();
let encoding = cell_as_atom!(self.deref_register(3));
let data = self.string_encoding_bytes(self.machine_st.registers[2], encoding);
let stub_gen = || functor_stub(atom!("ed25519_verify"), 4); let stub_gen = || functor_stub(atom!("ed25519_verify"), 4);
let signature = self {
.machine_st let key_bytes =
.integers_to_bytevec(self.machine_st.registers[4], stub_gen); self.string_encoding_bytes(self.machine_st.registers[1], atom!("octet"));
let pkey = ed25519::PublicKey::decode(&key_bytes).unwrap();
self.machine_st.fail = !pkey.verify_raw(&signature, &data); let encoding = cell_as_atom!(self.deref_register(3));
let data = self.string_encoding_bytes(self.machine_st.registers[2], encoding);
let signature = self
.machine_st
.integers_to_bytevec(self.machine_st.registers[4], stub_gen);
self.machine_st.fail = !pkey.verify_raw(&signature, &data);
}
{
let err = self.machine_st.missing_feature_error(atom!("crypto"));
let exception = self.machine_st.error_form(err, stub_gen());
self.machine_st.throw_exception(exception);
}
} }
#[inline(always)] #[inline(always)]
pub(crate) fn curve25519_scalar_mult(&mut self) { pub(crate) fn curve25519_scalar_mult(&mut self) {
let stub1_gen = || functor_stub(atom!("curve25519_scalar_mult"), 3); let stub_gen = || functor_stub(atom!("curve25519_scalar_mult"), 3);
let scalar_bytes = self
.machine_st
.integers_to_bytevec(self.machine_st.registers[1], stub1_gen);
let stub2_gen = || functor_stub(atom!("curve25519_scalar_mult"), 3);
let point_bytes = self
.machine_st
.integers_to_bytevec(self.machine_st.registers[2], stub2_gen);
let result = x25519::x25519( {
&<[u8; 32]>::try_from(&point_bytes[..]).unwrap(), let scalar_bytes = self
&<[u8; 32]>::try_from(&scalar_bytes[..]).unwrap(), .machine_st
); .integers_to_bytevec(self.machine_st.registers[1], stub_gen);
let point_bytes = self
.machine_st
.integers_to_bytevec(self.machine_st.registers[2], stub_gen);
let string = step_or_resource_error!(self.machine_st, self.u8s_to_string(&result[..])); let result = x25519::x25519(
&<[u8; 32]>::try_from(&point_bytes[..]).unwrap(),
&<[u8; 32]>::try_from(&scalar_bytes[..]).unwrap(),
);
unify!(self.machine_st, self.machine_st.registers[3], string); let string = step_or_resource_error!(self.machine_st, self.u8s_to_string(&result[..]));
unify!(self.machine_st, self.machine_st.registers[3], string);
}
{
let err = self.machine_st.missing_feature_error(atom!("crypto"));
let exception = self.machine_st.error_form(err, stub_gen());
self.machine_st.throw_exception(exception);
}
} }
#[inline(always)] #[inline(always)]
@@ -9509,7 +9611,9 @@ impl Machine {
} }
} }
#[cfg(feature = "crypto-inpure")]
fn rng() -> &'static dyn SecureRandom { fn rng() -> &'static dyn SecureRandom {
use lazy_static::lazy_static;
use std::ops::Deref; use std::ops::Deref;
static RANDOM: LazyLock<SystemRandom> = LazyLock::new(SystemRandom::new); static RANDOM: LazyLock<SystemRandom> = LazyLock::new(SystemRandom::new);
@@ -9517,8 +9621,10 @@ fn rng() -> &'static dyn SecureRandom {
RANDOM.deref() RANDOM.deref()
} }
#[cfg(feature = "crypto-inpure")]
struct MyKey<T: core::fmt::Debug + PartialEq>(T); struct MyKey<T: core::fmt::Debug + PartialEq>(T);
#[cfg(feature = "crypto-inpure")]
impl hkdf::KeyType for MyKey<usize> { impl hkdf::KeyType for MyKey<usize> {
fn len(&self) -> usize { fn len(&self) -> usize {
self.0 self.0