Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 35 additions & 12 deletions pkg/zkproofs/ciphertext_ciphertext_equality.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package zkproofs

import (
"crypto/rand"
"encoding/json"
"errors"

"github.com/coinbase/kryptology/pkg/core/curves"
"github.com/sei-protocol/sei-cryptography/pkg/encryption/elgamal"
)
Expand Down Expand Up @@ -67,10 +67,19 @@ func NewCiphertextCiphertextEqualityProof(
r := *destinationOpening

// Generate random scalars
ed25519 := curves.ED25519()
ys := ed25519.Scalar.Random(rand.Reader)
yx := ed25519.Scalar.Random(rand.Reader)
yr := ed25519.Scalar.Random(rand.Reader)
curve := curves.ED25519()
ys, err := GenerateRandomNonZeroScalar(curve)
if err != nil {
return nil, err
}
yx, err := GenerateRandomNonZeroScalar(curve)
if err != nil {
return nil, err
}
yr, err := GenerateRandomNonZeroScalar(curve)
if err != nil {
return nil, err
}

eg := elgamal.NewTwistedElgamal()
G := eg.GetG()
Expand Down Expand Up @@ -133,16 +142,15 @@ func VerifyCiphertextCiphertextEquality(
sourceCiphertext *elgamal.Ciphertext,
destinationCiphertext *elgamal.Ciphertext,
) bool {
// validate proof for nil values
if proof == nil || proof.Y0 == nil || proof.Y1 == nil || proof.Y2 == nil || proof.Y3 == nil || proof.Zs == nil ||
proof.Zx == nil || proof.Zr == nil {
// validate inputs
if proof == nil || sourcePubKey == nil || destinationPubKey == nil ||
sourceCiphertext == nil || sourceCiphertext.C == nil || sourceCiphertext.D == nil ||
destinationCiphertext == nil || destinationCiphertext.C == nil || destinationCiphertext.D == nil {
return false
}

// validate other input
if sourcePubKey == nil || destinationPubKey == nil ||
sourceCiphertext == nil || sourceCiphertext.C == nil || sourceCiphertext.D == nil ||
destinationCiphertext == nil || destinationCiphertext.C == nil || destinationCiphertext.D == nil {
// validate proof for nil and zero values
if !proof.validateContents() {
return false
}

Expand Down Expand Up @@ -213,6 +221,21 @@ func VerifyCiphertextCiphertextEquality(
return lhsY3.Equal(rhsY3)
}

func (c *CiphertextCiphertextEqualityProof) validateContents() bool {
// Validate that fields are not nil
if c == nil || c.Y0 == nil || c.Y1 == nil || c.Y2 == nil || c.Y3 == nil || c.Zs == nil ||
c.Zx == nil || c.Zr == nil {
return false
}

// Validate that fields are non zero. Though it is technically possible if the randomly generated scalars are zero, it is highly unlikely (1 in 2^255 chance)
if c.Y0.IsIdentity() || c.Y1.IsIdentity() || c.Y2.IsIdentity() || c.Y3.IsIdentity() || c.Zr.IsZero() || c.Zs.IsZero() || c.Zx.IsZero() {
return false
}

return true
}

// MarshalJSON for CiphertextCiphertextEqualityProof
func (p *CiphertextCiphertextEqualityProof) MarshalJSON() ([]byte, error) {
// Serialize the points and scalars to a format you prefer
Expand Down
36 changes: 36 additions & 0 deletions pkg/zkproofs/ciphertext_ciphertext_equality_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -415,4 +415,40 @@ func TestVerifyCiphertextCiphertextEquality_InvalidInputs(t *testing.T) {
)
require.False(t, valid, "Proof verification should fail for nil destination ciphertext")
})

t.Run("Invalid Proof Params", func(t *testing.T) {
// Y2 is zero point
clone := *proof
clone.Y2 = curves.ED25519().NewIdentityPoint()
valid := VerifyCiphertextCiphertextEquality(
&clone,
&sourceKeypair.PublicKey,
&destinationKeypair.PublicKey,
sourceCiphertext,
sourceCiphertext,
)
require.False(t, valid, "Proof verification should fail for proof params with zero value")

clone = *proof
clone.Zx = curves.ED25519().Scalar.Zero()
valid = VerifyCiphertextCiphertextEquality(
&clone,
&sourceKeypair.PublicKey,
&destinationKeypair.PublicKey,
sourceCiphertext,
sourceCiphertext,
)
require.False(t, valid, "Proof verification should fail for proof params with zero value")

clone = *proof
clone.Y1 = nil
valid = VerifyCiphertextCiphertextEquality(
&clone,
&sourceKeypair.PublicKey,
&destinationKeypair.PublicKey,
sourceCiphertext,
sourceCiphertext,
)
require.False(t, valid, "Proof verification should fail for proof params with zero value")
})
}
42 changes: 32 additions & 10 deletions pkg/zkproofs/ciphertext_commitment_equality.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package zkproofs

import (
"crypto/rand"
"encoding/json"
"errors"

"github.com/coinbase/kryptology/pkg/core/curves"
"github.com/sei-protocol/sei-cryptography/pkg/encryption/elgamal"
)
Expand Down Expand Up @@ -59,11 +59,22 @@ func NewCiphertextCommitmentEqualityProof(
G := eg.GetG() // Fixed base point G
H := eg.GetH() // Fixed base point H

ed25519 := curves.ED25519()
// Generate random masking factors
ys := ed25519.Scalar.Random(rand.Reader)
yx := ed25519.Scalar.Random(rand.Reader)
yr := ed25519.Scalar.Random(rand.Reader)
curve := curves.ED25519()
ys, err := GenerateRandomNonZeroScalar(curve)
if err != nil {
return nil, err
}

yx, err := GenerateRandomNonZeroScalar(curve)
if err != nil {
return nil, err
}

yr, err := GenerateRandomNonZeroScalar(curve)
if err != nil {
return nil, err
}

// Compute Y0 = ys * P
Y0 := P.Mul(ys)
Expand Down Expand Up @@ -118,14 +129,13 @@ func VerifyCiphertextCommitmentEquality(
sourceCiphertext *elgamal.Ciphertext,
pedersenCommitment *curves.Point,
) bool {
// Validate proof
if proof == nil || proof.Y0 == nil || proof.Y1 == nil || proof.Y2 == nil || proof.Zs == nil || proof.Zx == nil ||
proof.Zr == nil {
// Validate input
if proof == nil || sourcePubKey == nil || sourceCiphertext == nil || pedersenCommitment == nil {
return false
}

// Validate input
if sourcePubKey == nil || sourceCiphertext == nil || pedersenCommitment == nil {
// Validate proof
if !proof.validateContents() {
return false
}

Expand Down Expand Up @@ -176,6 +186,18 @@ func VerifyCiphertextCommitmentEquality(
return lhsY2.Equal(rhsY2)
}

func (c *CiphertextCommitmentEqualityProof) validateContents() bool {
if c.Y0 == nil || c.Y1 == nil || c.Y2 == nil || c.Zs == nil || c.Zx == nil || c.Zr == nil {
return false
}

if c.Y0.IsIdentity() || c.Y1.IsIdentity() || c.Y2.IsIdentity() || c.Zs.IsZero() || c.Zx.IsZero() || c.Zr.IsZero() {
return false
}

return true
}

// MarshalJSON for CiphertextCommitmentEqualityProof
func (p *CiphertextCommitmentEqualityProof) MarshalJSON() ([]byte, error) {
// Serialize the points and scalars to a format you prefer
Expand Down
33 changes: 33 additions & 0 deletions pkg/zkproofs/ciphertext_commitment_equality_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,39 @@ func TestVerifyCiphertextCommitmentEquality_InvalidInput(t *testing.T) {
require.False(t, valid, "Proof verification should fail for proof with nil fields")
})

t.Run("Invalid Proof Params", func(t *testing.T) {
// Y2 is zero point
clone := *proof
clone.Y2 = curves.ED25519().NewIdentityPoint()
valid := VerifyCiphertextCommitmentEquality(
&clone,
&sourceKeypair.PublicKey,
sourceCiphertext,
&sourceCiphertext.C,
)
require.False(t, valid, "Proof verification should fail for proof params with zero value")

clone = *proof
clone.Zx = curves.ED25519().Scalar.Zero()
valid = VerifyCiphertextCommitmentEquality(
&clone,
&sourceKeypair.PublicKey,
sourceCiphertext,
&sourceCiphertext.C,
)
require.False(t, valid, "Proof verification should fail for proof params with zero value")

clone = *proof
clone.Y1 = nil
valid = VerifyCiphertextCommitmentEquality(
&clone,
&sourceKeypair.PublicKey,
sourceCiphertext,
&sourceCiphertext.C,
)
require.False(t, valid, "Proof verification should fail for proof params with zero value")
})

t.Run("Invalid Source Public Key", func(t *testing.T) {
// Source public key is nil
valid := VerifyCiphertextCommitmentEquality(
Expand Down
32 changes: 27 additions & 5 deletions pkg/zkproofs/ciphertext_validity.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package zkproofs

import (
crand "crypto/rand"
"encoding/json"
"errors"
"math/big"
Expand Down Expand Up @@ -48,8 +47,16 @@ func NewCiphertextValidityProof(pedersenOpening *curves.Scalar, pubKey curves.Po
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
xBlind := ed25519.Scalar.Random(crand.Reader) // Blinding factor for random value x
curve := curves.ED25519()
rBlind, err := GenerateRandomNonZeroScalar(curve) // Blinding factor for random value r
if err != nil {
return nil, err
}

xBlind, err := GenerateRandomNonZeroScalar(curve) // Blinding factor for random value x
if err != nil {
return nil, err
}

// Step 2: Create commitments
rBlindH := H.Mul(rBlind) // rBlind * H
Expand Down Expand Up @@ -88,8 +95,11 @@ func NewCiphertextValidityProof(pedersenOpening *curves.Scalar, pubKey curves.Po
// - ciphertext: The ciphertext to prove the validity of.
func VerifyCiphertextValidity(proof *CiphertextValidityProof, pubKey curves.Point, ciphertext *elgamal.Ciphertext) bool {
// Validate input
if proof == nil || proof.Commitment1 == nil || proof.Commitment2 == nil || proof.Response1 == nil ||
proof.Response2 == nil || pubKey == nil || ciphertext == nil || ciphertext.C == nil || ciphertext.D == nil {
if proof == nil || pubKey == nil || ciphertext == nil || ciphertext.C == nil || ciphertext.D == nil {
return false
}

if !proof.validateContents() {
return false
}

Expand Down Expand Up @@ -119,6 +129,18 @@ func VerifyCiphertextValidity(proof *CiphertextValidityProof, pubKey curves.Poin
return recomputedCommitment1.Equal(proof.Commitment1) && recomputedCommitment2.Equal(proof.Commitment2)
}

func (p *CiphertextValidityProof) validateContents() bool {
if p.Commitment1 == nil || p.Commitment2 == nil || p.Response1 == nil || p.Response2 == nil {
return false
}

if p.Commitment1.IsIdentity() || p.Commitment2.IsIdentity() || p.Response1.IsZero() || p.Response2.IsZero() {
return false
}

return true
}

// MarshalJSON for CiphertextValidityProof
func (p *CiphertextValidityProof) MarshalJSON() ([]byte, error) {
// Serialize the points and scalars to a format you prefer
Expand Down
25 changes: 25 additions & 0 deletions pkg/zkproofs/ciphertext_validity_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"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"
Expand Down Expand Up @@ -155,6 +156,30 @@ func TestVerifyCiphertextValidityProof_Invalid_Input(t *testing.T) {
require.False(t, validated, "Validation should fail for proof with nil fields")
})

t.Run("Invalid Proof Params", func(t *testing.T) {
// Y2 is zero point
clone := *proof
clone.Commitment1 = curves.ED25519().NewIdentityPoint()
valid := VerifyCiphertextValidity(
&clone, keys.PublicKey, ciphertext,
)
require.False(t, valid, "Proof verification should fail for proof params with zero value")

clone = *proof
clone.Response1 = curves.ED25519().Scalar.Zero()
valid = VerifyCiphertextValidity(
&clone, keys.PublicKey, ciphertext,
)
require.False(t, valid, "Proof verification should fail for proof params with zero value")

clone = *proof
clone.Commitment2 = nil
valid = VerifyCiphertextValidity(
&clone, keys.PublicKey, ciphertext,
)
require.False(t, valid, "Proof verification should fail for proof params with zero value")
})

t.Run("Invalid Public Key", func(t *testing.T) {
// Proof challenge is nil
validated := VerifyCiphertextValidity(proof, nil, ciphertext)
Expand Down
28 changes: 24 additions & 4 deletions pkg/zkproofs/pubkey_validity.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package zkproofs

import (
"crypto/rand"
"encoding/json"
"errors"

"github.com/coinbase/kryptology/pkg/core/curves"
"github.com/sei-protocol/sei-cryptography/pkg/encryption/elgamal"
)
Expand Down Expand Up @@ -36,8 +36,13 @@ func NewPubKeyValidityProof(pubKey curves.Point, privKey curves.Scalar) (*PubKey

eg := elgamal.NewTwistedElgamal()
H := eg.GetH()

// Prover generates a random scalar y
y := curves.ED25519().Scalar.Random(rand.Reader)
curve := curves.ED25519()
y, err := GenerateRandomNonZeroScalar(curve)
if err != nil {
return nil, err
}

// Commitment Y = y * H
Y := H.Mul(y)
Expand Down Expand Up @@ -65,9 +70,12 @@ func NewPubKeyValidityProof(pubKey curves.Point, privKey curves.Scalar) (*PubKey
// Parameters:
// - pubKey: The PublicKey to validate.
// - proof: The proof that the prover knows the corresponding PrivateKey.
func VerifyPubKeyValidity(pubKey curves.Point, proof PubKeyValidityProof) bool {
func VerifyPubKeyValidity(pubKey curves.Point, proof *PubKeyValidityProof) bool {
// Validate input
if pubKey == nil || proof.Y == nil || proof.Z == nil {
if proof == nil || pubKey == nil {
return false
}
if !proof.validateContents() {
return false
}

Expand All @@ -92,6 +100,18 @@ func VerifyPubKeyValidity(pubKey curves.Point, proof PubKeyValidityProof) bool {
return lhs.Equal(rhs)
}

func (p *PubKeyValidityProof) validateContents() bool {
if p.Y == nil || p.Z == nil {
return false
}

if p.Y.IsIdentity() || p.Z.IsZero() {
return false
}

return true
}

// MarshalJSON for PubKeyValidityProof
func (p *PubKeyValidityProof) MarshalJSON() ([]byte, error) {
// Serialize the points and scalars to a format you prefer
Expand Down
Loading
Loading