From a62d6bd75c486e44776fa782a3cf5ff349665740 Mon Sep 17 00:00:00 2001 From: armfazh Date: Thu, 14 May 2020 14:15:02 -0700 Subject: [PATCH] Adding decaf v1.1 and kat tests. --- ecc/goldilocks/constants.go | 34 ++-- ecc/goldilocks/decaf.go | 122 +++++++------ ecc/goldilocks/decaf_test.go | 137 ++++++++++---- .../testdata/decafv1.1_vectors.json | 172 ++++++++++++++++++ ecc/goldilocks/twist.go | 15 +- ecc/goldilocks/twistPoint.go | 13 -- ecc/goldilocks/twist_basemult.go | 16 +- 7 files changed, 378 insertions(+), 131 deletions(-) create mode 100644 ecc/goldilocks/testdata/decafv1.1_vectors.json diff --git a/ecc/goldilocks/constants.go b/ecc/goldilocks/constants.go index c3b1fe044..857fe3956 100644 --- a/ecc/goldilocks/constants.go +++ b/ecc/goldilocks/constants.go @@ -37,10 +37,28 @@ var ( 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, } - // aMinusD is paramA-paramD used for Decaf. - aMinusD = fp.Elt{0xaa, 0x98} - // aMinusD is paramA-paramD used for Decaf. + // paramDTwist is -39082 in Fp. The D parameter of the twist curve. + paramDTwist = fp.Elt{ + 0x55, 0x67, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + } + // aMinusD is paramA-paramD used in Decaf. aMinusDTwist = fp.Elt{0xa9, 0x98} + // sqrtAMinusDTwist is the smallest sqrt(paramATwist-paramDTwist) used in Decaf. + sqrtAMinusDTwist = fp.Elt{ + 0x36, 0x27, 0x57, 0x45, 0x0f, 0xef, 0x42, 0x96, + 0x52, 0xce, 0x20, 0xaa, 0xf6, 0x7b, 0x33, 0x60, + 0xd2, 0xde, 0x6e, 0xfd, 0xf4, 0x66, 0x9a, 0x83, + 0xba, 0x14, 0x8c, 0x96, 0x80, 0xd7, 0xa2, 0x64, + 0x4b, 0xd5, 0xb8, 0xa5, 0xb8, 0xa7, 0xf1, 0xa1, + 0xa0, 0x6a, 0xa2, 0x2f, 0x72, 0x8d, 0xf6, 0x3b, + 0x68, 0xf7, 0x24, 0xeb, 0xfb, 0x62, 0xd9, 0x22, + } // order is 2^446-0x8335dc163bb124b65129c96fde933d8d723a70aadc873d6d54a7bb0d, // which is the number of points in the prime subgroup. order = Scalar{ @@ -66,15 +84,5 @@ var ( 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, } - // paramDTwist is -39082 in Fp. The D parameter of the twist curve. - paramDTwist = fp.Elt{ - 0x55, 0x67, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - } errInvalidDecoding = errors.New("invalid decoding") ) diff --git a/ecc/goldilocks/decaf.go b/ecc/goldilocks/decaf.go index c01afdedd..55452b710 100644 --- a/ecc/goldilocks/decaf.go +++ b/ecc/goldilocks/decaf.go @@ -1,6 +1,8 @@ package goldilocks -import fp "github.com/cloudflare/circl/math/fp448" +import ( + fp "github.com/cloudflare/circl/math/fp448" +) // Decaf provides a prime-order group. // Internally, the implementation uses the twist of goldilocks curve. @@ -29,6 +31,9 @@ func (d Decaf) Order() Scalar { return order } // Add is func (d Decaf) Add(c, a, b *Elt) { c.p = a.p; c.p.Add(&b.p) } +// Double is +func (d Decaf) Double(c, a *Elt) { c.p = a.p; c.p.Double() } + // Neg is func (d Decaf) Neg(c, a *Elt) { c.p = a.p; c.p.cneg(1) } @@ -49,35 +54,30 @@ func (d Decaf) AreEqual(a, b *Elt) bool { // Marshal is func (e *Elt) Marshal() []byte { - r, u := &fp.Elt{}, &fp.Elt{} - one, s := &fp.Elt{}, &fp.Elt{} - x, y, ta, tb, z := e.p.x, e.p.y, e.p.ta, e.p.tb, e.p.z - t0, t1 := z, y + x, ta, tb, z := e.p.x, e.p.ta, e.p.tb, e.p.z + one, t, t2, s := &fp.Elt{}, &fp.Elt{}, &fp.Elt{}, &fp.Elt{} fp.SetOne(one) - fp.AddSub(&t0, &t1) // (t0,t1) = (z+y,z-y) - fp.Mul(&t0, &t0, &t1) // t0 = (z+y)*(z-y) - fp.Mul(&t0, &t0, &aMinusDTwist) // t0 = (a-d)*(z+y)*(z-y) - fp.InvSqrt(r, one, &t0) // r = 1/sqrt( (a-d)*(z+y)*(z-y) ) - fp.Mul(u, r, &aMinusDTwist) // u = (a-d)*r - fp.Mul(&t0, u, &z) // t0 = u*Z - fp.Add(&t0, &t0, &t0) // t0 = 2*u*Z - fp.Neg(&t0, &t0) // t0 = -2*u*Z - isNeg := fp.Parity(&t0) // isNeg = sgn(t0) - fp.Neg(&t1, r) // t1 = -r - fp.Cmov(r, &t1, uint(isNeg)) // if -2*u*Z is negative then r = -r - fp.Mul(&t1, &ta, &tb) // t1 = Ta*Tb = T - fp.Mul(&t1, &t1, &y) // t1 = Y*T - fp.Mul(&t1, &t1, ¶mDTwist) // t1 = d*Y*T - fp.Mul(&t0, &z, &x) // t0 = Z*X - fp.Neg(&t0, &t0) // t0 = a*Z*X - fp.Sub(&t0, &t0, &t1) // t0 = a*Z*X - d*Y*T - fp.Mul(&t0, &t0, r) // t0 = r*(a*Z*X - d*Y*T) - fp.Add(&t0, &t0, &y) // t0 = r*(a*Z*X - d*Y*T) + Y - fp.Mul(s, &t0, u) // s = (u)*(r*(a*Z*X - d*Y*T) + Y) - fp.Neg(s, s) // s = (u/a)*(r*(a*Z*X - d*Y*T) + Y) - isNeg = fp.Parity(s) // isNeg = sgn(s) - fp.Neg(&t1, s) // t1 = -s - fp.Cmov(s, &t1, uint(isNeg)) // if s is negative then s = -s + fp.Mul(t, &ta, &tb) // t = ta*tb + t0, t1 := x, *t // (t0,t1) = (x,t) + fp.Sqr(t2, &x) // t2 = x^2 + fp.AddSub(&t0, &t1) // (t0,t1) = (x+t,x-t) + fp.Mul(&t1, &t0, &t1) // t1 = (x+t)*(x-t) + fp.Mul(&t0, &t1, &aMinusDTwist) // t0 = (a-d)*(x+t)*(x-t) + fp.Mul(&t0, &t0, t2) // t0 = x^2*(a-d)*(x+t)*(x-t) + fp.InvSqrt(&t0, one, &t0) // t0 = 1/sqrt( x^2*(a-d)*(z+y)*(z-y) ) + fp.Mul(&t1, &t1, &t0) // t1 = (z+y)*(z-y)/sqrt( x^2*(a-d)*(z+y)*(z-y) ) + fp.Mul(t2, &t1, &sqrtAMinusDTwist) // t2 = sqrt( (z+y)*(z-y) )/z + isNeg := fp.Parity(t2) // isNeg = sgn(t2) + fp.Neg(t2, &t1) // t2 = -t1 + fp.Cmov(&t1, t2, uint(isNeg)) // if t2 is negative then t1 = -t1 + fp.Mul(s, &t1, &z) // s = t1*z + fp.Sub(s, s, t) // s = t1*z - t + fp.Mul(s, s, &x) // s = x*(t1*z - t) + fp.Mul(s, s, &t0) // s = isr*x*(t1*z - t) + fp.Mul(s, s, &aMinusDTwist) // s = (a-d)*isr*x*(t1*z - t) + isNeg = fp.Parity(s) // isNeg = sgn(s) + fp.Neg(&t0, s) // t0 = -s + fp.Cmov(s, &t0, uint(isNeg)) // if s is negative then s = -s var encS [fp.Size]byte _ = fp.ToBytes(encS[:], s) @@ -85,9 +85,9 @@ func (e *Elt) Marshal() []byte { } // Unmarshal is -func (d Decaf) Unmarshal(b []byte) (*Elt, error) { +func (e *Elt) Unmarshal(b []byte) error { if len(b) < fp.Size { - return nil, errInvalidDecoding + return errInvalidDecoding } s := &fp.Elt{} @@ -95,39 +95,41 @@ func (d Decaf) Unmarshal(b []byte) (*Elt, error) { isNeg := fp.Parity(s) p := fp.P() if isNeg == 1 || !isLessThan(b[:fp.Size], p[:]) { - return nil, errInvalidDecoding + return errInvalidDecoding } - one, u, v, w := &fp.Elt{}, &fp.Elt{}, &fp.Elt{}, &fp.Elt{} + one, s2, den, num := &fp.Elt{}, &fp.Elt{}, &fp.Elt{}, &fp.Elt{} + isr, altx := &fp.Elt{}, &fp.Elt{} t0, t1 := &fp.Elt{}, &fp.Elt{} - e := &Elt{} fp.SetOne(one) - fp.Add(&e.p.x, s, s) // X = 2*s - fp.Sqr(t0, s) // t0 = s^2 - fp.Sub(&e.p.z, one, t0) // Z = 1 + a*s^2 - fp.Mul(t1, t0, ¶mDTwist) // t1 = d*s^2 - fp.Add(t1, t1, t1) // t1 = 2*d*s^2 - fp.Add(t1, t1, t1) // t1 = 4*d*s^2 - fp.Sqr(u, &e.p.z) // u = Z^2 - fp.Sub(u, u, t1) // u = Z^2 - 4*d*s^2 - fp.Mul(t0, t0, u) // t0 = u*s^2 - isQR := fp.InvSqrt(v, one, t0) // v = 1/sqrt(u*s^2) - var isZero byte + fp.Sqr(s2, s) // s2 = s^2 + fp.Sub(den, one, s2) // den = 1 + a*s^2 + fp.Mul(t1, s2, ¶mDTwist) // t1 = d*s^2 + fp.Add(t1, t1, t1) // t1 = 2*d*s^2 + fp.Add(t1, t1, t1) // t1 = 4*d*s^2 + fp.Sqr(t0, den) // num = (1 + a*s^2)^2 + fp.Sub(num, t0, t1) // num = (1 + a*s^2)^2 - 4*d*s^2 + fp.Mul(t0, t0, num) // t0 = num*den^2 + isQR := fp.InvSqrt(isr, one, t0) // v = 1/sqrt(num*den^2) if !isQR { - if !fp.IsZero(t0) { - return nil, errInvalidDecoding - } - isZero = 1 + return errInvalidDecoding } - fp.Mul(t0, u, v) // t0 = u*v - isNeg = fp.Parity(t0) // isNeg = sgn(u*v) - fp.Neg(t1, v) // t1 = -v - fp.Cmov(v, t1, uint(isNeg)) // if u*v is negative then v = -v - fp.Sub(w, &fp.Elt{2}, &e.p.z) // w = 2-Z - fp.Mul(w, w, s) // w = s*(2-Z) - fp.Mul(w, w, v) // w = v*s*(2-Z) - fp.Add(w, w, &fp.Elt{isZero}) // if s=0 then w = w+1 - fp.Mul(&e.p.y, &e.p.z, w) // Y = w*Z - e.p.ta, e.p.tb = e.p.x, *w // T = Ta*Tb = w*X - return e, nil + fp.Mul(t1, den, isr) // altx = isr*den + fp.Mul(t1, t1, s) // altx = s*isr*den + fp.Add(t1, t1, t1) // t1 = 2*s*isr*den + fp.Mul(altx, t1, &sqrtAMinusDTwist) // altx = 2*s*isr*den*sqrt(A-D) + isNeg = fp.Parity(altx) // isNeg = sgn(altx) + fp.Neg(t0, isr) // t0 = -isr + fp.Cmov(isr, t0, uint(isNeg)) // if altx is negative then isr = -isr + fp.Sqr(&e.p.x, isr) // x = isr^2 + fp.Mul(&e.p.x, &e.p.x, den) // x = isr^2*den + fp.Mul(&e.p.x, &e.p.x, num) // x = isr^2*den*num + fp.Mul(&e.p.x, &e.p.x, s) // x = s*isr^2*den*num + fp.Add(&e.p.x, &e.p.x, &e.p.x) // x = 2*s*isr^2*den*num + fp.Mul(&e.p.y, isr, den) // y = isr*den + fp.Add(t0, one, s2) // t0 = 1 - a*s^2 + fp.Mul(&e.p.y, &e.p.y, t0) // y = (1 - a*s^2)*isr*den + e.p.ta, e.p.tb = e.p.x, e.p.y // T = Ta*Tb = x*y + fp.SetOne(&e.p.z) + return nil } diff --git a/ecc/goldilocks/decaf_test.go b/ecc/goldilocks/decaf_test.go index 07babbe11..c0e4c03f3 100644 --- a/ecc/goldilocks/decaf_test.go +++ b/ecc/goldilocks/decaf_test.go @@ -1,9 +1,13 @@ package goldilocks_test import ( + "bytes" "crypto/rand" "encoding/hex" + "encoding/json" "fmt" + "io/ioutil" + "os" "testing" "github.com/cloudflare/circl/ecc/goldilocks" @@ -12,40 +16,107 @@ import ( func TestDecafDevel(t *testing.T) { var d goldilocks.Decaf + var P goldilocks.Elt + G := d.Generator() - fmt.Printf("G: %v\n%v\n\n", G, hex.EncodeToString(G.Marshal())) - - Q := d.Identity() - for i := 0; i < 18; i++ { - enc := Q.Marshal() - decP, err := d.Unmarshal(enc) - if err != nil { - t.Fatalf("dd") - } - got := d.AreEqual(Q, decP) - want := true - if got != want { - fmt.Printf("%v\n", Q) - fmt.Printf("%v\n", decP) - test.ReportError(t, got, want, i) - } - d.Add(Q, Q, G) + d.Double(G, G) + encG := G.Marshal() + P.Unmarshal(encG) + encP := P.Marshal() + // fmt.Printf("G: %v\n", G) + fmt.Printf("encG: %v\n", hex.EncodeToString(encG)) + // fmt.Printf("P: %v\n", P) + fmt.Printf("valid: %v\n", d.IsValid(&P)) + fmt.Printf("equal: %v\n", d.AreEqual(G, &P)) + fmt.Printf("encP: %v\n", hex.EncodeToString(encP)) + +} + +type testJSONFile struct { + Group string `json:"group"` + Version string `json:"version"` + Generator struct { + X string `json:"x"` + Y string `json:"y"` + T string `json:"t"` + Z string `json:"z"` + } `json:"generator"` + Vectors []struct { + K string `json:"k"` + KG string `json:"kG"` + KP string `json:"kP"` + } `json:"vectors"` +} + +func (kat *testJSONFile) readFile(t *testing.T, fileName string) { + jsonFile, err := os.Open(fileName) + if err != nil { + t.Fatalf("File %v can not be opened. Error: %v", fileName, err) + } + defer jsonFile.Close() + input, _ := ioutil.ReadAll(jsonFile) + + err = json.Unmarshal(input, &kat) + if err != nil { + t.Fatalf("File %v can not be loaded. Error: %v", fileName, err) + } +} + +func verify(t *testing.T, i int, gotkG *goldilocks.Elt, wantEnckG []byte) { + var d goldilocks.Decaf + wantkG := &goldilocks.Elt{} + + gotEnckG := gotkG.Marshal() + got := bytes.Equal(gotEnckG, wantEnckG) + want := true + if got != want { + test.ReportError(t, got, want, i) + } + + err := wantkG.Unmarshal(wantEnckG) + got = err == nil && + d.IsValid(gotkG) && + d.IsValid(wantkG) && + d.AreEqual(gotkG, wantkG) + want = true + if got != want { + test.ReportError(t, got, want, i) + } +} + +func TestDecafv1_1(t *testing.T) { + var kat testJSONFile + kat.readFile(t, "testdata/decafv1.1_vectors.json") + + got := kat.Group + want := "decaf" + if got != want { + test.ReportError(t, got, want) + } + got = kat.Version + want = "v1.1" + if got != want { + test.ReportError(t, got, want) + } + var d goldilocks.Decaf + var scalar goldilocks.Scalar + var P goldilocks.Elt + + for i := range kat.Vectors { + k, _ := hex.DecodeString(kat.Vectors[i].K) + wantEnckG, _ := hex.DecodeString(kat.Vectors[i].KG) + wantEnckP, _ := hex.DecodeString(kat.Vectors[i].KP) + scalar.FromBytes(k) + + d.MulGen(&P, &scalar) + verify(t, i, &P, wantEnckG) + + d.Mul(&P, &scalar, d.Generator()) + verify(t, i, &P, wantEnckG) + + d.Mul(&P, &scalar, &P) + verify(t, i, &P, wantEnckP) } - // fmt.Printf("2GE: %v\n%v\n\n", GE, enc(GE)) - - // GT := c.push(GE) - // GT.ToAffine() - // fmt.Printf("GT: %v\n%v\n", GT, enc(GT)) - - // fmt.Printf("0: %v\n", hex.EncodeToString(d.Marshal(d.Identity()))) - // fmt.Printf("G: %v\n", hex.EncodeToString(d.Marshal(d.Generator()))) - // P := d.Generator() - // fmt.Printf("G:\n%v\n%v\n", P, hex.EncodeToString(d.Marshal(P))) - // for i := 1; i < 2; i++ { - // P = d.Add(P, P) - // fmt.Printf("[2^%v]G:\n%v\n", i, P) - // fmt.Printf("[2^%v]G: %v\n", i, hex.EncodeToString(d.Marshal(P))) - // } } func BenchmarkDecaf(b *testing.B) { @@ -79,7 +150,7 @@ func BenchmarkDecaf(b *testing.B) { }) b.Run("Unmarshal", func(b *testing.B) { for i := 0; i < b.N; i++ { - d.Unmarshal(enc) + P.Unmarshal(enc) } }) } diff --git a/ecc/goldilocks/testdata/decafv1.1_vectors.json b/ecc/goldilocks/testdata/decafv1.1_vectors.json new file mode 100644 index 000000000..ef0989bf8 --- /dev/null +++ b/ecc/goldilocks/testdata/decafv1.1_vectors.json @@ -0,0 +1,172 @@ +{ + "group": "decaf", + "version": "v1.1", + "generator": { + "x": "7ffffffffffffffffffffffffffffffffffffffffffffffffffffffe80000000000000000000000000000000000000000000000000000000", + "y": "8508de14f04286d48d06c13078ca240805264370504c74c393d5242c5045271414181844d73f48e5199b0c1e3ab470a1c86079b4dfdd4a64", + "t": "6d3669e173c6a450e23d5682a9ffe1ddc2b86da60f794be956382384a319b57519c9854dde98e342140362071833f4e093e3c816dc198105", + "z": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001" + }, + "vectors": [ + { + "k": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "kG": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "kP": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + }, + { + "k": "0100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "kG": "6666666666666666666666666666666666666666666666666666666633333333333333333333333333333333333333333333333333333333", + "kP": "6666666666666666666666666666666666666666666666666666666633333333333333333333333333333333333333333333333333333333" + }, + { + "k": "0200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "kG": "c898eb4f87f97c564c6fd61fc7e49689314a1f818ec85eeb3bd5514ac816d38778f69ef347a89fca817e66defdedce178c7cc709b2116e75", + "kP": "b46f1836aa287c0a5a5653f0ec5ef9e903f436e21c1570c29ad9e5f596da97eeaf17150ae30bcb3174d04bc2d712c8c7789d7cb4fda138f4" + }, + { + "k": "0300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "kG": "a0c09bf2ba7208fda0f4bfe3d0f5b29a543012306d43831b5adc6fe7f8596fa308763db15468323b11cf6e4aeb8c18fe44678f44545a69bc", + "kP": "20d41d85a18d5657a29640321563bbd04c2ffbd0a37a7ba43a4f7d263ce26faf4e1f74f9f4b590c69229ae571fe37fa639b5b8eb48bd9a55" + }, + { + "k": "0400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "kG": "b46f1836aa287c0a5a5653f0ec5ef9e903f436e21c1570c29ad9e5f596da97eeaf17150ae30bcb3174d04bc2d712c8c7789d7cb4fda138f4", + "kP": "66e5cf59220cec1b47914ff83187a90d731ca77ee4f00115e610e5798f19dd9cf38293aeef6aec91ae1b50cb09d7e2434806ff29d2a86170" + }, + { + "k": "0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "kG": "1c5bbecf4741dfaae79db72dface00eaaac502c2060934b6eaaeca6a20bd3da9e0be8777f7d02033d1b15884232281a41fc7f80eed04af5e", + "kP": "642336c69b7b755769131248fedd3764f139ca44cc5d982b518f85e3516e2ce565706a775193512225cded5ff7ec538f3d0e485158199424" + }, + { + "k": "0600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "kG": "86ff0182d40f7f9edb7862515821bd67bfd6165a3c44de95d7df79b8779ccf6460e3c68b70c16aaa280f2d7b3f22d745b97a89906cfc476c", + "kP": "dea6945dfffc6e52d3de765fb9ff7dab52bd4b264951d3350b3f1ba25cf6b9bfed3682e1a93e85e4d14e5e4cfcc24055cfcc20da76f37482" + }, + { + "k": "0700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "kG": "502bcb6842eb06f0e49032bae87c554c031d6d4d2d7694efbf9c468d48220c50f8ca28843364d70cee92d6fe246e61448f9db9808b3b2408", + "kP": "7c4ef65864d5de7b2b8a25086d4725754fa64e9784b2f9a55f7f9887a1732c7f13fab453081415328a877bf6eca6d1bd55344a9c12971304" + }, + { + "k": "0800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "kG": "0c9810f1e2ebd389caa789374d78007974ef4d17227316f40e578b336827da3f6b482a4794eb6a3975b971b5e1388f52e91ea2f1bcb0f912", + "kP": "d4cd125d65012e419e73383162837aa4eef1da706d3e8ba1eb9b86116f0a15feea9ab6195db555b8e9b5894f20a39a03131eb4e2ef645403" + }, + { + "k": "0900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "kG": "20d41d85a18d5657a29640321563bbd04c2ffbd0a37a7ba43a4f7d263ce26faf4e1f74f9f4b590c69229ae571fe37fa639b5b8eb48bd9a55", + "kP": "887f28cc15265462ceaf1cf701612ffc1505cc686c9ba355a95cbffbb03c4863a94ddb91e40f4a3de06a6da6b715540c6d05b1654a80d956" + }, + { + "k": "0a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "kG": "e6b4b8f408c7010d0601e7eda0c309a1a42720d6d06b5759fdc4e1efe22d076d6c44d42f508d67be462914d28b8edce32e7094305164af17", + "kP": "e8b29a0ac41f194f8a5d8f33970dd0f2004877788924d8be7b545eb65bd7079bf0252f87af7fea46deac9678857ccd2b89ea39e3b91338cc" + }, + { + "k": "0b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "kG": "be88bbb86c59c13d8e9d09ab98105f69c2d1dd134dbcd3b0863658f53159db64c0e139d180f3c89b8296d0ae324419c06fa87fc7daaf34c1", + "kP": "4adbe973f6a0390030cf094306ad65d826e6ce856e3f89713b1dfb5cef5bf388fbf413dd0c6cff477030c17f4c6a648410d79c8b75da224d" + }, + { + "k": "0c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "kG": "a456f9369769e8f08902124a0314c7a06537a06e32411f4f93415950a17badfa7442b6217434a3a05ef45be5f10bd7b2ef8ea00c431edec5", + "kP": "8262db825edabdd8a621fb309c5d0276137b72ac15b5d85442e2ca18f4dc8907bf39511295d2271ed040c27f17f00b38fd5d3d8cc922868e" + }, + { + "k": "0d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "kG": "186e452c4466aa4383b4c00210d52e7922dbf9771e8b47e229a9b7b73c8d10fd7ef0b6e41530f91f24a3ed9ab71fa38b98b2fe4746d51d68", + "kP": "3637f9cc7e147b6c23199c4bd9e21aa2eb30b6bdc656e7cb42a14b713f8e5bee177641283a939f0b88b39ac351828adaa2426afa6943b1c8" + }, + { + "k": "0e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "kG": "4ae7fdcae9453f195a8ead5cbe1a7b9699673b52c40ab27927464887be53237f7f3a21b938d40d0ec9e15b1d5130b13ffed81373a53e2b43", + "kP": "1e27c8c3eb1c97c1c1a32e0cc5ce985ba5d6a1bd243dca8fc3c98846ccae8867ab0493dcd1956e08c4d28d50fc52ca1b90423adecd879555" + }, + { + "k": "0f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "kG": "841981c3bfeec3f60cfeca75d9d8dc17f46cf0106f2422b59aec580a58f342272e3a5e575a055ddb051390c54c24c6ecb1e0aceb075f6056", + "kP": "ca51d5471817aa93af04519dadadb310c1cee4a787ad5ed5b61ff97205e47a4d872235d5c6248e1d93ea99eb0aef1343c0d4ecbc2ad017ed" + }, + { + "k": "1ea7a181770d59e9a6b8ead99331d9506d4351be35fc9383ae4da749c79b4a2f1dc549050a112133b2ee0b7fe248556caec2d6445a1198a0", + "kG": "36b24b0eebcc486b760b4ccf05a23e867f6867848f37fa5ba69a377313f1db677c4b8d970c3692f61e90516d66652a76fd02a95ace6f9037", + "kP": "2e575be97ff2ca36cd97f948d2baad4c906cf9141dbeb1225281147e28e771b8e976eae7f475c721acc69647eb981ce5fdf0000e77f0d62f" + }, + { + "k": "23f1bfbbef181839548507c0f0f908ec9d756f2ec09aa50cfb8ab04f69d3d3a41710d36da1b27ab4039b83a232ab6651b76d29e335f3b442", + "kG": "7cfc97b493d9ab871cd633fc13b9f55f41385b144871752185210251a011c48bd4a0a28cf52206c71d9ac7250782b422efbd09a43a7048ed", + "kP": "c6369834822de8dbb11a7daa8209dbd5bf914fd4ec57af7130b97c98cf064d5426c567fc946f87660c3c7beb2beac345753f26e55c0c05b2" + }, + { + "k": "2c613d4f00fe3a5307d20c6d2aff0059f182b09a4cb69cce212d383ca17e73895925174c1c9929b0719522661688f8853f324fd391ec37da", + "kG": "e08c867b098522b6cc8fb89ac1a78ba2fc0cfc0083a55745a51e86e5c9d27f637f04dddb222d3a750400b194f8c7c58e78987771606e3134", + "kP": "86e047f1bd6b6d921e3f620c229fb3a7b3b24f53a8ef20d5e4e6b651f4fcd87474d66e9e127dcec00af95b5754fe095287190549d0c6f795" + }, + { + "k": "93db3f44d941f8365242671e81064f43189763a8a092e17b848691e6c2be4063b082e6dc0d85e8a22eca39b60809298a91c63257c4424301", + "kG": "88de6be5897853c9fc99a5c0f2296c3eac8760bd84812a213684fd2c20a8304ab18efb76eb4f3133331321018cd8bb07c8cc8b1603c1d7b9", + "kP": "a2c5561d986b96fe871a34523c541952ea1ab7b2af260c2b2d7b9ac43dcba50a6da59a7208ba73efc24466964bca7358986cbc0e0047c5f8" + }, + { + "k": "d18f08269d1d347762cb81f4f0bc0a7d0a383d4ea8b8e7467bd9be6b76d1640e36e73d845d2bcbe036fddd2fb5bf5b7d13ce404b59865d62", + "kG": "6222020e4ad10cdf53a4822452737df9cfb07911063b23f8976e474007e22a51c48ed4771551e69d686c3a6c7725d4c86f414a319bac9cd8", + "kP": "ca336b5797ed63844852ed6649482f3600db2cac33ba425dc69db61fc0017894796011f1c0d96437204ebeee6d4ced8867051904ab9fcf7b" + }, + { + "k": "8d7b69eb3b6b36eed70d0a54c39d39f257c1906c7b52605fe7b04f9b060b721b41bc8c644ed1e4f2b4c82b77b4449748445b0d8c876239ec", + "kG": "ac0323ae3646d9239fcc311594fb065e6d6f24639b3abcd6ee81bde5ef5091e5fa1f17263c763bc600c0bebafb753495ab8e60414ac460c0", + "kP": "0819fbff59e7432e3ad62da1540ca8ae088962a6e12228d1fb14dd66c403208145f26fd5d53bf8253fa826a58182e4bb8432eca8432e7748" + }, + { + "k": "7eaf72ecd8e18e4e685fcdb57be89ffe9f3af97ebd3407a66e8e3da9aaaf64bdbb534c18e35758ed6a53f0d90c765b05d2d3c488d6d1d401", + "kG": "a6d3ca8dfdef261e1cbe7196ff22cac001aa5f882ff665ced2417329b7ed361733d6f010f829b08ccdf05a74ba1c4ffb91fbeb49ec9e8436", + "kP": "386f5e4ba9aee0ad1a75a9f4727f320898448ab6ed4b3e9c63fe985d756eb5e15513f1f2c345b1aa7a8573c33503e6f4a06f7cf73d1bccdd" + }, + { + "k": "4e95b175be6d04d4e2a6955523e93bcf4e7abf184faa895d99ba1e36fe08c166565423f75e4a434f3118f855dc4bb4063e46f2d0a79c37f6", + "kG": "504e5b66e93821cdcc29d6983e23eedd3072fb7e4c2a4243db57731dc0cc5c5c8db6fda9f79f58f9d93b55c4b8a3e79379ae2319e63b4e60", + "kP": "fcc4381046fd71f73ad5b8b178fe38a864077eb872bf2a27743051a97662c01805fb9f521ec43a8227905ced1e13af37993f616f0f4ac481" + }, + { + "k": "46ba584c9487732ad67478658d64230d3544f8b4664e13332dcab98e7d0dcc94d7ce4a27ebae4d668d05e96ec8c96f41e115ab538fc122cd", + "kG": "b210305cb5b7f0ba69bbc1ae315f3eed7e9e0b1c303fe63dcc9c9e158a6a207177b4ea12093fbbd8c9127dc25f479288b3777958d4d068f8", + "kP": "127df4e08289c206dbb11699b3d0c7bae0e6c32d4cff653b9f5c29570b2c247a88a9f83f4862973773f5be99e09af363cbae0e1169b8fd9a" + }, + { + "k": "f92816a0ecaf336d75739a3ca90ff9b44fd7b080fb6787048d1f41dfad2c544909125ced85b6ed5850c191219748d42ca599c559a8451c07", + "kG": "90a032eb6af46877f1e3090c489a857f3c179a9e725d8bbec5182728c84d9ff0a245dd89a4af0e40a18e65c1410d92044553671becccea1a", + "kP": "8828e7fd31ff8a3c14ef3ee3b65cd3a85420940bf85ad4184808043caf9ec1328c913ee17532bb2a7c43f244c38e068d05208b88bded7aeb" + }, + { + "k": "491431d53119db34cdd44eef94d2d17227102ca382491ea64a382d6d5b027160b04fde56a7305e378c490b6049bf63dce837230a9a8eaaec", + "kG": "522a1ac2cf16dbc27829cd8efae0c12469fe30cb162262dcaf9ac434ebfb243798a8e25cba0aed8ccb960c37f05035bdbaa8bef86abbbd15", + "kP": "8e01bb0e0a1a0a214b7623a17b8aaf721624ef25d927b8c189570add96c03bdf55d584be7484adb27ff8ebe1f4a610956945a30628c99765" + }, + { + "k": "3a01fa0be1a79ecd5f7956313ac9d8355aebfa0ad649cd343407068310e2591f43e9585488f9488c97270501cec551c0ef093120c575a449", + "kG": "ba896e4bdefd8048b8bcd00a1a344ca7a678c196ffac44187fc72f5c6a9d6b712962898bf3844f2ed610d53738a15f6d502c2022c8f978e4", + "kP": "6849368ee781fc3fc68057ee29824e6b44c5f5358bd45f83117163a4411fa28ba5a1195055adcbfd2ecacccb06684033229514c596d0cc0d" + }, + { + "k": "2b95e89d6e845b4d3646635f281534a82744f165a64e43cc194a49f5641d50b63e4b5e6750b6b009fb3bccebbbf98783cb6b965fe8f990f4", + "kG": "4c57b2c544c4c55989171afe46c4f3bab1d7de4a3ce9f8e40d94293961b1efb74b0e5d3fe442f6e416fc31f00d2fb65ec0f95ef6181157ba", + "kP": "42cd791699d7c20886f2e5c4eb75613c7dfb0706e58740e4e7ce05345d6527035335e40c881d48de8fe59b33efbaff3d8736a08e13739e20" + }, + { + "k": "ebebda771cc393263ac2390d205cf99e10cd6a84a1099845661ace2792e10fa515c8560f04d59ba5819e6ec3c50b4350d3e32c4bca3a0c4d", + "kG": "44aece93acef3827dd6d89db95ab5cdba97f6c125f3a9a3626580664b51e2e5ca43ecd4e9a07a5b0e2e72e604aa79d5c5df499094c1ae97b", + "kP": "70d136e82612d108dbd86e55e8466985fcf868ff3cdd636038bee0cf7ce914752c25adfa505d7a990c725d6de0c6264d00252877228b8a14" + }, + { + "k": "18359b58aebe2ef41cd078ed7c9d3d39585d46169aba3f96e66ba5f71b99193448c403232d308c7b47bf33af6c69a3cab097a5107b907a2d", + "kG": "0c946158762a885db0e97c34618a7b14badf85bc5b8554d9e3d0aae6f541570d72708bfc080a8b05c9e9410796bc0a0a4e5faf8861c9c35d", + "kP": "542311f85756629b8341439f2432ae9cb772d5f4764df5ca57028e5abf2ed09785dafcc7ed574503505f9739fd0327663a0a0d7795cc468b" + }, + { + "k": "57de42ebc90f7ef00ba7f2b86bc8fa350d1784fc3cec43e3fd7b2a92399c80f8b7477105c70f3c2b76bf4b8c77555326c67c97c32d84f3c3", + "kG": "e060cb072f1cb748b00e8e40d256e929025b9c59e1cc463cef3bedd257ee65756e65789f5701ce0a6e852fabe4797d365bb8cc47302a88cc", + "kP": "366a1cd595c5a975b99845c4ec698e1ddd83789ceea49af39afb60cb4d564dcba5657ee73a073452f00391f11889dde96d8f8096dd68fb5c" + } + ] +} diff --git a/ecc/goldilocks/twist.go b/ecc/goldilocks/twist.go index cb3afd48d..0a4928346 100644 --- a/ecc/goldilocks/twist.go +++ b/ecc/goldilocks/twist.go @@ -86,17 +86,20 @@ func (e twistCurve) ScalarMult(k *Scalar, P *twistPoint) *twistPoint { var S preTwistPointProy var d [113]int8 + var kk Scalar + kk = *k + var isZero int - if k.IsZero() { + if kk.IsZero() { isZero = 1 } - subtle.ConstantTimeCopy(isZero, k[:], order[:]) + subtle.ConstantTimeCopy(isZero, kk[:], order[:]) - minusK := *k - isEven := 1 - int(k[0]&0x1) + minusK := kk + isEven := 1 - int(kk[0]&0x1) minusK.Neg() - subtle.ConstantTimeCopy(isEven, k[:], minusK[:]) - recodeScalar(&d, k) + subtle.ConstantTimeCopy(isEven, kk[:], minusK[:]) + recodeScalar(&d, &kk) P.oddMultiples(TabP[:]) Q := e.Identity() diff --git a/ecc/goldilocks/twistPoint.go b/ecc/goldilocks/twistPoint.go index 85856bc48..f13157bb4 100644 --- a/ecc/goldilocks/twistPoint.go +++ b/ecc/goldilocks/twistPoint.go @@ -140,16 +140,3 @@ func (P *preTwistPointProy) FromTwistPoint(Q *twistPoint) { fp.Add(&P.dt2, &P.dt2, &P.dt2) // dt2 = 2*D*T fp.Add(&P.z2, &Q.z, &Q.z) // z2 = 2*Z } - -// ToAffine returns the x,y affine coordinates of P. TODO: remove this method -func (P *twistPoint) ToAffine() (x, y fp.Elt) { - fp.Inv(&P.z, &P.z) // 1/z - fp.Mul(&P.x, &P.x, &P.z) // x/z - fp.Mul(&P.y, &P.y, &P.z) // y/z - fp.Modp(&P.x) - fp.Modp(&P.y) - fp.SetOne(&P.z) - P.ta = P.x - P.tb = P.y - return P.x, P.y -} diff --git a/ecc/goldilocks/twist_basemult.go b/ecc/goldilocks/twist_basemult.go index f6ac5edbb..b9aac3d40 100644 --- a/ecc/goldilocks/twist_basemult.go +++ b/ecc/goldilocks/twist_basemult.go @@ -24,17 +24,21 @@ func (e twistCurve) ScalarBaseMult(k *Scalar) *twistPoint { panic("not extended") } + var kk Scalar + kk = *k + var isZero int - if k.IsZero() { + if kk.IsZero() { isZero = 1 } - subtle.ConstantTimeCopy(isZero, k[:], order[:]) - minusK := *k - isEven := 1 - int(k[0]&0x1) + subtle.ConstantTimeCopy(isZero, kk[:], order[:]) + + minusK := kk + isEven := 1 - int(kk[0]&0x1) minusK.Neg() - subtle.ConstantTimeCopy(isEven, k[:], minusK[:]) - c, err := m.Encode(k[:]) + subtle.ConstantTimeCopy(isEven, kk[:], minusK[:]) + c, err := m.Encode(kk[:]) if err != nil { panic(err) }