Skip to content

Commit

Permalink
Refactor ZKP class to use ProofProvider for HMAC and salt generation;…
Browse files Browse the repository at this point in the history
… remove old ZKP implementation
  • Loading branch information
asagynbaev committed Jan 2, 2025
1 parent fe55d9b commit c7f4b82
Show file tree
Hide file tree
Showing 5 changed files with 176 additions and 105 deletions.
36 changes: 36 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Changelog

## [Unreleased]

### Added
- New method for range proofs (`ProveRange` and `VerifyRange`).
- Support for time-based proofs (`ProveTimestamp` and `VerifyTimestamp`).
- Support for proving set membership (`ProveSetMembership` and `VerifySetMembership`).

### Changed
- Updated HMAC implementation to use more secure random salts.

### Fixed
- Bug in age verification logic that caused incorrect validation for dates close to the required age.

---

## [1.1.0] - 2025-01-01

### Added
- Proof of Balance feature (`ProveBalance` and `VerifyBalance`).
- Salt generation improvements for stronger proofs.

### Changed
- Refactored `ZKP` class to improve performance and modularity.

### Fixed
- Fixed an issue where incorrect salt generation would sometimes lead to hash mismatches.

---

## [1.0.0] - 2025-01-01

### Initial release
- Proof of Age feature (`ProveAge` and `VerifyAge`).
- Proof of Balance feature (`ProveBalance` and `VerifyBalance`).
26 changes: 18 additions & 8 deletions ZkpSharp.Tests/ZKPTests.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using System;
using Xunit;
using ZkpSharp.Core;
using ZkpSharp.Security;

namespace ZkpSharp.Tests
{
Expand All @@ -8,7 +10,8 @@ public class ZKPTests
[Fact]
public void TestProveAndVerifyAge_ValidAge_ShouldPass()
{
var zkp = new ZKP();
var proofProvider = new ProofProvider();
var zkp = new ZKP(proofProvider);
var dateOfBirth = new DateTime(2000, 1, 1); // Age 25
var (proof, salt) = zkp.ProveAge(dateOfBirth);

Expand All @@ -18,7 +21,8 @@ public void TestProveAndVerifyAge_ValidAge_ShouldPass()
[Fact]
public void TestProveAndVerifyAge_InsufficientAge_ShouldFail()
{
var zkp = new ZKP();
var proofProvider = new ProofProvider();
var zkp = new ZKP(proofProvider);
var dateOfBirth = new DateTime(2010, 1, 1); // Age 15

var exception = Assert.Throws<ArgumentException>(() => zkp.ProveAge(dateOfBirth));
Expand All @@ -28,7 +32,8 @@ public void TestProveAndVerifyAge_InsufficientAge_ShouldFail()
[Fact]
public void TestProveAndVerifyBalance_ValidBalance_ShouldPass()
{
var zkp = new ZKP();
var proofProvider = new ProofProvider();
var zkp = new ZKP(proofProvider);
double userBalance = 1000.0;
double requestedAmount = 500.0;

Expand All @@ -41,7 +46,8 @@ public void TestProveAndVerifyBalance_ValidBalance_ShouldPass()
[Fact]
public void TestProveAndVerifyBalance_InsufficientBalance_ShouldFail()
{
var zkp = new ZKP();
var proofProvider = new ProofProvider();
var zkp = new ZKP(proofProvider);
double userBalance = 300.0;
double requestedAmount = 500.0;

Expand All @@ -53,7 +59,8 @@ public void TestProveAndVerifyBalance_InsufficientBalance_ShouldFail()
[Fact]
public void TestBalanceVerificationWithSalt_ValidBalance_ShouldPass()
{
var zkp = new ZKP();
var proofProvider = new ProofProvider();
var zkp = new ZKP(proofProvider);
double userBalance = 1000.0;
double requestedAmount = 500.0;
var (proof, salt) = zkp.ProveBalance(userBalance, requestedAmount);
Expand All @@ -64,7 +71,8 @@ public void TestBalanceVerificationWithSalt_ValidBalance_ShouldPass()
[Fact]
public void TestBalanceVerificationWithSalt_InsufficientBalance_ShouldFail()
{
var zkp = new ZKP();
var proofProvider = new ProofProvider();
var zkp = new ZKP(proofProvider);
double userBalance = 100.0;
double requestedAmount = 150.0;

Expand All @@ -75,7 +83,8 @@ public void TestBalanceVerificationWithSalt_InsufficientBalance_ShouldFail()
[Fact]
public void TestProveAndVerifyAge_InvalidSalt_ShouldFail()
{
var zkp = new ZKP();
var proofProvider = new ProofProvider();
var zkp = new ZKP(proofProvider);
var dateOfBirth = new DateTime(2000, 1, 1); // Возраст 25 лет
var (proof, salt) = zkp.ProveAge(dateOfBirth);

Expand All @@ -87,7 +96,8 @@ public void TestProveAndVerifyAge_InvalidSalt_ShouldFail()
[Fact]
public void TestBalanceVerificationWithSalt_InvalidSalt_ShouldFail()
{
var zkp = new ZKP();
var proofProvider = new ProofProvider();
var zkp = new ZKP(proofProvider);
double userBalance = 1000.0;
double requestedAmount = 500.0;
var (proof, salt) = zkp.ProveBalance(userBalance, requestedAmount);
Expand Down
62 changes: 62 additions & 0 deletions ZkpSharp/Core/ZKP.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
using ZkpSharp.Security;

namespace ZkpSharp.Core
{
public class ZKP
{
private const int RequiredAge = 18;
private readonly IProofProvider _proofProvider;

public ZKP(IProofProvider proofProvider)
{
_proofProvider = proofProvider;
}

// Proof of Age
public (string Proof, string Salt) ProveAge(DateTime dateOfBirth)
{
if (CalculateAge(dateOfBirth) < RequiredAge)
{
throw new ArgumentException("Insufficient age");
}

string salt = _proofProvider.GenerateSalt();
string proof = _proofProvider.GenerateHMAC(dateOfBirth.ToString("yyyy-MM-dd") + salt);
return (proof, salt);
}

public bool VerifyAge(string proof, DateTime dateOfBirth, string salt)
{
int age = CalculateAge(dateOfBirth);
string calculatedProof = _proofProvider.GenerateHMAC(dateOfBirth.ToString("yyyy-MM-dd") + salt);
return age >= RequiredAge && _proofProvider.SecureEqual(calculatedProof, proof);
}

private int CalculateAge(DateTime dateOfBirth)
{
DateTime today = DateTime.UtcNow;
int age = today.Year - dateOfBirth.Year;
if (dateOfBirth > today.AddYears(-age)) age--;
return age;
}

// Proof of Balance
public (string Proof, string Salt) ProveBalance(double balance, double requestedAmount)
{
if (balance < requestedAmount)
{
throw new ArgumentException("Insufficient balance");
}

string salt = _proofProvider.GenerateSalt();
string proof = _proofProvider.GenerateHMAC(balance.ToString() + salt);
return (proof, salt);
}

public bool VerifyBalance(string proof, double requestedAmount, string salt, double balance)
{
string calculatedProof = _proofProvider.GenerateHMAC(balance.ToString() + salt);
return _proofProvider.SecureEqual(calculatedProof, proof) && balance >= requestedAmount;
}
}
}
60 changes: 60 additions & 0 deletions ZkpSharp/Security/ProofProvider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
using System.Security.Cryptography;
using System.Text;

namespace ZkpSharp.Security
{
public interface IProofProvider
{
string GenerateSalt();
string GenerateHMAC(string input);
bool SecureEqual(string a, string b);
}

public class ProofProvider : IProofProvider
{
private readonly byte[] _hmacKey;

public ProofProvider()
{
_hmacKey = LoadHmacKey();
}

public string GenerateSalt()
{
byte[] saltBytes = new byte[16];
using (var rng = RandomNumberGenerator.Create())
{
rng.GetBytes(saltBytes);
}
return Convert.ToBase64String(saltBytes);
}

public string GenerateHMAC(string input)
{
using (var hmac = new HMACSHA256(_hmacKey))
{
byte[] hashBytes = hmac.ComputeHash(Encoding.UTF8.GetBytes(input));
return Convert.ToBase64String(hashBytes);
}
}

public bool SecureEqual(string a, string b)
{
if (a.Length != b.Length) return false;

int diff = 0;
for (int i = 0; i < a.Length; i++)
{
diff |= a[i] ^ b[i];
}

return diff == 0;
}

private byte[] LoadHmacKey()
{
// Load HMAC key from secure storage
return new byte[32]; // Here we just return a dummy key
}
}
}
97 changes: 0 additions & 97 deletions ZkpSharp/ZKP.cs

This file was deleted.

0 comments on commit c7f4b82

Please sign in to comment.