Skip to content

Commit

Permalink
zkproofs
Browse files Browse the repository at this point in the history
  • Loading branch information
mj850 committed Nov 25, 2024
1 parent 0dd0c0f commit e6dd4ac
Show file tree
Hide file tree
Showing 7 changed files with 125 additions and 90 deletions.
53 changes: 24 additions & 29 deletions pkg/zkproofs/ciphertext_ciphertext_equality_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,50 +2,51 @@ 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"

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,
},
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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)
Expand All @@ -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(
Expand Down Expand Up @@ -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)
Expand All @@ -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(
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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,
Expand Down
37 changes: 17 additions & 20 deletions pkg/zkproofs/ciphertext_commitment_equality_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,46 +3,47 @@ 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
expectValid bool
}{
{
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,
Expand All @@ -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

Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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(
Expand Down
8 changes: 4 additions & 4 deletions pkg/zkproofs/ciphertext_validity.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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")
Expand All @@ -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
Expand Down
14 changes: 8 additions & 6 deletions pkg/zkproofs/ciphertext_validity_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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)

Expand All @@ -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)
Expand Down Expand Up @@ -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)
Expand All @@ -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)

Expand Down Expand Up @@ -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)

Expand Down
10 changes: 8 additions & 2 deletions pkg/zkproofs/range.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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")
}
Expand All @@ -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
Expand Down
Loading

0 comments on commit e6dd4ac

Please sign in to comment.