[API Proposal]: Support Balloon Hashing
Nobody has claimed this yet.
Assessment
- Difficulty
- 5/5
- Estimated time
- Over a week
- Newbie friendliness
- 30/100
- Issue type
- Feature
- Clarity
- Mostly clear
- Activity status
- Stale
- Tech stack
- csharp
- Domain
- cryptography, security
Research direction
Start by reviewing the Balloon Hashing specification linked in the issue and the referenced Argon2 and Blake2 discussions (#19933 and #80900). Compare the proposed BalloonHasher API and BalloonParameters with existing System.Security.Cryptography patterns; done means agreeing on the API and implementing the proposal with validation and coverage, though no files or tests are identified here.
Written by the indexing model from the issue text.
Description
Background and motivation
#105745
PBKDF2 has no tolerance toward the offline attack using GPUs.
Unlike Argon2 (https://github.com/dotnet/runtime/issues/19933), Balloon Hashing can be combined with existing standard hash functions like SHA-2.
Additional hash functions like Blake2 (#80900) to be implemented are unnecessary.
https://crypto.stanford.edu/balloon/
Used to be mentioned in the previous revision (3) of the draft of the next version of NIST SP 800-63B.
API Proposal
namespace System.Security.Cryptography;
public partial class BalloonHasher
{
public HashAlgorithmName HashAlgorithm { get; }
public BalloonHasher(HashAlgorithmName hashAlgorithm, int sCost, int tCost, int nThreads);
public BalloonHahser(HashAlgorithmName hashAlgorithm, BalloonParameters parameters);
public int SCost { get; set; }
public int TCost { get; set; }
public int NThreads { get; set; }
public byte[] GetBytes(string passowrd, byte[] salt);
public byte[] GetBytes(byte[] passowrd, byte[] salt);
public byte[] GetBytes(ReadOnlySpan<char> password, ReadOnlySpan<byte> salt);
public byte[] GetBytes(ReadOnlySpan<byte> password, ReadOnlySpan<byte> salt);
public void GetBytes(ReadOnlySpan<char> password, ReadOnlySpan<byte> salt, Span<byte> hash);
public void GetBytes(ReadOnlySpan<byte> password, ReadOnlySpan<byte> salt, Span<byte> hash);
}
public partial class BalloonHahser
{
public static byte[] Balloon(
byte[] password,
byte[] salt,
HashAlgorithmName hashAlgorithm,
BalloonParameters parameters);
public static byte[] Balloon(
ReadOnlySpan<byte> password,
ReadOnlySpan<byte> salt,
HashAlgorithmName hashAlgorithm,
BalloonParameters parameters);
public static void Balloon(
ReadOnlySpan<byte> password,
ReadOnlySpan<byte> salt,
Span<byte> destination,
HashAlgorithmName hashAlgorithm,
BalloonParameters parameters);
public static byte[] Balloon(
string password,
byte[] salt,
HashAlgorithmName hashAlgorithm,
BalloonParameters parameters);
public static byte[] Balloon(
ReadOnlySpan<char> password,
ReadOnlySpan<byte> salt,
HashAlgorithmName hashAlgorithm,
BalloonParameters parameters);
public static void Balloon(
ReadOnlySpan<char> password,
ReadOnlySpan<byte> salt,
Span<byte> destination,
HashAlgorithmName hashAlgorithm,
BalloonParameters parameters);
}
public record struct BalloonParameters(
int SCost,
int TCost,
int NThreads
);
API Usage
using System.Security.Cryprography;
// From https://docs.rs/balloon-hash/latest/balloon_hash/struct.Params.html#fields
var balloon = new BalloonHasher(HashAlgorithmName.SHA256, new BalloonParameters(1024, 3, 1));
var salt = RandomNumberGenerator.GetBytes(16);
var hash = balloon.GetBytess("P@$$w0rD", salt);
Alternative Designs
- PBKDF2: requires huge number of iterations (100K+); no GPU attack tolerance (i.e. not memory-hard at all)
- Argon2: best, but requires an additional hash functions to be implemented (#80900) and has not been approved by NIST
- bcrypt: a little bit legacy, and has a input length limit and the same issues in Argon2
- Yescrypt: has not been mentioned by NIST (apparently approved though). Only used by some recent Linux distributions (e.g. Ubuntu 22.04+, RHEL 10+, Arch, Fedora)
Risks
No risks other than runtime size increase.
- Dominant language
- C#
- Stars
- 18.3k
- Forks
- 5.6k
- Avg merge
- 2d 19h
- Merged PRs (30d)
- 589
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from dotnet/runtime
-
agentic-workflows untriaged
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
-
area-System.Reflection blocking-clean-ci-optional Known Build Error os-mac-os-x untriaged
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
-
area-CodeGen-coreclr untriaged
Difficulty 1/5 Under an hour Newbie friendliness 92/100
-
agentic-workflows untriaged
Difficulty 1/5 Under an hour Newbie friendliness 78/100
-
area-VM-meta-mono untriaged
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
Similar issues
-
bug documentation frontend
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
azurenoops/spin_agent#975 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 86/100
-
:watch: Not Triaged 11.0 fundamentals/subsvc
Difficulty 2/5 1-3 hours Newbie friendliness 92/100
dotnet/AspNetCore.Docs#37699 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
SubtitleEdit/subtitleedit#15108 · 1 comment ·
-
area/docs-content Bug pulumi/docs
Difficulty 1/5 1-3 hours Newbie friendliness 94/100