fabic has joined #rust-embedded
emerent_ has joined #rust-embedded
emerent has quit [Killed (platinum.libera.chat (Nickname regained by services))]
emerent_ is now known as emerent
<re_irc> <@n​ewam:m​atrix.org> Wow Curve25519 is _fast_.
<re_irc> <@n​ewam:m​atrix.org> NIST P-256 with the ST hardware public key accelerator takes an eye watering 5,249,000 cycles (109 milliseconds at the highest clock speed for the STM32WL) to sign a message.
<re_irc> <@n​ewam:m​atrix.org> Using the `no_std` implementation of Curve25519 signing from `ed25519-dalek` (`{ version = "=1.0.1", default-features = false, features = ["u32_backend", "rand"] }`, all optimizations, but with debug assertions and overflow checks) takes only 866,802 cycles (18 milliseconds at highest clock speed for the STM32WL).
<re_irc> <@n​ewam:m​atrix.org> ...the only downside is the 80KiB of flash that `ed25519-dalek` eats up 😕
<re_irc> <@n​ewam:m​atrix.org> and on the verification side:
<re_irc> <@n​ewam:m​atrix.org> SW w/ ed25519: 2,081,189 cycles, 43ms @ max of 48MHz
<re_irc> <@n​ewam:m​atrix.org> HW PKA w/ P256: 10,498,000 cycles, 219ms @ max of 48MHz
fabic has quit [Ping timeout: 248 seconds]
<re_irc> <@t​hejpster:m​atrix.org> jamesmunns: I mean, I have Eben's phone number...
<re_irc> <@d​isasm-ewg:m​atrix.org> almindor: Added dkhayes117 as an outside collaborator with proper access rights
<re_irc> <@w​cpannell:m​atrix.org> Is the output of cargo run supposed to be different than cargo rustc? When I do "cargo rustc --release -- --emit asm" the .s files show my const fn is done at compile time and replaced with a numeric literal. When I do "cargo run --release" and step through it the const fn is run time. I haven't checked the...
<re_irc> ... binaries made with just "cargo build --release" yet
<re_irc> <@w​cpannell:m​atrix.org> hmm. after clean and release build the objdump of the binary it is slightly different from the --emit asm .s files. It uses different regs, some ops moved around in the GPIO setup code right before the "call" to the const fn, nothing majorly different.
<re_irc> <@w​cpannell:m​atrix.org> except that the "call" in the .s file is just moving a literal and storing it. where the binary has a wall of text doing software division
<re_irc> <@w​cpannell:m​atrix.org> so the const fn did get inlined
<re_irc> <@w​cpannell:m​atrix.org> call in example app is here: https://github.com/wcpannell/kea-hal/blob/feature-spi/examples/spi-talking-to-myself/src/main.rs#L82
<re_irc> <@w​cpannell:m​atrix.org> const fn's in hal crate are here: https://github.com/wcpannell/kea-hal/blob/feature-spi/src/spi.rs#L459
fabic has joined #rust-embedded
<re_irc> <@w​cpannell:m​atrix.org> I guess it is different and it's not an embedded or arm thing. https://siliconsprawl.com/2020/11/09/rust-emit-asm.html
<re_irc> <@a​damgreig:m​atrix.org> I think `const fn` are not _guaranteed_ to be run at compile time, it's just that they may be used in `const` contexts; any runtime function might be optimised to compile-time if the compiler can do it and decides to, regardless of whether it's const
<re_irc> <@a​damgreig:m​atrix.org> maybe it would help if you #[inline] those methods? I suspect when `set_baudrate` is being compiled, it doesn't know it's being called with constant integer arguments, and `set_baudrate` isn't being inlined into the binary because it's another crate and not marked `#[inline]`
<re_irc> <@a​damgreig:m​atrix.org> so while `bus_to_baudrate_divisor` is getting inlined into `set_baudrate` (because they're in the same library), it still needs to emit code for runtime division, because it doesn't know it's only getting called with constant arguments by your binary crate
<re_irc> <@a​damgreig:m​atrix.org> (maybe turning on/up LTO will let it make this link-time optimisation, I'm not sure)
<re_irc> <@y​atekii:m​atrix.org> hmm is it bad to have cargo workspaces across different build targets (arm/x86)?
<re_irc> <@9​names:m​atrix.org> it's certainly not fun, but does that make it bad?
<re_irc> <@y​atekii:m​atrix.org> I get endless dependency cycles across projects
<re_irc> <@y​atekii:m​atrix.org> and rust-analyzer seems to choke hard on it, not sure
<re_irc> <@y​atekii:m​atrix.org> so two arguments against it
<re_irc> <@y​atekii:m​atrix.org> but if I do not use a single cargo workspace, using xtask becomes a nuissance
<re_irc> <@y​atekii:m​atrix.org> error: cyclic package dependency: package `ahash v0.7.4` depends on itself. Cycle:
<re_irc> <@y​atekii:m​atrix.org> package `ahash v0.7.4`
<re_irc> <@y​atekii:m​atrix.org> ... which is depended on by `hashbrown v0.11.2`
<re_irc> <@y​atekii:m​atrix.org> ... which is depended on by `indexmap v1.7.0`
<re_irc> <@j​amesmunns:m​atrix.org> newam: newam: I feel like someone... maybe the folks from SoloKeys, have a different 25519 impl that doesn't require the huge look up table?
<re_irc> <@j​amesmunns:m​atrix.org> Maybe CC Nicolas Stalder | SoloKeys?
<re_irc> <@j​amesmunns:m​atrix.org> https://github.com/ycrypto/salty might be what they use
<re_irc> <@j​amesmunns:m​atrix.org> Likely to be used as part of https://github.com/trussed-dev
<re_irc> <@n​ewam:m​atrix.org> jamesmunns: That is awesome, thank you!
<re_irc> <@j​amesmunns:m​atrix.org> No idea on the completeness of that, but I know Nicolas has been working on it for a while
<re_irc> <@j​amesmunns:m​atrix.org> and can probably give better usage guidance
<re_irc> <@n​ewam:m​atrix.org> > One reason the current ed25519-dalek library in its current state is not usable for microcontrollers is that it includes ~40kB of pre-computed data to speed things up.
<re_irc> <@n​ewam:m​atrix.org> Ah, that explains the ~80KiB extra binary size.
<re_irc> <@j​amesmunns:m​atrix.org> yeah
<re_irc> <@d​irbaio:m​atrix.org> there's this thing too https://github.com/Emill/X25519-Cortex-M4
<re_irc> <@d​irbaio:m​atrix.org> it's suuuuuuper fast
<re_irc> <@d​irbaio:m​atrix.org> only x25519 though, no ed25519 :|
<re_irc> <@n​ewam:m​atrix.org> Speaking of all this encryption anyone know if there is a good resource for learning more on an embedded scale?
<re_irc> <@n​ewam:m​atrix.org> I keep learning piecemeal because most of the resources I find are targeted towards people working on higher level software.
fabic has quit [Ping timeout: 248 seconds]
<re_irc> <@n​ickray:s​olokeys.com> yes, https://github.com/ycrypto/salty/ uses assembly for the field ops, it's pretty speedy. i'd like to eventually upstream as backend for dalek, but there's push back/reluctance.
<re_irc> <@n​ickray:s​olokeys.com> emil's assembly impl (for curve255) is slightly faster than haase's which salty uses. could be swapped out if someone feels the need.
<re_irc> <@n​ickray:s​olokeys.com> for p256 i wrapped emil's *insanely* fast assembly-all-the-way impl in https://github.com/ycrypto/p256-cortex-m4. this one is just nuts.
<re_irc> <@n​ickray:s​olokeys.com> generally the philosophy in ycrypto is to use pure rust for mid (group) and high (signatures etc.) level, but use the best known assembly for low (base field) level. - to complement rustcrypto/dalek and the other conceptual/pure rust work for microcontrollers. and upstream perhaps, if we find ways to do this...
<re_irc> ... neatly.
<re_irc> <@d​irbaio:m​atrix.org> ooh coooool
<re_irc> <@d​irbaio:m​atrix.org> I didn't see it had asm too
<re_irc> <@n​ickray:s​olokeys.com> i feel like "this is the way" for crypto on microcontrollers. looking forward to stable inline assembly to clean it up more.
<re_irc> <@d​irbaio:m​atrix.org> all-asm is too hardcore yeah :\
<re_irc> <@n​ickray:s​olokeys.com> not according to emil 😅
<re_irc> <@d​irbaio:m​atrix.org> I guess you can get slightly faster with all-asm
<re_irc> <@d​irbaio:m​atrix.org> emil's field op functions use a weird abi where one field element is passed in r0-r8
<re_irc> <@d​irbaio:m​atrix.org> I don't think there's a way to call that from rust
<re_irc> <@d​irbaio:m​atrix.org> and that makes it slightly faster because you can remove unused loads/stores
<re_irc> <@n​ickray:s​olokeys.com> it'd be nice if the compiler actively used umaal etc., which is tricky. but a lot of the final optimisations are register level, which i don't think a non-specialized compiler can figure out (research project)
<re_irc> <@n​ewam:m​atrix.org> > i'd like to eventually upstream as backend for dalek, but there's push back/reluctance.
<re_irc> <@n​ewam:m​atrix.org> Unfortunately it seems like ed25519-dalek is unmaintained these days :/
<re_irc> <@n​ickray:s​olokeys.com> i wouldn't say that. it forked and both forks are active.
<re_irc> <@n​ewam:m​atrix.org> Ah
<re_irc> <@n​ewam:m​atrix.org> How fast is that assembly p256 implementation, got any cycle counts?
<re_irc> <@n​ickray:s​olokeys.com> hoping to contract emil for some more curve base fields, and grow ycrypto. if anybody else is interested in this, happy to collab.
<re_irc> <@d​irbaio:m​atrix.org> newam: https://github.com/Emill/P256-Cortex-M4#performance
<re_irc> <@n​ickray:s​olokeys.com> 🖕i.e. nuts
<re_irc> <@n​ewam:m​atrix.org> Ah, it's that one, thanks :D
<re_irc> <@n​ewam:m​atrix.org> wow that's a lot faster than the hardware accelerator provided by ST...
<re_irc> <@d​irbaio:m​atrix.org> yeah
<re_irc> <@n​ickray:s​olokeys.com> yeah beats the lpc55 demo impl on C for the lpc55 accelerator too.
<re_irc> <@d​irbaio:m​atrix.org> it beats the cc310 accelerator in nrf52 chips too
<re_irc> <@d​irbaio:m​atrix.org> it's insane 🤣
<re_irc> <@d​khayes117:m​atrix.org> What is the current state of inline-asm nowadays?
<re_irc> <@a​damgreig:m​atrix.org> what were they doing with the hardware accel... lol
<re_irc> <@a​damgreig:m​atrix.org> dkhayes117: it's really lovely, but I don't think there's any ETA on it being stable, so you have to either use nightly, or do what crates like c-m-rt do and use a nightly compiler to build a static lib that you distribute and link against for stable users
<re_irc> <@a​damgreig:m​atrix.org> that said, there's also been progress on bringing the cortex-m dsp intrinsics into core::arch, which might make it easier to not need asm for some things
<re_irc> <@a​damgreig:m​atrix.org> (currently still nightly-only though)
<re_irc> <@d​khayes117:m​atrix.org> I've used the new `asm!` syntax, I like it much better than `llvm_asm!`
<re_irc> <@n​ickray:s​olokeys.com> corporate C 🤪 in earnest, i think you'd need bigger curves to beat optimal register use and umaal, to take advantage of 64bit mult in an accelerator
<re_irc> <@a​damgreig:m​atrix.org> yea, the new `asm!` is the one that will get stabilised sooner or later, and it's so nicely designed
<re_irc> <@n​ickray:s​olokeys.com> > dkhayes117: it's really lovely, but I don't think there's any ETA on it being stable, so you have to either use nightly, or do what crates like c-m-rt do and use a nightly compiler to build a static lib that you distribute and link against for stable users
<re_irc> <@n​ickray:s​olokeys.com> this is what we do in ycrypto, it's honestly not that bad either.
<re_irc> <@a​damgreig:m​atrix.org> yea. I can't wait for stable inline asm, but in the meantime there's not many disadvantages to this
<re_irc> <@a​damgreig:m​atrix.org> can't be inlined is the main problem we have
<re_irc> <@a​damgreig:m​atrix.org> well-
<re_irc> <@a​damgreig:m​atrix.org> it _can_ be inlined with the linker plugin stuff, even
<re_irc> <@d​irbaio:m​atrix.org> a few months ago I started writing all-asm ed25519 on top of emil's asm
<re_irc> <@d​irbaio:m​atrix.org> gave up halfway 🤣
<re_irc> <@d​irbaio:m​atrix.org> when I saw I needed sha512 :c
<re_irc> <@w​cpannell:m​atrix.org> adamgreig: I'll have to check the dissasm in the morning, away from computer for the day. IIRC the set_baudrate args were literals and everything in the app (except cortex-m inline asm and the software division) got inlined into main. lto = true in release profile, so that should be fat lto. So It's doing...
<re_irc> ... stuff, just not the same as --emit asm
<re_irc> <@d​irbaio:m​atrix.org> W.C. Pannell: if you run rustc directly, you're not including many flags that cargo would include
<re_irc> <@d​irbaio:m​atrix.org> rustc doen't read `cargo.toml` or `.cargo/config.toml`
<re_irc> <@w​cpannell:m​atrix.org> I was under the impression that using "cargo rustc blahblah" instead of calling rustc directly did use all the config.
<re_irc> <@d​irbaio:m​atrix.org> ah okay, no idea about that one, sorry :)
<re_irc> <@d​irbaio:m​atrix.org> I thought you were calling bare rustc
<re_irc> <@w​cpannell:m​atrix.org> I think it does because it cranked the lto when i added it to the profile. Idk. I'll dig in more in the morning.
<re_irc> <@n​ewam:m​atrix.org> Ok so with the rust overhead on `P256-Cortex-M4` (e.g. passing a CryptoRng impl which takes 412 cycles instead of pre-generating)
<re_irc> <@n​ewam:m​atrix.org> signing: 375k -> 440k cycles (HW accel 5,249k)
<re_irc> <@n​ewam:m​atrix.org> verify: 975k -> 1,195k cycles (HW accel 10,498k)
<re_irc> <@n​ewam:m​atrix.org> ...all my wut.
<re_irc> <@n​ewam:m​atrix.org> that's an order of magnitude faster than hardware. just wow.
<re_irc> <@d​irbaio:m​atrix.org> why does verify get rust overhead?
<re_irc> <@n​ewam:m​atrix.org> In theory it shouldn't, it's just a passthrough 🤔
<re_irc> <@n​ewam:m​atrix.org> ```rs
<re_irc> <@n​ewam:m​atrix.org> /// Verify signature on message assumed to be hashed, if needed.
<re_irc> <@n​ewam:m​atrix.org> pub fn verify_prehashed(&self, prehashed_message: &[u8], signature: &Signature) -> bool {
<re_irc> <@t​herealprof:m​atrix.org> Nicolas Stalder | SoloKeys: LLVM can lower such instructions if compiler generates the proper LLVM instructions. It is quite a bit of an uphill battle though, all of the reviewers are mostly interested in getting support for the latest and greatest architectures in and don't care too much about our lowly...
<re_irc> ... micros, despite the higher ups also profiting quite a bit from lowly instruction support. There's quite a bit of low hanging fruit still to be picked...
<re_irc> <@n​ewam:m​atrix.org> dirbaio: I think this might actually be the instruction cache size difference between our targets, the NRF Emil tested on has a 2K icache, my STM32WL has a 1K icache.
<re_irc> <@t​herealprof:m​atrix.org> The fun part with the ARM ISA is that the registers are shared between the different extensions so basically you can use any "special" instruction as is without needing to ensure the data is in the right set of registers which makes actually utilizing the instructions a whole lot easier.
<re_irc> <@n​ewam:m​atrix.org> At the very least my benchmarks for rust overhead are inaccurate since our targets are pretty dissimilar in a few ways that matter for performance.
fabic has joined #rust-embedded
fabic has quit [Ping timeout: 272 seconds]
SanchayanMaity has quit [Ping timeout: 258 seconds]
dreamcat4 has quit [Ping timeout: 256 seconds]
<re_irc> <@n​ewam:m​atrix.org> Nicolas Stalder | SoloKeys: Sent a couple PRs your way, thanks for these crates, they're great!
<re_irc> <@n​ewam:m​atrix.org> Going to sleep a few million cycles faster is going to help my power budget a ton 😀
edm has joined #rust-embedded
SanchayanMaity has joined #rust-embedded
dreamcat4 has joined #rust-embedded
troth has quit [Quit: Leaving.]
<re_irc> <@w​indfisch42:m​atrix.org> Heya! I'm trying to implement the embedded_hal::blocking::spi::Write trait for my struct, but it fails due to "conflicting implementation"; it seems that Write<T> is implemented for each implementor of the Default trait, and rust tells me that "someone else could implement Default on your struct"...
<re_irc> <@w​indfisch42:m​atrix.org> how can I implement that Write trait for my struct without this error?
<re_irc> <@a​damgreig:m​atrix.org> Windfisch: I think https://github.com/rust-embedded/embedded-hal/pull/289#issuecomment-873756479 could fix your specific issue
<re_irc> <@a​damgreig:m​atrix.org> that thread has some discussion, those default impls will be removed eventually
<re_irc> <@w​indfisch42:m​atrix.org> ooof, thanks. so i'd need to add a patch line to my Cargo.toml?
<re_irc> <@a​damgreig:m​atrix.org> (or, they are removed already in master, but I don't think backported)
<re_irc> <@a​damgreig:m​atrix.org> no, you shouldn't need to patch
<re_irc> <@a​damgreig:m​atrix.org> assuming you're currently impl'ing for a generic T, instead impl for a concrete u8 and/or u16
<re_irc> <@w​indfisch42:m​atrix.org> how do I fix this then? embedded_hal wasn't pulled in by myself, but by display-interface-spi and/or stm32f1xx_hal
<re_irc> <@w​indfisch42:m​atrix.org> ah oh.
<re_irc> <@w​indfisch42:m​atrix.org> ah nice, that seems to fix it. thanks!
<re_irc> <@w​indfisch42:m​atrix.org> btw, maybe what I am trying to do already exists: Is there an implementation (adapter) that gives me Write<T> for WriteDma<T>?
<re_irc> <@w​indfisch42:m​atrix.org> I have a library that wants blocking::spi::Write, but I'd like to allocate a DMA buffer and use DMA for the blocking write operation. The operation shall still block, but if it gets interrupted, the DMA should continue to write
<re_irc> <@n​ewam:m​atrix.org> Windfisch: For situations like that I just make a different type that implements `blocking::spi::Write` with DMAs.
<re_irc> <@n​ewam:m​atrix.org> I think that's the intended use-case, but I may be wrong about that.
<re_irc> <@w​indfisch42:m​atrix.org> that's what I am doing right now, i was hoping that someone else already did that work :D
<re_irc> <@n​ewam:m​atrix.org> Ahhh gotcha
cr19011 has joined #rust-embedded
cr1901 has quit [Killed (NickServ (GHOST command used by cr19011!~William@2601:8d:8600:911:456:81f2:40b3:f921))]
cr19011 is now known as cr1901
<re_irc> <@u​007d:m​atrix.org> Hi, all. I am reading the schematics for the SiFive Unmatched (RISC-V) board (https://sifive.cdn.prismic.io/sifive/6a06d6c0-6e66-49b5-8e9e-e68ce76f4192_hifive-unmatched-schematics-v3.pdf). On page 2, the schematics show that `PWM0` is connected to "Header Pins".
<re_irc> <@u​007d:m​atrix.org> For the life of me I can't find these alleged header pins :). I suppose I'm not reading the schematic correctly--can someone help me understand which header pins (and bonus marks for which chip package pins) the `PWMx`s are on?