Uh oh!
There was an error while loading. Please reload this page.
') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); })();
There was an error while loading. Please reload this page.
Continued from #397.
This PR implements AES for riscv64 using the scalar and vector crypto extensions.
The scalar implementation is complete, sans hazmat support.
The vector implementation is complete, sans hazmat support. I plan to make some further refinements and optimizations though.
Currently there's no easy way to auto-detect the RISC-V features so instead the implementation selection relies on the appropriate target-features being enabled (plus a
cfgflags calledtarget_feature_zvkned) since that is apparently too new to have it's own Rust target-feature.For the vector implementation, I resorted to using the
global_asm!. There are a few reasons for behind this:First, Rust doesn't even have a way to represent scalable vectors yet so there's no clear way how to even encode the appropriate function signatures for this. It might be possible to do it somehow through an encoding using opaque types and a C-FFI API wrapping the C intrinsics, but that would be difficult just for this relatively limited use case.
There is some progress toward addressing this situation though: rust-lang/rust#118917
Secondly, there seem to be some problems with using certain RISC-V features with inline
asm!. It may be related to this issue, which also affectsglobal_asm!, but in the case ofasm!the errors actually cause compilation to fail (whereas forglobal_asm!they just add noise, but can be silenced with the.architectureattribute). The feature in question iszvkned, and it may be that this causes a problem because Rust doesn't even expose this feature yet (which is why I'm using thecfgsetting).In any case, things work fine with
global_asm!.I don't have any real hardware that implements these extensions, so I don't have any useful information about benchmarks. If anyone has access to hardware that can run this it would be great to get some feedback about that (or any other issues).
One last thing to note, I think it might be worth considering extending the
cipherAPI to account for VLA-style implementations.For example, consider the vector implementation for AES-128:
Here you can see that the
encrypt_vlafunction is the general case, which is N-ary (perblocks). The 1-block and 8-block cases are just special cases of this and entirely redundant.Generally you would want to pass as many blocks as possible to
encrypt_vla, which might be substantially larger than 8, depending on the size of the vector registers for the specific RISC-V platform.What might be an appropriate API then would be to add a method to one of the traits which would query the implementation for a "block parallelism hint", which would indicate how many blocks would be optimal to pass to the codec. This hint method would in turn execute some of the RVV instructions to calculate what is the (current) maximum available length for processing.