From 38281cb0a624b40b4c7249ce6218cdab2c51f110 Mon Sep 17 00:00:00 2001 From: Lucas Menendez Date: Mon, 11 Nov 2024 09:40:53 +0100 Subject: [PATCH] twistedEdwards helpers --- go.mod | 1 + go.sum | 2 + internal/twistededwards/twistededwards.go | 77 +++++++++++++++++++ .../twistededwards/twistededwards_test.go | 22 ++++++ 4 files changed, 102 insertions(+) create mode 100644 internal/twistededwards/twistededwards.go create mode 100644 internal/twistededwards/twistededwards_test.go diff --git a/go.mod b/go.mod index e278700..777f8c4 100644 --- a/go.mod +++ b/go.mod @@ -26,6 +26,7 @@ require ( github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect github.com/consensys/bavard v0.1.22 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/dchest/blake512 v1.0.0 // indirect github.com/fxamacker/cbor/v2 v2.7.0 // indirect github.com/getsentry/sentry-go v0.27.0 // indirect github.com/glendc/go-external-ip v0.1.0 // indirect diff --git a/go.sum b/go.sum index 4688c6a..d627896 100644 --- a/go.sum +++ b/go.sum @@ -34,6 +34,8 @@ github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSV github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dchest/blake512 v1.0.0 h1:oDFEQFIqFSeuA34xLtXZ/rWxCXdSjirjzPhey5EUvmA= +github.com/dchest/blake512 v1.0.0/go.mod h1:FV1x7xPPLWukZlpDpWQ88rF/SFwZ5qbskrzhLMB92JI= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= diff --git a/internal/twistededwards/twistededwards.go b/internal/twistededwards/twistededwards.go new file mode 100644 index 0000000..c50b08b --- /dev/null +++ b/internal/twistededwards/twistededwards.go @@ -0,0 +1,77 @@ +// twistededwards package provides helper functions to transform points (x, y) +// from TwistedEdwards to Reduced TwistedEdwards and vice versa. These functions +// are required because Gnark uses the Reduced TwistedEdwards formula while +// Iden3 uses the standard TwistedEdwards formula. +// See https://github.com/bellesmarta/baby_jubjub for more information. +package twistededwards + +import ( + "math/big" + + "github.com/consensys/gnark-crypto/ecc/bn254/fr" +) + +var scalingFactor, _ = new(big.Int).SetString("6360561867910373094066688120553762416144456282423235903351243436111059670888", 10) + +type Point struct { + X, Y *big.Int +} + +// Convert Reduced TwistedEdwards x' to TwistedEdwards: +// +// x = x'/(-f) +// y' = y +func (p *Point) FromRTEtoTE() *Point { + // Step 1: Convert scalingFactor to fr.Element (mod p) + var f fr.Element + f.SetBigInt(scalingFactor) // f = scalingFactor mod p + + // Step 2: Compute negF = -f mod p + var negF fr.Element + negF.Neg(&f) // negF = -f mod p + + // Step 3: Compute the inverse of negF in the field + var negFInv fr.Element + negFInv.Inverse(&negF) // negFInv = (-f)^{-1} mod p + + xTE := new(fr.Element) + xTE.SetBigInt(p.X) + // Step 4: Multiply g.inner.X by negFInv to get xTE + xRTE := new(fr.Element) + xRTE.Mul(xTE, &negFInv) // xTE = g.inner.X * negFInv mod p + + // Step 5: Convert xTE and g.inner.Y to *big.Int + xRTEBigInt := new(big.Int) + xRTE.BigInt(xRTEBigInt) + return &Point{ + X: xRTEBigInt, // x = x' / (-f) + Y: p.Y, // y' = y + } +} + +// Convert TwistedEdwards to Reduced TwistedEdwards: +// +// x' = x*(-f) +// y = y' +func (p *Point) FromTEtoRTE() *Point { + // Step 1: Convert scalingFactor to fr.Element (mod p) + var f fr.Element + f.SetBigInt(scalingFactor) // f = scalingFactor mod p + + // Step 2: Compute negF = -f mod p + var negF fr.Element + negF.Neg(&f) // negF = -f mod p + + // Step 4: Multiply g.inner.X by negF to get xTE + xRTE := new(fr.Element).SetBigInt(p.X) + xTE := new(fr.Element) + xTE.Mul(xRTE, &negF) // xTE = g.inner.X * -f mod p + + // Step 5: Convert xTE and g.inner.Y to *big.Int + xTEBigInt := new(big.Int) + xTE.BigInt(xTEBigInt) + return &Point{ + X: xTEBigInt, // x' = x * (-f) + Y: p.Y, // y = y' + } +} diff --git a/internal/twistededwards/twistededwards_test.go b/internal/twistededwards/twistededwards_test.go new file mode 100644 index 0000000..e2c2af7 --- /dev/null +++ b/internal/twistededwards/twistededwards_test.go @@ -0,0 +1,22 @@ +package twistededwards + +import ( + "math/big" + "testing" +) + +func TestXxx(t *testing.T) { + p := new(Point) + p.X, _ = new(big.Int).SetString("20284931487578954787250358776722960153090567235942462656834196519767860852891", 10) + p.Y, _ = new(big.Int).SetString("21185575020764391300398134415668786804224896114060668011215204645513129497221", 10) + + expectedRTE, _ := new(big.Int).SetString("5730906301301611931737915251485454905492689746504994962065413628158661689313", 10) + pPrime := p.FromTEtoRTE() + if pPrime.X.Cmp(expectedRTE) != 0 { + t.Errorf("Expected %v, got %v", expectedRTE, pPrime.X) + } + pPrimePrime := pPrime.FromRTEtoTE() + if pPrimePrime.X.Cmp(p.X) != 0 || pPrimePrime.Y.Cmp(p.Y) != 0 { + t.Errorf("Expected %v, got %v", p, pPrimePrime) + } +}