From e6dd4acf476cb0f1bc0a3f17a11c5132f9ebeb59 Mon Sep 17 00:00:00 2001 From: mj Date: Mon, 25 Nov 2024 17:52:21 -0500 Subject: [PATCH] zkproofs --- .../ciphertext_ciphertext_equality_test.go | 53 +++++++------- .../ciphertext_commitment_equality_test.go | 37 +++++----- pkg/zkproofs/ciphertext_validity.go | 8 +-- pkg/zkproofs/ciphertext_validity_test.go | 14 ++-- pkg/zkproofs/range.go | 10 ++- pkg/zkproofs/range_test.go | 71 ++++++++++++++----- pkg/zkproofs/zero_balance_test.go | 22 +++--- 7 files changed, 125 insertions(+), 90 deletions(-) diff --git a/pkg/zkproofs/ciphertext_ciphertext_equality_test.go b/pkg/zkproofs/ciphertext_ciphertext_equality_test.go index 9af50a3..9ce833b 100644 --- a/pkg/zkproofs/ciphertext_ciphertext_equality_test.go +++ b/pkg/zkproofs/ciphertext_ciphertext_equality_test.go @@ -2,13 +2,14 @@ package zkproofs import ( "encoding/json" + "math/big" + "testing" + "github.com/coinbase/kryptology/pkg/core/curves" "github.com/sei-protocol/sei-cryptography/pkg/encryption/elgamal" testutils "github.com/sei-protocol/sei-cryptography/pkg/testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "math/big" - "testing" ) const TestDenom = "factory/sei15zv4wz8kpa4jz5ahretje97u5xsp9vttvyaffd/testToken" @@ -16,36 +17,36 @@ const TestDenom = "factory/sei15zv4wz8kpa4jz5ahretje97u5xsp9vttvyaffd/testToken" func TestCiphertextCiphertextEqualityProof(t *testing.T) { tests := []struct { name string - sourceAmount uint64 - destinationAmount uint64 + sourceAmount *big.Int + destinationAmount *big.Int useDifferentPublicKey bool expectValid bool }{ { name: "Valid Proof - Equal Amounts", - sourceAmount: 100, - destinationAmount: 100, + sourceAmount: big.NewInt(100), + destinationAmount: big.NewInt(100), useDifferentPublicKey: false, expectValid: true, }, { name: "Invalid Proof - Mismatched Amounts", - sourceAmount: 100, - destinationAmount: 101, + sourceAmount: big.NewInt(100), + destinationAmount: big.NewInt(101), useDifferentPublicKey: false, expectValid: false, }, { name: "Invalid Proof - Wrong Dest Public Key", - sourceAmount: 200, - destinationAmount: 200, + sourceAmount: big.NewInt(200), + destinationAmount: big.NewInt(200), useDifferentPublicKey: true, expectValid: false, }, { name: "Invalid Proof - Different Public Keys and Mismatched Amounts", - sourceAmount: 150, - destinationAmount: 151, + sourceAmount: big.NewInt(150), + destinationAmount: big.NewInt(151), useDifferentPublicKey: true, expectValid: false, }, @@ -78,8 +79,7 @@ func TestCiphertextCiphertextEqualityProof(t *testing.T) { destinationCiphertext, destinationRandomness, err := eg.Encrypt(destinationKeypair.PublicKey, tt.destinationAmount) assert.NoError(t, err, "Encryption should succeed for destinationCiphertext") - srcAmtValue := new(big.Int).SetUint64(tt.sourceAmount) - amount, _ := curves.ED25519().Scalar.SetBigInt(srcAmtValue) + amount, _ := curves.ED25519().Scalar.SetBigInt(tt.sourceAmount) // Generate the proof proof, err := NewCiphertextCiphertextEqualityProof( @@ -118,7 +118,7 @@ func TestCiphertextCiphertextEqualityProof_EdgeCases(t *testing.T) { sourceKeypair, _ := eg.KeyGen(*sourcePrivateKey, TestDenom) destinationKeypair, _ := eg.KeyGen(*destPrivateKey, TestDenom) - amount := uint64(0) + amount := big.NewInt(0) // Encrypt the amount using source and destination public keys sourceCiphertext, _, err := eg.Encrypt(sourceKeypair.PublicKey, amount) @@ -127,8 +127,7 @@ func TestCiphertextCiphertextEqualityProof_EdgeCases(t *testing.T) { destinationCiphertext, destinationRandomness, err := eg.Encrypt(destinationKeypair.PublicKey, amount) assert.NoError(t, err, "Encryption should succeed for destinationCiphertext") - srcAmtValue := new(big.Int).SetUint64(amount) - scalarAmount, _ := curves.ED25519().Scalar.SetBigInt(srcAmtValue) + scalarAmount, _ := curves.ED25519().Scalar.SetBigInt(amount) // Generate the proof proof, err := NewCiphertextCiphertextEqualityProof( @@ -160,7 +159,7 @@ func TestCiphertextCiphertextEqualityProof_EdgeCases(t *testing.T) { destinationKeypair, _ := eg.KeyGen(*destPrivateKey, TestDenom) - amount := uint64(1 << 60) // A large amount to test scalability + amount := big.NewInt(1 << 60) // A large amount to test scalability // Encrypt the amount using source and destination public keys sourceCiphertext, _, err := eg.Encrypt(sourceKeypair.PublicKey, amount) @@ -170,8 +169,7 @@ func TestCiphertextCiphertextEqualityProof_EdgeCases(t *testing.T) { assert.NoError(t, err, "Encryption should succeed for destinationCiphertext") // Generate the proof - scalarAmtValue := new(big.Int).SetUint64(amount) - scalarAmount, _ := curves.ED25519().Scalar.SetBigInt(scalarAmtValue) + scalarAmount, _ := curves.ED25519().Scalar.SetBigInt(amount) // Generate the proof proof, err := NewCiphertextCiphertextEqualityProof( @@ -202,13 +200,12 @@ func TestCiphertextCiphertextEqualityProof_UnmarshalJSON_Valid(t *testing.T) { sourceKeypair, _ := eg.KeyGen(*sourcePrivateKey, TestDenom) destinationKeypair, _ := eg.KeyGen(*destPrivateKey, TestDenom) - amount := uint64(100) + amount := big.NewInt(100) // Encrypt the amount using source and destination public keys sourceCiphertext, _, _ := eg.Encrypt(sourceKeypair.PublicKey, amount) _, destinationRandomness, _ := eg.Encrypt(destinationKeypair.PublicKey, amount) - scalarAmtValue := new(big.Int).SetUint64(amount) - scalarAmount, _ := curves.ED25519().Scalar.SetBigInt(scalarAmtValue) + scalarAmount, _ := curves.ED25519().Scalar.SetBigInt(amount) proof, err := NewCiphertextCiphertextEqualityProof( sourceKeypair, @@ -250,13 +247,12 @@ func TestNewCiphertextCiphertextEqualityProof_InvalidInputs(t *testing.T) { sourceKeypair, _ := eg.KeyGen(*sourcePrivateKey, TestDenom) destinationKeypair, _ := eg.KeyGen(*destPrivateKey, TestDenom) - amount := uint64(100) + amount := big.NewInt(100) // Encrypt the amount using source and destination public keys sourceCiphertext, _, _ := eg.Encrypt(sourceKeypair.PublicKey, amount) _, destinationRandomness, _ := eg.Encrypt(destinationKeypair.PublicKey, amount) - scalarAmtValue := new(big.Int).SetUint64(amount) - scalarAmount, _ := curves.ED25519().Scalar.SetBigInt(scalarAmtValue) + scalarAmount, _ := curves.ED25519().Scalar.SetBigInt(amount) t.Run("Invalid Source Keypair", func(t *testing.T) { // Source keypair is nil @@ -333,13 +329,12 @@ func TestVerifyCiphertextCiphertextEquality_InvalidInputs(t *testing.T) { sourceKeypair, _ := eg.KeyGen(*sourcePrivateKey, TestDenom) destinationKeypair, _ := eg.KeyGen(*destPrivateKey, TestDenom) - amount := uint64(100) + amount := big.NewInt(100) // Encrypt the amount using source and destination public keys sourceCiphertext, _, _ := eg.Encrypt(sourceKeypair.PublicKey, amount) _, destinationRandomness, _ := eg.Encrypt(destinationKeypair.PublicKey, amount) - scalarAmtValue := new(big.Int).SetUint64(amount) - scalarAmount, _ := curves.ED25519().Scalar.SetBigInt(scalarAmtValue) + scalarAmount, _ := curves.ED25519().Scalar.SetBigInt(amount) proof, _ := NewCiphertextCiphertextEqualityProof( sourceKeypair, diff --git a/pkg/zkproofs/ciphertext_commitment_equality_test.go b/pkg/zkproofs/ciphertext_commitment_equality_test.go index c86ce05..5cf81cf 100644 --- a/pkg/zkproofs/ciphertext_commitment_equality_test.go +++ b/pkg/zkproofs/ciphertext_commitment_equality_test.go @@ -3,19 +3,20 @@ package zkproofs import ( "crypto/rand" "encoding/json" + "math/big" + "testing" + "github.com/coinbase/kryptology/pkg/core/curves" "github.com/sei-protocol/sei-cryptography/pkg/encryption/elgamal" testutils "github.com/sei-protocol/sei-cryptography/pkg/testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "math/big" - "testing" ) func TestCiphertextCommitmentEqualityProof(t *testing.T) { tests := []struct { name string - sourceAmount uint64 + sourceAmount *big.Int alternativePedersenCommitment bool incorrectPedersenOpening bool incorrectAmount bool @@ -23,26 +24,26 @@ func TestCiphertextCommitmentEqualityProof(t *testing.T) { }{ { name: "Valid Proof - Equal Amounts and Commitments", - sourceAmount: 100, + sourceAmount: big.NewInt(100), alternativePedersenCommitment: false, expectValid: true, }, { name: "Valid Proof - Equal Amounts and Alternative Commitments", - sourceAmount: 100, + sourceAmount: big.NewInt(100), alternativePedersenCommitment: true, expectValid: true, }, { name: "Invalid Proof - Different Pedersen Opening", - sourceAmount: 200, + sourceAmount: big.NewInt(200), alternativePedersenCommitment: false, incorrectPedersenOpening: true, expectValid: false, }, { name: "Invalid Proof - Incorrect Amount in Pedersen Commitment", - sourceAmount: 200, + sourceAmount: big.NewInt(200), alternativePedersenCommitment: true, incorrectPedersenOpening: false, incorrectAmount: true, @@ -61,14 +62,13 @@ func TestCiphertextCommitmentEqualityProof(t *testing.T) { sourceCiphertext, sourceRandomness, err := eg.Encrypt(sourceKeypair.PublicKey, tt.sourceAmount) assert.NoError(t, err, "Encryption should succeed for sourceCiphertext") - var amountToSet uint64 + amountToSet := new(big.Int) if tt.incorrectAmount { - amountToSet = tt.sourceAmount + 1 + amountToSet = amountToSet.Add(tt.sourceAmount, big.NewInt(1)) } else { amountToSet = tt.sourceAmount } - scalarAmtValue := new(big.Int).SetUint64(amountToSet) - scalarAmount, _ := curves.ED25519().Scalar.SetBigInt(scalarAmtValue) + scalarAmount, _ := curves.ED25519().Scalar.SetBigInt(amountToSet) pedersenCommitment := sourceCiphertext.C @@ -125,13 +125,12 @@ func TestCiphertextCommitmentEqualityProof_MarshalUnmarshalJSON(t *testing.T) { eg := elgamal.NewTwistedElgamal() sourceKeypair, _ := eg.KeyGen(*sourcePrivateKey, TestDenom) - amount := uint64(232436) + amount := big.NewInt(232436) // Encrypt the source amount sourceCiphertext, sourceRandomness, err := eg.Encrypt(sourceKeypair.PublicKey, amount) assert.NoError(t, err, "Encryption should succeed for sourceCiphertext") - scalarAmtValue := new(big.Int).SetUint64(amount) - scalarAmount, _ := curves.ED25519().Scalar.SetBigInt(scalarAmtValue) + scalarAmount, _ := curves.ED25519().Scalar.SetBigInt(amount) // Create a sample CiphertextCommitmentEqualityProof proof, err := NewCiphertextCommitmentEqualityProof( @@ -166,12 +165,11 @@ func TestNewCiphertextCommitmentEqualityProof_InvalidInput(t *testing.T) { eg := elgamal.NewTwistedElgamal() sourceKeypair, _ := eg.KeyGen(*sourcePrivateKey, TestDenom) - amount := uint64(100) + amount := big.NewInt(100) // Encrypt the amount using source and destination public keys sourceCiphertext, sourceRandomness, _ := eg.Encrypt(sourceKeypair.PublicKey, amount) - scalarAmtValue := new(big.Int).SetUint64(amount) - scalarAmount, _ := curves.ED25519().Scalar.SetBigInt(scalarAmtValue) + scalarAmount, _ := curves.ED25519().Scalar.SetBigInt(amount) t.Run("Invalid Source Keypair", func(t *testing.T) { // Source keypair is nil @@ -227,12 +225,11 @@ func TestVerifyCiphertextCommitmentEquality_InvalidInput(t *testing.T) { eg := elgamal.NewTwistedElgamal() sourceKeypair, _ := eg.KeyGen(*sourcePrivateKey, TestDenom) - amount := uint64(100) + amount := big.NewInt(100) // Encrypt the amount using source and destination public keys sourceCiphertext, sourceRandomness, _ := eg.Encrypt(sourceKeypair.PublicKey, amount) - scalarAmtValue := new(big.Int).SetUint64(amount) - scalarAmount, _ := curves.ED25519().Scalar.SetBigInt(scalarAmtValue) + scalarAmount, _ := curves.ED25519().Scalar.SetBigInt(amount) // Generate the proof proof, _ := NewCiphertextCommitmentEqualityProof( diff --git a/pkg/zkproofs/ciphertext_validity.go b/pkg/zkproofs/ciphertext_validity.go index 1efc60b..b1e2429 100644 --- a/pkg/zkproofs/ciphertext_validity.go +++ b/pkg/zkproofs/ciphertext_validity.go @@ -4,9 +4,10 @@ import ( crand "crypto/rand" "encoding/json" "errors" + "math/big" + "github.com/coinbase/kryptology/pkg/core/curves" "github.com/sei-protocol/sei-cryptography/pkg/encryption/elgamal" - "math/big" ) // CiphertextValidityProof represents a zero-knowledge proof that a ciphertext is valid. @@ -23,7 +24,7 @@ type CiphertextValidityProof struct { // - pubKey: The public key used in the encryption. // - ciphertext: The ciphertext to prove the validity of. // - message: The message that was encrypted in the ciphertext. -func NewCiphertextValidityProof(pedersenOpening *curves.Scalar, pubKey curves.Point, ciphertext *elgamal.Ciphertext, message uint64) (*CiphertextValidityProof, error) { +func NewCiphertextValidityProof(pedersenOpening *curves.Scalar, pubKey curves.Point, ciphertext *elgamal.Ciphertext, message *big.Int) (*CiphertextValidityProof, error) { // Validate input if pedersenOpening == nil { return nil, errors.New("invalid randomness factor") @@ -44,8 +45,7 @@ func NewCiphertextValidityProof(pedersenOpening *curves.Scalar, pubKey curves.Po ed25519 := curves.ED25519() // Convert message to a scalar - messageValue := new(big.Int).SetUint64(message) - x, _ := ed25519.Scalar.SetBigInt(messageValue) + x, _ := ed25519.Scalar.SetBigInt(message) // Step 1: Generate random blinding factors for the proof rBlind := ed25519.Scalar.Random(crand.Reader) // Blinding factor for random value r diff --git a/pkg/zkproofs/ciphertext_validity_test.go b/pkg/zkproofs/ciphertext_validity_test.go index ecc557b..7b4e813 100644 --- a/pkg/zkproofs/ciphertext_validity_test.go +++ b/pkg/zkproofs/ciphertext_validity_test.go @@ -2,10 +2,12 @@ package zkproofs import ( "encoding/json" + "math/big" + "testing" + "github.com/sei-protocol/sei-cryptography/pkg/encryption/elgamal" testutils "github.com/sei-protocol/sei-cryptography/pkg/testing" "github.com/stretchr/testify/require" - "testing" ) func TestValidityProof(t *testing.T) { @@ -16,7 +18,7 @@ func TestValidityProof(t *testing.T) { keys, _ := eg.KeyGen(*privateKey, TestDenom) altKeys, _ := eg.KeyGen(*altPrivateKey, TestDenom) - message12 := uint64(12) + message12 := big.NewInt(12) ciphertext12, randomness12, err := eg.Encrypt(keys.PublicKey, message12) require.Nil(t, err) @@ -30,7 +32,7 @@ func TestValidityProof(t *testing.T) { require.False(t, validated, "Validating with the wrong PublicKey should validate as false") // Encrypt a message (e.g., x = 42) - message42 := uint64(42) + message42 := big.NewInt(42) ciphertext42, randomness42, _ := eg.Encrypt(keys.PublicKey, message42) validated = VerifyCiphertextValidity(proof12, altKeys.PublicKey, ciphertext42) @@ -64,7 +66,7 @@ func TestCiphertextValidityProof_MarshalUnmarshalJSON(t *testing.T) { eg := elgamal.NewTwistedElgamal() keys, _ := eg.KeyGen(*privateKey, TestDenom) - message12 := uint64(12) + message12 := big.NewInt(12) ciphertext12, randomness12, _ := eg.Encrypt(keys.PublicKey, message12) original, err := NewCiphertextValidityProof(&randomness12, keys.PublicKey, ciphertext12, message12) @@ -90,7 +92,7 @@ func TestNewCiphertextValidityProof_InvalidInput(t *testing.T) { eg := elgamal.NewTwistedElgamal() keys, _ := eg.KeyGen(*privateKey, TestDenom) - amount := uint64(100) + amount := big.NewInt(100) // Encrypt the amount using source and destination public keys ciphertext, randomness, _ := eg.Encrypt(keys.PublicKey, amount) @@ -136,7 +138,7 @@ func TestVerifyCiphertextValidityProof_Invalid_Input(t *testing.T) { eg := elgamal.NewTwistedElgamal() keys, _ := eg.KeyGen(*privateKey, TestDenom) - amount := uint64(100) + amount := big.NewInt(100) // Encrypt the amount using source and destination public keys ciphertext, randomness, _ := eg.Encrypt(keys.PublicKey, amount) diff --git a/pkg/zkproofs/range.go b/pkg/zkproofs/range.go index 772819d..8811ee6 100644 --- a/pkg/zkproofs/range.go +++ b/pkg/zkproofs/range.go @@ -4,6 +4,8 @@ import ( crand "crypto/rand" "encoding/json" "errors" + "math/big" + "github.com/coinbase/kryptology/pkg/bulletproof" "github.com/coinbase/kryptology/pkg/core/curves" "github.com/gtank/merlin" @@ -24,7 +26,7 @@ type RangeProof struct { // - upperBound The upper bound of the range we want to prove the value lies within, calculated as 2^upperBound // - value: The value encrypted by the ciphertext on which we are creating this proof for // - randomness: The randomness used in the generation of the ciphertext on which we are creating this proof for -func NewRangeProof(upperBound, value int, randomness curves.Scalar) (*RangeProof, error) { +func NewRangeProof(upperBound int, value *big.Int, randomness curves.Scalar) (*RangeProof, error) { if randomness == nil { return nil, errors.New("invalid randomness factor") } @@ -41,7 +43,11 @@ func NewRangeProof(upperBound, value int, randomness curves.Scalar) (*RangeProof proofGenerators := bulletproof.NewRangeProofGenerators(g, h, u) transcript := getTranscript() - vScalar := curve.Scalar.New(value) + vScalar, err := curve.Scalar.SetBigInt(value) + if err != nil { + return nil, err + } + proof, err := prover.Prove(vScalar, randomness, upperBound, proofGenerators, transcript) if err != nil { return nil, err diff --git a/pkg/zkproofs/range_test.go b/pkg/zkproofs/range_test.go index 1f74c81..b560fa1 100644 --- a/pkg/zkproofs/range_test.go +++ b/pkg/zkproofs/range_test.go @@ -3,20 +3,22 @@ package zkproofs import ( crand "crypto/rand" "encoding/json" + "math/big" + "testing" + "github.com/coinbase/kryptology/pkg/bulletproof" "github.com/coinbase/kryptology/pkg/core/curves" "github.com/gtank/merlin" "github.com/sei-protocol/sei-cryptography/pkg/encryption/elgamal" testutils "github.com/sei-protocol/sei-cryptography/pkg/testing" "github.com/stretchr/testify/require" - "testing" ) // Coinbase Kryptology's bulletproof package is used to generate range proofs func TestValueIsInRange(t *testing.T) { curve := curves.ED25519() - value := 100 - v := curve.Scalar.New(value) + value := big.NewInt(100) + v, _ := curve.Scalar.SetBigInt(value) n := 64 // the range is [0, 2^64] privateKey, err := testutils.GenerateKey() @@ -26,7 +28,7 @@ func TestValueIsInRange(t *testing.T) { keyPair, err := eg.KeyGen(*privateKey, TestDenom) require.Nil(t, err, "Error generating key pair") - ciphertext, gamma, _ := eg.Encrypt(keyPair.PublicKey, uint64(value)) + ciphertext, gamma, _ := eg.Encrypt(keyPair.PublicKey, value) prover, err := bulletproof.NewRangeProver(n, []byte("rangeDomain"), []byte("ippDomain"), *curve) require.NoError(t, err) @@ -48,16 +50,17 @@ func TestValueIsInRange(t *testing.T) { require.NoError(t, err) require.True(t, verified) - ciphertext101, _, err := eg.Encrypt(keyPair.PublicKey, uint64(101)) + ciphertext101, _, err := eg.Encrypt(keyPair.PublicKey, big.NewInt(101)) require.Nil(t, err) verified, err = verifier.Verify(proof, ciphertext101.C, proofGenerators, n, transcriptVerifier) require.Error(t, err) require.False(t, verified) } + func TestRangeAttacksAreInfeasible(t *testing.T) { curve := curves.ED25519() - value := 100 - v := curve.Scalar.New(value) + value := big.NewInt(100) + v, _ := curve.Scalar.SetBigInt(value) n := 64 // the range is [0, 2^64] privateKey, err := testutils.GenerateKey() @@ -67,7 +70,7 @@ func TestRangeAttacksAreInfeasible(t *testing.T) { keyPair, err := eg.KeyGen(*privateKey, TestDenom) require.Nil(t, err, "Error generating key pair") - ciphertext, gamma, _ := eg.Encrypt(keyPair.PublicKey, uint64(value)) + ciphertext, gamma, _ := eg.Encrypt(keyPair.PublicKey, value) prover, err := bulletproof.NewRangeProver(n, []byte("rangeDomain"), []byte("ippDomain"), *curve) require.NoError(t, err) @@ -83,7 +86,7 @@ func TestRangeAttacksAreInfeasible(t *testing.T) { // for 90 to 110 generate ciphertexts and see if we can guess the encrypted value for i := 90; i < 110; i++ { transcriptVerifier := merlin.NewTranscript("test") - ct, _, e := eg.Encrypt(keyPair.PublicKey, uint64(i)) + ct, _, e := eg.Encrypt(keyPair.PublicKey, big.NewInt(int64(i))) require.NoError(t, e) verifier, e := bulletproof.NewRangeVerifier(n, []byte("rangeDomain"), []byte("ippDomain"), *curve) @@ -146,7 +149,7 @@ func TestRangeVerifyNotInRangeNegativeValue(t *testing.T) { } func TestRangeProofs(t *testing.T) { - value := 100 + value := big.NewInt(100) n := 64 // the range is [0, 2^64] privateKey, err := testutils.GenerateKey() @@ -156,7 +159,36 @@ func TestRangeProofs(t *testing.T) { keyPair, err := eg.KeyGen(*privateKey, TestDenom) require.Nil(t, err, "Error generating key pair") - ciphertext, gamma, _ := eg.Encrypt(keyPair.PublicKey, uint64(value)) + ciphertext, gamma, _ := eg.Encrypt(keyPair.PublicKey, value) + + proof, err := NewRangeProof(n, value, gamma) + require.Nil(t, err) + + verified, err := VerifyRangeProof(proof, ciphertext, n) + require.NoError(t, err) + require.True(t, verified) + + // Check that a ciphertext with a different value cannot use the same proof to verify as true, even if it meets the requirements. + ciphertext101, _, err := eg.Encrypt(keyPair.PublicKey, big.NewInt(101)) + require.Nil(t, err) + + verified, err = VerifyRangeProof(proof, ciphertext101, n) + require.Error(t, err) + require.False(t, verified) +} + +func TestRangeProofsLargeN(t *testing.T) { + value := big.NewInt(100) + n := 128 // the range is [0, 2^128] + + privateKey, err := testutils.GenerateKey() + require.Nil(t, err, "Error generating private key") + + eg := elgamal.NewTwistedElgamal() + keyPair, err := eg.KeyGen(*privateKey, TestDenom) + require.Nil(t, err, "Error generating key pair") + + ciphertext, gamma, _ := eg.Encrypt(keyPair.PublicKey, value) proof, err := NewRangeProof(n, value, gamma) require.Nil(t, err) @@ -166,7 +198,7 @@ func TestRangeProofs(t *testing.T) { require.True(t, verified) // Check that a ciphertext with a different value cannot use the same proof to verify as true, even if it meets the requirements. - ciphertext101, _, err := eg.Encrypt(keyPair.PublicKey, uint64(101)) + ciphertext101, _, err := eg.Encrypt(keyPair.PublicKey, big.NewInt(101)) require.Nil(t, err) verified, err = VerifyRangeProof(proof, ciphertext101, n) @@ -177,7 +209,7 @@ func TestRangeProofs(t *testing.T) { // We test marshaling and unmarshaling of the range proof this way as bulletproof.RangeProof does not implement Equals // and particular fields are not exported. func TestRangeProofsWithMarshaling(t *testing.T) { - value := 100 + value := big.NewInt(100) n := 64 // the range is [0, 2^64] privateKey, err := testutils.GenerateKey() @@ -187,7 +219,7 @@ func TestRangeProofsWithMarshaling(t *testing.T) { keyPair, err := eg.KeyGen(*privateKey, TestDenom) require.Nil(t, err, "Error generating key pair") - ciphertext, gamma, _ := eg.Encrypt(keyPair.PublicKey, uint64(value)) + ciphertext, gamma, _ := eg.Encrypt(keyPair.PublicKey, value) proof, err := NewRangeProof(n, value, gamma) require.Nil(t, err) @@ -214,12 +246,12 @@ func TestRangeProofs_InvalidInput(t *testing.T) { keyPair, err := eg.KeyGen(*privateKey, TestDenom) require.Nil(t, err, "Error generating key pair") - _, gamma, _ := eg.Encrypt(keyPair.PublicKey, uint64(10)) + _, gamma, _ := eg.Encrypt(keyPair.PublicKey, big.NewInt(10)) t.Run("Invalid upper bound", func(t *testing.T) { // Proof is nil _, err := NewRangeProof( - 0, 0, gamma, + 0, big.NewInt(0), gamma, ) require.EqualError(t, err, "range NewRangeProver: getGeneratorPoints splitPointVector: length of points must be at least one") }) @@ -227,7 +259,7 @@ func TestRangeProofs_InvalidInput(t *testing.T) { t.Run("Invalid randomness factor", func(t *testing.T) { // Proof is nil _, err := NewRangeProof( - 1, 0, nil, + 1, big.NewInt(0), nil, ) require.EqualError(t, err, "invalid randomness factor") }) @@ -236,10 +268,11 @@ func TestRangeProofs_InvalidInput(t *testing.T) { func TestVerifyRangeProof_InvalidInput(t *testing.T) { privateKey, _ := testutils.GenerateKey() eg := elgamal.NewTwistedElgamal() + value := big.NewInt(10) keyPair, _ := eg.KeyGen(*privateKey, TestDenom) - ciphertext, gamma, _ := eg.Encrypt(keyPair.PublicKey, uint64(10)) + ciphertext, gamma, _ := eg.Encrypt(keyPair.PublicKey, value) - proof, err := NewRangeProof(64, 10, gamma) + proof, err := NewRangeProof(64, value, gamma) require.NoError(t, err) t.Run("Nil proof", func(t *testing.T) { diff --git a/pkg/zkproofs/zero_balance_test.go b/pkg/zkproofs/zero_balance_test.go index 8730f66..a2435fe 100644 --- a/pkg/zkproofs/zero_balance_test.go +++ b/pkg/zkproofs/zero_balance_test.go @@ -3,35 +3,37 @@ package zkproofs import ( "crypto/rand" "encoding/json" + "math/big" + "testing" + "github.com/coinbase/kryptology/pkg/core/curves" "github.com/sei-protocol/sei-cryptography/pkg/encryption/elgamal" testutils "github.com/sei-protocol/sei-cryptography/pkg/testing" "github.com/stretchr/testify/require" - "testing" ) func TestZeroBalanceProof(t *testing.T) { tests := []struct { name string - encryptAmount uint64 + encryptAmount *big.Int useDifferentPubKey bool expectValid bool }{ { name: "Valid Proof - Correct Encryption and Commitment", - encryptAmount: 0, + encryptAmount: big.NewInt(0), useDifferentPubKey: false, expectValid: true, }, { name: "Invalid Proof - Non-Zero Value", - encryptAmount: 10000, + encryptAmount: big.NewInt(10000), useDifferentPubKey: false, expectValid: false, }, { name: "Invalid Proof - Different Public Key", - encryptAmount: 0, + encryptAmount: big.NewInt(0), useDifferentPubKey: true, expectValid: false, }, @@ -78,7 +80,7 @@ func TestZeroBalanceProof_MarshalUnmarshalJSON(t *testing.T) { eg := elgamal.NewTwistedElgamal() keypair, _ := eg.KeyGen(*privateKey, TestDenom) - ciphertext, _, _ := eg.Encrypt(keypair.PublicKey, 0) + ciphertext, _, _ := eg.Encrypt(keypair.PublicKey, big.NewInt(0)) original, err := NewZeroBalanceProof(keypair, ciphertext) require.NoError(t, err, "Proof generation should not produce an error") @@ -105,7 +107,7 @@ func TestZeroBalanceProof_InvalidRandomness(t *testing.T) { keypair, err := eg.KeyGen(*privateKey, TestDenom) require.NoError(t, err, "Failed to generate key pair") - ciphertext, _, err := eg.Encrypt(keypair.PublicKey, 0) + ciphertext, _, err := eg.Encrypt(keypair.PublicKey, big.NewInt(0)) require.NoError(t, err, "Failed to encrypt amount") curve := curves.ED25519() @@ -132,7 +134,7 @@ func TestZeroBalanceProof_ExtremelyLargeScalars(t *testing.T) { keypair, err := eg.KeyGen(*privateKey, TestDenom) require.NoError(t, err, "Failed to generate key pair") - ciphertext, _, err := eg.Encrypt(keypair.PublicKey, 0) + ciphertext, _, err := eg.Encrypt(keypair.PublicKey, big.NewInt(0)) require.NoError(t, err, "Failed to encrypt amount") // Manually set Z to an extremely large scalar @@ -162,7 +164,7 @@ func TestZeroBalanceProof_TamperedProof(t *testing.T) { keypair, err := eg.KeyGen(*privateKey, TestDenom) require.NoError(t, err, "Failed to generate key pair") - ciphertext, _, err := eg.Encrypt(keypair.PublicKey, 0) + ciphertext, _, err := eg.Encrypt(keypair.PublicKey, big.NewInt(0)) require.NoError(t, err, "Failed to encrypt amount") // Generate ZeroBalanceProof @@ -236,7 +238,7 @@ func TestVerifyZeroProof_InvalidInput(t *testing.T) { keypair, err := eg.KeyGen(*privateKey, TestDenom) require.NoError(t, err, "Failed to generate key pair") - ciphertext, _, err := eg.Encrypt(keypair.PublicKey, 0) + ciphertext, _, err := eg.Encrypt(keypair.PublicKey, big.NewInt(0)) require.NoError(t, err, "Failed to encrypt amount") proof, err := NewZeroBalanceProof(keypair, ciphertext)