[API Proposal]: Support Balloon Hashing

Open
#116,263 4 comments 0 reactions 0 assignees View on GitHub

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

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

api-suggestion area-System.Security
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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from dotnet/runtime

All issues in dotnet/runtime

Similar issues

More C# issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.