Closed ghost closed 1 year ago
It's been on the watch list since it was announced. Since we don't implement cryptographic algorithms within .NET we're waiting on support from the underlying platforms (Windows CNG, Apple Security.framework, and OpenSSL).
As far as speed, I'm given to understand that SHA-3 can never be as fast as SHA-2, due to an inability to hardware optimize it.
Hello @bartonjs:
Thanks for your quick reply, and I get the complete code from here: http://keccak.noekeon.org/KeccakReferenceAndOptimized-3.2.zip.
For more about speed and other things, please read here:http://www.drdobbs.com/security/keccak-the-new-sha-3-encryption-standard/240154037?pgno=1
Yeah, Keccak is (per your linked article) 12.5 cycles/byte. SHA-2-512 with 64-bit instructions on an Intel processor is 8.5 cycles/byte.
That said, we're just at the mercy of 1) Our underlying providers supporting it. 2) Figuring out what to name the classes. Since SHA-3 also supports a 256, 384, and 512-bit mode, we can't go with "SHA256", etc. And "SHA3256" is a bit weird.... "SHA3_256" violates our naming rules, "SHA3-256" is an invalid identifier.
Well……I think you can rename it as "Keccak256,384 or 512", because Keccak is just the algorithm of SHA3 as the standard one.
A persudo code may look like this following:
var keccak = Keccak256.Create().……;
Also something like for these providers:
Keccak256CrytoServiceProvider Keccak384CrytoServiceProvider Keccak512CrytoServiceProvider
Sorry to jump in the thread, but I would suggest to consider the SHAKE extendable-output functions (XOF) from FIPS 202, or the cSHAKE from SP 800-185. They are more flexible than the plain SHA-3 hash functions and have about the same speed as SHA-2.
For higher speed, there is ParallelHash [SP 800-185] or KangarooTwelve. https://twitter.com/KeccakTeam/status/834789451708628995
Kind regards, Gilles (a Keccak co-designer)
SHA3_256
seems a reasonable enough reason to bend the rules.
Based on @gvanas 's points, I'd be interested to see an API design that keeps those other functions in mind. Maybe that would even affect the naming question.
@JonHanna:Agree. The name is something like the inner class that isn't publicly published to the public to be used, it's really a bit strange for us. Maybe this can be used as a wrapper or something else like this dynamically generated. And for us, the published one can be something like what I've mentioned above in my post.
The naming SHA3
violates the Microsoft naming guidelines which dictate that three-letter algorithms should not be uppercase.
https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines/capitalization-conventions
The proper name according to the capitalization convention would be Sha3
.
My port of Keccak (including both original and FIPS 202 SHA3 padding) integrates with HashAlgorithm as the others in that namespace. I would be happy to contribute it.
@jdluzen Nice! Ideally, your code should also support the SHAKE and cSHAKE functions. Not much extra work, the underlying function is the same.
@jdluzen, we appreciate the offer, but we have a strict policy of only using cryptographic algorithms provided by underlying platforms (CNG on Windows, OpenSSL on Linux, Apple Crypto on Mac). That ensures we don't have to worry about provable correctness or avoiding side channels. Right now, I think OpenSSL has SHA3, but not the other two platforms.
Well, we could implement the SHA3 API and just throw a "PlatformNotSupportedException" exception, when running on Mac or Windows.
Well, we could implement the SHA3 API and just throw a "PlatformNotSupportedException" exception, when running on Mac or Windows.
@Spacefish we generally try to avoid this, as it makes it harder to write cross platform libraries if an API that seems relevant to all platforms only works on some.
As far as I can see, there are several free implementations (at least BouncyCastle and the one by @jdluzen mentioned above), so users have alternatives as long as it's not supported in the Framework.
@bartonjs Is SHA3 realistically something that we're going to be able to support in the near-to-intermediate future? Should we resolve this issue for now and reopen it once there's a critical mass of support?
(Just a heads up; I don't feel as strongly as the wording I've written here implies, this one's a little cynical.)
You might also want to consider the impact on driving adoption in the direction opposite vendor support to encourage vendor support by creating adopters by creating the API.
When SHA3 is suggested and no implementation is present the framework, at present (emphasis on it's 2020) many architects opt for SHA2 and concrete their architectures around it. The lifespan of SHA2 is shortening, and as SHA3 was standardized in late 2015, given that now we're looking for post-quantum solutions like SPHINCS+ and others - the NIST began officially requesting post-quantum solutions in 2017, and now we're on round 2 of PQC standardization - the ball appears dropped.
Those that do opt to use SHA3 end up using OpenSSL/BouncyCastle/etc. or rolling their own, which is perfectly fine, and 'demand' is met and none is perceived by the OS vendors or framework.
OS vendor implementation appears to be driven by demand, of which dependent frameworks are the prime mover. So then .NET and Windows CNG are both waiting on each other. (Or do you think there are relatively many that use Windows CNG directly instead of as a supplment or fallback?)
Microsoft has their own PQC initiative, sans hashing algo at present. Wait much longer, the question won't be "Where's SHA3?" it'll be "Where's PQSHA1?"
Microsoft added XTS mode for AES in Windows 10, though I honestly have no idea if you can use it via System.Security.Cryptography. :shrug:
I think the general consensus of those still using SHA2 is vaguely "the world didn’t move to SHA3 because almost none of the world’s software or hardware supported it" ... which isn't true in the technical sense of software and hardware, only true in the business sense of software and hardware. The .NET framework, Java, and other language-level frameworks are what the business sense is going to refer to. Many of the crypto-kids went to Rust, Go, JS, back to C/C++ (but not to Windows CNG, obviously) and even OCaml - but you don't want to count that as demand though you probably should.
Since you're both (OS vendor and framework) waiting on demand that isn't measured by uses of the algo. in general or whether the algo. should be used, or as some sort of leading example w.r.t ASP.NET Core, you may as well do the industry a favor just declare the whole namespace legacy support and encourage the use of some 3rd party solutions for legitimate up-to-date solutions or create a 1st party .NET crypto lib solution, but you probably can't for some reason that involves recursion.
We'll call it the SHA3 pickle.
edit: So no Keccak256Managed/SHA3b256Managed then?
.NET 5.0 is here!
SHA3 has been added?
Linked to:
If anyone is interested, I have implemented SHA3 + SHAKE variants here...
https://github.com/MrMatthewLayton/CORE/tree/master/Core/Security/Cryptography
@Xyncgas srsly, stop spamming, it is helping no-one.. SHA3 will come to .NET sooner or later.
@Xyncgas Disparaging remarks about other contributors are not welcome. Please review our code of conduct (https://dotnetfoundation.org/about/code-of-conduct) for more information.
@Xyncgas is a 3rd party implementation such as the ones linked above sufficient for you? If not, why not? (I recognize the leadership argument above made by another contributor, but that's philosphical: not blocking.)
if that's the only problem stopping you from putting it in .NET
The biggest problem stopping us from putting it in .NET is that it's not supported on macOS or Windows, and by policy .NET doesn't have implementations of cryptographic algorithms that are subject to CAVP testing / FIPS certification.
Maybe our Linux numbers are high enough that we can justify adding it with only one supported platform, but the notion that we'd do it without universal (or, at least, those 3) support is itself a fairly recent change.
We would have SHA3 hash function with witch algorithms? ~> Shake, keccak, Blake?
The biggest problem stopping us from putting it in .NET is that it's not supported on macOS or Windows, and by policy .NET doesn't have implementations of cryptographic algorithms that are subject to CAVP testing / FIPS certification.
Maybe our Linux numbers are high enough that we can justify adding it with only one supported platform, but the notion that we'd do it without universal (or, at least, those 3) support is itself a fairly recent change.
Maybe it could be in form of a platform specific API, but maintained by the core team? In the spirit of the Support for Windows Forms/WPF which only comes with the -win TFM, or the already existing platform extensions packages?
This way, it could still be "promoted" to main .NET later, when more platforms support it.
There are no plans at the current time for .NET to include a SHA-3 implementation inbox in .NET 6. As Dan mentioned previously, the best bet right now is to pull in your own trusted third-party implementation.
If SHA-3 support is added in a future release, this issue will definitely be updated to reflect that.
Continuing to spam this issue / antagonize the product team will not make SHA-3 support come any faster.
would you prefer using someone's library that doesn't have a name on the battle field in your production code?
As you gain experience in the software development field, you get a feel for what works and what doesn't. Usually if something is implemented well, has good documentation and covered in unit tests, it's relatively speaking, trustworthy. Whether the software is written by Joe Bloggs, me, or the team at Microsoft, it's still ultimately written by fallible human beings.
Especially we are talking about algorithm and SHA3 in specific has several implementations I think
Correct. Last time I was researching SHA-3, the competition version was known as Keccak, and the standardized version was known (or standardized) as FIPS-202. There may be some other implementations that I don't know about.
so I want my stuff to standardize on .NET's version, and I am literally waiting for you to do it.
Well then be prepared to wait. The only other option you have is to use a 3rd party implementation. Complaining isn't helping.
Because honestly the reason I am still using whatever instead of someone's SHA-3 library is that, I don't want my SHA-3 hash to be a different result than .NET
Why? If you have a dependency on a 3rd party implementation, then just leave it that way! I would hedge my bets that .NET will implement the FIPS-202 version anyway, so if you can find a 3rd party implementation of that (which I've written by the way), then you can use that.
it doesn't make sense in business and I am depending on .NET I would RATHER do this than having dependency on someone's library so it's gonna get discontinued in 2 years n I am screwed.
Well if the library is hosted on nuget then you're not screwed because you can't delete nuget packages (only hide them), and if the source code exists as open source on GitHub (and I can assure you it does), then fork or clone the repository and maintain it yourself.
FYI, I had exactly the same problem as you, probably around the release of .NET Core 2.0 I was wondering whether SHA-3 would make it to .NET...sadly no (not yet anyway), so I implemented it myself. First step was research into Keccak vs FIPS-202 - I opted for FIPS-202. Second step was to find unit tested implementations in other languages; Go, C, C++, Java, Python, etc. Eventually I found one written in Managed C++, so it was really easy to port to C#.
The final implementation is here. If you really want SHA-3 (FIPS-202) in .NET, feel free to copy as required. https://github.com/MrMatthewLayton/CORE/tree/master/Core/Security/Cryptography
Just as an additional hint: The mature bouncy castle library, implemented by a charity, also has an implementation: https://www.bouncycastle.org/csharp/index.html
I wrote the rant above specifically about this scenario. Everyone here has likely run into it, the SHA3 pickle.
I proposed deprecating System.Security and officially recommending a 3rd party library (I endorse Bouncy Castle and OpenSSL wrappers) so that people can move on with their projects and lives. "Business" isn't always (sanely) supportive of extra-institutional or 3rd party (NIH) implementations of standards given some core framework, especially when it appears standards at least partially exist; IMO that's why implementations today still get concreted around SHA2 instead of SHA3.
In summary, just use Bouncy Castle and pretend there are no hashes built into the .NET framework.
This was absolutely fantastic! I honestly can't remember the last time I enjoyed reading something so much. Rest assured, the next time I go for a job interview and they ask me about myself, I'm going to describe myself as a "fishy, chinese communist!" :rofl::rofl::rofl:
I think u are the guy that created the repository for SHA-3 (the one that shows up on google when I searched for it)
Who knows? I just googled "SHA-3 .NET C#" but I didn't find my implementation anywhere on the first two pages at least, but I did find this as the top result:
https://www.nuget.org/packages/SHA3.Net/
https://github.com/griffo-io/sha3.net
For starters...
Now, here's why I decided to implement it myself rather than using something that already existed...
Essentially what I wanted (which isn't a million miles from what you're asking for) was a FIPS 202 implementation of SHA-3 with no underlying dependencies, except for .NET itself (respectfully System.Security.Cryptography.HashAlgorithm
). In actual fact, I only wanted the SHAKE-256 variant of SHA-3 for a quantum cryptography research project, but for completeness I decided to build the whole suite of FIPS 202 SHA-3 implementation variants anyway.
I forgot to mention and I will say it here, the repository that you own, seemingly stopped maintaining 2 years ago, that's a big red flag and so I stopped there the first time I saw it, and I think people should be alerted of this, because it's what looks like a personal project that's decorated as some kinds of influencing program with seemingly legit documentations, so you mean to say that you just so conveniently to have this repository sitting over here for two years, and now all the sudden you just showed up to everyone and advertising it, it's almost like you knew the virus was coming and created this repository according to your lords' plan.
Well, here I will grant you your dues; yes, the repository has not been maintained for a long time and is actually in dire need of retiring or updating. Hmmm, maybe I should add that to my ever-growing todo list?
The reason for this was that I moved professionally from being a C# developer to a Kotlin developer, specifically working in Blockchain and DLT (an area of computer science which is notably steeped in cryptography).
Acknowledgements and excuses aside, FIPS 202 is FIPS 202, regardless of whether it was implemented 2 years ago or an hour ago. Even if I were to actively maintain this repository, the only things I could improve are performance, and importantly adding useful unit tests to prove that the algorithm continues to work as expected. I cannot change the algorithm because then it's not FIPS 202 anymore. So yes, it's a piece of legacy code, but it's a piece of legacy code that works according to the FIPS 202 specification.
Somehow I don't think that the Lord has any plans for SHA-3.
Why encourage people to use your own library, when we can use the official product
You CAN'T use the official product (yet). What other choices do people have? As I stated before, complaining isn't helping! Throwing your toys out of the pram just because you want something isn't going to make Microsoft deliver this any faster! So, if you really want/need SHA-3 in .NET, use a 3rd party implementation whether it's mine or someone elses!
In general it is undesirable to drive people away from products made from for example Microsoft and have a dependency on some no body's code, it's creditable, reputable, and if anything goes wrong microsoft is going to fix it (in general, microsoft is like a mom to me, that take cares of my everything, and disciplines me, through windows updates to remind me who's the alpha here), when clearly you are just one man on the internet it doesn't make sense usually for people to use you library when you may be gone in two years and people's issues aren't getting replied in your repository...
"In general" you don't seem to have grapsed the point of "open-source" (something that Microsoft has enbraced in recent years). Much less do you understand the potential of individuals in this field...
All of these nobodys, became somebody!
Notably and with respect to this debate, JSON.NET and Automapper are free, open-source products that have MASSIVE adoption in the .NET community (JSON.NET ranks as the most downloaded NuGet package). The community is welcome to contribute to them, but hey, they're not part of .NET and are maintained by "some nobody" rather than by Microsoft, so...not trustworthy, right?
For full transparency to the above, James Newton-King was invited to, and now works for Microsoft, due to his personal successes with JSON.NET.
...and now we have to hire new people to study the codes u've written or actually it's more likely that people wouldn't be bothered with this authoritarian cliché that this world requires you to learn something...
...I don't think you should be responsible for the mistakes at work when you are working under a billion dollar company.
I'm sorry to be blunt but if there was ever an argument for laziness, ignorance and lack of responsibility, this is it!
...it's the policy and namely the "naming - policy" whatever that was...
The existing SHA implementations in .NET are called SHA1, SHA256, SHA384 and SHA512. Aside from SHA1 being a special case, the 1 indicating the first version of SHA, the remaining 256, 384 and 512 indicate the number of bits that the algorithm implements.
According to .NET's naming conventions, they should be called Sha1, Sha256, Sha384 and Sha512.
The dispute is not that Microsoft made a mistake. The implementations were probably created before the naming conventions were standardized and there's nothing that can be done about it now.
The dispute is what to call SHA3 variant implementations:
There are only two hard things in Computer Science: cache invalidation and naming things.
Phil Karlton
As if naming wasn't hard enough, the other things that Microsoft will have to consider...
But hey, they're a multi-billion dollar company, they can just do it faster...right?
@Xyncgas i've hidden your message for multiple fairly extreme violations of the .NET Code of Conduct. In particular, but not limited to:
a. Being respectful of differing opinions, viewpoints, and experiences b. Giving and gracefully accepting constructive feedback c. Trolling, insulting or derogatory comments, and personal or political attacks d. Other conduct which could reasonably be considered inappropriate in a professional setting
For now, I'm just starting with a warning that such behavior is not acceptable here. Further similar behavior will lead to necessary action, including either temporary or permanent bans.
To @MrMatthewLayton and others, i ask that you not respond to that post (or any referenced parts of it in the post that followed), and keep the discussion purely on topic about the main issue's subject. Thanks!
I would appreciate if there are news about underlying providers. Search for "Windows CNG SHA-3" gets nothing for me. You internal ones may contact Windows cryptography folks about their plan.
You can use bouncy castle.
public static string GET512(string input)
{
var hashAlgorithm = new Org.BouncyCastle.Crypto.Digests.Sha3Digest(512);
byte[] byte_array = System.Text.Encoding.UTF8.GetBytes(input);
hashAlgorithm.BlockUpdate(byte_array, 0, byte_array.Length);
byte[] result = new byte[64]; // 512 / 8 = 64
hashAlgorithm.DoFinal(result, 0);
string hashString = BitConverter.ToString(result);
hashString = hashString.Replace("-", "").ToUpperInvariant();
return hashString;
}
public static string GET512(byte[] input)
{
var hashAlgorithm = new Org.BouncyCastle.Crypto.Digests.Sha3Digest(512);
hashAlgorithm.BlockUpdate(input, 0, input.Length);
byte[] result = new byte[64]; // 512 / 8 = 64
hashAlgorithm.DoFinal(result, 0);
string hashString = BitConverter.ToString(result);
hashString = hashString.Replace("-", "").ToUpperInvariant();
return hashString;
}
public static string GET256(string input)
{
var hashAlgorithm = new Org.BouncyCastle.Crypto.Digests.Sha3Digest(256);
byte[] byte_array = System.Text.Encoding.UTF8.GetBytes(input);
hashAlgorithm.BlockUpdate(byte_array, 0, byte_array.Length);
byte[] result = new byte[32]; // 256 / 8 = 32
hashAlgorithm.DoFinal(result, 0);
string hashString = BitConverter.ToString(result);
hashString = hashString.Replace("-", "").ToUpperInvariant();
return hashString;
}
public static string GET256(byte[] input)
{
var hashAlgorithm = new Org.BouncyCastle.Crypto.Digests.Sha3Digest(256);
hashAlgorithm.BlockUpdate(input, 0, input.Length);
byte[] result = new byte[32]; // 256 / 8 = 32
hashAlgorithm.DoFinal(result, 0);
string hashString = BitConverter.ToString(result);
hashString = hashString.Replace("-", "").ToUpperInvariant();
return hashString;
}
You can use bouncy castle.
- Install BouncyCatle package
- use these codes as examples, try other packages like BouncyCatle.portable if you want
public static string GET512(string input) { var hashAlgorithm = new Org.BouncyCastle.Crypto.Digests.Sha3Digest(512); byte[] byte_array = System.Text.Encoding.UTF8.GetBytes(input); hashAlgorithm.BlockUpdate(byte_array, 0, byte_array.Length); byte[] result = new byte[64]; // 512 / 8 = 64 hashAlgorithm.DoFinal(result, 0); string hashString = BitConverter.ToString(result); hashString = hashString.Replace("-", "").ToUpperInvariant(); return hashString; } public static string GET512(byte[] input) { var hashAlgorithm = new Org.BouncyCastle.Crypto.Digests.Sha3Digest(512); hashAlgorithm.BlockUpdate(input, 0, input.Length); byte[] result = new byte[64]; // 512 / 8 = 64 hashAlgorithm.DoFinal(result, 0); string hashString = BitConverter.ToString(result); hashString = hashString.Replace("-", "").ToUpperInvariant(); return hashString; } public static string GET256(string input) { var hashAlgorithm = new Org.BouncyCastle.Crypto.Digests.Sha3Digest(256); byte[] byte_array = System.Text.Encoding.UTF8.GetBytes(input); hashAlgorithm.BlockUpdate(byte_array, 0, byte_array.Length); byte[] result = new byte[32]; // 256 / 8 = 32 hashAlgorithm.DoFinal(result, 0); string hashString = BitConverter.ToString(result); hashString = hashString.Replace("-", "").ToUpperInvariant(); return hashString; } public static string GET256(byte[] input) { var hashAlgorithm = new Org.BouncyCastle.Crypto.Digests.Sha3Digest(256); hashAlgorithm.BlockUpdate(input, 0, input.Length); byte[] result = new byte[32]; // 256 / 8 = 32 hashAlgorithm.DoFinal(result, 0); string hashString = BitConverter.ToString(result); hashString = hashString.Replace("-", "").ToUpperInvariant(); return hashString; }
I guess I'm that guy you referred that created the library. Sorry to disappoint you but I'm argentinian living in Europe, not Asian. I have released a new version of the library that doesn't depend on bouncy castle but is the actual code of bouncy castle to perform Keccak. This new version has an execution time 10% of what it was and has no other dependencies, targeted net5 and 6. I removed any dependencies to net fwk 4.5 and 4.6. On a side note I'm happy you have you have friends. We all have, but some of us like to provide to the open source community, and open source means that, you can copy, modify and use other people's code as long as you don't break their licenses. The beauty of open source is that you can read the code and understand what is doing avoiding security issues. You can see now that waiting for Microsoft to implement this will take time, but if you do things right you can easily change implementationa on your app and try new libraries. Plenty of people here published code but not packages, just make sure your application"s quotes them and their licenses. Happy coding
Is SHA3 going to be in .NET 7 ?
Is SHA3 going to be in .NET 7 ?
No. Windows doesn't already have it, and we're wrapping up the release.
Plus, I don't think I've seen any good naming proposals for how we can incorporate it (other than calling it Keccak, which no few will understand)
Now, I know I've been here before, flogging my own horse, but since SHA-3 isn't appearing in .NET any time soon, allow me to collate and be at least somewhat impartial as to the available options:
I said I've been here before...DON'T USE THIS! https://github.com/MrMatthewLayton/CORE This is my project implementing FIPS-202 however it's massively out of date and no longer supported.
Other Options https://www.nuget.org/packages/SHA3.Net/ implemented by @dariogriffo https://www.bouncycastle.org/csharp/
If you are interested in what I have been doing since I retired the codebase above, all of my open-source cryptography APIs are now released under ONIXLabs Ltd.
https://github.com/onix-labs/onixlabs-dotnet https://github.com/onix-labs/onixlabs-dotnet/tree/main/OnixLabs.Security.Cryptography
I hope this helps.
P.S. I Think I cracked the naming. It doesn't follow the ~wrong~ naming convention already in .NET...
With Windows SHA-3 Support now announced, we will move forward with this proposal and include it in .NET 8.
@jeffhandley Excellent news! Do you know whether the same APIs may be available for Linux and macOS?
@jeffhandley Excellent news! Do you know whether the same APIs may be available for Linux and macOS?
One would assume that, as it would be quite trivial to support it there. The main reason new Crypto is hold back in the .NET standard libs is native platform support in windows. The .NET devs have been hesitant to support Crypto Algorithms in the .NET standard libs which would return "Plaform Not Supported" on Windows. Probably for obvious reasons..
You can always use bouncy castle and or openssl via NuGet packages on windows as well to get SHA3 today.
@Spacefish or, I could just use my own ;) https://github.com/dotnet/runtime/issues/20342#issuecomment-1193156664
That is, until they're provided in .NET, in which case I will probably refactor my own APIs to use the platform provided API, and fall back to my own in the event that platform not supported exceptions are thrown.
The top post is updated with the proposal for SHA3.
IsSupported
)abstract class Shake
, and just copied the instance members up to the derived types. We can insert it later if we change our minds.void GetCurrentHash(Span<byte> destination)
methods (because they will fill the entire buffer). We discussed things like void FillWithCurrentHash
and int GetCurrentHash
. In the end, we kept it as void GetCurrentHash
namespace System.Security.Cryptography;
public partial struct HashAlgorithmName {
public static HashAlgorithmName SHA3_256 { get; }
public static HashAlgorithmName SHA3_384 { get; }
public static HashAlgorithmName SHA3_512 { get; }
}
public sealed partial class RSAEncryptionPadding {
public static RSAEncryptionPadding OaepSHA3_256 { get; }
public static RSAEncryptionPadding OaepSHA3_384 { get; }
public static RSAEncryptionPadding OaepSHA3_512 { get; }
}
public abstract partial class SHA3_256 : HashAlgorithm {
public const int HashSizeInBits = 256;
public const int HashSizeInBytes = 32;
protected SHA3_256();
[UnsupportedOSPlatformGuard("ios")]
[UnsupportedOSPlatformGuard("tvos")]
[UnsupportedOSPlatformGuard("android")]
[UnsupportedOSPlatformGuard("browser")]
[UnsupportedOSPlatformGuard("osx")]
public static bool IsSupported { get; }
[UnsupportedOSPlatform("ios")]
[UnsupportedOSPlatform("tvos")]
[UnsupportedOSPlatform("android")]
[UnsupportedOSPlatform("browser")]
[UnsupportedOSPlatform("osx")]
public static new SHA3_256 Create();
[UnsupportedOSPlatform("ios")]
[UnsupportedOSPlatform("tvos")]
[UnsupportedOSPlatform("android")]
[UnsupportedOSPlatform("browser")]
[UnsupportedOSPlatform("osx")]
public static byte[] HashData(byte[] source);
[UnsupportedOSPlatform("ios")]
[UnsupportedOSPlatform("tvos")]
[UnsupportedOSPlatform("android")]
[UnsupportedOSPlatform("browser")]
[UnsupportedOSPlatform("osx")]
public static byte[] HashData(ReadOnlySpan<byte> source);
[UnsupportedOSPlatform("ios")]
[UnsupportedOSPlatform("tvos")]
[UnsupportedOSPlatform("android")]
[UnsupportedOSPlatform("browser")]
[UnsupportedOSPlatform("osx")]
public static int HashData(ReadOnlySpan<byte> source, Span<byte> destination);
[UnsupportedOSPlatform("ios")]
[UnsupportedOSPlatform("tvos")]
[UnsupportedOSPlatform("android")]
[UnsupportedOSPlatform("browser")]
[UnsupportedOSPlatform("osx")]
public static bool TryHashData(ReadOnlySpan<byte> source, Span<byte> destination, out int bytesWritten);
[UnsupportedOSPlatform("ios")]
[UnsupportedOSPlatform("tvos")]
[UnsupportedOSPlatform("android")]
[UnsupportedOSPlatform("browser")]
[UnsupportedOSPlatform("osx")]
public static byte[] HashData(Stream source);
[UnsupportedOSPlatform("ios")]
[UnsupportedOSPlatform("tvos")]
[UnsupportedOSPlatform("android")]
[UnsupportedOSPlatform("browser")]
[UnsupportedOSPlatform("osx")]
public static int HashData(Stream source, Span<byte> destination);
[UnsupportedOSPlatform("ios")]
[UnsupportedOSPlatform("tvos")]
[UnsupportedOSPlatform("android")]
[UnsupportedOSPlatform("browser")]
[UnsupportedOSPlatform("osx")]
public static ValueTask<byte[]> HashDataAsync(Stream source, CancellationToken cancellationToken = default);
[UnsupportedOSPlatform("ios")]
[UnsupportedOSPlatform("tvos")]
[UnsupportedOSPlatform("android")]
[UnsupportedOSPlatform("browser")]
[UnsupportedOSPlatform("osx")]
public static ValueTask<int> HashDataAsync(
Stream source,
Memory<byte> destination,
CancellationToken cancellationToken = default);
}
public abstract partial class SHA3_384 : HashAlgorithm {
public const int HashSizeInBits = 384;
public const int HashSizeInBytes = 48;
protected SHA3_384();
[UnsupportedOSPlatformGuard("ios")]
[UnsupportedOSPlatformGuard("tvos")]
[UnsupportedOSPlatformGuard("android")]
[UnsupportedOSPlatformGuard("browser")]
[UnsupportedOSPlatformGuard("osx")]
public static bool IsSupported { get; }
[UnsupportedOSPlatform("ios")]
[UnsupportedOSPlatform("tvos")]
[UnsupportedOSPlatform("android")]
[UnsupportedOSPlatform("browser")]
[UnsupportedOSPlatform("osx")]
public static new SHA3_384 Create();
[UnsupportedOSPlatform("ios")]
[UnsupportedOSPlatform("tvos")]
[UnsupportedOSPlatform("android")]
[UnsupportedOSPlatform("browser")]
[UnsupportedOSPlatform("osx")]
public static byte[] HashData(byte[] source);
[UnsupportedOSPlatform("ios")]
[UnsupportedOSPlatform("tvos")]
[UnsupportedOSPlatform("android")]
[UnsupportedOSPlatform("browser")]
[UnsupportedOSPlatform("osx")]
public static byte[] HashData(ReadOnlySpan<byte> source);
[UnsupportedOSPlatform("ios")]
[UnsupportedOSPlatform("tvos")]
[UnsupportedOSPlatform("android")]
[UnsupportedOSPlatform("browser")]
[UnsupportedOSPlatform("osx")]
public static int HashData(ReadOnlySpan<byte> source, Span<byte> destination);
[UnsupportedOSPlatform("ios")]
[UnsupportedOSPlatform("tvos")]
[UnsupportedOSPlatform("android")]
[UnsupportedOSPlatform("browser")]
[UnsupportedOSPlatform("osx")]
public static bool TryHashData(ReadOnlySpan<byte> source, Span<byte> destination, out int bytesWritten);
[UnsupportedOSPlatform("ios")]
[UnsupportedOSPlatform("tvos")]
[UnsupportedOSPlatform("android")]
[UnsupportedOSPlatform("browser")]
[UnsupportedOSPlatform("osx")]
public static byte[] HashData(Stream source);
[UnsupportedOSPlatform("ios")]
[UnsupportedOSPlatform("tvos")]
[UnsupportedOSPlatform("android")]
[UnsupportedOSPlatform("browser")]
[UnsupportedOSPlatform("osx")]
public static int HashData(Stream source, Span<byte> destination);
[UnsupportedOSPlatform("ios")]
[UnsupportedOSPlatform("tvos")]
[UnsupportedOSPlatform("android")]
[UnsupportedOSPlatform("browser")]
[UnsupportedOSPlatform("osx")]
public static ValueTask<byte[]> HashDataAsync(Stream source, CancellationToken cancellationToken = default);
[UnsupportedOSPlatform("ios")]
[UnsupportedOSPlatform("tvos")]
[UnsupportedOSPlatform("android")]
[UnsupportedOSPlatform("browser")]
[UnsupportedOSPlatform("osx")]
public static ValueTask<int> HashDataAsync(
Stream source,
Memory<byte> destination,
CancellationToken cancellationToken = default);
}
public abstract partial class SHA3_512 : HashAlgorithm {
public const int HashSizeInBits = 512;
public const int HashSizeInBytes = 64;
protected SHA3_512();
[UnsupportedOSPlatformGuard("ios")]
[UnsupportedOSPlatformGuard("tvos")]
[UnsupportedOSPlatformGuard("android")]
[UnsupportedOSPlatformGuard("browser")]
[UnsupportedOSPlatformGuard("osx")]
public static bool IsSupported { get; }
[UnsupportedOSPlatform("ios")]
[UnsupportedOSPlatform("tvos")]
[UnsupportedOSPlatform("android")]
[UnsupportedOSPlatform("browser")]
[UnsupportedOSPlatform("osx")]
public static new SHA3_512 Create();
[UnsupportedOSPlatform("ios")]
[UnsupportedOSPlatform("tvos")]
[UnsupportedOSPlatform("android")]
[UnsupportedOSPlatform("browser")]
[UnsupportedOSPlatform("osx")]
public static byte[] HashData(byte[] source);
[UnsupportedOSPlatform("ios")]
[UnsupportedOSPlatform("tvos")]
[UnsupportedOSPlatform("android")]
[UnsupportedOSPlatform("browser")]
[UnsupportedOSPlatform("osx")]
public static byte[] HashData(ReadOnlySpan<byte> source);
[UnsupportedOSPlatform("ios")]
[UnsupportedOSPlatform("tvos")]
[UnsupportedOSPlatform("android")]
[UnsupportedOSPlatform("browser")]
[UnsupportedOSPlatform("osx")]
public static int HashData(ReadOnlySpan<byte> source, Span<byte> destination);
[UnsupportedOSPlatform("ios")]
[UnsupportedOSPlatform("tvos")]
[UnsupportedOSPlatform("android")]
[UnsupportedOSPlatform("browser")]
[UnsupportedOSPlatform("osx")]
public static bool TryHashData(ReadOnlySpan<byte> source, Span<byte> destination, out int bytesWritten);
[UnsupportedOSPlatform("ios")]
[UnsupportedOSPlatform("tvos")]
[UnsupportedOSPlatform("android")]
[UnsupportedOSPlatform("browser")]
[UnsupportedOSPlatform("osx")]
public static byte[] HashData(Stream source);
[UnsupportedOSPlatform("ios")]
[UnsupportedOSPlatform("tvos")]
[UnsupportedOSPlatform("android")]
[UnsupportedOSPlatform("browser")]
[UnsupportedOSPlatform("osx")]
public static int HashData(Stream source, Span<byte> destination);
[UnsupportedOSPlatform("ios")]
[UnsupportedOSPlatform("tvos")]
[UnsupportedOSPlatform("android")]
[UnsupportedOSPlatform("browser")]
[UnsupportedOSPlatform("osx")]
public static ValueTask<byte[]> HashDataAsync(Stream source, CancellationToken cancellationToken = default);
[UnsupportedOSPlatform("ios")]
[UnsupportedOSPlatform("tvos")]
[UnsupportedOSPlatform("android")]
[UnsupportedOSPlatform("browser")]
[UnsupportedOSPlatform("osx")]
public static ValueTask<int> HashDataAsync(
Stream source,
Memory<byte> destination,
CancellationToken cancellationToken = default);
}
public partial class HMACSHA3_256 : HMAC {
public const int HashSizeInBits = 256;
public const int HashSizeInBytes = 32;
[UnsupportedOSPlatform("ios")]
[UnsupportedOSPlatform("tvos")]
[UnsupportedOSPlatform("android")]
[UnsupportedOSPlatform("browser")]
[UnsupportedOSPlatform("osx")]
public HMACSHA3_256();
[UnsupportedOSPlatform("ios")]
[UnsupportedOSPlatform("tvos")]
[UnsupportedOSPlatform("android")]
[UnsupportedOSPlatform("browser")]
[UnsupportedOSPlatform("osx")]
public HMACSHA3_256(byte[] key);
[UnsupportedOSPlatformGuard("ios")]
[UnsupportedOSPlatformGuard("tvos")]
[UnsupportedOSPlatformGuard("android")]
[UnsupportedOSPlatformGuard("browser")]
[UnsupportedOSPlatformGuard("osx")]
public static bool IsSupported { get; } // New
[UnsupportedOSPlatform("ios")]
[UnsupportedOSPlatform("tvos")]
[UnsupportedOSPlatform("android")]
[UnsupportedOSPlatform("browser")]
[UnsupportedOSPlatform("osx")]
public static byte[] HashData(byte[] key, byte[] source);
[UnsupportedOSPlatform("ios")]
[UnsupportedOSPlatform("tvos")]
[UnsupportedOSPlatform("android")]
[UnsupportedOSPlatform("browser")]
[UnsupportedOSPlatform("osx")]
public static byte[] HashData(ReadOnlySpan<byte> key, ReadOnlySpan<byte> source);
[UnsupportedOSPlatform("ios")]
[UnsupportedOSPlatform("tvos")]
[UnsupportedOSPlatform("android")]
[UnsupportedOSPlatform("browser")]
[UnsupportedOSPlatform("osx")]
public static int HashData(ReadOnlySpan<byte> key, ReadOnlySpan<byte> source, Span<byte> destination);
[UnsupportedOSPlatform("ios")]
[UnsupportedOSPlatform("tvos")]
[UnsupportedOSPlatform("android")]
[UnsupportedOSPlatform("browser")]
[UnsupportedOSPlatform("osx")]
public static bool TryHashData(
ReadOnlySpan<byte> key,
ReadOnlySpan<byte> source,
Span<byte> destination,
out int bytesWritten);
[UnsupportedOSPlatform("ios")]
[UnsupportedOSPlatform("tvos")]
[UnsupportedOSPlatform("android")]
[UnsupportedOSPlatform("browser")]
[UnsupportedOSPlatform("osx")]
public static byte[] HashData(byte[] key, Stream source);
[UnsupportedOSPlatform("ios")]
[UnsupportedOSPlatform("tvos")]
[UnsupportedOSPlatform("android")]
[UnsupportedOSPlatform("browser")]
[UnsupportedOSPlatform("osx")]
public static byte[] HashData(ReadOnlySpan<byte> key, Stream source);
[UnsupportedOSPlatform("ios")]
[UnsupportedOSPlatform("tvos")]
[UnsupportedOSPlatform("android")]
[UnsupportedOSPlatform("browser")]
[UnsupportedOSPlatform("osx")]
public static int HashData(ReadOnlySpan<byte> key, Stream source, Span<byte> destination);
[UnsupportedOSPlatform("ios")]
[UnsupportedOSPlatform("tvos")]
[UnsupportedOSPlatform("android")]
[UnsupportedOSPlatform("browser")]
[UnsupportedOSPlatform("osx")]
public static ValueTask<byte[]> HashDataAsync(byte[] key, Stream source, CancellationToken cancellationToken = default);
[UnsupportedOSPlatform("ios")]
[UnsupportedOSPlatform("tvos")]
[UnsupportedOSPlatform("android")]
[UnsupportedOSPlatform("browser")]
[UnsupportedOSPlatform("osx")]
public static ValueTask<byte[]> HashDataAsync(ReadOnlyMemory<byte> key, Stream source, CancellationToken cancellationToken = default);
[UnsupportedOSPlatform("ios")]
[UnsupportedOSPlatform("tvos")]
[UnsupportedOSPlatform("android")]
[UnsupportedOSPlatform("browser")]
[UnsupportedOSPlatform("osx")]
public static ValueTask<int> HashDataAsync(
ReadOnlyMemory<byte> key,
Stream source,
Memory<byte> destination,
CancellationToken cancellationToken = default);
}
public partial class HMACSHA3_384 : HMAC {
public const int HashSizeInBits = 384;
public const int HashSizeInBytes = 48;
[UnsupportedOSPlatform("ios")]
[UnsupportedOSPlatform("tvos")]
[UnsupportedOSPlatform("android")]
[UnsupportedOSPlatform("browser")]
[UnsupportedOSPlatform("osx")]
public HMACSHA3_384();
[UnsupportedOSPlatform("ios")]
[UnsupportedOSPlatform("tvos")]
[UnsupportedOSPlatform("android")]
[UnsupportedOSPlatform("browser")]
[UnsupportedOSPlatform("osx")]
public HMACSHA3_384(byte[] key);
[UnsupportedOSPlatformGuard("ios")]
[UnsupportedOSPlatformGuard("tvos")]
[UnsupportedOSPlatformGuard("android")]
[UnsupportedOSPlatformGuard("browser")]
[UnsupportedOSPlatformGuard("osx")]
public static bool IsSupported { get; } // New
[UnsupportedOSPlatform("ios")]
[UnsupportedOSPlatform("tvos")]
[UnsupportedOSPlatform("android")]
[UnsupportedOSPlatform("browser")]
[UnsupportedOSPlatform("osx")]
public static byte[] HashData(byte[] key, byte[] source);
[UnsupportedOSPlatform("ios")]
[UnsupportedOSPlatform("tvos")]
[UnsupportedOSPlatform("android")]
[UnsupportedOSPlatform("browser")]
[UnsupportedOSPlatform("osx")]
public static byte[] HashData(ReadOnlySpan<byte> key, ReadOnlySpan<byte> source);
[UnsupportedOSPlatform("ios")]
[UnsupportedOSPlatform("tvos")]
[UnsupportedOSPlatform("android")]
[UnsupportedOSPlatform("browser")]
[UnsupportedOSPlatform("osx")]
public static int HashData(ReadOnlySpan<byte> key, ReadOnlySpan<byte> source, Span<byte> destination);
[UnsupportedOSPlatform("ios")]
[UnsupportedOSPlatform("tvos")]
[UnsupportedOSPlatform("android")]
[UnsupportedOSPlatform("browser")]
[UnsupportedOSPlatform("osx")]
public static bool TryHashData(
ReadOnlySpan<byte> key,
ReadOnlySpan<byte> source,
Span<byte> destination,
out int bytesWritten);
[UnsupportedOSPlatform("ios")]
[UnsupportedOSPlatform("tvos")]
[UnsupportedOSPlatform("android")]
[UnsupportedOSPlatform("browser")]
[UnsupportedOSPlatform("osx")]
public static byte[] HashData(byte[] key, Stream source);
[UnsupportedOSPlatform("ios")]
[UnsupportedOSPlatform("tvos")]
[UnsupportedOSPlatform("android")]
[UnsupportedOSPlatform("browser")]
[UnsupportedOSPlatform("osx")]
public static byte[] HashData(ReadOnlySpan<byte> key, Stream source);
[UnsupportedOSPlatform("ios")]
[UnsupportedOSPlatform("tvos")]
[UnsupportedOSPlatform("android")]
[UnsupportedOSPlatform("browser")]
[UnsupportedOSPlatform("osx")]
public static int HashData(ReadOnlySpan<byte> key, Stream source, Span<byte> destination);
[UnsupportedOSPlatform("ios")]
[UnsupportedOSPlatform("tvos")]
[UnsupportedOSPlatform("android")]
[UnsupportedOSPlatform("browser")]
[UnsupportedOSPlatform("osx")]
public static ValueTask<byte[]> HashDataAsync(byte[] key, Stream source, CancellationToken cancellationToken = default);
[UnsupportedOSPlatform("ios")]
[UnsupportedOSPlatform("tvos")]
[UnsupportedOSPlatform("android")]
[UnsupportedOSPlatform("browser")]
[UnsupportedOSPlatform("osx")]
public static ValueTask<byte[]> HashDataAsync(ReadOnlyMemory<byte> key, Stream source, CancellationToken cancellationToken = default);
[UnsupportedOSPlatform("ios")]
[UnsupportedOSPlatform("tvos")]
[UnsupportedOSPlatform("android")]
[UnsupportedOSPlatform("browser")]
[UnsupportedOSPlatform("osx")]
public static ValueTask<int> HashDataAsync(
ReadOnlyMemory<byte> key,
Stream source,
Memory<byte> destination,
CancellationToken cancellationToken = default);
}
public partial class HMACSHA3_512 : HMAC {
public const int HashSizeInBits = 512;
public const int HashSizeInBytes = 64;
[UnsupportedOSPlatform("ios")]
[UnsupportedOSPlatform("tvos")]
[UnsupportedOSPlatform("android")]
[UnsupportedOSPlatform("browser")]
[UnsupportedOSPlatform("osx")]
public HMACSHA3_512();
[UnsupportedOSPlatform("ios")]
[UnsupportedOSPlatform("tvos")]
[UnsupportedOSPlatform("android")]
[UnsupportedOSPlatform("browser")]
[UnsupportedOSPlatform("osx")]
public HMACSHA3_512(byte[] key);
[UnsupportedOSPlatformGuard("ios")]
[UnsupportedOSPlatformGuard("tvos")]
[UnsupportedOSPlatformGuard("android")]
[UnsupportedOSPlatformGuard("browser")]
[UnsupportedOSPlatformGuard("osx")]
public static bool IsSupported { get; } // New
[UnsupportedOSPlatform("ios")]
[UnsupportedOSPlatform("tvos")]
[UnsupportedOSPlatform("android")]
[UnsupportedOSPlatform("browser")]
[UnsupportedOSPlatform("osx")]
public static byte[] HashData(byte[] key, byte[] source);
[UnsupportedOSPlatform("ios")]
[UnsupportedOSPlatform("tvos")]
[UnsupportedOSPlatform("android")]
[UnsupportedOSPlatform("browser")]
[UnsupportedOSPlatform("osx")]
public static byte[] HashData(ReadOnlySpan<byte> key, ReadOnlySpan<byte> source);
[UnsupportedOSPlatform("ios")]
[UnsupportedOSPlatform("tvos")]
[UnsupportedOSPlatform("android")]
[UnsupportedOSPlatform("browser")]
[UnsupportedOSPlatform("osx")]
public static int HashData(ReadOnlySpan<byte> key, ReadOnlySpan<byte> source, Span<byte> destination);
[UnsupportedOSPlatform("ios")]
[UnsupportedOSPlatform("tvos")]
[UnsupportedOSPlatform("android")]
[UnsupportedOSPlatform("browser")]
[UnsupportedOSPlatform("osx")]
public static bool TryHashData(
ReadOnlySpan<byte> key,
ReadOnlySpan<byte> source,
Span<byte> destination,
out int bytesWritten);
[UnsupportedOSPlatform("ios")]
[UnsupportedOSPlatform("tvos")]
[UnsupportedOSPlatform("android")]
[UnsupportedOSPlatform("browser")]
[UnsupportedOSPlatform("osx")]
public static byte[] HashData(byte[] key, Stream source);
[UnsupportedOSPlatform("ios")]
[UnsupportedOSPlatform("tvos")]
[UnsupportedOSPlatform("android")]
[UnsupportedOSPlatform("browser")]
[UnsupportedOSPlatform("osx")]
public static byte[] HashData(ReadOnlySpan<byte> key, Stream source);
[UnsupportedOSPlatform("ios")]
[UnsupportedOSPlatform("tvos")]
[UnsupportedOSPlatform("android")]
[UnsupportedOSPlatform("browser")]
[UnsupportedOSPlatform("osx")]
public static int HashData(ReadOnlySpan<byte> key, Stream source, Span<byte> destination);
[UnsupportedOSPlatform("ios")]
[UnsupportedOSPlatform("tvos")]
[UnsupportedOSPlatform("android")]
[UnsupportedOSPlatform("browser")]
[UnsupportedOSPlatform("osx")]
public static ValueTask<byte[]> HashDataAsync(byte[] key, Stream source, CancellationToken cancellationToken = default);
[UnsupportedOSPlatform("ios")]
[UnsupportedOSPlatform("tvos")]
[UnsupportedOSPlatform("android")]
[UnsupportedOSPlatform("browser")]
[UnsupportedOSPlatform("osx")]
public static ValueTask<byte[]> HashDataAsync(ReadOnlyMemory<byte> key, Stream source, CancellationToken cancellationToken = default);
[UnsupportedOSPlatform("ios")]
[UnsupportedOSPlatform("tvos")]
[UnsupportedOSPlatform("android")]
[UnsupportedOSPlatform("browser")]
[UnsupportedOSPlatform("osx")]
public static ValueTask<int> HashDataAsync(
ReadOnlyMemory<byte> key,
Stream source,
Memory<byte> destination,
CancellationToken cancellationToken = default);
}
[UnsupportedOSPlatform("ios")]
[UnsupportedOSPlatform("tvos")]
[UnsupportedOSPlatform("android")]
[UnsupportedOSPlatform("browser")]
[UnsupportedOSPlatform("osx")]
public sealed partial class Shake128 : IDisposable {
public Shake128();
[UnsupportedOSPlatformGuard("ios")]
[UnsupportedOSPlatformGuard("tvos")]
[UnsupportedOSPlatformGuard("android")]
[UnsupportedOSPlatformGuard("browser")]
[UnsupportedOSPlatformGuard("osx")]
public static bool IsSupported { get; }
public void AppendData(byte[] data);
public void AppendData(ReadOnlySpan<byte> data);
public byte[] GetCurrentHash(int outputLength);
public void GetCurrentHash(Span<byte> destination);
public byte[] GetHashAndReset(int outputLength);
public void GetHashAndReset(Span<byte> destination);
public void Dispose();
public static byte[] HashData(byte[] source, int outputLength);
public static byte[] HashData(ReadOnlySpan<byte> source, int outputLength);
public static void HashData(ReadOnlySpan<byte> source, Span<byte> destination);
public static byte[] HashData(Stream source, int outputLength);
public static void HashData(Stream source, Span<byte> destination);
public static ValueTask HashDataAsync(Stream source, Memory<byte> destination, CancellationToken cancellationToken = default);
public static ValueTask<byte[]> HashDataAsync(Stream source, int outputLength, CancellationToken cancellationToken = default);
}
[UnsupportedOSPlatform("ios")]
[UnsupportedOSPlatform("tvos")]
[UnsupportedOSPlatform("android")]
[UnsupportedOSPlatform("browser")]
[UnsupportedOSPlatform("osx")]
public sealed partial class Shake256 : IDisposable {
public Shake256();
[UnsupportedOSPlatformGuard("ios")]
[UnsupportedOSPlatformGuard("tvos")]
[UnsupportedOSPlatformGuard("android")]
[UnsupportedOSPlatformGuard("browser")]
[UnsupportedOSPlatformGuard("osx")]
public static bool IsSupported { get; }
public void AppendData(byte[] data);
public void AppendData(ReadOnlySpan<byte> data);
public byte[] GetCurrentHash(int outputLength);
public void GetCurrentHash(Span<byte> destination);
public byte[] GetHashAndReset(int outputLength);
public void GetHashAndReset(Span<byte> destination);
public void Dispose();
public static byte[] HashData(byte[] source, int outputLength);
public static byte[] HashData(ReadOnlySpan<byte> source, int outputLength);
public static void HashData(ReadOnlySpan<byte> source, Span<byte> destination);
public static byte[] HashData(Stream source, int outputLength);
public static void HashData(Stream source, Span<byte> destination);
public static ValueTask HashDataAsync(Stream source, Memory<byte> destination, CancellationToken cancellationToken = default);
public static ValueTask<byte[]> HashDataAsync(Stream source, int outputLength, CancellationToken cancellationToken = default);
}
This is going back to review just to further discuss the SupportedOSPlatform
attributes. The proposal in the top post has been amended.
We discussed removing the attributes and treating it similar to how we do the intrinsics... if there's an IsSupported it's up to you to know to check it (or to not check it because you have no fallback).
We should similarly remove the OS-support attributes from Ed25519 types.
namespace System.Security.Cryptography;
public partial struct HashAlgorithmName {
public static HashAlgorithmName SHA3_256 { get; }
public static HashAlgorithmName SHA3_384 { get; }
public static HashAlgorithmName SHA3_512 { get; }
}
public sealed partial class RSAEncryptionPadding {
public static RSAEncryptionPadding OaepSHA3_256 { get; }
public static RSAEncryptionPadding OaepSHA3_384 { get; }
public static RSAEncryptionPadding OaepSHA3_512 { get; }
}
public abstract partial class SHA3_256 : HashAlgorithm {
public const int HashSizeInBits = 256;
public const int HashSizeInBytes = 32;
protected SHA3_256();
public static bool IsSupported { get; }
public static new SHA3_256 Create();
public static byte[] HashData(byte[] source);
public static byte[] HashData(ReadOnlySpan<byte> source);
public static int HashData(ReadOnlySpan<byte> source, Span<byte> destination);
public static bool TryHashData(ReadOnlySpan<byte> source, Span<byte> destination, out int bytesWritten);
public static byte[] HashData(Stream source);
public static int HashData(Stream source, Span<byte> destination);
public static ValueTask<byte[]> HashDataAsync(Stream source, CancellationToken cancellationToken = default);
public static ValueTask<int> HashDataAsync(
Stream source,
Memory<byte> destination,
CancellationToken cancellationToken = default);
}
public abstract partial class SHA3_384 : HashAlgorithm {
public const int HashSizeInBits = 384;
public const int HashSizeInBytes = 48;
protected SHA3_384();
public static bool IsSupported { get; }
public static new SHA3_384 Create();
public static byte[] HashData(byte[] source);
public static byte[] HashData(ReadOnlySpan<byte> source);
public static int HashData(ReadOnlySpan<byte> source, Span<byte> destination);
public static bool TryHashData(ReadOnlySpan<byte> source, Span<byte> destination, out int bytesWritten);
public static byte[] HashData(Stream source);
public static int HashData(Stream source, Span<byte> destination);
public static ValueTask<byte[]> HashDataAsync(Stream source, CancellationToken cancellationToken = default);
public static ValueTask<int> HashDataAsync(
Stream source,
Memory<byte> destination,
CancellationToken cancellationToken = default);
}
public abstract partial class SHA3_512 : HashAlgorithm {
public const int HashSizeInBits = 512;
public const int HashSizeInBytes = 64;
protected SHA3_512();
public static bool IsSupported { get; }
public static new SHA3_512 Create();
public static byte[] HashData(byte[] source);
public static byte[] HashData(ReadOnlySpan<byte> source);
public static int HashData(ReadOnlySpan<byte> source, Span<byte> destination);
public static bool TryHashData(ReadOnlySpan<byte> source, Span<byte> destination, out int bytesWritten);
public static byte[] HashData(Stream source);
public static int HashData(Stream source, Span<byte> destination);
public static ValueTask<byte[]> HashDataAsync(Stream source, CancellationToken cancellationToken = default);
public static ValueTask<int> HashDataAsync(
Stream source,
Memory<byte> destination,
CancellationToken cancellationToken = default);
}
public partial class HMACSHA3_256 : HMAC {
public const int HashSizeInBits = 256;
public const int HashSizeInBytes = 32;
public HMACSHA3_256();
public HMACSHA3_256(byte[] key);
public static bool IsSupported { get; } // New
public static byte[] HashData(byte[] key, byte[] source);
public static byte[] HashData(ReadOnlySpan<byte> key, ReadOnlySpan<byte> source);
public static int HashData(ReadOnlySpan<byte> key, ReadOnlySpan<byte> source, Span<byte> destination);
public static bool TryHashData(
ReadOnlySpan<byte> key,
ReadOnlySpan<byte> source,
Span<byte> destination,
out int bytesWritten);
public static byte[] HashData(byte[] key, Stream source);
public static byte[] HashData(ReadOnlySpan<byte> key, Stream source);
public static int HashData(ReadOnlySpan<byte> key, Stream source, Span<byte> destination);
public static ValueTask<byte[]> HashDataAsync(byte[] key, Stream source, CancellationToken cancellationToken = default);
public static ValueTask<byte[]> HashDataAsync(ReadOnlyMemory<byte> key, Stream source, CancellationToken cancellationToken = default);
public static ValueTask<int> HashDataAsync(
ReadOnlyMemory<byte> key,
Stream source,
Memory<byte> destination,
CancellationToken cancellationToken = default);
}
public partial class HMACSHA3_384 : HMAC {
public const int HashSizeInBits = 384;
public const int HashSizeInBytes = 48;
public HMACSHA3_384();
public HMACSHA3_384(byte[] key);
public static bool IsSupported { get; } // New
public static byte[] HashData(byte[] key, byte[] source);
public static byte[] HashData(ReadOnlySpan<byte> key, ReadOnlySpan<byte> source);
public static int HashData(ReadOnlySpan<byte> key, ReadOnlySpan<byte> source, Span<byte> destination);
public static bool TryHashData(
ReadOnlySpan<byte> key,
ReadOnlySpan<byte> source,
Span<byte> destination,
out int bytesWritten);
public static byte[] HashData(byte[] key, Stream source);
public static byte[] HashData(ReadOnlySpan<byte> key, Stream source);
public static int HashData(ReadOnlySpan<byte> key, Stream source, Span<byte> destination);
public static ValueTask<byte[]> HashDataAsync(byte[] key, Stream source, CancellationToken cancellationToken = default);
public static ValueTask<byte[]> HashDataAsync(ReadOnlyMemory<byte> key, Stream source, CancellationToken cancellationToken = default);
public static ValueTask<int> HashDataAsync(
ReadOnlyMemory<byte> key,
Stream source,
Memory<byte> destination,
CancellationToken cancellationToken = default);
}
public partial class HMACSHA3_512 : HMAC {
public const int HashSizeInBits = 512;
public const int HashSizeInBytes = 64;
public HMACSHA3_512();
public HMACSHA3_512(byte[] key);
public static bool IsSupported { get; } // New
public static byte[] HashData(byte[] key, byte[] source);
public static byte[] HashData(ReadOnlySpan<byte> key, ReadOnlySpan<byte> source);
public static int HashData(ReadOnlySpan<byte> key, ReadOnlySpan<byte> source, Span<byte> destination);
public static bool TryHashData(
ReadOnlySpan<byte> key,
ReadOnlySpan<byte> source,
Span<byte> destination,
out int bytesWritten);
public static byte[] HashData(byte[] key, Stream source);
public static byte[] HashData(ReadOnlySpan<byte> key, Stream source);
public static int HashData(ReadOnlySpan<byte> key, Stream source, Span<byte> destination);
public static ValueTask<byte[]> HashDataAsync(byte[] key, Stream source, CancellationToken cancellationToken = default);
public static ValueTask<byte[]> HashDataAsync(ReadOnlyMemory<byte> key, Stream source, CancellationToken cancellationToken = default);
public static ValueTask<int> HashDataAsync(
ReadOnlyMemory<byte> key,
Stream source,
Memory<byte> destination,
CancellationToken cancellationToken = default);
}
public sealed partial class Shake128 : IDisposable {
public Shake128();
public static bool IsSupported { get; }
public void AppendData(byte[] data);
public void AppendData(ReadOnlySpan<byte> data);
public byte[] GetCurrentHash(int outputLength);
public void GetCurrentHash(Span<byte> destination);
public byte[] GetHashAndReset(int outputLength);
public void GetHashAndReset(Span<byte> destination);
public void Dispose();
public static byte[] HashData(byte[] source, int outputLength);
public static byte[] HashData(ReadOnlySpan<byte> source, int outputLength);
public static void HashData(ReadOnlySpan<byte> source, Span<byte> destination);
public static byte[] HashData(Stream source, int outputLength);
public static void HashData(Stream source, Span<byte> destination);
public static ValueTask HashDataAsync(Stream source, Memory<byte> destination, CancellationToken cancellationToken = default);
public static ValueTask<byte[]> HashDataAsync(Stream source, int outputLength, CancellationToken cancellationToken = default);
}
public sealed partial class Shake256 : IDisposable {
public Shake256();
public static bool IsSupported { get; }
public void AppendData(byte[] data);
public void AppendData(ReadOnlySpan<byte> data);
public byte[] GetCurrentHash(int outputLength);
public void GetCurrentHash(Span<byte> destination);
public byte[] GetHashAndReset(int outputLength);
public void GetHashAndReset(Span<byte> destination);
public void Dispose();
public static byte[] HashData(byte[] source, int outputLength);
public static byte[] HashData(ReadOnlySpan<byte> source, int outputLength);
public static void HashData(ReadOnlySpan<byte> source, Span<byte> destination);
public static byte[] HashData(Stream source, int outputLength);
public static void HashData(Stream source, Span<byte> destination);
public static ValueTask HashDataAsync(Stream source, Memory<byte> destination, CancellationToken cancellationToken = default);
public static ValueTask<byte[]> HashDataAsync(Stream source, int outputLength, CancellationToken cancellationToken = default);
}
SHA-3 has been merged, except for SHAKE128 and SHAKE256. I hope to get a pull request open for those in the next week or two.
@vcsjones: Thanks a lot for your work!
Linked to:
Since SHA1 has been known as an "unsafe" algorithm, but now a safer algorithm called "SHA3" is created. So this algorithm should also be included here. Any plans or options for Microsoft now? As far as we see, SHA3 is a little faster than SHA2 and what's more——It's SAFER.
API Proposal v2
The original proposal was outfitted with many annotations for
[SupportedOSPlatform{Guard}]
. We discussed this in the original review and made it a point to revisit this topic. The current thinking now is that we should simply omit the attributes.We have
IsSupported
properties that folks should be using to determine if the platform is supported or not.The platform support may change over time. None of these APIs are inherently OS-specific. If macOS gives us SHA3 APIs we can use later, then we will do so, and the
IsSupported
is the source of truth for this information, not the platform name.The API below is the new proposal. It is the same as the previously approved API, but
[SupportedOSPlatform("XYZ")]
and[SupportedOSPlatformGuard("XYZ")]
have been removed.Old proposal
## API Proposal ```C# namespace System.Security.Cryptography; public partial struct HashAlgorithmName { public static HashAlgorithmName SHA3_256 { get; } public static HashAlgorithmName SHA3_384 { get; } public static HashAlgorithmName SHA3_512 { get; } } public sealed partial class RSAEncryptionPadding { public static RSAEncryptionPadding OaepSHA3_256 { get; } public static RSAEncryptionPadding OaepSHA3_384 { get; } public static RSAEncryptionPadding OaepSHA3_512 { get; } } public abstract partial class SHA3_256 : HashAlgorithm { public const int HashSizeInBits = 256; public const int HashSizeInBytes = 32; protected SHA3_256(); [UnsupportedOSPlatformGuard("ios")] [UnsupportedOSPlatformGuard("tvos")] [UnsupportedOSPlatformGuard("android")] [UnsupportedOSPlatformGuard("browser")] [UnsupportedOSPlatformGuard("osx")] public static bool IsSupported { get; } [UnsupportedOSPlatform("ios")] [UnsupportedOSPlatform("tvos")] [UnsupportedOSPlatform("android")] [UnsupportedOSPlatform("browser")] [UnsupportedOSPlatform("osx")] public static new SHA3_256 Create(); [UnsupportedOSPlatform("ios")] [UnsupportedOSPlatform("tvos")] [UnsupportedOSPlatform("android")] [UnsupportedOSPlatform("browser")] [UnsupportedOSPlatform("osx")] public static byte[] HashData(byte[] source); [UnsupportedOSPlatform("ios")] [UnsupportedOSPlatform("tvos")] [UnsupportedOSPlatform("android")] [UnsupportedOSPlatform("browser")] [UnsupportedOSPlatform("osx")] public static byte[] HashData(ReadOnlySpan