Skip to content

feat: Add authenticated shares with HMAC-SHA256 signatures#9

Open
stevehansen wants to merge 1 commit intodevelopmentfrom
issues/8-authenticated-share
Open

feat: Add authenticated shares with HMAC-SHA256 signatures#9
stevehansen wants to merge 1 commit intodevelopmentfrom
issues/8-authenticated-share

Conversation

@stevehansen
Copy link
Copy Markdown
Owner

Summary

  • Implements GitHub issue AuthenticatedShare #8 to add authentication capabilities to Shamir Secret Sharing
  • Adds HMAC-SHA256 based signatures to detect tampered or corrupted shares
  • Provides temporal validity tracking with optional share expiration

Changes

Core Implementation

  • AuthenticatedShare.cs: New class wrapping regular shares with cryptographic signatures and timestamps
  • IShareAuthenticator.cs: Interface for implementing different authentication strategies
  • HmacShareAuthenticator.cs: HMAC-SHA256 implementation for symmetric key authentication
  • AuthenticatedShamirService.cs: Service orchestrating authenticated share creation and validation

Features

  • Automatic validation of share integrity during reconstruction
  • Optional share expiration for time-bound secrets
  • Flexible authentication through the IShareAuthenticator interface
  • Comprehensive serialization/deserialization for authenticated shares

Documentation

  • Updated README with authenticated shares usage examples
  • Enhanced security paper with authentication vulnerability mitigation
  • Added best practices for key management and share expiration

Test plan

  • Build solution successfully
  • All existing tests pass
  • New test suite covers authenticated share functionality
  • Test tamper detection works correctly
  • Test expiration validation functions properly
  • Test serialization/deserialization round-trips

Closes #8

🤖 Generated with Claude Code

Implements GitHub issue #8 to add authentication capabilities to shares:
- Created AuthenticatedShare class with signature and temporal validity
- Added IShareAuthenticator interface for flexible authentication strategies
- Implemented HmacShareAuthenticator using HMAC-SHA256 for tamper detection
- Created AuthenticatedShamirService for authenticated share operations
- Added comprehensive test suite for authenticated shares
- Updated documentation and security paper with authentication details

This enhancement addresses the vulnerability of traditional SSS to malicious or corrupted shares by providing automatic validation during reconstruction.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
@stevehansen stevehansen linked an issue Sep 1, 2025 that may be closed by this pull request
Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary of Changes

Hello @stevehansen, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the Shamir Secret Sharing library by integrating robust authentication mechanisms. The primary goal is to protect against malicious or accidental tampering of shares and to allow for time-bound secrets. This feature ensures that reconstructed secrets are derived only from valid, untampered, and unexpired shares, thereby increasing the overall security and reliability of the secret sharing process.

Highlights

  • Authenticated Secret Sharing: Introduces the capability to add cryptographic signatures (HMAC-SHA256) to Shamir Secret Shares.
  • Tamper Detection & Temporal Validity: Shares now include HMAC-SHA256 signatures to detect tampering and optional expiration timestamps for temporal validity.
  • New Core Components: Adds AuthenticatedShare, IShareAuthenticator, HmacShareAuthenticator, and AuthenticatedShamirService classes to manage authenticated shares.
  • Automatic Validation: The new service automatically validates share integrity and expiration during reconstruction, throwing exceptions for invalid or expired shares.
  • Flexible Authentication: Provides an IShareAuthenticator interface for custom authentication strategies beyond HMAC-SHA256.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in issue comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a significant and well-implemented feature for authenticated shares using HMAC-SHA256, which greatly enhances the security of the library by providing tamper detection and temporal validity for shares. The implementation is clean, follows good security practices like using constant-time comparison and secure key handling, and is accompanied by thorough tests and documentation updates. My review includes a few suggestions to further improve robustness and maintainability, such as defining a canonical serialization format for signing to prevent future breakages, refining exception handling, and leveraging LINQ for more concise code.

Comment on lines +93 to +112
private static byte[] GetShareData(Share share, DateTimeOffset createdAt, DateTimeOffset? expiresAt)
{
var sb = new StringBuilder();

// Include share data
sb.Append(share.ToString());
sb.Append('|');

// Include creation timestamp
sb.Append(createdAt.ToUnixTimeMilliseconds());

// Include expiration if present
if (expiresAt.HasValue)
{
sb.Append('|');
sb.Append(expiresAt.Value.ToUnixTimeMilliseconds());
}

return Encoding.UTF8.GetBytes(sb.ToString());
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The GetShareData method's reliance on share.ToString() to generate the data for the HMAC signature creates a brittle dependency. If the Share.ToString() method is ever changed for display or logging purposes, it will invalidate all previously generated signatures. The data format for signing should be canonical and stable, defined independently of any display-oriented methods.

    private static byte[] GetShareData(Share share, DateTimeOffset createdAt, DateTimeOffset? expiresAt)
    {
        var sb = new StringBuilder();

        // Use a stable, canonical format for signing, independent of Share.ToString().
        // Format: "X_in_hex:Y_values_in_hex_separated_by_commas|timestamp[|timestamp]"
        sb.Append(share.X.ToString("X", System.Globalization.CultureInfo.InvariantCulture));
        sb.Append(':');
        sb.Append(string.Join(",", share.YValues.Select(y => y.ToString("X", System.Globalization.CultureInfo.InvariantCulture))));
        sb.Append('|');
        
        // Include creation timestamp
        sb.Append(createdAt.ToUnixTimeMilliseconds());
        
        // Include expiration if present
        if (expiresAt.HasValue)
        {
            sb.Append('|');
            sb.Append(expiresAt.Value.ToUnixTimeMilliseconds());
        }

        return Encoding.UTF8.GetBytes(sb.ToString());
    }

Comment on lines +47 to +52
var authenticatedShares = new AuthenticatedShare[shares.Length];
for (var i = 0; i < shares.Length; i++)
{
var signature = _authenticator.SignShare(shares[i], createdAt, expiresAt);
authenticatedShares[i] = new AuthenticatedShare(shares[i], signature, createdAt, expiresAt);
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The for loop used to create authenticatedShares can be expressed more concisely and functionally using LINQ's Select method. This improves readability by making the transformation from a Share to an AuthenticatedShare more declarative.

        var authenticatedShares = shares
            .Select(share =>
            {
                var signature = _authenticator.SignShare(share, createdAt, expiresAt);
                return new AuthenticatedShare(share, signature, createdAt, expiresAt);
            })
            .ToArray();

Comment on lines +173 to +181
try
{
signatureValid = _authenticator.VerifyShare(share);
}
catch (Exception ex)
{
results.Add(new ShareValidationResult(share, false, $"Signature verification failed: {ex.Message}"));
continue;
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The try-catch block for signature verification catches a generic Exception. This is too broad as it can mask unrelated runtime issues (e.g., OutOfMemoryException) or bugs within the VerifyShare implementation. It's a better practice to catch more specific exceptions that are expected from a cryptographic operation, such as System.Security.Cryptography.CryptographicException.

            catch (System.Security.Cryptography.CryptographicException ex)
            {
                results.Add(new ShareValidationResult(share, false, $"Signature verification failed: {ex.Message}"));
                continue;
            }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

AuthenticatedShare

1 participant