fix(useragent): unsafe, but working implementation of ml-dsa

This commit is contained in:
hdbg
2026-04-07 15:41:50 +02:00
parent 6b8da567dd
commit a4070e7df7
104 changed files with 11133 additions and 461 deletions

View File

@@ -0,0 +1,29 @@
use anyhow::anyhow;
use flutter_rust_bridge::frb;
use arbiter_crypto::authn::{self, USERAGENT_CONTEXT};
#[frb(opaque)]
pub struct MldsaKey(authn::SigningKey);
impl MldsaKey {
pub fn from_bytes(bytes: &[u8]) -> anyhow::Result<Self> {
let bytes: [u8; 32] = bytes.try_into().map_err(|_| anyhow!("Invalid key length"))?;
Ok(Self(authn::SigningKey::from_seed(bytes)))
}
pub fn to_bytes(&self) -> Vec<u8> {
self.0.to_seed().to_vec()
}
pub fn sign(&self, message: &[u8]) -> anyhow::Result<Vec<u8>> {
Ok(self.0.sign_message(message, USERAGENT_CONTEXT)?.to_bytes())
}
pub fn generate() -> Self {
Self(authn::SigningKey::generate())
}
pub fn get_public_key(&self) -> Vec<u8> {
self.0.public_key().to_bytes().to_vec()
}
}

View File

@@ -0,0 +1,558 @@
// This file is automatically generated, so please do not edit it.
// @generated by `flutter_rust_bridge`@ 2.12.0.
#![allow(
non_camel_case_types,
unused,
non_snake_case,
clippy::needless_return,
clippy::redundant_closure_call,
clippy::redundant_closure,
clippy::useless_conversion,
clippy::unit_arg,
clippy::unused_unit,
clippy::double_parens,
clippy::let_and_return,
clippy::too_many_arguments,
clippy::match_single_binding,
clippy::clone_on_copy,
clippy::let_unit_value,
clippy::deref_addrof,
clippy::explicit_auto_deref,
clippy::borrow_deref_ref,
clippy::uninlined_format_args,
clippy::needless_borrow
)]
// Section: imports
use crate::api::*;
use flutter_rust_bridge::for_generated::byteorder::{NativeEndian, ReadBytesExt, WriteBytesExt};
use flutter_rust_bridge::for_generated::{transform_result_dco, Lifetimeable, Lockable};
use flutter_rust_bridge::{Handler, IntoIntoDart};
// Section: boilerplate
flutter_rust_bridge::frb_generated_boilerplate!(
default_stream_sink_codec = SseCodec,
default_rust_opaque = RustOpaqueMoi,
default_rust_auto_opaque = RustAutoOpaqueMoi,
);
pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_VERSION: &str = "2.12.0";
pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_CONTENT_HASH: i32 = -437661335;
// Section: executor
flutter_rust_bridge::frb_generated_default_handler!();
// Section: wire_funcs
fn wire__crate__api__MldsaKey_from_bytes_impl(
port_: flutter_rust_bridge::for_generated::MessagePort,
ptr_: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr,
rust_vec_len_: i32,
data_len_: i32,
) {
FLUTTER_RUST_BRIDGE_HANDLER.wrap_normal::<flutter_rust_bridge::for_generated::SseCodec, _, _>(
flutter_rust_bridge::for_generated::TaskInfo {
debug_name: "MldsaKey_from_bytes",
port: Some(port_),
mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal,
},
move || {
let message = unsafe {
flutter_rust_bridge::for_generated::Dart2RustMessageSse::from_wire(
ptr_,
rust_vec_len_,
data_len_,
)
};
let mut deserializer =
flutter_rust_bridge::for_generated::SseDeserializer::new(message);
let api_bytes = <Vec<u8>>::sse_decode(&mut deserializer);
deserializer.end();
move |context| {
transform_result_sse::<_, flutter_rust_bridge::for_generated::anyhow::Error>(
(move || {
let output_ok = crate::api::MldsaKey::from_bytes(&api_bytes)?;
Ok(output_ok)
})(),
)
}
},
)
}
fn wire__crate__api__MldsaKey_generate_impl(
port_: flutter_rust_bridge::for_generated::MessagePort,
ptr_: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr,
rust_vec_len_: i32,
data_len_: i32,
) {
FLUTTER_RUST_BRIDGE_HANDLER.wrap_normal::<flutter_rust_bridge::for_generated::SseCodec, _, _>(
flutter_rust_bridge::for_generated::TaskInfo {
debug_name: "MldsaKey_generate",
port: Some(port_),
mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal,
},
move || {
let message = unsafe {
flutter_rust_bridge::for_generated::Dart2RustMessageSse::from_wire(
ptr_,
rust_vec_len_,
data_len_,
)
};
let mut deserializer =
flutter_rust_bridge::for_generated::SseDeserializer::new(message);
deserializer.end();
move |context| {
transform_result_sse::<_, ()>((move || {
let output_ok = Result::<_, ()>::Ok(crate::api::MldsaKey::generate())?;
Ok(output_ok)
})())
}
},
)
}
fn wire__crate__api__MldsaKey_get_public_key_impl(
port_: flutter_rust_bridge::for_generated::MessagePort,
ptr_: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr,
rust_vec_len_: i32,
data_len_: i32,
) {
FLUTTER_RUST_BRIDGE_HANDLER.wrap_normal::<flutter_rust_bridge::for_generated::SseCodec, _, _>(
flutter_rust_bridge::for_generated::TaskInfo {
debug_name: "MldsaKey_get_public_key",
port: Some(port_),
mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal,
},
move || {
let message = unsafe {
flutter_rust_bridge::for_generated::Dart2RustMessageSse::from_wire(
ptr_,
rust_vec_len_,
data_len_,
)
};
let mut deserializer =
flutter_rust_bridge::for_generated::SseDeserializer::new(message);
let api_that = <RustOpaqueMoi<
flutter_rust_bridge::for_generated::RustAutoOpaqueInner<MldsaKey>,
>>::sse_decode(&mut deserializer);
deserializer.end();
move |context| {
transform_result_sse::<_, ()>((move || {
let mut api_that_guard = None;
let decode_indices_ =
flutter_rust_bridge::for_generated::lockable_compute_decode_order(vec![
flutter_rust_bridge::for_generated::LockableOrderInfo::new(
&api_that, 0, false,
),
]);
for i in decode_indices_ {
match i {
0 => api_that_guard = Some(api_that.lockable_decode_sync_ref()),
_ => unreachable!(),
}
}
let api_that_guard = api_that_guard.unwrap();
let output_ok = Result::<_, ()>::Ok(crate::api::MldsaKey::get_public_key(
&*api_that_guard,
))?;
Ok(output_ok)
})())
}
},
)
}
fn wire__crate__api__MldsaKey_sign_impl(
port_: flutter_rust_bridge::for_generated::MessagePort,
ptr_: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr,
rust_vec_len_: i32,
data_len_: i32,
) {
FLUTTER_RUST_BRIDGE_HANDLER.wrap_normal::<flutter_rust_bridge::for_generated::SseCodec, _, _>(
flutter_rust_bridge::for_generated::TaskInfo {
debug_name: "MldsaKey_sign",
port: Some(port_),
mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal,
},
move || {
let message = unsafe {
flutter_rust_bridge::for_generated::Dart2RustMessageSse::from_wire(
ptr_,
rust_vec_len_,
data_len_,
)
};
let mut deserializer =
flutter_rust_bridge::for_generated::SseDeserializer::new(message);
let api_that = <RustOpaqueMoi<
flutter_rust_bridge::for_generated::RustAutoOpaqueInner<MldsaKey>,
>>::sse_decode(&mut deserializer);
let api_message = <Vec<u8>>::sse_decode(&mut deserializer);
deserializer.end();
move |context| {
transform_result_sse::<_, flutter_rust_bridge::for_generated::anyhow::Error>(
(move || {
let mut api_that_guard = None;
let decode_indices_ =
flutter_rust_bridge::for_generated::lockable_compute_decode_order(
vec![flutter_rust_bridge::for_generated::LockableOrderInfo::new(
&api_that, 0, false,
)],
);
for i in decode_indices_ {
match i {
0 => api_that_guard = Some(api_that.lockable_decode_sync_ref()),
_ => unreachable!(),
}
}
let api_that_guard = api_that_guard.unwrap();
let output_ok = crate::api::MldsaKey::sign(&*api_that_guard, &api_message)?;
Ok(output_ok)
})(),
)
}
},
)
}
fn wire__crate__api__MldsaKey_to_bytes_impl(
port_: flutter_rust_bridge::for_generated::MessagePort,
ptr_: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr,
rust_vec_len_: i32,
data_len_: i32,
) {
FLUTTER_RUST_BRIDGE_HANDLER.wrap_normal::<flutter_rust_bridge::for_generated::SseCodec, _, _>(
flutter_rust_bridge::for_generated::TaskInfo {
debug_name: "MldsaKey_to_bytes",
port: Some(port_),
mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal,
},
move || {
let message = unsafe {
flutter_rust_bridge::for_generated::Dart2RustMessageSse::from_wire(
ptr_,
rust_vec_len_,
data_len_,
)
};
let mut deserializer =
flutter_rust_bridge::for_generated::SseDeserializer::new(message);
let api_that = <RustOpaqueMoi<
flutter_rust_bridge::for_generated::RustAutoOpaqueInner<MldsaKey>,
>>::sse_decode(&mut deserializer);
deserializer.end();
move |context| {
transform_result_sse::<_, ()>((move || {
let mut api_that_guard = None;
let decode_indices_ =
flutter_rust_bridge::for_generated::lockable_compute_decode_order(vec![
flutter_rust_bridge::for_generated::LockableOrderInfo::new(
&api_that, 0, false,
),
]);
for i in decode_indices_ {
match i {
0 => api_that_guard = Some(api_that.lockable_decode_sync_ref()),
_ => unreachable!(),
}
}
let api_that_guard = api_that_guard.unwrap();
let output_ok =
Result::<_, ()>::Ok(crate::api::MldsaKey::to_bytes(&*api_that_guard))?;
Ok(output_ok)
})())
}
},
)
}
// Section: related_funcs
flutter_rust_bridge::frb_generated_moi_arc_impl_value!(
flutter_rust_bridge::for_generated::RustAutoOpaqueInner<MldsaKey>
);
// Section: dart2rust
impl SseDecode for flutter_rust_bridge::for_generated::anyhow::Error {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
let mut inner = <String>::sse_decode(deserializer);
return flutter_rust_bridge::for_generated::anyhow::anyhow!("{}", inner);
}
}
impl SseDecode for MldsaKey {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
let mut inner = <RustOpaqueMoi<
flutter_rust_bridge::for_generated::RustAutoOpaqueInner<MldsaKey>,
>>::sse_decode(deserializer);
return flutter_rust_bridge::for_generated::rust_auto_opaque_decode_owned(inner);
}
}
impl SseDecode
for RustOpaqueMoi<flutter_rust_bridge::for_generated::RustAutoOpaqueInner<MldsaKey>>
{
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
let mut inner = <usize>::sse_decode(deserializer);
return decode_rust_opaque_moi(inner);
}
}
impl SseDecode for String {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
let mut inner = <Vec<u8>>::sse_decode(deserializer);
return String::from_utf8(inner).unwrap();
}
}
impl SseDecode for Vec<u8> {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
let mut len_ = <i32>::sse_decode(deserializer);
let mut ans_ = Vec::with_capacity(len_ as usize);
for idx_ in 0..len_ {
ans_.push(<u8>::sse_decode(deserializer));
}
return ans_;
}
}
impl SseDecode for u8 {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
deserializer.cursor.read_u8().unwrap()
}
}
impl SseDecode for () {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {}
}
impl SseDecode for usize {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
deserializer.cursor.read_u64::<NativeEndian>().unwrap() as _
}
}
impl SseDecode for i32 {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
deserializer.cursor.read_i32::<NativeEndian>().unwrap()
}
}
impl SseDecode for bool {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
deserializer.cursor.read_u8().unwrap() != 0
}
}
fn pde_ffi_dispatcher_primary_impl(
func_id: i32,
port: flutter_rust_bridge::for_generated::MessagePort,
ptr: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr,
rust_vec_len: i32,
data_len: i32,
) {
// Codec=Pde (Serialization + dispatch), see doc to use other codecs
match func_id {
1 => wire__crate__api__MldsaKey_from_bytes_impl(port, ptr, rust_vec_len, data_len),
2 => wire__crate__api__MldsaKey_generate_impl(port, ptr, rust_vec_len, data_len),
3 => wire__crate__api__MldsaKey_get_public_key_impl(port, ptr, rust_vec_len, data_len),
4 => wire__crate__api__MldsaKey_sign_impl(port, ptr, rust_vec_len, data_len),
5 => wire__crate__api__MldsaKey_to_bytes_impl(port, ptr, rust_vec_len, data_len),
_ => unreachable!(),
}
}
fn pde_ffi_dispatcher_sync_impl(
func_id: i32,
ptr: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr,
rust_vec_len: i32,
data_len: i32,
) -> flutter_rust_bridge::for_generated::WireSyncRust2DartSse {
// Codec=Pde (Serialization + dispatch), see doc to use other codecs
match func_id {
_ => unreachable!(),
}
}
// Section: rust2dart
// Codec=Dco (DartCObject based), see doc to use other codecs
impl flutter_rust_bridge::IntoDart for FrbWrapper<MldsaKey> {
fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi {
flutter_rust_bridge::for_generated::rust_auto_opaque_encode::<_, MoiArc<_>>(self.0)
.into_dart()
}
}
impl flutter_rust_bridge::for_generated::IntoDartExceptPrimitive for FrbWrapper<MldsaKey> {}
impl flutter_rust_bridge::IntoIntoDart<FrbWrapper<MldsaKey>> for MldsaKey {
fn into_into_dart(self) -> FrbWrapper<MldsaKey> {
self.into()
}
}
impl SseEncode for flutter_rust_bridge::for_generated::anyhow::Error {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
<String>::sse_encode(format!("{:?}", self), serializer);
}
}
impl SseEncode for MldsaKey {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
<RustOpaqueMoi<flutter_rust_bridge::for_generated::RustAutoOpaqueInner<MldsaKey>>>::sse_encode(flutter_rust_bridge::for_generated::rust_auto_opaque_encode::<_, MoiArc<_>>(self), serializer);
}
}
impl SseEncode
for RustOpaqueMoi<flutter_rust_bridge::for_generated::RustAutoOpaqueInner<MldsaKey>>
{
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
let (ptr, size) = self.sse_encode_raw();
<usize>::sse_encode(ptr, serializer);
<i32>::sse_encode(size, serializer);
}
}
impl SseEncode for String {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
<Vec<u8>>::sse_encode(self.into_bytes(), serializer);
}
}
impl SseEncode for Vec<u8> {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
<i32>::sse_encode(self.len() as _, serializer);
for item in self {
<u8>::sse_encode(item, serializer);
}
}
}
impl SseEncode for u8 {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
serializer.cursor.write_u8(self).unwrap();
}
}
impl SseEncode for () {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {}
}
impl SseEncode for usize {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
serializer
.cursor
.write_u64::<NativeEndian>(self as _)
.unwrap();
}
}
impl SseEncode for i32 {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
serializer.cursor.write_i32::<NativeEndian>(self).unwrap();
}
}
impl SseEncode for bool {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
serializer.cursor.write_u8(self as _).unwrap();
}
}
#[cfg(not(target_family = "wasm"))]
mod io {
// This file is automatically generated, so please do not edit it.
// @generated by `flutter_rust_bridge`@ 2.12.0.
// Section: imports
use super::*;
use crate::api::*;
use flutter_rust_bridge::for_generated::byteorder::{
NativeEndian, ReadBytesExt, WriteBytesExt,
};
use flutter_rust_bridge::for_generated::{transform_result_dco, Lifetimeable, Lockable};
use flutter_rust_bridge::{Handler, IntoIntoDart};
// Section: boilerplate
flutter_rust_bridge::frb_generated_boilerplate_io!();
#[unsafe(no_mangle)]
pub extern "C" fn frbgen_arbiter_rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMldsaKey(
ptr: *const std::ffi::c_void,
) {
MoiArc::<flutter_rust_bridge::for_generated::RustAutoOpaqueInner<MldsaKey>>::increment_strong_count(ptr as _);
}
#[unsafe(no_mangle)]
pub extern "C" fn frbgen_arbiter_rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMldsaKey(
ptr: *const std::ffi::c_void,
) {
MoiArc::<flutter_rust_bridge::for_generated::RustAutoOpaqueInner<MldsaKey>>::decrement_strong_count(ptr as _);
}
}
#[cfg(not(target_family = "wasm"))]
pub use io::*;
/// cbindgen:ignore
#[cfg(target_family = "wasm")]
mod web {
// This file is automatically generated, so please do not edit it.
// @generated by `flutter_rust_bridge`@ 2.12.0.
// Section: imports
use super::*;
use crate::api::*;
use flutter_rust_bridge::for_generated::byteorder::{
NativeEndian, ReadBytesExt, WriteBytesExt,
};
use flutter_rust_bridge::for_generated::wasm_bindgen;
use flutter_rust_bridge::for_generated::wasm_bindgen::prelude::*;
use flutter_rust_bridge::for_generated::{transform_result_dco, Lifetimeable, Lockable};
use flutter_rust_bridge::{Handler, IntoIntoDart};
// Section: boilerplate
flutter_rust_bridge::frb_generated_boilerplate_web!();
#[wasm_bindgen]
pub fn rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMldsaKey(
ptr: *const std::ffi::c_void,
) {
MoiArc::<flutter_rust_bridge::for_generated::RustAutoOpaqueInner<MldsaKey>>::increment_strong_count(ptr as _);
}
#[wasm_bindgen]
pub fn rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMldsaKey(
ptr: *const std::ffi::c_void,
) {
MoiArc::<flutter_rust_bridge::for_generated::RustAutoOpaqueInner<MldsaKey>>::decrement_strong_count(ptr as _);
}
}
#[cfg(target_family = "wasm")]
pub use web::*;

View File

@@ -0,0 +1,2 @@
pub mod api;
mod frb_generated;