From e4fc3b9bb94adab469258d8909b718dc2c060c7e Mon Sep 17 00:00:00 2001 From: Arya Tabaie Date: Fri, 18 Nov 2022 17:43:21 -0500 Subject: [PATCH 1/6] feat: field.Hash --- ecc/bls12-377/fp/element.go | 22 +++++ ecc/bls12-377/fr/element.go | 22 +++++ ecc/bls12-377/hash_to_g1.go | 25 +---- ecc/bls12-377/hash_to_g2.go | 4 +- ecc/bls12-378/fp/element.go | 22 +++++ ecc/bls12-378/fr/element.go | 22 +++++ ecc/bls12-378/hash_to_g1.go | 25 +---- ecc/bls12-381/fp/element.go | 22 +++++ ecc/bls12-381/fr/element.go | 22 +++++ ecc/bls12-381/hash_to_g1.go | 25 +---- ecc/bls12-381/hash_to_g2.go | 4 +- ecc/bls24-315/fp/element.go | 22 +++++ ecc/bls24-315/fr/element.go | 22 +++++ ecc/bls24-315/hash_to_g1.go | 25 +---- ecc/bls24-317/fp/element.go | 22 +++++ ecc/bls24-317/fr/element.go | 22 +++++ ecc/bls24-317/hash_to_g1.go | 25 +---- ecc/bn254/fp/element.go | 22 +++++ ecc/bn254/fr/element.go | 22 +++++ ecc/bn254/hash_to_g1.go | 25 +---- ecc/bn254/hash_to_g2.go | 4 +- ecc/bw6-633/fp/element.go | 22 +++++ ecc/bw6-633/fr/element.go | 22 +++++ ecc/bw6-633/hash_to_g1.go | 25 +---- ecc/bw6-633/hash_to_g2.go | 4 +- ecc/bw6-756/fp/element.go | 22 +++++ ecc/bw6-756/fr/element.go | 22 +++++ ecc/bw6-756/hash_to_g1.go | 25 +---- ecc/bw6-756/hash_to_g2.go | 4 +- ecc/bw6-761/fp/element.go | 22 +++++ ecc/bw6-761/fr/element.go | 22 +++++ ecc/bw6-761/hash_to_g1.go | 25 +---- ecc/bw6-761/hash_to_g2.go | 4 +- ecc/utils.go | 90 ------------------ hash/hash_utils.go | 94 +++++++++++++++++++ .../field/internal/templates/element/base.go | 21 +++++ .../ecc/template/hash_to_curve.go.tmpl | 27 +----- 37 files changed, 543 insertions(+), 334 deletions(-) create mode 100644 hash/hash_utils.go diff --git a/ecc/bls12-377/fp/element.go b/ecc/bls12-377/fp/element.go index e3fda1148..6fb23a8f5 100644 --- a/ecc/bls12-377/fp/element.go +++ b/ecc/bls12-377/fp/element.go @@ -20,6 +20,7 @@ import ( "crypto/rand" "encoding/binary" "errors" + "github.com/consensys/gnark-crypto/hash" //TODO: Make sure gnark-crypto dependence is okay "io" "math/big" "math/bits" @@ -916,6 +917,27 @@ func (z *Element) BitLen() int { return bits.Len64(z[0]) } +// Hash msg to count prime field elements. +// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#section-5.2 +func Hash(msg, dst []byte, count int) ([]Element, error) { + // 128 bits of security + // L = ceil((ceil(log2(p)) + k) / 8), where k is the security parameter = 128 + const Bytes = 1 + (Bits-1)/8 + const L = 16 + Bytes + + lenInBytes := count * L + pseudoRandomBytes, err := hash.ExpandMsgXmd(msg, dst, lenInBytes) + if err != nil { + return nil, err + } + + res := make([]Element, count) + for i := 0; i < count; i++ { + res[i].SetBytes(pseudoRandomBytes[i*L : (i+1)*L]) + } + return res, nil +} + // Exp z = xᵏ (mod q) func (z *Element) Exp(x Element, k *big.Int) *Element { if k.IsUint64() && k.Uint64() == 0 { diff --git a/ecc/bls12-377/fr/element.go b/ecc/bls12-377/fr/element.go index 381d47101..b592ececf 100644 --- a/ecc/bls12-377/fr/element.go +++ b/ecc/bls12-377/fr/element.go @@ -20,6 +20,7 @@ import ( "crypto/rand" "encoding/binary" "errors" + "github.com/consensys/gnark-crypto/hash" //TODO: Make sure gnark-crypto dependence is okay "io" "math/big" "math/bits" @@ -758,6 +759,27 @@ func (z *Element) BitLen() int { return bits.Len64(z[0]) } +// Hash msg to count prime field elements. +// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#section-5.2 +func Hash(msg, dst []byte, count int) ([]Element, error) { + // 128 bits of security + // L = ceil((ceil(log2(p)) + k) / 8), where k is the security parameter = 128 + const Bytes = 1 + (Bits-1)/8 + const L = 16 + Bytes + + lenInBytes := count * L + pseudoRandomBytes, err := hash.ExpandMsgXmd(msg, dst, lenInBytes) + if err != nil { + return nil, err + } + + res := make([]Element, count) + for i := 0; i < count; i++ { + res[i].SetBytes(pseudoRandomBytes[i*L : (i+1)*L]) + } + return res, nil +} + // Exp z = xᵏ (mod q) func (z *Element) Exp(x Element, k *big.Int) *Element { if k.IsUint64() && k.Uint64() == 0 { diff --git a/ecc/bls12-377/hash_to_g1.go b/ecc/bls12-377/hash_to_g1.go index 5f2fdc026..833395786 100644 --- a/ecc/bls12-377/hash_to_g1.go +++ b/ecc/bls12-377/hash_to_g1.go @@ -254,27 +254,6 @@ func g1EvalPolynomial(z *fp.Element, monic bool, coefficients []fp.Element, x *f z.Set(&dst) } -// hashToFp hashes msg to count prime field elements. -// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#section-5.2 -func hashToFp(msg, dst []byte, count int) ([]fp.Element, error) { - // 128 bits of security - // L = ceil((ceil(log2(p)) + k) / 8), where k is the security parameter = 128 - const Bytes = 1 + (fp.Bits-1)/8 - const L = 16 + Bytes - - lenInBytes := count * L - pseudoRandomBytes, err := ecc.ExpandMsgXmd(msg, dst, lenInBytes) - if err != nil { - return nil, err - } - - res := make([]fp.Element, count) - for i := 0; i < count; i++ { - res[i].SetBytes(pseudoRandomBytes[i*L : (i+1)*L]) - } - return res, nil -} - // g1Sgn0 is an algebraic substitute for the notion of sign in ordered fields // Namely, every non-zero quadratic residue in a finite field of characteristic =/= 2 has exactly two square roots, one of each sign // https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-16.html#name-the-sgn0-function @@ -304,7 +283,7 @@ func MapToG1(u fp.Element) G1Affine { func EncodeToG1(msg, dst []byte) (G1Affine, error) { var res G1Affine - u, err := hashToFp(msg, dst, 1) + u, err := fp.Hash(msg, dst, 1) if err != nil { return res, err } @@ -322,7 +301,7 @@ func EncodeToG1(msg, dst []byte) (G1Affine, error) { // dst stands for "domain separation tag", a string unique to the construction using the hash function // https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-16.html#roadmap func HashToG1(msg, dst []byte) (G1Affine, error) { - u, err := hashToFp(msg, dst, 2*1) + u, err := fp.Hash(msg, dst, 2*1) if err != nil { return G1Affine{}, err } diff --git a/ecc/bls12-377/hash_to_g2.go b/ecc/bls12-377/hash_to_g2.go index 30a924a76..6584a12a9 100644 --- a/ecc/bls12-377/hash_to_g2.go +++ b/ecc/bls12-377/hash_to_g2.go @@ -754,7 +754,7 @@ func MapToG2(u fptower.E2) G2Affine { func EncodeToG2(msg, dst []byte) (G2Affine, error) { var res G2Affine - u, err := hashToFp(msg, dst, 2) + u, err := fp.Hash(msg, dst, 2) if err != nil { return res, err } @@ -775,7 +775,7 @@ func EncodeToG2(msg, dst []byte) (G2Affine, error) { // dst stands for "domain separation tag", a string unique to the construction using the hash function // https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-16.html#roadmap func HashToG2(msg, dst []byte) (G2Affine, error) { - u, err := hashToFp(msg, dst, 2*2) + u, err := fp.Hash(msg, dst, 2*2) if err != nil { return G2Affine{}, err } diff --git a/ecc/bls12-378/fp/element.go b/ecc/bls12-378/fp/element.go index d1569ac1c..be65cf2a5 100644 --- a/ecc/bls12-378/fp/element.go +++ b/ecc/bls12-378/fp/element.go @@ -20,6 +20,7 @@ import ( "crypto/rand" "encoding/binary" "errors" + "github.com/consensys/gnark-crypto/hash" //TODO: Make sure gnark-crypto dependence is okay "io" "math/big" "math/bits" @@ -916,6 +917,27 @@ func (z *Element) BitLen() int { return bits.Len64(z[0]) } +// Hash msg to count prime field elements. +// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#section-5.2 +func Hash(msg, dst []byte, count int) ([]Element, error) { + // 128 bits of security + // L = ceil((ceil(log2(p)) + k) / 8), where k is the security parameter = 128 + const Bytes = 1 + (Bits-1)/8 + const L = 16 + Bytes + + lenInBytes := count * L + pseudoRandomBytes, err := hash.ExpandMsgXmd(msg, dst, lenInBytes) + if err != nil { + return nil, err + } + + res := make([]Element, count) + for i := 0; i < count; i++ { + res[i].SetBytes(pseudoRandomBytes[i*L : (i+1)*L]) + } + return res, nil +} + // Exp z = xᵏ (mod q) func (z *Element) Exp(x Element, k *big.Int) *Element { if k.IsUint64() && k.Uint64() == 0 { diff --git a/ecc/bls12-378/fr/element.go b/ecc/bls12-378/fr/element.go index a6361e7ba..1bf7223ca 100644 --- a/ecc/bls12-378/fr/element.go +++ b/ecc/bls12-378/fr/element.go @@ -20,6 +20,7 @@ import ( "crypto/rand" "encoding/binary" "errors" + "github.com/consensys/gnark-crypto/hash" //TODO: Make sure gnark-crypto dependence is okay "io" "math/big" "math/bits" @@ -758,6 +759,27 @@ func (z *Element) BitLen() int { return bits.Len64(z[0]) } +// Hash msg to count prime field elements. +// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#section-5.2 +func Hash(msg, dst []byte, count int) ([]Element, error) { + // 128 bits of security + // L = ceil((ceil(log2(p)) + k) / 8), where k is the security parameter = 128 + const Bytes = 1 + (Bits-1)/8 + const L = 16 + Bytes + + lenInBytes := count * L + pseudoRandomBytes, err := hash.ExpandMsgXmd(msg, dst, lenInBytes) + if err != nil { + return nil, err + } + + res := make([]Element, count) + for i := 0; i < count; i++ { + res[i].SetBytes(pseudoRandomBytes[i*L : (i+1)*L]) + } + return res, nil +} + // Exp z = xᵏ (mod q) func (z *Element) Exp(x Element, k *big.Int) *Element { if k.IsUint64() && k.Uint64() == 0 { diff --git a/ecc/bls12-378/hash_to_g1.go b/ecc/bls12-378/hash_to_g1.go index ce67c9e13..8d0abf681 100644 --- a/ecc/bls12-378/hash_to_g1.go +++ b/ecc/bls12-378/hash_to_g1.go @@ -256,27 +256,6 @@ func g1EvalPolynomial(z *fp.Element, monic bool, coefficients []fp.Element, x *f z.Set(&dst) } -// hashToFp hashes msg to count prime field elements. -// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#section-5.2 -func hashToFp(msg, dst []byte, count int) ([]fp.Element, error) { - // 128 bits of security - // L = ceil((ceil(log2(p)) + k) / 8), where k is the security parameter = 128 - const Bytes = 1 + (fp.Bits-1)/8 - const L = 16 + Bytes - - lenInBytes := count * L - pseudoRandomBytes, err := ecc.ExpandMsgXmd(msg, dst, lenInBytes) - if err != nil { - return nil, err - } - - res := make([]fp.Element, count) - for i := 0; i < count; i++ { - res[i].SetBytes(pseudoRandomBytes[i*L : (i+1)*L]) - } - return res, nil -} - // g1Sgn0 is an algebraic substitute for the notion of sign in ordered fields // Namely, every non-zero quadratic residue in a finite field of characteristic =/= 2 has exactly two square roots, one of each sign // https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-16.html#name-the-sgn0-function @@ -306,7 +285,7 @@ func MapToG1(u fp.Element) G1Affine { func EncodeToG1(msg, dst []byte) (G1Affine, error) { var res G1Affine - u, err := hashToFp(msg, dst, 1) + u, err := fp.Hash(msg, dst, 1) if err != nil { return res, err } @@ -324,7 +303,7 @@ func EncodeToG1(msg, dst []byte) (G1Affine, error) { // dst stands for "domain separation tag", a string unique to the construction using the hash function // https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-16.html#roadmap func HashToG1(msg, dst []byte) (G1Affine, error) { - u, err := hashToFp(msg, dst, 2*1) + u, err := fp.Hash(msg, dst, 2*1) if err != nil { return G1Affine{}, err } diff --git a/ecc/bls12-381/fp/element.go b/ecc/bls12-381/fp/element.go index ed00a08b4..dc7f5ac0b 100644 --- a/ecc/bls12-381/fp/element.go +++ b/ecc/bls12-381/fp/element.go @@ -20,6 +20,7 @@ import ( "crypto/rand" "encoding/binary" "errors" + "github.com/consensys/gnark-crypto/hash" //TODO: Make sure gnark-crypto dependence is okay "io" "math/big" "math/bits" @@ -916,6 +917,27 @@ func (z *Element) BitLen() int { return bits.Len64(z[0]) } +// Hash msg to count prime field elements. +// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#section-5.2 +func Hash(msg, dst []byte, count int) ([]Element, error) { + // 128 bits of security + // L = ceil((ceil(log2(p)) + k) / 8), where k is the security parameter = 128 + const Bytes = 1 + (Bits-1)/8 + const L = 16 + Bytes + + lenInBytes := count * L + pseudoRandomBytes, err := hash.ExpandMsgXmd(msg, dst, lenInBytes) + if err != nil { + return nil, err + } + + res := make([]Element, count) + for i := 0; i < count; i++ { + res[i].SetBytes(pseudoRandomBytes[i*L : (i+1)*L]) + } + return res, nil +} + // Exp z = xᵏ (mod q) func (z *Element) Exp(x Element, k *big.Int) *Element { if k.IsUint64() && k.Uint64() == 0 { diff --git a/ecc/bls12-381/fr/element.go b/ecc/bls12-381/fr/element.go index db1472397..2341a7971 100644 --- a/ecc/bls12-381/fr/element.go +++ b/ecc/bls12-381/fr/element.go @@ -20,6 +20,7 @@ import ( "crypto/rand" "encoding/binary" "errors" + "github.com/consensys/gnark-crypto/hash" //TODO: Make sure gnark-crypto dependence is okay "io" "math/big" "math/bits" @@ -758,6 +759,27 @@ func (z *Element) BitLen() int { return bits.Len64(z[0]) } +// Hash msg to count prime field elements. +// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#section-5.2 +func Hash(msg, dst []byte, count int) ([]Element, error) { + // 128 bits of security + // L = ceil((ceil(log2(p)) + k) / 8), where k is the security parameter = 128 + const Bytes = 1 + (Bits-1)/8 + const L = 16 + Bytes + + lenInBytes := count * L + pseudoRandomBytes, err := hash.ExpandMsgXmd(msg, dst, lenInBytes) + if err != nil { + return nil, err + } + + res := make([]Element, count) + for i := 0; i < count; i++ { + res[i].SetBytes(pseudoRandomBytes[i*L : (i+1)*L]) + } + return res, nil +} + // Exp z = xᵏ (mod q) func (z *Element) Exp(x Element, k *big.Int) *Element { if k.IsUint64() && k.Uint64() == 0 { diff --git a/ecc/bls12-381/hash_to_g1.go b/ecc/bls12-381/hash_to_g1.go index a0679abf2..32d36fee2 100644 --- a/ecc/bls12-381/hash_to_g1.go +++ b/ecc/bls12-381/hash_to_g1.go @@ -265,27 +265,6 @@ func g1EvalPolynomial(z *fp.Element, monic bool, coefficients []fp.Element, x *f z.Set(&dst) } -// hashToFp hashes msg to count prime field elements. -// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#section-5.2 -func hashToFp(msg, dst []byte, count int) ([]fp.Element, error) { - // 128 bits of security - // L = ceil((ceil(log2(p)) + k) / 8), where k is the security parameter = 128 - const Bytes = 1 + (fp.Bits-1)/8 - const L = 16 + Bytes - - lenInBytes := count * L - pseudoRandomBytes, err := ecc.ExpandMsgXmd(msg, dst, lenInBytes) - if err != nil { - return nil, err - } - - res := make([]fp.Element, count) - for i := 0; i < count; i++ { - res[i].SetBytes(pseudoRandomBytes[i*L : (i+1)*L]) - } - return res, nil -} - // g1Sgn0 is an algebraic substitute for the notion of sign in ordered fields // Namely, every non-zero quadratic residue in a finite field of characteristic =/= 2 has exactly two square roots, one of each sign // https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-16.html#name-the-sgn0-function @@ -315,7 +294,7 @@ func MapToG1(u fp.Element) G1Affine { func EncodeToG1(msg, dst []byte) (G1Affine, error) { var res G1Affine - u, err := hashToFp(msg, dst, 1) + u, err := fp.Hash(msg, dst, 1) if err != nil { return res, err } @@ -333,7 +312,7 @@ func EncodeToG1(msg, dst []byte) (G1Affine, error) { // dst stands for "domain separation tag", a string unique to the construction using the hash function // https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-16.html#roadmap func HashToG1(msg, dst []byte) (G1Affine, error) { - u, err := hashToFp(msg, dst, 2*1) + u, err := fp.Hash(msg, dst, 2*1) if err != nil { return G1Affine{}, err } diff --git a/ecc/bls12-381/hash_to_g2.go b/ecc/bls12-381/hash_to_g2.go index 7a2f485bc..748980458 100644 --- a/ecc/bls12-381/hash_to_g2.go +++ b/ecc/bls12-381/hash_to_g2.go @@ -354,7 +354,7 @@ func MapToG2(u fptower.E2) G2Affine { func EncodeToG2(msg, dst []byte) (G2Affine, error) { var res G2Affine - u, err := hashToFp(msg, dst, 2) + u, err := fp.Hash(msg, dst, 2) if err != nil { return res, err } @@ -375,7 +375,7 @@ func EncodeToG2(msg, dst []byte) (G2Affine, error) { // dst stands for "domain separation tag", a string unique to the construction using the hash function // https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-16.html#roadmap func HashToG2(msg, dst []byte) (G2Affine, error) { - u, err := hashToFp(msg, dst, 2*2) + u, err := fp.Hash(msg, dst, 2*2) if err != nil { return G2Affine{}, err } diff --git a/ecc/bls24-315/fp/element.go b/ecc/bls24-315/fp/element.go index 3ab5cafb2..1541bb170 100644 --- a/ecc/bls24-315/fp/element.go +++ b/ecc/bls24-315/fp/element.go @@ -20,6 +20,7 @@ import ( "crypto/rand" "encoding/binary" "errors" + "github.com/consensys/gnark-crypto/hash" //TODO: Make sure gnark-crypto dependence is okay "io" "math/big" "math/bits" @@ -834,6 +835,27 @@ func (z *Element) BitLen() int { return bits.Len64(z[0]) } +// Hash msg to count prime field elements. +// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#section-5.2 +func Hash(msg, dst []byte, count int) ([]Element, error) { + // 128 bits of security + // L = ceil((ceil(log2(p)) + k) / 8), where k is the security parameter = 128 + const Bytes = 1 + (Bits-1)/8 + const L = 16 + Bytes + + lenInBytes := count * L + pseudoRandomBytes, err := hash.ExpandMsgXmd(msg, dst, lenInBytes) + if err != nil { + return nil, err + } + + res := make([]Element, count) + for i := 0; i < count; i++ { + res[i].SetBytes(pseudoRandomBytes[i*L : (i+1)*L]) + } + return res, nil +} + // Exp z = xᵏ (mod q) func (z *Element) Exp(x Element, k *big.Int) *Element { if k.IsUint64() && k.Uint64() == 0 { diff --git a/ecc/bls24-315/fr/element.go b/ecc/bls24-315/fr/element.go index d8ce043ee..755241709 100644 --- a/ecc/bls24-315/fr/element.go +++ b/ecc/bls24-315/fr/element.go @@ -20,6 +20,7 @@ import ( "crypto/rand" "encoding/binary" "errors" + "github.com/consensys/gnark-crypto/hash" //TODO: Make sure gnark-crypto dependence is okay "io" "math/big" "math/bits" @@ -758,6 +759,27 @@ func (z *Element) BitLen() int { return bits.Len64(z[0]) } +// Hash msg to count prime field elements. +// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#section-5.2 +func Hash(msg, dst []byte, count int) ([]Element, error) { + // 128 bits of security + // L = ceil((ceil(log2(p)) + k) / 8), where k is the security parameter = 128 + const Bytes = 1 + (Bits-1)/8 + const L = 16 + Bytes + + lenInBytes := count * L + pseudoRandomBytes, err := hash.ExpandMsgXmd(msg, dst, lenInBytes) + if err != nil { + return nil, err + } + + res := make([]Element, count) + for i := 0; i < count; i++ { + res[i].SetBytes(pseudoRandomBytes[i*L : (i+1)*L]) + } + return res, nil +} + // Exp z = xᵏ (mod q) func (z *Element) Exp(x Element, k *big.Int) *Element { if k.IsUint64() && k.Uint64() == 0 { diff --git a/ecc/bls24-315/hash_to_g1.go b/ecc/bls24-315/hash_to_g1.go index 1f95a41c5..618cb779b 100644 --- a/ecc/bls24-315/hash_to_g1.go +++ b/ecc/bls24-315/hash_to_g1.go @@ -256,27 +256,6 @@ func g1EvalPolynomial(z *fp.Element, monic bool, coefficients []fp.Element, x *f z.Set(&dst) } -// hashToFp hashes msg to count prime field elements. -// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#section-5.2 -func hashToFp(msg, dst []byte, count int) ([]fp.Element, error) { - // 128 bits of security - // L = ceil((ceil(log2(p)) + k) / 8), where k is the security parameter = 128 - const Bytes = 1 + (fp.Bits-1)/8 - const L = 16 + Bytes - - lenInBytes := count * L - pseudoRandomBytes, err := ecc.ExpandMsgXmd(msg, dst, lenInBytes) - if err != nil { - return nil, err - } - - res := make([]fp.Element, count) - for i := 0; i < count; i++ { - res[i].SetBytes(pseudoRandomBytes[i*L : (i+1)*L]) - } - return res, nil -} - // g1Sgn0 is an algebraic substitute for the notion of sign in ordered fields // Namely, every non-zero quadratic residue in a finite field of characteristic =/= 2 has exactly two square roots, one of each sign // https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-16.html#name-the-sgn0-function @@ -306,7 +285,7 @@ func MapToG1(u fp.Element) G1Affine { func EncodeToG1(msg, dst []byte) (G1Affine, error) { var res G1Affine - u, err := hashToFp(msg, dst, 1) + u, err := fp.Hash(msg, dst, 1) if err != nil { return res, err } @@ -324,7 +303,7 @@ func EncodeToG1(msg, dst []byte) (G1Affine, error) { // dst stands for "domain separation tag", a string unique to the construction using the hash function // https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-16.html#roadmap func HashToG1(msg, dst []byte) (G1Affine, error) { - u, err := hashToFp(msg, dst, 2*1) + u, err := fp.Hash(msg, dst, 2*1) if err != nil { return G1Affine{}, err } diff --git a/ecc/bls24-317/fp/element.go b/ecc/bls24-317/fp/element.go index d0fed9c40..b60353fd9 100644 --- a/ecc/bls24-317/fp/element.go +++ b/ecc/bls24-317/fp/element.go @@ -20,6 +20,7 @@ import ( "crypto/rand" "encoding/binary" "errors" + "github.com/consensys/gnark-crypto/hash" //TODO: Make sure gnark-crypto dependence is okay "io" "math/big" "math/bits" @@ -834,6 +835,27 @@ func (z *Element) BitLen() int { return bits.Len64(z[0]) } +// Hash msg to count prime field elements. +// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#section-5.2 +func Hash(msg, dst []byte, count int) ([]Element, error) { + // 128 bits of security + // L = ceil((ceil(log2(p)) + k) / 8), where k is the security parameter = 128 + const Bytes = 1 + (Bits-1)/8 + const L = 16 + Bytes + + lenInBytes := count * L + pseudoRandomBytes, err := hash.ExpandMsgXmd(msg, dst, lenInBytes) + if err != nil { + return nil, err + } + + res := make([]Element, count) + for i := 0; i < count; i++ { + res[i].SetBytes(pseudoRandomBytes[i*L : (i+1)*L]) + } + return res, nil +} + // Exp z = xᵏ (mod q) func (z *Element) Exp(x Element, k *big.Int) *Element { if k.IsUint64() && k.Uint64() == 0 { diff --git a/ecc/bls24-317/fr/element.go b/ecc/bls24-317/fr/element.go index 3e91d0399..d60f89287 100644 --- a/ecc/bls24-317/fr/element.go +++ b/ecc/bls24-317/fr/element.go @@ -20,6 +20,7 @@ import ( "crypto/rand" "encoding/binary" "errors" + "github.com/consensys/gnark-crypto/hash" //TODO: Make sure gnark-crypto dependence is okay "io" "math/big" "math/bits" @@ -758,6 +759,27 @@ func (z *Element) BitLen() int { return bits.Len64(z[0]) } +// Hash msg to count prime field elements. +// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#section-5.2 +func Hash(msg, dst []byte, count int) ([]Element, error) { + // 128 bits of security + // L = ceil((ceil(log2(p)) + k) / 8), where k is the security parameter = 128 + const Bytes = 1 + (Bits-1)/8 + const L = 16 + Bytes + + lenInBytes := count * L + pseudoRandomBytes, err := hash.ExpandMsgXmd(msg, dst, lenInBytes) + if err != nil { + return nil, err + } + + res := make([]Element, count) + for i := 0; i < count; i++ { + res[i].SetBytes(pseudoRandomBytes[i*L : (i+1)*L]) + } + return res, nil +} + // Exp z = xᵏ (mod q) func (z *Element) Exp(x Element, k *big.Int) *Element { if k.IsUint64() && k.Uint64() == 0 { diff --git a/ecc/bls24-317/hash_to_g1.go b/ecc/bls24-317/hash_to_g1.go index f13579d82..410a05c93 100644 --- a/ecc/bls24-317/hash_to_g1.go +++ b/ecc/bls24-317/hash_to_g1.go @@ -233,27 +233,6 @@ func g1EvalPolynomial(z *fp.Element, monic bool, coefficients []fp.Element, x *f z.Set(&dst) } -// hashToFp hashes msg to count prime field elements. -// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#section-5.2 -func hashToFp(msg, dst []byte, count int) ([]fp.Element, error) { - // 128 bits of security - // L = ceil((ceil(log2(p)) + k) / 8), where k is the security parameter = 128 - const Bytes = 1 + (fp.Bits-1)/8 - const L = 16 + Bytes - - lenInBytes := count * L - pseudoRandomBytes, err := ecc.ExpandMsgXmd(msg, dst, lenInBytes) - if err != nil { - return nil, err - } - - res := make([]fp.Element, count) - for i := 0; i < count; i++ { - res[i].SetBytes(pseudoRandomBytes[i*L : (i+1)*L]) - } - return res, nil -} - // g1Sgn0 is an algebraic substitute for the notion of sign in ordered fields // Namely, every non-zero quadratic residue in a finite field of characteristic =/= 2 has exactly two square roots, one of each sign // https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-16.html#name-the-sgn0-function @@ -283,7 +262,7 @@ func MapToG1(u fp.Element) G1Affine { func EncodeToG1(msg, dst []byte) (G1Affine, error) { var res G1Affine - u, err := hashToFp(msg, dst, 1) + u, err := fp.Hash(msg, dst, 1) if err != nil { return res, err } @@ -301,7 +280,7 @@ func EncodeToG1(msg, dst []byte) (G1Affine, error) { // dst stands for "domain separation tag", a string unique to the construction using the hash function // https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-16.html#roadmap func HashToG1(msg, dst []byte) (G1Affine, error) { - u, err := hashToFp(msg, dst, 2*1) + u, err := fp.Hash(msg, dst, 2*1) if err != nil { return G1Affine{}, err } diff --git a/ecc/bn254/fp/element.go b/ecc/bn254/fp/element.go index ced389a74..d7c4affa0 100644 --- a/ecc/bn254/fp/element.go +++ b/ecc/bn254/fp/element.go @@ -20,6 +20,7 @@ import ( "crypto/rand" "encoding/binary" "errors" + "github.com/consensys/gnark-crypto/hash" //TODO: Make sure gnark-crypto dependence is okay "io" "math/big" "math/bits" @@ -758,6 +759,27 @@ func (z *Element) BitLen() int { return bits.Len64(z[0]) } +// Hash msg to count prime field elements. +// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#section-5.2 +func Hash(msg, dst []byte, count int) ([]Element, error) { + // 128 bits of security + // L = ceil((ceil(log2(p)) + k) / 8), where k is the security parameter = 128 + const Bytes = 1 + (Bits-1)/8 + const L = 16 + Bytes + + lenInBytes := count * L + pseudoRandomBytes, err := hash.ExpandMsgXmd(msg, dst, lenInBytes) + if err != nil { + return nil, err + } + + res := make([]Element, count) + for i := 0; i < count; i++ { + res[i].SetBytes(pseudoRandomBytes[i*L : (i+1)*L]) + } + return res, nil +} + // Exp z = xᵏ (mod q) func (z *Element) Exp(x Element, k *big.Int) *Element { if k.IsUint64() && k.Uint64() == 0 { diff --git a/ecc/bn254/fr/element.go b/ecc/bn254/fr/element.go index 100331b62..bd556ca34 100644 --- a/ecc/bn254/fr/element.go +++ b/ecc/bn254/fr/element.go @@ -20,6 +20,7 @@ import ( "crypto/rand" "encoding/binary" "errors" + "github.com/consensys/gnark-crypto/hash" //TODO: Make sure gnark-crypto dependence is okay "io" "math/big" "math/bits" @@ -758,6 +759,27 @@ func (z *Element) BitLen() int { return bits.Len64(z[0]) } +// Hash msg to count prime field elements. +// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#section-5.2 +func Hash(msg, dst []byte, count int) ([]Element, error) { + // 128 bits of security + // L = ceil((ceil(log2(p)) + k) / 8), where k is the security parameter = 128 + const Bytes = 1 + (Bits-1)/8 + const L = 16 + Bytes + + lenInBytes := count * L + pseudoRandomBytes, err := hash.ExpandMsgXmd(msg, dst, lenInBytes) + if err != nil { + return nil, err + } + + res := make([]Element, count) + for i := 0; i < count; i++ { + res[i].SetBytes(pseudoRandomBytes[i*L : (i+1)*L]) + } + return res, nil +} + // Exp z = xᵏ (mod q) func (z *Element) Exp(x Element, k *big.Int) *Element { if k.IsUint64() && k.Uint64() == 0 { diff --git a/ecc/bn254/hash_to_g1.go b/ecc/bn254/hash_to_g1.go index f3d723414..71f6c65c4 100644 --- a/ecc/bn254/hash_to_g1.go +++ b/ecc/bn254/hash_to_g1.go @@ -98,27 +98,6 @@ func mapToCurve1(u *fp.Element) G1Affine { return G1Affine{x, y} } -// hashToFp hashes msg to count prime field elements. -// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#section-5.2 -func hashToFp(msg, dst []byte, count int) ([]fp.Element, error) { - // 128 bits of security - // L = ceil((ceil(log2(p)) + k) / 8), where k is the security parameter = 128 - const Bytes = 1 + (fp.Bits-1)/8 - const L = 16 + Bytes - - lenInBytes := count * L - pseudoRandomBytes, err := ecc.ExpandMsgXmd(msg, dst, lenInBytes) - if err != nil { - return nil, err - } - - res := make([]fp.Element, count) - for i := 0; i < count; i++ { - res[i].SetBytes(pseudoRandomBytes[i*L : (i+1)*L]) - } - return res, nil -} - // g1Sgn0 is an algebraic substitute for the notion of sign in ordered fields // Namely, every non-zero quadratic residue in a finite field of characteristic =/= 2 has exactly two square roots, one of each sign // https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-16.html#name-the-sgn0-function @@ -145,7 +124,7 @@ func MapToG1(u fp.Element) G1Affine { func EncodeToG1(msg, dst []byte) (G1Affine, error) { var res G1Affine - u, err := hashToFp(msg, dst, 1) + u, err := fp.Hash(msg, dst, 1) if err != nil { return res, err } @@ -160,7 +139,7 @@ func EncodeToG1(msg, dst []byte) (G1Affine, error) { // dst stands for "domain separation tag", a string unique to the construction using the hash function // https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-16.html#roadmap func HashToG1(msg, dst []byte) (G1Affine, error) { - u, err := hashToFp(msg, dst, 2*1) + u, err := fp.Hash(msg, dst, 2*1) if err != nil { return G1Affine{}, err } diff --git a/ecc/bn254/hash_to_g2.go b/ecc/bn254/hash_to_g2.go index da2c1f490..648de4b20 100644 --- a/ecc/bn254/hash_to_g2.go +++ b/ecc/bn254/hash_to_g2.go @@ -156,7 +156,7 @@ func MapToG2(u fptower.E2) G2Affine { func EncodeToG2(msg, dst []byte) (G2Affine, error) { var res G2Affine - u, err := hashToFp(msg, dst, 2) + u, err := fp.Hash(msg, dst, 2) if err != nil { return res, err } @@ -175,7 +175,7 @@ func EncodeToG2(msg, dst []byte) (G2Affine, error) { // dst stands for "domain separation tag", a string unique to the construction using the hash function // https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-16.html#roadmap func HashToG2(msg, dst []byte) (G2Affine, error) { - u, err := hashToFp(msg, dst, 2*2) + u, err := fp.Hash(msg, dst, 2*2) if err != nil { return G2Affine{}, err } diff --git a/ecc/bw6-633/fp/element.go b/ecc/bw6-633/fp/element.go index c73baf2cc..ee5e099d4 100644 --- a/ecc/bw6-633/fp/element.go +++ b/ecc/bw6-633/fp/element.go @@ -20,6 +20,7 @@ import ( "crypto/rand" "encoding/binary" "errors" + "github.com/consensys/gnark-crypto/hash" //TODO: Make sure gnark-crypto dependence is okay "io" "math/big" "math/bits" @@ -1304,6 +1305,27 @@ func (z *Element) BitLen() int { return bits.Len64(z[0]) } +// Hash msg to count prime field elements. +// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#section-5.2 +func Hash(msg, dst []byte, count int) ([]Element, error) { + // 128 bits of security + // L = ceil((ceil(log2(p)) + k) / 8), where k is the security parameter = 128 + const Bytes = 1 + (Bits-1)/8 + const L = 16 + Bytes + + lenInBytes := count * L + pseudoRandomBytes, err := hash.ExpandMsgXmd(msg, dst, lenInBytes) + if err != nil { + return nil, err + } + + res := make([]Element, count) + for i := 0; i < count; i++ { + res[i].SetBytes(pseudoRandomBytes[i*L : (i+1)*L]) + } + return res, nil +} + // Exp z = xᵏ (mod q) func (z *Element) Exp(x Element, k *big.Int) *Element { if k.IsUint64() && k.Uint64() == 0 { diff --git a/ecc/bw6-633/fr/element.go b/ecc/bw6-633/fr/element.go index be5e40fa9..a16f989b4 100644 --- a/ecc/bw6-633/fr/element.go +++ b/ecc/bw6-633/fr/element.go @@ -20,6 +20,7 @@ import ( "crypto/rand" "encoding/binary" "errors" + "github.com/consensys/gnark-crypto/hash" //TODO: Make sure gnark-crypto dependence is okay "io" "math/big" "math/bits" @@ -834,6 +835,27 @@ func (z *Element) BitLen() int { return bits.Len64(z[0]) } +// Hash msg to count prime field elements. +// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#section-5.2 +func Hash(msg, dst []byte, count int) ([]Element, error) { + // 128 bits of security + // L = ceil((ceil(log2(p)) + k) / 8), where k is the security parameter = 128 + const Bytes = 1 + (Bits-1)/8 + const L = 16 + Bytes + + lenInBytes := count * L + pseudoRandomBytes, err := hash.ExpandMsgXmd(msg, dst, lenInBytes) + if err != nil { + return nil, err + } + + res := make([]Element, count) + for i := 0; i < count; i++ { + res[i].SetBytes(pseudoRandomBytes[i*L : (i+1)*L]) + } + return res, nil +} + // Exp z = xᵏ (mod q) func (z *Element) Exp(x Element, k *big.Int) *Element { if k.IsUint64() && k.Uint64() == 0 { diff --git a/ecc/bw6-633/hash_to_g1.go b/ecc/bw6-633/hash_to_g1.go index b9c933b4e..e8486293d 100644 --- a/ecc/bw6-633/hash_to_g1.go +++ b/ecc/bw6-633/hash_to_g1.go @@ -258,27 +258,6 @@ func g1EvalPolynomial(z *fp.Element, monic bool, coefficients []fp.Element, x *f z.Set(&dst) } -// hashToFp hashes msg to count prime field elements. -// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#section-5.2 -func hashToFp(msg, dst []byte, count int) ([]fp.Element, error) { - // 128 bits of security - // L = ceil((ceil(log2(p)) + k) / 8), where k is the security parameter = 128 - const Bytes = 1 + (fp.Bits-1)/8 - const L = 16 + Bytes - - lenInBytes := count * L - pseudoRandomBytes, err := ecc.ExpandMsgXmd(msg, dst, lenInBytes) - if err != nil { - return nil, err - } - - res := make([]fp.Element, count) - for i := 0; i < count; i++ { - res[i].SetBytes(pseudoRandomBytes[i*L : (i+1)*L]) - } - return res, nil -} - // g1Sgn0 is an algebraic substitute for the notion of sign in ordered fields // Namely, every non-zero quadratic residue in a finite field of characteristic =/= 2 has exactly two square roots, one of each sign // https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-16.html#name-the-sgn0-function @@ -308,7 +287,7 @@ func MapToG1(u fp.Element) G1Affine { func EncodeToG1(msg, dst []byte) (G1Affine, error) { var res G1Affine - u, err := hashToFp(msg, dst, 1) + u, err := fp.Hash(msg, dst, 1) if err != nil { return res, err } @@ -326,7 +305,7 @@ func EncodeToG1(msg, dst []byte) (G1Affine, error) { // dst stands for "domain separation tag", a string unique to the construction using the hash function // https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-16.html#roadmap func HashToG1(msg, dst []byte) (G1Affine, error) { - u, err := hashToFp(msg, dst, 2*1) + u, err := fp.Hash(msg, dst, 2*1) if err != nil { return G1Affine{}, err } diff --git a/ecc/bw6-633/hash_to_g2.go b/ecc/bw6-633/hash_to_g2.go index b7d908458..e97beef01 100644 --- a/ecc/bw6-633/hash_to_g2.go +++ b/ecc/bw6-633/hash_to_g2.go @@ -260,7 +260,7 @@ func MapToG2(u fp.Element) G2Affine { func EncodeToG2(msg, dst []byte) (G2Affine, error) { var res G2Affine - u, err := hashToFp(msg, dst, 1) + u, err := fp.Hash(msg, dst, 1) if err != nil { return res, err } @@ -278,7 +278,7 @@ func EncodeToG2(msg, dst []byte) (G2Affine, error) { // dst stands for "domain separation tag", a string unique to the construction using the hash function // https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-16.html#roadmap func HashToG2(msg, dst []byte) (G2Affine, error) { - u, err := hashToFp(msg, dst, 2*1) + u, err := fp.Hash(msg, dst, 2*1) if err != nil { return G2Affine{}, err } diff --git a/ecc/bw6-756/fp/element.go b/ecc/bw6-756/fp/element.go index 9b6a564ba..f6a6b7348 100644 --- a/ecc/bw6-756/fp/element.go +++ b/ecc/bw6-756/fp/element.go @@ -20,6 +20,7 @@ import ( "crypto/rand" "encoding/binary" "errors" + "github.com/consensys/gnark-crypto/hash" //TODO: Make sure gnark-crypto dependence is okay "io" "math/big" "math/bits" @@ -1534,6 +1535,27 @@ func (z *Element) BitLen() int { return bits.Len64(z[0]) } +// Hash msg to count prime field elements. +// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#section-5.2 +func Hash(msg, dst []byte, count int) ([]Element, error) { + // 128 bits of security + // L = ceil((ceil(log2(p)) + k) / 8), where k is the security parameter = 128 + const Bytes = 1 + (Bits-1)/8 + const L = 16 + Bytes + + lenInBytes := count * L + pseudoRandomBytes, err := hash.ExpandMsgXmd(msg, dst, lenInBytes) + if err != nil { + return nil, err + } + + res := make([]Element, count) + for i := 0; i < count; i++ { + res[i].SetBytes(pseudoRandomBytes[i*L : (i+1)*L]) + } + return res, nil +} + // Exp z = xᵏ (mod q) func (z *Element) Exp(x Element, k *big.Int) *Element { if k.IsUint64() && k.Uint64() == 0 { diff --git a/ecc/bw6-756/fr/element.go b/ecc/bw6-756/fr/element.go index e7cb99717..aaa10e188 100644 --- a/ecc/bw6-756/fr/element.go +++ b/ecc/bw6-756/fr/element.go @@ -20,6 +20,7 @@ import ( "crypto/rand" "encoding/binary" "errors" + "github.com/consensys/gnark-crypto/hash" //TODO: Make sure gnark-crypto dependence is okay "io" "math/big" "math/bits" @@ -916,6 +917,27 @@ func (z *Element) BitLen() int { return bits.Len64(z[0]) } +// Hash msg to count prime field elements. +// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#section-5.2 +func Hash(msg, dst []byte, count int) ([]Element, error) { + // 128 bits of security + // L = ceil((ceil(log2(p)) + k) / 8), where k is the security parameter = 128 + const Bytes = 1 + (Bits-1)/8 + const L = 16 + Bytes + + lenInBytes := count * L + pseudoRandomBytes, err := hash.ExpandMsgXmd(msg, dst, lenInBytes) + if err != nil { + return nil, err + } + + res := make([]Element, count) + for i := 0; i < count; i++ { + res[i].SetBytes(pseudoRandomBytes[i*L : (i+1)*L]) + } + return res, nil +} + // Exp z = xᵏ (mod q) func (z *Element) Exp(x Element, k *big.Int) *Element { if k.IsUint64() && k.Uint64() == 0 { diff --git a/ecc/bw6-756/hash_to_g1.go b/ecc/bw6-756/hash_to_g1.go index 6c6445c50..b71f628d3 100644 --- a/ecc/bw6-756/hash_to_g1.go +++ b/ecc/bw6-756/hash_to_g1.go @@ -256,27 +256,6 @@ func g1EvalPolynomial(z *fp.Element, monic bool, coefficients []fp.Element, x *f z.Set(&dst) } -// hashToFp hashes msg to count prime field elements. -// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#section-5.2 -func hashToFp(msg, dst []byte, count int) ([]fp.Element, error) { - // 128 bits of security - // L = ceil((ceil(log2(p)) + k) / 8), where k is the security parameter = 128 - const Bytes = 1 + (fp.Bits-1)/8 - const L = 16 + Bytes - - lenInBytes := count * L - pseudoRandomBytes, err := ecc.ExpandMsgXmd(msg, dst, lenInBytes) - if err != nil { - return nil, err - } - - res := make([]fp.Element, count) - for i := 0; i < count; i++ { - res[i].SetBytes(pseudoRandomBytes[i*L : (i+1)*L]) - } - return res, nil -} - // g1Sgn0 is an algebraic substitute for the notion of sign in ordered fields // Namely, every non-zero quadratic residue in a finite field of characteristic =/= 2 has exactly two square roots, one of each sign // https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-16.html#name-the-sgn0-function @@ -306,7 +285,7 @@ func MapToG1(u fp.Element) G1Affine { func EncodeToG1(msg, dst []byte) (G1Affine, error) { var res G1Affine - u, err := hashToFp(msg, dst, 1) + u, err := fp.Hash(msg, dst, 1) if err != nil { return res, err } @@ -324,7 +303,7 @@ func EncodeToG1(msg, dst []byte) (G1Affine, error) { // dst stands for "domain separation tag", a string unique to the construction using the hash function // https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-16.html#roadmap func HashToG1(msg, dst []byte) (G1Affine, error) { - u, err := hashToFp(msg, dst, 2*1) + u, err := fp.Hash(msg, dst, 2*1) if err != nil { return G1Affine{}, err } diff --git a/ecc/bw6-756/hash_to_g2.go b/ecc/bw6-756/hash_to_g2.go index 053c8db55..1fd8fd3c5 100644 --- a/ecc/bw6-756/hash_to_g2.go +++ b/ecc/bw6-756/hash_to_g2.go @@ -356,7 +356,7 @@ func MapToG2(u fp.Element) G2Affine { func EncodeToG2(msg, dst []byte) (G2Affine, error) { var res G2Affine - u, err := hashToFp(msg, dst, 1) + u, err := fp.Hash(msg, dst, 1) if err != nil { return res, err } @@ -374,7 +374,7 @@ func EncodeToG2(msg, dst []byte) (G2Affine, error) { // dst stands for "domain separation tag", a string unique to the construction using the hash function // https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-16.html#roadmap func HashToG2(msg, dst []byte) (G2Affine, error) { - u, err := hashToFp(msg, dst, 2*1) + u, err := fp.Hash(msg, dst, 2*1) if err != nil { return G2Affine{}, err } diff --git a/ecc/bw6-761/fp/element.go b/ecc/bw6-761/fp/element.go index 0b2986cb1..19216cfce 100644 --- a/ecc/bw6-761/fp/element.go +++ b/ecc/bw6-761/fp/element.go @@ -20,6 +20,7 @@ import ( "crypto/rand" "encoding/binary" "errors" + "github.com/consensys/gnark-crypto/hash" //TODO: Make sure gnark-crypto dependence is okay "io" "math/big" "math/bits" @@ -1534,6 +1535,27 @@ func (z *Element) BitLen() int { return bits.Len64(z[0]) } +// Hash msg to count prime field elements. +// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#section-5.2 +func Hash(msg, dst []byte, count int) ([]Element, error) { + // 128 bits of security + // L = ceil((ceil(log2(p)) + k) / 8), where k is the security parameter = 128 + const Bytes = 1 + (Bits-1)/8 + const L = 16 + Bytes + + lenInBytes := count * L + pseudoRandomBytes, err := hash.ExpandMsgXmd(msg, dst, lenInBytes) + if err != nil { + return nil, err + } + + res := make([]Element, count) + for i := 0; i < count; i++ { + res[i].SetBytes(pseudoRandomBytes[i*L : (i+1)*L]) + } + return res, nil +} + // Exp z = xᵏ (mod q) func (z *Element) Exp(x Element, k *big.Int) *Element { if k.IsUint64() && k.Uint64() == 0 { diff --git a/ecc/bw6-761/fr/element.go b/ecc/bw6-761/fr/element.go index 220f10bb9..340f50c82 100644 --- a/ecc/bw6-761/fr/element.go +++ b/ecc/bw6-761/fr/element.go @@ -20,6 +20,7 @@ import ( "crypto/rand" "encoding/binary" "errors" + "github.com/consensys/gnark-crypto/hash" //TODO: Make sure gnark-crypto dependence is okay "io" "math/big" "math/bits" @@ -916,6 +917,27 @@ func (z *Element) BitLen() int { return bits.Len64(z[0]) } +// Hash msg to count prime field elements. +// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#section-5.2 +func Hash(msg, dst []byte, count int) ([]Element, error) { + // 128 bits of security + // L = ceil((ceil(log2(p)) + k) / 8), where k is the security parameter = 128 + const Bytes = 1 + (Bits-1)/8 + const L = 16 + Bytes + + lenInBytes := count * L + pseudoRandomBytes, err := hash.ExpandMsgXmd(msg, dst, lenInBytes) + if err != nil { + return nil, err + } + + res := make([]Element, count) + for i := 0; i < count; i++ { + res[i].SetBytes(pseudoRandomBytes[i*L : (i+1)*L]) + } + return res, nil +} + // Exp z = xᵏ (mod q) func (z *Element) Exp(x Element, k *big.Int) *Element { if k.IsUint64() && k.Uint64() == 0 { diff --git a/ecc/bw6-761/hash_to_g1.go b/ecc/bw6-761/hash_to_g1.go index a6b91a198..b8d5321c3 100644 --- a/ecc/bw6-761/hash_to_g1.go +++ b/ecc/bw6-761/hash_to_g1.go @@ -219,27 +219,6 @@ func g1EvalPolynomial(z *fp.Element, monic bool, coefficients []fp.Element, x *f z.Set(&dst) } -// hashToFp hashes msg to count prime field elements. -// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#section-5.2 -func hashToFp(msg, dst []byte, count int) ([]fp.Element, error) { - // 128 bits of security - // L = ceil((ceil(log2(p)) + k) / 8), where k is the security parameter = 128 - const Bytes = 1 + (fp.Bits-1)/8 - const L = 16 + Bytes - - lenInBytes := count * L - pseudoRandomBytes, err := ecc.ExpandMsgXmd(msg, dst, lenInBytes) - if err != nil { - return nil, err - } - - res := make([]fp.Element, count) - for i := 0; i < count; i++ { - res[i].SetBytes(pseudoRandomBytes[i*L : (i+1)*L]) - } - return res, nil -} - // g1Sgn0 is an algebraic substitute for the notion of sign in ordered fields // Namely, every non-zero quadratic residue in a finite field of characteristic =/= 2 has exactly two square roots, one of each sign // https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-16.html#name-the-sgn0-function @@ -269,7 +248,7 @@ func MapToG1(u fp.Element) G1Affine { func EncodeToG1(msg, dst []byte) (G1Affine, error) { var res G1Affine - u, err := hashToFp(msg, dst, 1) + u, err := fp.Hash(msg, dst, 1) if err != nil { return res, err } @@ -287,7 +266,7 @@ func EncodeToG1(msg, dst []byte) (G1Affine, error) { // dst stands for "domain separation tag", a string unique to the construction using the hash function // https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-16.html#roadmap func HashToG1(msg, dst []byte) (G1Affine, error) { - u, err := hashToFp(msg, dst, 2*1) + u, err := fp.Hash(msg, dst, 2*1) if err != nil { return G1Affine{}, err } diff --git a/ecc/bw6-761/hash_to_g2.go b/ecc/bw6-761/hash_to_g2.go index 5f93776ba..a35ddc78c 100644 --- a/ecc/bw6-761/hash_to_g2.go +++ b/ecc/bw6-761/hash_to_g2.go @@ -423,7 +423,7 @@ func MapToG2(u fp.Element) G2Affine { func EncodeToG2(msg, dst []byte) (G2Affine, error) { var res G2Affine - u, err := hashToFp(msg, dst, 1) + u, err := fp.Hash(msg, dst, 1) if err != nil { return res, err } @@ -441,7 +441,7 @@ func EncodeToG2(msg, dst []byte) (G2Affine, error) { // dst stands for "domain separation tag", a string unique to the construction using the hash function // https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-16.html#roadmap func HashToG2(msg, dst []byte) (G2Affine, error) { - u, err := hashToFp(msg, dst, 2*1) + u, err := fp.Hash(msg, dst, 2*1) if err != nil { return G2Affine{}, err } diff --git a/ecc/utils.go b/ecc/utils.go index f02b3c3d7..78126fc1c 100644 --- a/ecc/utils.go +++ b/ecc/utils.go @@ -1,8 +1,6 @@ package ecc import ( - "crypto/sha256" - "errors" "math/big" "math/bits" ) @@ -180,94 +178,6 @@ func getVector(l *Lattice, a, b *big.Int) [2]big.Int { return res } -func min(a, b int) int { - if a < b { - return a - } - return b -} - -// ExpandMsgXmd expands msg to a slice of lenInBytes bytes. -// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#section-5 -// https://tools.ietf.org/html/rfc8017#section-4.1 (I2OSP/O2ISP) -func ExpandMsgXmd(msg, dst []byte, lenInBytes int) ([]byte, error) { - - h := sha256.New() - ell := (lenInBytes + h.Size() - 1) / h.Size() // ceil(len_in_bytes / b_in_bytes) - if ell > 255 { - return nil, errors.New("invalid lenInBytes") - } - if len(dst) > 255 { - return nil, errors.New("invalid domain size (>255 bytes)") - } - sizeDomain := uint8(len(dst)) - - // Z_pad = I2OSP(0, r_in_bytes) - // l_i_b_str = I2OSP(len_in_bytes, 2) - // DST_prime = I2OSP(len(DST), 1) ∥ DST - // b₀ = H(Z_pad ∥ msg ∥ l_i_b_str ∥ I2OSP(0, 1) ∥ DST_prime) - h.Reset() - if _, err := h.Write(make([]byte, h.BlockSize())); err != nil { - return nil, err - } - if _, err := h.Write(msg); err != nil { - return nil, err - } - if _, err := h.Write([]byte{uint8(lenInBytes >> 8), uint8(lenInBytes), uint8(0)}); err != nil { - return nil, err - } - if _, err := h.Write(dst); err != nil { - return nil, err - } - if _, err := h.Write([]byte{sizeDomain}); err != nil { - return nil, err - } - b0 := h.Sum(nil) - - // b₁ = H(b₀ ∥ I2OSP(1, 1) ∥ DST_prime) - h.Reset() - if _, err := h.Write(b0); err != nil { - return nil, err - } - if _, err := h.Write([]byte{uint8(1)}); err != nil { - return nil, err - } - if _, err := h.Write(dst); err != nil { - return nil, err - } - if _, err := h.Write([]byte{sizeDomain}); err != nil { - return nil, err - } - b1 := h.Sum(nil) - - res := make([]byte, lenInBytes) - copy(res[:h.Size()], b1) - - for i := 2; i <= ell; i++ { - // b_i = H(strxor(b₀, b_(i - 1)) ∥ I2OSP(i, 1) ∥ DST_prime) - h.Reset() - strxor := make([]byte, h.Size()) - for j := 0; j < h.Size(); j++ { - strxor[j] = b0[j] ^ b1[j] - } - if _, err := h.Write(strxor); err != nil { - return nil, err - } - if _, err := h.Write([]byte{uint8(i)}); err != nil { - return nil, err - } - if _, err := h.Write(dst); err != nil { - return nil, err - } - if _, err := h.Write([]byte{sizeDomain}); err != nil { - return nil, err - } - b1 = h.Sum(nil) - copy(res[h.Size()*(i-1):min(h.Size()*i, len(res))], b1) - } - return res, nil -} - // NextPowerOfTwo returns the next power of 2 of n func NextPowerOfTwo(n uint64) uint64 { c := bits.OnesCount64(n) diff --git a/hash/hash_utils.go b/hash/hash_utils.go new file mode 100644 index 000000000..db7cff3e1 --- /dev/null +++ b/hash/hash_utils.go @@ -0,0 +1,94 @@ +package hash + +import ( + "crypto/sha256" + "errors" +) + +// ExpandMsgXmd expands msg to a slice of lenInBytes bytes. +// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#section-5 +// https://tools.ietf.org/html/rfc8017#section-4.1 (I2OSP/O2ISP) +func ExpandMsgXmd(msg, dst []byte, lenInBytes int) ([]byte, error) { + + h := sha256.New() + ell := (lenInBytes + h.Size() - 1) / h.Size() // ceil(len_in_bytes / b_in_bytes) + if ell > 255 { + return nil, errors.New("invalid lenInBytes") + } + if len(dst) > 255 { + return nil, errors.New("invalid domain size (>255 bytes)") + } + sizeDomain := uint8(len(dst)) + + // Z_pad = I2OSP(0, r_in_bytes) + // l_i_b_str = I2OSP(len_in_bytes, 2) + // DST_prime = I2OSP(len(DST), 1) ∥ DST + // b₀ = H(Z_pad ∥ msg ∥ l_i_b_str ∥ I2OSP(0, 1) ∥ DST_prime) + h.Reset() + if _, err := h.Write(make([]byte, h.BlockSize())); err != nil { + return nil, err + } + if _, err := h.Write(msg); err != nil { + return nil, err + } + if _, err := h.Write([]byte{uint8(lenInBytes >> 8), uint8(lenInBytes), uint8(0)}); err != nil { + return nil, err + } + if _, err := h.Write(dst); err != nil { + return nil, err + } + if _, err := h.Write([]byte{sizeDomain}); err != nil { + return nil, err + } + b0 := h.Sum(nil) + + // b₁ = H(b₀ ∥ I2OSP(1, 1) ∥ DST_prime) + h.Reset() + if _, err := h.Write(b0); err != nil { + return nil, err + } + if _, err := h.Write([]byte{uint8(1)}); err != nil { + return nil, err + } + if _, err := h.Write(dst); err != nil { + return nil, err + } + if _, err := h.Write([]byte{sizeDomain}); err != nil { + return nil, err + } + b1 := h.Sum(nil) + + res := make([]byte, lenInBytes) + copy(res[:h.Size()], b1) + + for i := 2; i <= ell; i++ { + // b_i = H(strxor(b₀, b_(i - 1)) ∥ I2OSP(i, 1) ∥ DST_prime) + h.Reset() + strxor := make([]byte, h.Size()) + for j := 0; j < h.Size(); j++ { + strxor[j] = b0[j] ^ b1[j] + } + if _, err := h.Write(strxor); err != nil { + return nil, err + } + if _, err := h.Write([]byte{uint8(i)}); err != nil { + return nil, err + } + if _, err := h.Write(dst); err != nil { + return nil, err + } + if _, err := h.Write([]byte{sizeDomain}); err != nil { + return nil, err + } + b1 = h.Sum(nil) + copy(res[h.Size()*(i-1):min(h.Size()*i, len(res))], b1) + } + return res, nil +} + +func min(a, b int) int { + if a < b { + return a + } + return b +} diff --git a/internal/field/internal/templates/element/base.go b/internal/field/internal/templates/element/base.go index a60824016..a158b32d6 100644 --- a/internal/field/internal/templates/element/base.go +++ b/internal/field/internal/templates/element/base.go @@ -3,6 +3,7 @@ package element const Base = ` import ( + "github.com/consensys/gnark-crypto/hash" //TODO: Make sure gnark-crypto dependence is okay "math/big" "math/bits" "io" @@ -626,6 +627,26 @@ func (z *{{.ElementName}}) BitLen() int { return bits.Len64(z[0]) } +// Hash msg to count prime field elements. +// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#section-5.2 +func Hash(msg, dst []byte, count int) ([]{{.ElementName}}, error) { + // 128 bits of security + // L = ceil((ceil(log2(p)) + k) / 8), where k is the security parameter = 128 + const Bytes = 1 + (Bits-1)/8 + const L = 16 + Bytes + + lenInBytes := count * L + pseudoRandomBytes, err := hash.ExpandMsgXmd(msg, dst, lenInBytes) + if err != nil { + return nil, err + } + + res := make([]{{.ElementName}}, count) + for i := 0; i < count; i++ { + res[i].SetBytes(pseudoRandomBytes[i*L : (i+1)*L]) + } + return res, nil +} {{ define "rsh V nbWords" }} diff --git a/internal/generator/ecc/template/hash_to_curve.go.tmpl b/internal/generator/ecc/template/hash_to_curve.go.tmpl index d4e720bf5..260968c9d 100644 --- a/internal/generator/ecc/template/hash_to_curve.go.tmpl +++ b/internal/generator/ecc/template/hash_to_curve.go.tmpl @@ -25,29 +25,6 @@ import( {{template "svdw" .}} {{end}} -{{if $IsG1}} -// hashToFp hashes msg to count prime field elements. -// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#section-5.2 -func hashToFp(msg, dst []byte, count int) ([]fp.Element, error) { - // 128 bits of security - // L = ceil((ceil(log2(p)) + k) / 8), where k is the security parameter = 128 - const Bytes = 1 + (fp.Bits - 1 ) / 8 - const L = 16 + Bytes - - lenInBytes := count * L - pseudoRandomBytes, err := ecc.ExpandMsgXmd(msg, dst, lenInBytes) - if err != nil { - return nil, err - } - - res := make([]fp.Element, count) - for i := 0; i < count; i++ { - res[i].SetBytes(pseudoRandomBytes[i*L : (i+1)*L]) - } - return res, nil -} -{{end}} - // {{$CurveName}}Sgn0 is an algebraic substitute for the notion of sign in ordered fields // Namely, every non-zero quadratic residue in a finite field of characteristic =/= 2 has exactly two square roots, one of each sign // https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-16.html#name-the-sgn0-function @@ -105,7 +82,7 @@ func MapTo{{$CurveTitle}}(u {{$CoordType}}) {{$AffineType}} { func EncodeTo{{$CurveTitle}}(msg, dst []byte) ({{$AffineType}}, error) { var res {{$AffineType}} - u, err := hashToFp(msg, dst, {{$TowerDegree}}) + u, err := fp.Hash(msg, dst, {{$TowerDegree}}) if err != nil { return res, err } @@ -133,7 +110,7 @@ func EncodeTo{{$CurveTitle}}(msg, dst []byte) ({{$AffineType}}, error) { // dst stands for "domain separation tag", a string unique to the construction using the hash function //https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-16.html#roadmap func HashTo{{$CurveTitle}}(msg, dst []byte) ({{$AffineType}}, error) { - u, err := hashToFp(msg, dst, 2 * {{$TowerDegree}}) + u, err := fp.Hash(msg, dst, 2 * {{$TowerDegree}}) if err != nil { return {{$AffineType}}{}, err } From cece09eed9b5aa375d3a5e85e28ef9a225807c52 Mon Sep 17 00:00:00 2001 From: Arya Tabaie Date: Fri, 18 Nov 2022 17:54:17 -0500 Subject: [PATCH 2/6] fix: circular dependency --- ecc/bls12-377/fp/element.go | 4 ++-- ecc/bls12-377/fr/element.go | 4 ++-- ecc/bls12-377/hash_to_g1.go | 1 - ecc/bls12-377/hash_to_g1_test.go | 4 ++-- ecc/bls12-377/hash_to_g2_test.go | 4 ++-- ecc/bls12-378/fp/element.go | 4 ++-- ecc/bls12-378/fr/element.go | 4 ++-- ecc/bls12-378/hash_to_g1.go | 1 - ecc/bls12-378/hash_to_g1_test.go | 4 ++-- ecc/bls12-381/fp/element.go | 4 ++-- ecc/bls12-381/fr/element.go | 4 ++-- ecc/bls12-381/hash_to_g1.go | 1 - ecc/bls12-381/hash_to_g1_test.go | 4 ++-- ecc/bls12-381/hash_to_g2_test.go | 4 ++-- ecc/bls24-315/fp/element.go | 4 ++-- ecc/bls24-315/fr/element.go | 4 ++-- ecc/bls24-315/hash_to_g1.go | 1 - ecc/bls24-315/hash_to_g1_test.go | 4 ++-- ecc/bls24-317/fp/element.go | 4 ++-- ecc/bls24-317/fr/element.go | 4 ++-- ecc/bls24-317/hash_to_g1.go | 1 - ecc/bls24-317/hash_to_g1_test.go | 4 ++-- ecc/bn254/fp/element.go | 4 ++-- ecc/bn254/fr/element.go | 4 ++-- ecc/bn254/hash_to_g1.go | 1 - ecc/bn254/hash_to_g1_test.go | 4 ++-- ecc/bn254/hash_to_g2_test.go | 4 ++-- ecc/bw6-633/fp/element.go | 4 ++-- ecc/bw6-633/fr/element.go | 4 ++-- ecc/bw6-633/hash_to_g1.go | 1 - ecc/bw6-633/hash_to_g1_test.go | 4 ++-- ecc/bw6-633/hash_to_g2_test.go | 4 ++-- ecc/bw6-756/fp/element.go | 4 ++-- ecc/bw6-756/fr/element.go | 4 ++-- ecc/bw6-756/hash_to_g1.go | 1 - ecc/bw6-756/hash_to_g1_test.go | 4 ++-- ecc/bw6-756/hash_to_g2_test.go | 4 ++-- ecc/bw6-761/fp/element.go | 4 ++-- ecc/bw6-761/fr/element.go | 4 ++-- ecc/bw6-761/hash_to_g1.go | 1 - ecc/bw6-761/hash_to_g1_test.go | 4 ++-- ecc/bw6-761/hash_to_g2_test.go | 4 ++-- internal/field/internal/templates/element/base.go | 4 ++-- internal/generator/ecc/template/hash_to_curve.go.tmpl | 3 --- internal/generator/ecc/template/tests/hash_to_curve.go.tmpl | 4 ++-- {hash => internal/hash_utils}/hash_utils.go | 2 +- 46 files changed, 71 insertions(+), 83 deletions(-) rename {hash => internal/hash_utils}/hash_utils.go (99%) diff --git a/ecc/bls12-377/fp/element.go b/ecc/bls12-377/fp/element.go index 6fb23a8f5..11817c6db 100644 --- a/ecc/bls12-377/fp/element.go +++ b/ecc/bls12-377/fp/element.go @@ -20,7 +20,7 @@ import ( "crypto/rand" "encoding/binary" "errors" - "github.com/consensys/gnark-crypto/hash" //TODO: Make sure gnark-crypto dependence is okay + "github.com/consensys/gnark-crypto/internal/hash_utils" //TODO: Make sure gnark-crypto dependence is okay "io" "math/big" "math/bits" @@ -926,7 +926,7 @@ func Hash(msg, dst []byte, count int) ([]Element, error) { const L = 16 + Bytes lenInBytes := count * L - pseudoRandomBytes, err := hash.ExpandMsgXmd(msg, dst, lenInBytes) + pseudoRandomBytes, err := hash_utils.ExpandMsgXmd(msg, dst, lenInBytes) if err != nil { return nil, err } diff --git a/ecc/bls12-377/fr/element.go b/ecc/bls12-377/fr/element.go index b592ececf..eadccaae8 100644 --- a/ecc/bls12-377/fr/element.go +++ b/ecc/bls12-377/fr/element.go @@ -20,7 +20,7 @@ import ( "crypto/rand" "encoding/binary" "errors" - "github.com/consensys/gnark-crypto/hash" //TODO: Make sure gnark-crypto dependence is okay + "github.com/consensys/gnark-crypto/internal/hash_utils" //TODO: Make sure gnark-crypto dependence is okay "io" "math/big" "math/bits" @@ -768,7 +768,7 @@ func Hash(msg, dst []byte, count int) ([]Element, error) { const L = 16 + Bytes lenInBytes := count * L - pseudoRandomBytes, err := hash.ExpandMsgXmd(msg, dst, lenInBytes) + pseudoRandomBytes, err := hash_utils.ExpandMsgXmd(msg, dst, lenInBytes) if err != nil { return nil, err } diff --git a/ecc/bls12-377/hash_to_g1.go b/ecc/bls12-377/hash_to_g1.go index 833395786..26a322c58 100644 --- a/ecc/bls12-377/hash_to_g1.go +++ b/ecc/bls12-377/hash_to_g1.go @@ -17,7 +17,6 @@ package bls12377 import ( - "github.com/consensys/gnark-crypto/ecc" "github.com/consensys/gnark-crypto/ecc/bls12-377/fp" "math/big" diff --git a/ecc/bls12-377/hash_to_g1_test.go b/ecc/bls12-377/hash_to_g1_test.go index 8fbc50e30..00ec21465 100644 --- a/ecc/bls12-377/hash_to_g1_test.go +++ b/ecc/bls12-377/hash_to_g1_test.go @@ -62,7 +62,7 @@ func TestG1SqrtRatio(t *testing.T) { func TestHashToFpG1(t *testing.T) { for _, c := range encodeToG1Vector.cases { - elems, err := hashToFp([]byte(c.msg), encodeToG1Vector.dst, 1) + elems, err := fp.Hash([]byte(c.msg), encodeToG1Vector.dst, 1) if err != nil { t.Error(err) } @@ -70,7 +70,7 @@ func TestHashToFpG1(t *testing.T) { } for _, c := range hashToG1Vector.cases { - elems, err := hashToFp([]byte(c.msg), hashToG1Vector.dst, 2*1) + elems, err := fp.Hash([]byte(c.msg), hashToG1Vector.dst, 2*1) if err != nil { t.Error(err) } diff --git a/ecc/bls12-377/hash_to_g2_test.go b/ecc/bls12-377/hash_to_g2_test.go index cf90051b5..f3b31b8a8 100644 --- a/ecc/bls12-377/hash_to_g2_test.go +++ b/ecc/bls12-377/hash_to_g2_test.go @@ -64,7 +64,7 @@ func TestG2SqrtRatio(t *testing.T) { func TestHashToFpG2(t *testing.T) { for _, c := range encodeToG2Vector.cases { - elems, err := hashToFp([]byte(c.msg), encodeToG2Vector.dst, 2) + elems, err := fp.Hash([]byte(c.msg), encodeToG2Vector.dst, 2) if err != nil { t.Error(err) } @@ -72,7 +72,7 @@ func TestHashToFpG2(t *testing.T) { } for _, c := range hashToG2Vector.cases { - elems, err := hashToFp([]byte(c.msg), hashToG2Vector.dst, 2*2) + elems, err := fp.Hash([]byte(c.msg), hashToG2Vector.dst, 2*2) if err != nil { t.Error(err) } diff --git a/ecc/bls12-378/fp/element.go b/ecc/bls12-378/fp/element.go index be65cf2a5..93e1e1b13 100644 --- a/ecc/bls12-378/fp/element.go +++ b/ecc/bls12-378/fp/element.go @@ -20,7 +20,7 @@ import ( "crypto/rand" "encoding/binary" "errors" - "github.com/consensys/gnark-crypto/hash" //TODO: Make sure gnark-crypto dependence is okay + "github.com/consensys/gnark-crypto/internal/hash_utils" //TODO: Make sure gnark-crypto dependence is okay "io" "math/big" "math/bits" @@ -926,7 +926,7 @@ func Hash(msg, dst []byte, count int) ([]Element, error) { const L = 16 + Bytes lenInBytes := count * L - pseudoRandomBytes, err := hash.ExpandMsgXmd(msg, dst, lenInBytes) + pseudoRandomBytes, err := hash_utils.ExpandMsgXmd(msg, dst, lenInBytes) if err != nil { return nil, err } diff --git a/ecc/bls12-378/fr/element.go b/ecc/bls12-378/fr/element.go index 1bf7223ca..6f3fa385f 100644 --- a/ecc/bls12-378/fr/element.go +++ b/ecc/bls12-378/fr/element.go @@ -20,7 +20,7 @@ import ( "crypto/rand" "encoding/binary" "errors" - "github.com/consensys/gnark-crypto/hash" //TODO: Make sure gnark-crypto dependence is okay + "github.com/consensys/gnark-crypto/internal/hash_utils" //TODO: Make sure gnark-crypto dependence is okay "io" "math/big" "math/bits" @@ -768,7 +768,7 @@ func Hash(msg, dst []byte, count int) ([]Element, error) { const L = 16 + Bytes lenInBytes := count * L - pseudoRandomBytes, err := hash.ExpandMsgXmd(msg, dst, lenInBytes) + pseudoRandomBytes, err := hash_utils.ExpandMsgXmd(msg, dst, lenInBytes) if err != nil { return nil, err } diff --git a/ecc/bls12-378/hash_to_g1.go b/ecc/bls12-378/hash_to_g1.go index 8d0abf681..3561bed08 100644 --- a/ecc/bls12-378/hash_to_g1.go +++ b/ecc/bls12-378/hash_to_g1.go @@ -17,7 +17,6 @@ package bls12378 import ( - "github.com/consensys/gnark-crypto/ecc" "github.com/consensys/gnark-crypto/ecc/bls12-378/fp" "math/big" diff --git a/ecc/bls12-378/hash_to_g1_test.go b/ecc/bls12-378/hash_to_g1_test.go index db9154dcf..2964a0869 100644 --- a/ecc/bls12-378/hash_to_g1_test.go +++ b/ecc/bls12-378/hash_to_g1_test.go @@ -62,7 +62,7 @@ func TestG1SqrtRatio(t *testing.T) { func TestHashToFpG1(t *testing.T) { for _, c := range encodeToG1Vector.cases { - elems, err := hashToFp([]byte(c.msg), encodeToG1Vector.dst, 1) + elems, err := fp.Hash([]byte(c.msg), encodeToG1Vector.dst, 1) if err != nil { t.Error(err) } @@ -70,7 +70,7 @@ func TestHashToFpG1(t *testing.T) { } for _, c := range hashToG1Vector.cases { - elems, err := hashToFp([]byte(c.msg), hashToG1Vector.dst, 2*1) + elems, err := fp.Hash([]byte(c.msg), hashToG1Vector.dst, 2*1) if err != nil { t.Error(err) } diff --git a/ecc/bls12-381/fp/element.go b/ecc/bls12-381/fp/element.go index dc7f5ac0b..3c5c91f68 100644 --- a/ecc/bls12-381/fp/element.go +++ b/ecc/bls12-381/fp/element.go @@ -20,7 +20,7 @@ import ( "crypto/rand" "encoding/binary" "errors" - "github.com/consensys/gnark-crypto/hash" //TODO: Make sure gnark-crypto dependence is okay + "github.com/consensys/gnark-crypto/internal/hash_utils" //TODO: Make sure gnark-crypto dependence is okay "io" "math/big" "math/bits" @@ -926,7 +926,7 @@ func Hash(msg, dst []byte, count int) ([]Element, error) { const L = 16 + Bytes lenInBytes := count * L - pseudoRandomBytes, err := hash.ExpandMsgXmd(msg, dst, lenInBytes) + pseudoRandomBytes, err := hash_utils.ExpandMsgXmd(msg, dst, lenInBytes) if err != nil { return nil, err } diff --git a/ecc/bls12-381/fr/element.go b/ecc/bls12-381/fr/element.go index 2341a7971..d6aae8349 100644 --- a/ecc/bls12-381/fr/element.go +++ b/ecc/bls12-381/fr/element.go @@ -20,7 +20,7 @@ import ( "crypto/rand" "encoding/binary" "errors" - "github.com/consensys/gnark-crypto/hash" //TODO: Make sure gnark-crypto dependence is okay + "github.com/consensys/gnark-crypto/internal/hash_utils" //TODO: Make sure gnark-crypto dependence is okay "io" "math/big" "math/bits" @@ -768,7 +768,7 @@ func Hash(msg, dst []byte, count int) ([]Element, error) { const L = 16 + Bytes lenInBytes := count * L - pseudoRandomBytes, err := hash.ExpandMsgXmd(msg, dst, lenInBytes) + pseudoRandomBytes, err := hash_utils.ExpandMsgXmd(msg, dst, lenInBytes) if err != nil { return nil, err } diff --git a/ecc/bls12-381/hash_to_g1.go b/ecc/bls12-381/hash_to_g1.go index 32d36fee2..9ab34be4d 100644 --- a/ecc/bls12-381/hash_to_g1.go +++ b/ecc/bls12-381/hash_to_g1.go @@ -17,7 +17,6 @@ package bls12381 import ( - "github.com/consensys/gnark-crypto/ecc" "github.com/consensys/gnark-crypto/ecc/bls12-381/fp" "math/big" diff --git a/ecc/bls12-381/hash_to_g1_test.go b/ecc/bls12-381/hash_to_g1_test.go index b11735f06..bcadce17a 100644 --- a/ecc/bls12-381/hash_to_g1_test.go +++ b/ecc/bls12-381/hash_to_g1_test.go @@ -62,7 +62,7 @@ func TestG1SqrtRatio(t *testing.T) { func TestHashToFpG1(t *testing.T) { for _, c := range encodeToG1Vector.cases { - elems, err := hashToFp([]byte(c.msg), encodeToG1Vector.dst, 1) + elems, err := fp.Hash([]byte(c.msg), encodeToG1Vector.dst, 1) if err != nil { t.Error(err) } @@ -70,7 +70,7 @@ func TestHashToFpG1(t *testing.T) { } for _, c := range hashToG1Vector.cases { - elems, err := hashToFp([]byte(c.msg), hashToG1Vector.dst, 2*1) + elems, err := fp.Hash([]byte(c.msg), hashToG1Vector.dst, 2*1) if err != nil { t.Error(err) } diff --git a/ecc/bls12-381/hash_to_g2_test.go b/ecc/bls12-381/hash_to_g2_test.go index 6554a0318..b48b87ff2 100644 --- a/ecc/bls12-381/hash_to_g2_test.go +++ b/ecc/bls12-381/hash_to_g2_test.go @@ -64,7 +64,7 @@ func TestG2SqrtRatio(t *testing.T) { func TestHashToFpG2(t *testing.T) { for _, c := range encodeToG2Vector.cases { - elems, err := hashToFp([]byte(c.msg), encodeToG2Vector.dst, 2) + elems, err := fp.Hash([]byte(c.msg), encodeToG2Vector.dst, 2) if err != nil { t.Error(err) } @@ -72,7 +72,7 @@ func TestHashToFpG2(t *testing.T) { } for _, c := range hashToG2Vector.cases { - elems, err := hashToFp([]byte(c.msg), hashToG2Vector.dst, 2*2) + elems, err := fp.Hash([]byte(c.msg), hashToG2Vector.dst, 2*2) if err != nil { t.Error(err) } diff --git a/ecc/bls24-315/fp/element.go b/ecc/bls24-315/fp/element.go index 1541bb170..c09b1f36f 100644 --- a/ecc/bls24-315/fp/element.go +++ b/ecc/bls24-315/fp/element.go @@ -20,7 +20,7 @@ import ( "crypto/rand" "encoding/binary" "errors" - "github.com/consensys/gnark-crypto/hash" //TODO: Make sure gnark-crypto dependence is okay + "github.com/consensys/gnark-crypto/internal/hash_utils" //TODO: Make sure gnark-crypto dependence is okay "io" "math/big" "math/bits" @@ -844,7 +844,7 @@ func Hash(msg, dst []byte, count int) ([]Element, error) { const L = 16 + Bytes lenInBytes := count * L - pseudoRandomBytes, err := hash.ExpandMsgXmd(msg, dst, lenInBytes) + pseudoRandomBytes, err := hash_utils.ExpandMsgXmd(msg, dst, lenInBytes) if err != nil { return nil, err } diff --git a/ecc/bls24-315/fr/element.go b/ecc/bls24-315/fr/element.go index 755241709..957bdadf8 100644 --- a/ecc/bls24-315/fr/element.go +++ b/ecc/bls24-315/fr/element.go @@ -20,7 +20,7 @@ import ( "crypto/rand" "encoding/binary" "errors" - "github.com/consensys/gnark-crypto/hash" //TODO: Make sure gnark-crypto dependence is okay + "github.com/consensys/gnark-crypto/internal/hash_utils" //TODO: Make sure gnark-crypto dependence is okay "io" "math/big" "math/bits" @@ -768,7 +768,7 @@ func Hash(msg, dst []byte, count int) ([]Element, error) { const L = 16 + Bytes lenInBytes := count * L - pseudoRandomBytes, err := hash.ExpandMsgXmd(msg, dst, lenInBytes) + pseudoRandomBytes, err := hash_utils.ExpandMsgXmd(msg, dst, lenInBytes) if err != nil { return nil, err } diff --git a/ecc/bls24-315/hash_to_g1.go b/ecc/bls24-315/hash_to_g1.go index 618cb779b..dc05afa3b 100644 --- a/ecc/bls24-315/hash_to_g1.go +++ b/ecc/bls24-315/hash_to_g1.go @@ -17,7 +17,6 @@ package bls24315 import ( - "github.com/consensys/gnark-crypto/ecc" "github.com/consensys/gnark-crypto/ecc/bls24-315/fp" "math/big" diff --git a/ecc/bls24-315/hash_to_g1_test.go b/ecc/bls24-315/hash_to_g1_test.go index dafba7873..d536b1a23 100644 --- a/ecc/bls24-315/hash_to_g1_test.go +++ b/ecc/bls24-315/hash_to_g1_test.go @@ -62,7 +62,7 @@ func TestG1SqrtRatio(t *testing.T) { func TestHashToFpG1(t *testing.T) { for _, c := range encodeToG1Vector.cases { - elems, err := hashToFp([]byte(c.msg), encodeToG1Vector.dst, 1) + elems, err := fp.Hash([]byte(c.msg), encodeToG1Vector.dst, 1) if err != nil { t.Error(err) } @@ -70,7 +70,7 @@ func TestHashToFpG1(t *testing.T) { } for _, c := range hashToG1Vector.cases { - elems, err := hashToFp([]byte(c.msg), hashToG1Vector.dst, 2*1) + elems, err := fp.Hash([]byte(c.msg), hashToG1Vector.dst, 2*1) if err != nil { t.Error(err) } diff --git a/ecc/bls24-317/fp/element.go b/ecc/bls24-317/fp/element.go index b60353fd9..975f05e29 100644 --- a/ecc/bls24-317/fp/element.go +++ b/ecc/bls24-317/fp/element.go @@ -20,7 +20,7 @@ import ( "crypto/rand" "encoding/binary" "errors" - "github.com/consensys/gnark-crypto/hash" //TODO: Make sure gnark-crypto dependence is okay + "github.com/consensys/gnark-crypto/internal/hash_utils" //TODO: Make sure gnark-crypto dependence is okay "io" "math/big" "math/bits" @@ -844,7 +844,7 @@ func Hash(msg, dst []byte, count int) ([]Element, error) { const L = 16 + Bytes lenInBytes := count * L - pseudoRandomBytes, err := hash.ExpandMsgXmd(msg, dst, lenInBytes) + pseudoRandomBytes, err := hash_utils.ExpandMsgXmd(msg, dst, lenInBytes) if err != nil { return nil, err } diff --git a/ecc/bls24-317/fr/element.go b/ecc/bls24-317/fr/element.go index d60f89287..73baa975b 100644 --- a/ecc/bls24-317/fr/element.go +++ b/ecc/bls24-317/fr/element.go @@ -20,7 +20,7 @@ import ( "crypto/rand" "encoding/binary" "errors" - "github.com/consensys/gnark-crypto/hash" //TODO: Make sure gnark-crypto dependence is okay + "github.com/consensys/gnark-crypto/internal/hash_utils" //TODO: Make sure gnark-crypto dependence is okay "io" "math/big" "math/bits" @@ -768,7 +768,7 @@ func Hash(msg, dst []byte, count int) ([]Element, error) { const L = 16 + Bytes lenInBytes := count * L - pseudoRandomBytes, err := hash.ExpandMsgXmd(msg, dst, lenInBytes) + pseudoRandomBytes, err := hash_utils.ExpandMsgXmd(msg, dst, lenInBytes) if err != nil { return nil, err } diff --git a/ecc/bls24-317/hash_to_g1.go b/ecc/bls24-317/hash_to_g1.go index 410a05c93..cca8e8f5d 100644 --- a/ecc/bls24-317/hash_to_g1.go +++ b/ecc/bls24-317/hash_to_g1.go @@ -17,7 +17,6 @@ package bls24317 import ( - "github.com/consensys/gnark-crypto/ecc" "github.com/consensys/gnark-crypto/ecc/bls24-317/fp" "math/big" diff --git a/ecc/bls24-317/hash_to_g1_test.go b/ecc/bls24-317/hash_to_g1_test.go index 36c092f61..4abccacc1 100644 --- a/ecc/bls24-317/hash_to_g1_test.go +++ b/ecc/bls24-317/hash_to_g1_test.go @@ -62,7 +62,7 @@ func TestG1SqrtRatio(t *testing.T) { func TestHashToFpG1(t *testing.T) { for _, c := range encodeToG1Vector.cases { - elems, err := hashToFp([]byte(c.msg), encodeToG1Vector.dst, 1) + elems, err := fp.Hash([]byte(c.msg), encodeToG1Vector.dst, 1) if err != nil { t.Error(err) } @@ -70,7 +70,7 @@ func TestHashToFpG1(t *testing.T) { } for _, c := range hashToG1Vector.cases { - elems, err := hashToFp([]byte(c.msg), hashToG1Vector.dst, 2*1) + elems, err := fp.Hash([]byte(c.msg), hashToG1Vector.dst, 2*1) if err != nil { t.Error(err) } diff --git a/ecc/bn254/fp/element.go b/ecc/bn254/fp/element.go index d7c4affa0..37f3b3890 100644 --- a/ecc/bn254/fp/element.go +++ b/ecc/bn254/fp/element.go @@ -20,7 +20,7 @@ import ( "crypto/rand" "encoding/binary" "errors" - "github.com/consensys/gnark-crypto/hash" //TODO: Make sure gnark-crypto dependence is okay + "github.com/consensys/gnark-crypto/internal/hash_utils" //TODO: Make sure gnark-crypto dependence is okay "io" "math/big" "math/bits" @@ -768,7 +768,7 @@ func Hash(msg, dst []byte, count int) ([]Element, error) { const L = 16 + Bytes lenInBytes := count * L - pseudoRandomBytes, err := hash.ExpandMsgXmd(msg, dst, lenInBytes) + pseudoRandomBytes, err := hash_utils.ExpandMsgXmd(msg, dst, lenInBytes) if err != nil { return nil, err } diff --git a/ecc/bn254/fr/element.go b/ecc/bn254/fr/element.go index bd556ca34..39b2b47a4 100644 --- a/ecc/bn254/fr/element.go +++ b/ecc/bn254/fr/element.go @@ -20,7 +20,7 @@ import ( "crypto/rand" "encoding/binary" "errors" - "github.com/consensys/gnark-crypto/hash" //TODO: Make sure gnark-crypto dependence is okay + "github.com/consensys/gnark-crypto/internal/hash_utils" //TODO: Make sure gnark-crypto dependence is okay "io" "math/big" "math/bits" @@ -768,7 +768,7 @@ func Hash(msg, dst []byte, count int) ([]Element, error) { const L = 16 + Bytes lenInBytes := count * L - pseudoRandomBytes, err := hash.ExpandMsgXmd(msg, dst, lenInBytes) + pseudoRandomBytes, err := hash_utils.ExpandMsgXmd(msg, dst, lenInBytes) if err != nil { return nil, err } diff --git a/ecc/bn254/hash_to_g1.go b/ecc/bn254/hash_to_g1.go index 71f6c65c4..08760a914 100644 --- a/ecc/bn254/hash_to_g1.go +++ b/ecc/bn254/hash_to_g1.go @@ -17,7 +17,6 @@ package bn254 import ( - "github.com/consensys/gnark-crypto/ecc" "github.com/consensys/gnark-crypto/ecc/bn254/fp" ) diff --git a/ecc/bn254/hash_to_g1_test.go b/ecc/bn254/hash_to_g1_test.go index 549f16a35..da1b1312d 100644 --- a/ecc/bn254/hash_to_g1_test.go +++ b/ecc/bn254/hash_to_g1_test.go @@ -26,7 +26,7 @@ import ( func TestHashToFpG1(t *testing.T) { for _, c := range encodeToG1Vector.cases { - elems, err := hashToFp([]byte(c.msg), encodeToG1Vector.dst, 1) + elems, err := fp.Hash([]byte(c.msg), encodeToG1Vector.dst, 1) if err != nil { t.Error(err) } @@ -34,7 +34,7 @@ func TestHashToFpG1(t *testing.T) { } for _, c := range hashToG1Vector.cases { - elems, err := hashToFp([]byte(c.msg), hashToG1Vector.dst, 2*1) + elems, err := fp.Hash([]byte(c.msg), hashToG1Vector.dst, 2*1) if err != nil { t.Error(err) } diff --git a/ecc/bn254/hash_to_g2_test.go b/ecc/bn254/hash_to_g2_test.go index 588aff6e3..33e231c67 100644 --- a/ecc/bn254/hash_to_g2_test.go +++ b/ecc/bn254/hash_to_g2_test.go @@ -28,7 +28,7 @@ import ( func TestHashToFpG2(t *testing.T) { for _, c := range encodeToG2Vector.cases { - elems, err := hashToFp([]byte(c.msg), encodeToG2Vector.dst, 2) + elems, err := fp.Hash([]byte(c.msg), encodeToG2Vector.dst, 2) if err != nil { t.Error(err) } @@ -36,7 +36,7 @@ func TestHashToFpG2(t *testing.T) { } for _, c := range hashToG2Vector.cases { - elems, err := hashToFp([]byte(c.msg), hashToG2Vector.dst, 2*2) + elems, err := fp.Hash([]byte(c.msg), hashToG2Vector.dst, 2*2) if err != nil { t.Error(err) } diff --git a/ecc/bw6-633/fp/element.go b/ecc/bw6-633/fp/element.go index ee5e099d4..961b24f14 100644 --- a/ecc/bw6-633/fp/element.go +++ b/ecc/bw6-633/fp/element.go @@ -20,7 +20,7 @@ import ( "crypto/rand" "encoding/binary" "errors" - "github.com/consensys/gnark-crypto/hash" //TODO: Make sure gnark-crypto dependence is okay + "github.com/consensys/gnark-crypto/internal/hash_utils" //TODO: Make sure gnark-crypto dependence is okay "io" "math/big" "math/bits" @@ -1314,7 +1314,7 @@ func Hash(msg, dst []byte, count int) ([]Element, error) { const L = 16 + Bytes lenInBytes := count * L - pseudoRandomBytes, err := hash.ExpandMsgXmd(msg, dst, lenInBytes) + pseudoRandomBytes, err := hash_utils.ExpandMsgXmd(msg, dst, lenInBytes) if err != nil { return nil, err } diff --git a/ecc/bw6-633/fr/element.go b/ecc/bw6-633/fr/element.go index a16f989b4..7d53965de 100644 --- a/ecc/bw6-633/fr/element.go +++ b/ecc/bw6-633/fr/element.go @@ -20,7 +20,7 @@ import ( "crypto/rand" "encoding/binary" "errors" - "github.com/consensys/gnark-crypto/hash" //TODO: Make sure gnark-crypto dependence is okay + "github.com/consensys/gnark-crypto/internal/hash_utils" //TODO: Make sure gnark-crypto dependence is okay "io" "math/big" "math/bits" @@ -844,7 +844,7 @@ func Hash(msg, dst []byte, count int) ([]Element, error) { const L = 16 + Bytes lenInBytes := count * L - pseudoRandomBytes, err := hash.ExpandMsgXmd(msg, dst, lenInBytes) + pseudoRandomBytes, err := hash_utils.ExpandMsgXmd(msg, dst, lenInBytes) if err != nil { return nil, err } diff --git a/ecc/bw6-633/hash_to_g1.go b/ecc/bw6-633/hash_to_g1.go index e8486293d..c3a84cd8f 100644 --- a/ecc/bw6-633/hash_to_g1.go +++ b/ecc/bw6-633/hash_to_g1.go @@ -17,7 +17,6 @@ package bw6633 import ( - "github.com/consensys/gnark-crypto/ecc" "github.com/consensys/gnark-crypto/ecc/bw6-633/fp" "math/big" diff --git a/ecc/bw6-633/hash_to_g1_test.go b/ecc/bw6-633/hash_to_g1_test.go index 3ac05c2c4..8d299c729 100644 --- a/ecc/bw6-633/hash_to_g1_test.go +++ b/ecc/bw6-633/hash_to_g1_test.go @@ -62,7 +62,7 @@ func TestG1SqrtRatio(t *testing.T) { func TestHashToFpG1(t *testing.T) { for _, c := range encodeToG1Vector.cases { - elems, err := hashToFp([]byte(c.msg), encodeToG1Vector.dst, 1) + elems, err := fp.Hash([]byte(c.msg), encodeToG1Vector.dst, 1) if err != nil { t.Error(err) } @@ -70,7 +70,7 @@ func TestHashToFpG1(t *testing.T) { } for _, c := range hashToG1Vector.cases { - elems, err := hashToFp([]byte(c.msg), hashToG1Vector.dst, 2*1) + elems, err := fp.Hash([]byte(c.msg), hashToG1Vector.dst, 2*1) if err != nil { t.Error(err) } diff --git a/ecc/bw6-633/hash_to_g2_test.go b/ecc/bw6-633/hash_to_g2_test.go index 4458c56e1..130f43a0a 100644 --- a/ecc/bw6-633/hash_to_g2_test.go +++ b/ecc/bw6-633/hash_to_g2_test.go @@ -62,7 +62,7 @@ func TestG2SqrtRatio(t *testing.T) { func TestHashToFpG2(t *testing.T) { for _, c := range encodeToG2Vector.cases { - elems, err := hashToFp([]byte(c.msg), encodeToG2Vector.dst, 1) + elems, err := fp.Hash([]byte(c.msg), encodeToG2Vector.dst, 1) if err != nil { t.Error(err) } @@ -70,7 +70,7 @@ func TestHashToFpG2(t *testing.T) { } for _, c := range hashToG2Vector.cases { - elems, err := hashToFp([]byte(c.msg), hashToG2Vector.dst, 2*1) + elems, err := fp.Hash([]byte(c.msg), hashToG2Vector.dst, 2*1) if err != nil { t.Error(err) } diff --git a/ecc/bw6-756/fp/element.go b/ecc/bw6-756/fp/element.go index f6a6b7348..346596cf9 100644 --- a/ecc/bw6-756/fp/element.go +++ b/ecc/bw6-756/fp/element.go @@ -20,7 +20,7 @@ import ( "crypto/rand" "encoding/binary" "errors" - "github.com/consensys/gnark-crypto/hash" //TODO: Make sure gnark-crypto dependence is okay + "github.com/consensys/gnark-crypto/internal/hash_utils" //TODO: Make sure gnark-crypto dependence is okay "io" "math/big" "math/bits" @@ -1544,7 +1544,7 @@ func Hash(msg, dst []byte, count int) ([]Element, error) { const L = 16 + Bytes lenInBytes := count * L - pseudoRandomBytes, err := hash.ExpandMsgXmd(msg, dst, lenInBytes) + pseudoRandomBytes, err := hash_utils.ExpandMsgXmd(msg, dst, lenInBytes) if err != nil { return nil, err } diff --git a/ecc/bw6-756/fr/element.go b/ecc/bw6-756/fr/element.go index aaa10e188..0769f6f44 100644 --- a/ecc/bw6-756/fr/element.go +++ b/ecc/bw6-756/fr/element.go @@ -20,7 +20,7 @@ import ( "crypto/rand" "encoding/binary" "errors" - "github.com/consensys/gnark-crypto/hash" //TODO: Make sure gnark-crypto dependence is okay + "github.com/consensys/gnark-crypto/internal/hash_utils" //TODO: Make sure gnark-crypto dependence is okay "io" "math/big" "math/bits" @@ -926,7 +926,7 @@ func Hash(msg, dst []byte, count int) ([]Element, error) { const L = 16 + Bytes lenInBytes := count * L - pseudoRandomBytes, err := hash.ExpandMsgXmd(msg, dst, lenInBytes) + pseudoRandomBytes, err := hash_utils.ExpandMsgXmd(msg, dst, lenInBytes) if err != nil { return nil, err } diff --git a/ecc/bw6-756/hash_to_g1.go b/ecc/bw6-756/hash_to_g1.go index b71f628d3..876bee040 100644 --- a/ecc/bw6-756/hash_to_g1.go +++ b/ecc/bw6-756/hash_to_g1.go @@ -17,7 +17,6 @@ package bw6756 import ( - "github.com/consensys/gnark-crypto/ecc" "github.com/consensys/gnark-crypto/ecc/bw6-756/fp" "math/big" diff --git a/ecc/bw6-756/hash_to_g1_test.go b/ecc/bw6-756/hash_to_g1_test.go index b0e0000b9..7a7b2dbcf 100644 --- a/ecc/bw6-756/hash_to_g1_test.go +++ b/ecc/bw6-756/hash_to_g1_test.go @@ -62,7 +62,7 @@ func TestG1SqrtRatio(t *testing.T) { func TestHashToFpG1(t *testing.T) { for _, c := range encodeToG1Vector.cases { - elems, err := hashToFp([]byte(c.msg), encodeToG1Vector.dst, 1) + elems, err := fp.Hash([]byte(c.msg), encodeToG1Vector.dst, 1) if err != nil { t.Error(err) } @@ -70,7 +70,7 @@ func TestHashToFpG1(t *testing.T) { } for _, c := range hashToG1Vector.cases { - elems, err := hashToFp([]byte(c.msg), hashToG1Vector.dst, 2*1) + elems, err := fp.Hash([]byte(c.msg), hashToG1Vector.dst, 2*1) if err != nil { t.Error(err) } diff --git a/ecc/bw6-756/hash_to_g2_test.go b/ecc/bw6-756/hash_to_g2_test.go index 9dee3c67c..4ec5aa85b 100644 --- a/ecc/bw6-756/hash_to_g2_test.go +++ b/ecc/bw6-756/hash_to_g2_test.go @@ -62,7 +62,7 @@ func TestG2SqrtRatio(t *testing.T) { func TestHashToFpG2(t *testing.T) { for _, c := range encodeToG2Vector.cases { - elems, err := hashToFp([]byte(c.msg), encodeToG2Vector.dst, 1) + elems, err := fp.Hash([]byte(c.msg), encodeToG2Vector.dst, 1) if err != nil { t.Error(err) } @@ -70,7 +70,7 @@ func TestHashToFpG2(t *testing.T) { } for _, c := range hashToG2Vector.cases { - elems, err := hashToFp([]byte(c.msg), hashToG2Vector.dst, 2*1) + elems, err := fp.Hash([]byte(c.msg), hashToG2Vector.dst, 2*1) if err != nil { t.Error(err) } diff --git a/ecc/bw6-761/fp/element.go b/ecc/bw6-761/fp/element.go index 19216cfce..40ffd380b 100644 --- a/ecc/bw6-761/fp/element.go +++ b/ecc/bw6-761/fp/element.go @@ -20,7 +20,7 @@ import ( "crypto/rand" "encoding/binary" "errors" - "github.com/consensys/gnark-crypto/hash" //TODO: Make sure gnark-crypto dependence is okay + "github.com/consensys/gnark-crypto/internal/hash_utils" //TODO: Make sure gnark-crypto dependence is okay "io" "math/big" "math/bits" @@ -1544,7 +1544,7 @@ func Hash(msg, dst []byte, count int) ([]Element, error) { const L = 16 + Bytes lenInBytes := count * L - pseudoRandomBytes, err := hash.ExpandMsgXmd(msg, dst, lenInBytes) + pseudoRandomBytes, err := hash_utils.ExpandMsgXmd(msg, dst, lenInBytes) if err != nil { return nil, err } diff --git a/ecc/bw6-761/fr/element.go b/ecc/bw6-761/fr/element.go index 340f50c82..1ca6ee1b7 100644 --- a/ecc/bw6-761/fr/element.go +++ b/ecc/bw6-761/fr/element.go @@ -20,7 +20,7 @@ import ( "crypto/rand" "encoding/binary" "errors" - "github.com/consensys/gnark-crypto/hash" //TODO: Make sure gnark-crypto dependence is okay + "github.com/consensys/gnark-crypto/internal/hash_utils" //TODO: Make sure gnark-crypto dependence is okay "io" "math/big" "math/bits" @@ -926,7 +926,7 @@ func Hash(msg, dst []byte, count int) ([]Element, error) { const L = 16 + Bytes lenInBytes := count * L - pseudoRandomBytes, err := hash.ExpandMsgXmd(msg, dst, lenInBytes) + pseudoRandomBytes, err := hash_utils.ExpandMsgXmd(msg, dst, lenInBytes) if err != nil { return nil, err } diff --git a/ecc/bw6-761/hash_to_g1.go b/ecc/bw6-761/hash_to_g1.go index b8d5321c3..b1825197d 100644 --- a/ecc/bw6-761/hash_to_g1.go +++ b/ecc/bw6-761/hash_to_g1.go @@ -17,7 +17,6 @@ package bw6761 import ( - "github.com/consensys/gnark-crypto/ecc" "github.com/consensys/gnark-crypto/ecc/bw6-761/fp" "math/big" diff --git a/ecc/bw6-761/hash_to_g1_test.go b/ecc/bw6-761/hash_to_g1_test.go index 835ec8f1c..a268f8b0e 100644 --- a/ecc/bw6-761/hash_to_g1_test.go +++ b/ecc/bw6-761/hash_to_g1_test.go @@ -62,7 +62,7 @@ func TestG1SqrtRatio(t *testing.T) { func TestHashToFpG1(t *testing.T) { for _, c := range encodeToG1Vector.cases { - elems, err := hashToFp([]byte(c.msg), encodeToG1Vector.dst, 1) + elems, err := fp.Hash([]byte(c.msg), encodeToG1Vector.dst, 1) if err != nil { t.Error(err) } @@ -70,7 +70,7 @@ func TestHashToFpG1(t *testing.T) { } for _, c := range hashToG1Vector.cases { - elems, err := hashToFp([]byte(c.msg), hashToG1Vector.dst, 2*1) + elems, err := fp.Hash([]byte(c.msg), hashToG1Vector.dst, 2*1) if err != nil { t.Error(err) } diff --git a/ecc/bw6-761/hash_to_g2_test.go b/ecc/bw6-761/hash_to_g2_test.go index 9728fd757..246016b4c 100644 --- a/ecc/bw6-761/hash_to_g2_test.go +++ b/ecc/bw6-761/hash_to_g2_test.go @@ -62,7 +62,7 @@ func TestG2SqrtRatio(t *testing.T) { func TestHashToFpG2(t *testing.T) { for _, c := range encodeToG2Vector.cases { - elems, err := hashToFp([]byte(c.msg), encodeToG2Vector.dst, 1) + elems, err := fp.Hash([]byte(c.msg), encodeToG2Vector.dst, 1) if err != nil { t.Error(err) } @@ -70,7 +70,7 @@ func TestHashToFpG2(t *testing.T) { } for _, c := range hashToG2Vector.cases { - elems, err := hashToFp([]byte(c.msg), hashToG2Vector.dst, 2*1) + elems, err := fp.Hash([]byte(c.msg), hashToG2Vector.dst, 2*1) if err != nil { t.Error(err) } diff --git a/internal/field/internal/templates/element/base.go b/internal/field/internal/templates/element/base.go index a158b32d6..86a62ca66 100644 --- a/internal/field/internal/templates/element/base.go +++ b/internal/field/internal/templates/element/base.go @@ -3,7 +3,7 @@ package element const Base = ` import ( - "github.com/consensys/gnark-crypto/hash" //TODO: Make sure gnark-crypto dependence is okay + "github.com/consensys/gnark-crypto/internal/hash_utils" //TODO: Make sure gnark-crypto dependence is okay "math/big" "math/bits" "io" @@ -636,7 +636,7 @@ func Hash(msg, dst []byte, count int) ([]{{.ElementName}}, error) { const L = 16 + Bytes lenInBytes := count * L - pseudoRandomBytes, err := hash.ExpandMsgXmd(msg, dst, lenInBytes) + pseudoRandomBytes, err := hash_utils.ExpandMsgXmd(msg, dst, lenInBytes) if err != nil { return nil, err } diff --git a/internal/generator/ecc/template/hash_to_curve.go.tmpl b/internal/generator/ecc/template/hash_to_curve.go.tmpl index 260968c9d..e74be2eed 100644 --- a/internal/generator/ecc/template/hash_to_curve.go.tmpl +++ b/internal/generator/ecc/template/hash_to_curve.go.tmpl @@ -14,9 +14,6 @@ import( {{- if not (eq $TowerDegree 1) }} "github.com/consensys/gnark-crypto/ecc/{{.Name}}/internal/fptower" {{- end}} - {{- if $IsG1}} - "github.com/consensys/gnark-crypto/ecc" - {{- end}} {{if eq $.MappingAlgorithm "SSWU"}} {{template "sswu" .}} diff --git a/internal/generator/ecc/template/tests/hash_to_curve.go.tmpl b/internal/generator/ecc/template/tests/hash_to_curve.go.tmpl index 7739ea75f..053eaf753 100644 --- a/internal/generator/ecc/template/tests/hash_to_curve.go.tmpl +++ b/internal/generator/ecc/template/tests/hash_to_curve.go.tmpl @@ -68,7 +68,7 @@ func Test{{$CurveTitle}}SqrtRatio(t *testing.T) { func TestHashToFp{{$CurveTitle}}(t *testing.T) { for _, c := range encodeTo{{$CurveTitle}}Vector.cases { - elems, err := hashToFp([]byte(c.msg), encodeTo{{$CurveTitle}}Vector.dst, {{$TowerDegree}}) + elems, err := fp.Hash([]byte(c.msg), encodeTo{{$CurveTitle}}Vector.dst, {{$TowerDegree}}) if err != nil { t.Error(err) } @@ -76,7 +76,7 @@ func TestHashToFp{{$CurveTitle}}(t *testing.T) { } for _, c := range hashTo{{$CurveTitle}}Vector.cases { - elems, err := hashToFp([]byte(c.msg), hashTo{{$CurveTitle}}Vector.dst, 2 * {{$TowerDegree}}) + elems, err := fp.Hash([]byte(c.msg), hashTo{{$CurveTitle}}Vector.dst, 2 * {{$TowerDegree}}) if err != nil { t.Error(err) } diff --git a/hash/hash_utils.go b/internal/hash_utils/hash_utils.go similarity index 99% rename from hash/hash_utils.go rename to internal/hash_utils/hash_utils.go index db7cff3e1..aab72ee3f 100644 --- a/hash/hash_utils.go +++ b/internal/hash_utils/hash_utils.go @@ -1,4 +1,4 @@ -package hash +package hash_utils import ( "crypto/sha256" From 686b15cea85791b6587582d6a058860daa9a7fa5 Mon Sep 17 00:00:00 2001 From: Arya Tabaie Date: Fri, 18 Nov 2022 18:01:41 -0500 Subject: [PATCH 3/6] fix: minor errors --- ecc/bls12-378/hash_to_g2.go | 4 +- ecc/bls24-315/hash_to_g2.go | 4 +- ecc/bls24-317/hash_to_g2.go | 4 +- ecc/utils_test.go | 127 ------------------------ internal/hash_utils/hash_utils_test.go | 132 +++++++++++++++++++++++++ 5 files changed, 138 insertions(+), 133 deletions(-) create mode 100644 internal/hash_utils/hash_utils_test.go diff --git a/ecc/bls12-378/hash_to_g2.go b/ecc/bls12-378/hash_to_g2.go index 354fcc14d..d20ff1a77 100644 --- a/ecc/bls12-378/hash_to_g2.go +++ b/ecc/bls12-378/hash_to_g2.go @@ -100,7 +100,7 @@ func MapToG2(t fptower.E2) G2Affine { // https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#section-2.2.2 func EncodeToG2(msg, dst []byte) (G2Affine, error) { var res G2Affine - _t, err := hashToFp(msg, dst, 2) + _t, err := fp.Hash(msg, dst, 2) if err != nil { return res, err } @@ -115,7 +115,7 @@ func EncodeToG2(msg, dst []byte) (G2Affine, error) { // https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#section-3 func HashToG2(msg, dst []byte) (G2Affine, error) { var res G2Affine - u, err := hashToFp(msg, dst, 4) + u, err := fp.Hash(msg, dst, 4) if err != nil { return res, err } diff --git a/ecc/bls24-315/hash_to_g2.go b/ecc/bls24-315/hash_to_g2.go index 3686bba0e..2a4b37a32 100644 --- a/ecc/bls24-315/hash_to_g2.go +++ b/ecc/bls24-315/hash_to_g2.go @@ -107,7 +107,7 @@ func MapToG2(t fptower.E4) G2Affine { // https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#section-2.2.2 func EncodeToG2(msg, dst []byte) (G2Affine, error) { var res G2Affine - _t, err := hashToFp(msg, dst, 2) + _t, err := fp.Hash(msg, dst, 2) if err != nil { return res, err } @@ -122,7 +122,7 @@ func EncodeToG2(msg, dst []byte) (G2Affine, error) { // https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#section-3 func HashToG2(msg, dst []byte) (G2Affine, error) { var res G2Affine - u, err := hashToFp(msg, dst, 4) + u, err := fp.Hash(msg, dst, 4) if err != nil { return res, err } diff --git a/ecc/bls24-317/hash_to_g2.go b/ecc/bls24-317/hash_to_g2.go index ea3fab244..6e2411b78 100644 --- a/ecc/bls24-317/hash_to_g2.go +++ b/ecc/bls24-317/hash_to_g2.go @@ -106,7 +106,7 @@ func MapToG2(t fptower.E4) G2Affine { // https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#section-2.2.2 func EncodeToG2(msg, dst []byte) (G2Affine, error) { var res G2Affine - _t, err := hashToFp(msg, dst, 2) + _t, err := fp.Hash(msg, dst, 2) if err != nil { return res, err } @@ -121,7 +121,7 @@ func EncodeToG2(msg, dst []byte) (G2Affine, error) { // https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#section-3 func HashToG2(msg, dst []byte) (G2Affine, error) { var res G2Affine - u, err := hashToFp(msg, dst, 4) + u, err := fp.Hash(msg, dst, 4) if err != nil { return res, err } diff --git a/ecc/utils_test.go b/ecc/utils_test.go index 81a788843..3bd9e483a 100644 --- a/ecc/utils_test.go +++ b/ecc/utils_test.go @@ -1,8 +1,6 @@ package ecc import ( - "bytes" - "encoding/hex" "math/big" "testing" ) @@ -61,128 +59,3 @@ func BenchmarkSplitting256(b *testing.B) { } } - -type expandMsgXmdTestCase struct { - msg string - lenInBytes int - uniformBytesHex string -} - -// Test vectors from https://datatracker.ietf.org/doc/draft-irtf-cfrg-hash-to-curve/14/ Page 148 Section K.1. -func TestExpandMsgXmd(t *testing.T) { - //name := "expand_message_xmd" - dst := "QUUX-V01-CS02-with-expander-SHA256-128" - //hash := "SHA256" - //k := 128 - - testCases := []expandMsgXmdTestCase{ - { - "", - 0x20, - "68a985b87eb6b46952128911f2a4412bbc302a9d759667f87f7a21d803f07235", - }, - - { - "abc", - 0x20, - "d8ccab23b5985ccea865c6c97b6e5b8350e794e603b4b97902f53a8a0d605615", - }, - - { - "abcdef0123456789", - 0x20, - "eff31487c770a893cfb36f912fbfcbff40d5661771ca4b2cb4eafe524333f5c1", - }, - - { - "q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq", - 0x20, - "b23a1d2b4d97b2ef7785562a7e8bac7eed54ed6e97e29aa51bfe3f12ddad1ff9", - }, - - { - "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - 0x20, - "4623227bcc01293b8c130bf771da8c298dede7383243dc0993d2d94823958c4c", - }, - { - "", - 0x80, - "af84c27ccfd45d41914fdff5df25293e221afc53d8ad2ac06d5e3e29485dadbee0d121587713a3e0dd4d5e69e93eb7cd4f5df4cd103e188cf60cb02edc3edf18eda8576c412b18ffb658e3dd6ec849469b979d444cf7b26911a08e63cf31f9dcc541708d3491184472c2c29bb749d4286b004ceb5ee6b9a7fa5b646c993f0ced", - }, - { - "", - 0x20, - "68a985b87eb6b46952128911f2a4412bbc302a9d759667f87f7a21d803f07235", - }, - { - "abc", - 0x80, - "abba86a6129e366fc877aab32fc4ffc70120d8996c88aee2fe4b32d6c7b6437a647e6c3163d40b76a73cf6a5674ef1d890f95b664ee0afa5359a5c4e07985635bbecbac65d747d3d2da7ec2b8221b17b0ca9dc8a1ac1c07ea6a1e60583e2cb00058e77b7b72a298425cd1b941ad4ec65e8afc50303a22c0f99b0509b4c895f40", - }, - { - "abcdef0123456789", - 0x80, - "ef904a29bffc4cf9ee82832451c946ac3c8f8058ae97d8d629831a74c6572bd9ebd0df635cd1f208e2038e760c4994984ce73f0d55ea9f22af83ba4734569d4bc95e18350f740c07eef653cbb9f87910d833751825f0ebefa1abe5420bb52be14cf489b37fe1a72f7de2d10be453b2c9d9eb20c7e3f6edc5a60629178d9478df", - }, - { - "q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq", - 0x80, - "80be107d0884f0d881bb460322f0443d38bd222db8bd0b0a5312a6fedb49c1bbd88fd75d8b9a09486c60123dfa1d73c1cc3169761b17476d3c6b7cbbd727acd0e2c942f4dd96ae3da5de368d26b32286e32de7e5a8cb2949f866a0b80c58116b29fa7fabb3ea7d520ee603e0c25bcaf0b9a5e92ec6a1fe4e0391d1cdbce8c68a", - }, - { - "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - 0x80, - "546aff5444b5b79aa6148bd81728704c32decb73a3ba76e9e75885cad9def1d06d6792f8a7d12794e90efed817d96920d728896a4510864370c207f99bd4a608ea121700ef01ed879745ee3e4ceef777eda6d9e5e38b90c86ea6fb0b36504ba4a45d22e86f6db5dd43d98a294bebb9125d5b794e9d2a81181066eb954966a487", - }, - //test cases not in the standard - { - "", - 0x30, - "3808e9bb0ade2df3aa6f1b459eb5058a78142f439213ddac0c97dcab92ae5a8408d86b32bbcc87de686182cbdf65901f", - }, - { - "abc", - 0x30, - "2b877f5f0dfd881405426c6b87b39205ef53a548b0e4d567fc007cb37c6fa1f3b19f42871efefca518ac950c27ac4e28", - }, - { - "abcdef0123456789", - 0x30, - "226da1780b06e59723714f80da9a63648aebcfc1f08e0db87b5b4d16b108da118214c1450b0e86f9cefeb44903fd3aba", - }, - { - "q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq", - 0x30, - "12b23ae2e888f442fd6d0d85d90a0d7ed5337d38113e89cdc7c22db91bd0abaec1023e9a8f0ef583a111104e2f8a0637", - }, - { - "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - 0x30, - "1aaee90016547a85ab4dc55e4f78a364c2e239c0e58b05753453c63e6e818334005e90d9ce8f047bddab9fbb315f8722", - }, - } - - for _, testCase := range testCases { - uniformBytes, err := ExpandMsgXmd([]byte(testCase.msg), []byte(dst), testCase.lenInBytes) - if err != nil { - t.Fatal(err) - } - - var testCaseUniformBytes []byte - testCaseUniformBytes, err = hex.DecodeString(testCase.uniformBytesHex) - if err != nil { - t.Fatal(err) - } - - if len(uniformBytes) != testCase.lenInBytes { - t.Error("wrong length: expected", testCase.lenInBytes, "got", len(uniformBytes)) - } - - if !bytes.Equal(uniformBytes, testCaseUniformBytes) { - uniformBytesHex := make([]byte, len(uniformBytes)*2) - hex.Encode(uniformBytesHex, uniformBytes) - t.Errorf("expected \"%s\" got \"%s\"", testCase.uniformBytesHex, uniformBytesHex) - } - } -} diff --git a/internal/hash_utils/hash_utils_test.go b/internal/hash_utils/hash_utils_test.go new file mode 100644 index 000000000..dc43fd2ed --- /dev/null +++ b/internal/hash_utils/hash_utils_test.go @@ -0,0 +1,132 @@ +package hash_utils + +import ( + "bytes" + "encoding/hex" + "testing" +) + +type expandMsgXmdTestCase struct { + msg string + lenInBytes int + uniformBytesHex string +} + +// Test vectors from https://datatracker.ietf.org/doc/draft-irtf-cfrg-hash-to-curve/14/ Page 148 Section K.1. +func TestExpandMsgXmd(t *testing.T) { + //name := "expand_message_xmd" + dst := "QUUX-V01-CS02-with-expander-SHA256-128" + //hash := "SHA256" + //k := 128 + + testCases := []expandMsgXmdTestCase{ + { + "", + 0x20, + "68a985b87eb6b46952128911f2a4412bbc302a9d759667f87f7a21d803f07235", + }, + + { + "abc", + 0x20, + "d8ccab23b5985ccea865c6c97b6e5b8350e794e603b4b97902f53a8a0d605615", + }, + + { + "abcdef0123456789", + 0x20, + "eff31487c770a893cfb36f912fbfcbff40d5661771ca4b2cb4eafe524333f5c1", + }, + + { + "q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq", + 0x20, + "b23a1d2b4d97b2ef7785562a7e8bac7eed54ed6e97e29aa51bfe3f12ddad1ff9", + }, + + { + "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + 0x20, + "4623227bcc01293b8c130bf771da8c298dede7383243dc0993d2d94823958c4c", + }, + { + "", + 0x80, + "af84c27ccfd45d41914fdff5df25293e221afc53d8ad2ac06d5e3e29485dadbee0d121587713a3e0dd4d5e69e93eb7cd4f5df4cd103e188cf60cb02edc3edf18eda8576c412b18ffb658e3dd6ec849469b979d444cf7b26911a08e63cf31f9dcc541708d3491184472c2c29bb749d4286b004ceb5ee6b9a7fa5b646c993f0ced", + }, + { + "", + 0x20, + "68a985b87eb6b46952128911f2a4412bbc302a9d759667f87f7a21d803f07235", + }, + { + "abc", + 0x80, + "abba86a6129e366fc877aab32fc4ffc70120d8996c88aee2fe4b32d6c7b6437a647e6c3163d40b76a73cf6a5674ef1d890f95b664ee0afa5359a5c4e07985635bbecbac65d747d3d2da7ec2b8221b17b0ca9dc8a1ac1c07ea6a1e60583e2cb00058e77b7b72a298425cd1b941ad4ec65e8afc50303a22c0f99b0509b4c895f40", + }, + { + "abcdef0123456789", + 0x80, + "ef904a29bffc4cf9ee82832451c946ac3c8f8058ae97d8d629831a74c6572bd9ebd0df635cd1f208e2038e760c4994984ce73f0d55ea9f22af83ba4734569d4bc95e18350f740c07eef653cbb9f87910d833751825f0ebefa1abe5420bb52be14cf489b37fe1a72f7de2d10be453b2c9d9eb20c7e3f6edc5a60629178d9478df", + }, + { + "q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq", + 0x80, + "80be107d0884f0d881bb460322f0443d38bd222db8bd0b0a5312a6fedb49c1bbd88fd75d8b9a09486c60123dfa1d73c1cc3169761b17476d3c6b7cbbd727acd0e2c942f4dd96ae3da5de368d26b32286e32de7e5a8cb2949f866a0b80c58116b29fa7fabb3ea7d520ee603e0c25bcaf0b9a5e92ec6a1fe4e0391d1cdbce8c68a", + }, + { + "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + 0x80, + "546aff5444b5b79aa6148bd81728704c32decb73a3ba76e9e75885cad9def1d06d6792f8a7d12794e90efed817d96920d728896a4510864370c207f99bd4a608ea121700ef01ed879745ee3e4ceef777eda6d9e5e38b90c86ea6fb0b36504ba4a45d22e86f6db5dd43d98a294bebb9125d5b794e9d2a81181066eb954966a487", + }, + //test cases not in the standard + { + "", + 0x30, + "3808e9bb0ade2df3aa6f1b459eb5058a78142f439213ddac0c97dcab92ae5a8408d86b32bbcc87de686182cbdf65901f", + }, + { + "abc", + 0x30, + "2b877f5f0dfd881405426c6b87b39205ef53a548b0e4d567fc007cb37c6fa1f3b19f42871efefca518ac950c27ac4e28", + }, + { + "abcdef0123456789", + 0x30, + "226da1780b06e59723714f80da9a63648aebcfc1f08e0db87b5b4d16b108da118214c1450b0e86f9cefeb44903fd3aba", + }, + { + "q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq", + 0x30, + "12b23ae2e888f442fd6d0d85d90a0d7ed5337d38113e89cdc7c22db91bd0abaec1023e9a8f0ef583a111104e2f8a0637", + }, + { + "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + 0x30, + "1aaee90016547a85ab4dc55e4f78a364c2e239c0e58b05753453c63e6e818334005e90d9ce8f047bddab9fbb315f8722", + }, + } + + for _, testCase := range testCases { + uniformBytes, err := ExpandMsgXmd([]byte(testCase.msg), []byte(dst), testCase.lenInBytes) + if err != nil { + t.Fatal(err) + } + + var testCaseUniformBytes []byte + testCaseUniformBytes, err = hex.DecodeString(testCase.uniformBytesHex) + if err != nil { + t.Fatal(err) + } + + if len(uniformBytes) != testCase.lenInBytes { + t.Error("wrong length: expected", testCase.lenInBytes, "got", len(uniformBytes)) + } + + if !bytes.Equal(uniformBytes, testCaseUniformBytes) { + uniformBytesHex := make([]byte, len(uniformBytes)*2) + hex.Encode(uniformBytesHex, uniformBytes) + t.Errorf("expected \"%s\" got \"%s\"", testCase.uniformBytesHex, uniformBytesHex) + } + } +} From deefed58576ec42ddc72e2fe1bfa47846aeea4a2 Mon Sep 17 00:00:00 2001 From: Arya Tabaie Date: Fri, 18 Nov 2022 18:05:37 -0500 Subject: [PATCH 4/6] fix: generate goldilocks --- field/goldilocks/element.go | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/field/goldilocks/element.go b/field/goldilocks/element.go index 3d8375be9..9f2ef23b6 100644 --- a/field/goldilocks/element.go +++ b/field/goldilocks/element.go @@ -20,6 +20,7 @@ import ( "crypto/rand" "encoding/binary" "errors" + "github.com/consensys/gnark-crypto/internal/hash_utils" //TODO: Make sure gnark-crypto dependence is okay "io" "math/big" "math/bits" @@ -563,6 +564,27 @@ func (z *Element) BitLen() int { return bits.Len64(z[0]) } +// Hash msg to count prime field elements. +// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#section-5.2 +func Hash(msg, dst []byte, count int) ([]Element, error) { + // 128 bits of security + // L = ceil((ceil(log2(p)) + k) / 8), where k is the security parameter = 128 + const Bytes = 1 + (Bits-1)/8 + const L = 16 + Bytes + + lenInBytes := count * L + pseudoRandomBytes, err := hash_utils.ExpandMsgXmd(msg, dst, lenInBytes) + if err != nil { + return nil, err + } + + res := make([]Element, count) + for i := 0; i < count; i++ { + res[i].SetBytes(pseudoRandomBytes[i*L : (i+1)*L]) + } + return res, nil +} + // Exp z = xᵏ (mod q) func (z *Element) Exp(x Element, k *big.Int) *Element { if k.IsUint64() && k.Uint64() == 0 { From 7f2211184c765da7b2e455484c46c9dd2038847d Mon Sep 17 00:00:00 2001 From: Arya Tabaie Date: Mon, 21 Nov 2022 15:33:15 -0500 Subject: [PATCH 5/6] style: a better package name --- ecc/bls12-377/fp/element.go | 4 ++-- ecc/bls12-377/fr/element.go | 4 ++-- ecc/bls12-378/fp/element.go | 4 ++-- ecc/bls12-378/fr/element.go | 4 ++-- ecc/bls12-381/fp/element.go | 4 ++-- ecc/bls12-381/fr/element.go | 4 ++-- ecc/bls24-315/fp/element.go | 4 ++-- ecc/bls24-315/fr/element.go | 4 ++-- ecc/bls24-317/fp/element.go | 4 ++-- ecc/bls24-317/fr/element.go | 4 ++-- ecc/bn254/fp/element.go | 4 ++-- ecc/bn254/fr/element.go | 4 ++-- ecc/bw6-633/fp/element.go | 4 ++-- ecc/bw6-633/fr/element.go | 4 ++-- ecc/bw6-756/fp/element.go | 4 ++-- ecc/bw6-756/fr/element.go | 4 ++-- ecc/bw6-761/fp/element.go | 4 ++-- ecc/bw6-761/fr/element.go | 4 ++-- field/goldilocks/element.go | 4 ++-- internal/field/internal/templates/element/base.go | 4 ++-- internal/{hash_utils/hash_utils.go => hashutils/hashutils.go} | 2 +- .../hash_utils_test.go => hashutils/hashutils_test.go} | 2 +- 22 files changed, 42 insertions(+), 42 deletions(-) rename internal/{hash_utils/hash_utils.go => hashutils/hashutils.go} (99%) rename internal/{hash_utils/hash_utils_test.go => hashutils/hashutils_test.go} (99%) diff --git a/ecc/bls12-377/fp/element.go b/ecc/bls12-377/fp/element.go index 11817c6db..776ea9614 100644 --- a/ecc/bls12-377/fp/element.go +++ b/ecc/bls12-377/fp/element.go @@ -20,7 +20,7 @@ import ( "crypto/rand" "encoding/binary" "errors" - "github.com/consensys/gnark-crypto/internal/hash_utils" //TODO: Make sure gnark-crypto dependence is okay + "github.com/consensys/gnark-crypto/internal/hashutils" "io" "math/big" "math/bits" @@ -926,7 +926,7 @@ func Hash(msg, dst []byte, count int) ([]Element, error) { const L = 16 + Bytes lenInBytes := count * L - pseudoRandomBytes, err := hash_utils.ExpandMsgXmd(msg, dst, lenInBytes) + pseudoRandomBytes, err := hashutils.ExpandMsgXmd(msg, dst, lenInBytes) if err != nil { return nil, err } diff --git a/ecc/bls12-377/fr/element.go b/ecc/bls12-377/fr/element.go index eadccaae8..fd50cdfa2 100644 --- a/ecc/bls12-377/fr/element.go +++ b/ecc/bls12-377/fr/element.go @@ -20,7 +20,7 @@ import ( "crypto/rand" "encoding/binary" "errors" - "github.com/consensys/gnark-crypto/internal/hash_utils" //TODO: Make sure gnark-crypto dependence is okay + "github.com/consensys/gnark-crypto/internal/hashutils" "io" "math/big" "math/bits" @@ -768,7 +768,7 @@ func Hash(msg, dst []byte, count int) ([]Element, error) { const L = 16 + Bytes lenInBytes := count * L - pseudoRandomBytes, err := hash_utils.ExpandMsgXmd(msg, dst, lenInBytes) + pseudoRandomBytes, err := hashutils.ExpandMsgXmd(msg, dst, lenInBytes) if err != nil { return nil, err } diff --git a/ecc/bls12-378/fp/element.go b/ecc/bls12-378/fp/element.go index 93e1e1b13..72f70ab35 100644 --- a/ecc/bls12-378/fp/element.go +++ b/ecc/bls12-378/fp/element.go @@ -20,7 +20,7 @@ import ( "crypto/rand" "encoding/binary" "errors" - "github.com/consensys/gnark-crypto/internal/hash_utils" //TODO: Make sure gnark-crypto dependence is okay + "github.com/consensys/gnark-crypto/internal/hashutils" "io" "math/big" "math/bits" @@ -926,7 +926,7 @@ func Hash(msg, dst []byte, count int) ([]Element, error) { const L = 16 + Bytes lenInBytes := count * L - pseudoRandomBytes, err := hash_utils.ExpandMsgXmd(msg, dst, lenInBytes) + pseudoRandomBytes, err := hashutils.ExpandMsgXmd(msg, dst, lenInBytes) if err != nil { return nil, err } diff --git a/ecc/bls12-378/fr/element.go b/ecc/bls12-378/fr/element.go index 6f3fa385f..c0643cbc3 100644 --- a/ecc/bls12-378/fr/element.go +++ b/ecc/bls12-378/fr/element.go @@ -20,7 +20,7 @@ import ( "crypto/rand" "encoding/binary" "errors" - "github.com/consensys/gnark-crypto/internal/hash_utils" //TODO: Make sure gnark-crypto dependence is okay + "github.com/consensys/gnark-crypto/internal/hashutils" "io" "math/big" "math/bits" @@ -768,7 +768,7 @@ func Hash(msg, dst []byte, count int) ([]Element, error) { const L = 16 + Bytes lenInBytes := count * L - pseudoRandomBytes, err := hash_utils.ExpandMsgXmd(msg, dst, lenInBytes) + pseudoRandomBytes, err := hashutils.ExpandMsgXmd(msg, dst, lenInBytes) if err != nil { return nil, err } diff --git a/ecc/bls12-381/fp/element.go b/ecc/bls12-381/fp/element.go index 3c5c91f68..e5355ad98 100644 --- a/ecc/bls12-381/fp/element.go +++ b/ecc/bls12-381/fp/element.go @@ -20,7 +20,7 @@ import ( "crypto/rand" "encoding/binary" "errors" - "github.com/consensys/gnark-crypto/internal/hash_utils" //TODO: Make sure gnark-crypto dependence is okay + "github.com/consensys/gnark-crypto/internal/hashutils" "io" "math/big" "math/bits" @@ -926,7 +926,7 @@ func Hash(msg, dst []byte, count int) ([]Element, error) { const L = 16 + Bytes lenInBytes := count * L - pseudoRandomBytes, err := hash_utils.ExpandMsgXmd(msg, dst, lenInBytes) + pseudoRandomBytes, err := hashutils.ExpandMsgXmd(msg, dst, lenInBytes) if err != nil { return nil, err } diff --git a/ecc/bls12-381/fr/element.go b/ecc/bls12-381/fr/element.go index d6aae8349..38e5aafb8 100644 --- a/ecc/bls12-381/fr/element.go +++ b/ecc/bls12-381/fr/element.go @@ -20,7 +20,7 @@ import ( "crypto/rand" "encoding/binary" "errors" - "github.com/consensys/gnark-crypto/internal/hash_utils" //TODO: Make sure gnark-crypto dependence is okay + "github.com/consensys/gnark-crypto/internal/hashutils" "io" "math/big" "math/bits" @@ -768,7 +768,7 @@ func Hash(msg, dst []byte, count int) ([]Element, error) { const L = 16 + Bytes lenInBytes := count * L - pseudoRandomBytes, err := hash_utils.ExpandMsgXmd(msg, dst, lenInBytes) + pseudoRandomBytes, err := hashutils.ExpandMsgXmd(msg, dst, lenInBytes) if err != nil { return nil, err } diff --git a/ecc/bls24-315/fp/element.go b/ecc/bls24-315/fp/element.go index c09b1f36f..fe2e480fa 100644 --- a/ecc/bls24-315/fp/element.go +++ b/ecc/bls24-315/fp/element.go @@ -20,7 +20,7 @@ import ( "crypto/rand" "encoding/binary" "errors" - "github.com/consensys/gnark-crypto/internal/hash_utils" //TODO: Make sure gnark-crypto dependence is okay + "github.com/consensys/gnark-crypto/internal/hashutils" "io" "math/big" "math/bits" @@ -844,7 +844,7 @@ func Hash(msg, dst []byte, count int) ([]Element, error) { const L = 16 + Bytes lenInBytes := count * L - pseudoRandomBytes, err := hash_utils.ExpandMsgXmd(msg, dst, lenInBytes) + pseudoRandomBytes, err := hashutils.ExpandMsgXmd(msg, dst, lenInBytes) if err != nil { return nil, err } diff --git a/ecc/bls24-315/fr/element.go b/ecc/bls24-315/fr/element.go index 957bdadf8..e51bab6fe 100644 --- a/ecc/bls24-315/fr/element.go +++ b/ecc/bls24-315/fr/element.go @@ -20,7 +20,7 @@ import ( "crypto/rand" "encoding/binary" "errors" - "github.com/consensys/gnark-crypto/internal/hash_utils" //TODO: Make sure gnark-crypto dependence is okay + "github.com/consensys/gnark-crypto/internal/hashutils" "io" "math/big" "math/bits" @@ -768,7 +768,7 @@ func Hash(msg, dst []byte, count int) ([]Element, error) { const L = 16 + Bytes lenInBytes := count * L - pseudoRandomBytes, err := hash_utils.ExpandMsgXmd(msg, dst, lenInBytes) + pseudoRandomBytes, err := hashutils.ExpandMsgXmd(msg, dst, lenInBytes) if err != nil { return nil, err } diff --git a/ecc/bls24-317/fp/element.go b/ecc/bls24-317/fp/element.go index 975f05e29..cb30cd66d 100644 --- a/ecc/bls24-317/fp/element.go +++ b/ecc/bls24-317/fp/element.go @@ -20,7 +20,7 @@ import ( "crypto/rand" "encoding/binary" "errors" - "github.com/consensys/gnark-crypto/internal/hash_utils" //TODO: Make sure gnark-crypto dependence is okay + "github.com/consensys/gnark-crypto/internal/hashutils" "io" "math/big" "math/bits" @@ -844,7 +844,7 @@ func Hash(msg, dst []byte, count int) ([]Element, error) { const L = 16 + Bytes lenInBytes := count * L - pseudoRandomBytes, err := hash_utils.ExpandMsgXmd(msg, dst, lenInBytes) + pseudoRandomBytes, err := hashutils.ExpandMsgXmd(msg, dst, lenInBytes) if err != nil { return nil, err } diff --git a/ecc/bls24-317/fr/element.go b/ecc/bls24-317/fr/element.go index 73baa975b..599a4777e 100644 --- a/ecc/bls24-317/fr/element.go +++ b/ecc/bls24-317/fr/element.go @@ -20,7 +20,7 @@ import ( "crypto/rand" "encoding/binary" "errors" - "github.com/consensys/gnark-crypto/internal/hash_utils" //TODO: Make sure gnark-crypto dependence is okay + "github.com/consensys/gnark-crypto/internal/hashutils" "io" "math/big" "math/bits" @@ -768,7 +768,7 @@ func Hash(msg, dst []byte, count int) ([]Element, error) { const L = 16 + Bytes lenInBytes := count * L - pseudoRandomBytes, err := hash_utils.ExpandMsgXmd(msg, dst, lenInBytes) + pseudoRandomBytes, err := hashutils.ExpandMsgXmd(msg, dst, lenInBytes) if err != nil { return nil, err } diff --git a/ecc/bn254/fp/element.go b/ecc/bn254/fp/element.go index 37f3b3890..818277289 100644 --- a/ecc/bn254/fp/element.go +++ b/ecc/bn254/fp/element.go @@ -20,7 +20,7 @@ import ( "crypto/rand" "encoding/binary" "errors" - "github.com/consensys/gnark-crypto/internal/hash_utils" //TODO: Make sure gnark-crypto dependence is okay + "github.com/consensys/gnark-crypto/internal/hashutils" "io" "math/big" "math/bits" @@ -768,7 +768,7 @@ func Hash(msg, dst []byte, count int) ([]Element, error) { const L = 16 + Bytes lenInBytes := count * L - pseudoRandomBytes, err := hash_utils.ExpandMsgXmd(msg, dst, lenInBytes) + pseudoRandomBytes, err := hashutils.ExpandMsgXmd(msg, dst, lenInBytes) if err != nil { return nil, err } diff --git a/ecc/bn254/fr/element.go b/ecc/bn254/fr/element.go index 39b2b47a4..add971c1c 100644 --- a/ecc/bn254/fr/element.go +++ b/ecc/bn254/fr/element.go @@ -20,7 +20,7 @@ import ( "crypto/rand" "encoding/binary" "errors" - "github.com/consensys/gnark-crypto/internal/hash_utils" //TODO: Make sure gnark-crypto dependence is okay + "github.com/consensys/gnark-crypto/internal/hashutils" "io" "math/big" "math/bits" @@ -768,7 +768,7 @@ func Hash(msg, dst []byte, count int) ([]Element, error) { const L = 16 + Bytes lenInBytes := count * L - pseudoRandomBytes, err := hash_utils.ExpandMsgXmd(msg, dst, lenInBytes) + pseudoRandomBytes, err := hashutils.ExpandMsgXmd(msg, dst, lenInBytes) if err != nil { return nil, err } diff --git a/ecc/bw6-633/fp/element.go b/ecc/bw6-633/fp/element.go index 961b24f14..5ad593286 100644 --- a/ecc/bw6-633/fp/element.go +++ b/ecc/bw6-633/fp/element.go @@ -20,7 +20,7 @@ import ( "crypto/rand" "encoding/binary" "errors" - "github.com/consensys/gnark-crypto/internal/hash_utils" //TODO: Make sure gnark-crypto dependence is okay + "github.com/consensys/gnark-crypto/internal/hashutils" "io" "math/big" "math/bits" @@ -1314,7 +1314,7 @@ func Hash(msg, dst []byte, count int) ([]Element, error) { const L = 16 + Bytes lenInBytes := count * L - pseudoRandomBytes, err := hash_utils.ExpandMsgXmd(msg, dst, lenInBytes) + pseudoRandomBytes, err := hashutils.ExpandMsgXmd(msg, dst, lenInBytes) if err != nil { return nil, err } diff --git a/ecc/bw6-633/fr/element.go b/ecc/bw6-633/fr/element.go index 7d53965de..9c69cf520 100644 --- a/ecc/bw6-633/fr/element.go +++ b/ecc/bw6-633/fr/element.go @@ -20,7 +20,7 @@ import ( "crypto/rand" "encoding/binary" "errors" - "github.com/consensys/gnark-crypto/internal/hash_utils" //TODO: Make sure gnark-crypto dependence is okay + "github.com/consensys/gnark-crypto/internal/hashutils" "io" "math/big" "math/bits" @@ -844,7 +844,7 @@ func Hash(msg, dst []byte, count int) ([]Element, error) { const L = 16 + Bytes lenInBytes := count * L - pseudoRandomBytes, err := hash_utils.ExpandMsgXmd(msg, dst, lenInBytes) + pseudoRandomBytes, err := hashutils.ExpandMsgXmd(msg, dst, lenInBytes) if err != nil { return nil, err } diff --git a/ecc/bw6-756/fp/element.go b/ecc/bw6-756/fp/element.go index 346596cf9..71e3fcc00 100644 --- a/ecc/bw6-756/fp/element.go +++ b/ecc/bw6-756/fp/element.go @@ -20,7 +20,7 @@ import ( "crypto/rand" "encoding/binary" "errors" - "github.com/consensys/gnark-crypto/internal/hash_utils" //TODO: Make sure gnark-crypto dependence is okay + "github.com/consensys/gnark-crypto/internal/hashutils" "io" "math/big" "math/bits" @@ -1544,7 +1544,7 @@ func Hash(msg, dst []byte, count int) ([]Element, error) { const L = 16 + Bytes lenInBytes := count * L - pseudoRandomBytes, err := hash_utils.ExpandMsgXmd(msg, dst, lenInBytes) + pseudoRandomBytes, err := hashutils.ExpandMsgXmd(msg, dst, lenInBytes) if err != nil { return nil, err } diff --git a/ecc/bw6-756/fr/element.go b/ecc/bw6-756/fr/element.go index 0769f6f44..b32a0bcdc 100644 --- a/ecc/bw6-756/fr/element.go +++ b/ecc/bw6-756/fr/element.go @@ -20,7 +20,7 @@ import ( "crypto/rand" "encoding/binary" "errors" - "github.com/consensys/gnark-crypto/internal/hash_utils" //TODO: Make sure gnark-crypto dependence is okay + "github.com/consensys/gnark-crypto/internal/hashutils" "io" "math/big" "math/bits" @@ -926,7 +926,7 @@ func Hash(msg, dst []byte, count int) ([]Element, error) { const L = 16 + Bytes lenInBytes := count * L - pseudoRandomBytes, err := hash_utils.ExpandMsgXmd(msg, dst, lenInBytes) + pseudoRandomBytes, err := hashutils.ExpandMsgXmd(msg, dst, lenInBytes) if err != nil { return nil, err } diff --git a/ecc/bw6-761/fp/element.go b/ecc/bw6-761/fp/element.go index 40ffd380b..a24131825 100644 --- a/ecc/bw6-761/fp/element.go +++ b/ecc/bw6-761/fp/element.go @@ -20,7 +20,7 @@ import ( "crypto/rand" "encoding/binary" "errors" - "github.com/consensys/gnark-crypto/internal/hash_utils" //TODO: Make sure gnark-crypto dependence is okay + "github.com/consensys/gnark-crypto/internal/hashutils" "io" "math/big" "math/bits" @@ -1544,7 +1544,7 @@ func Hash(msg, dst []byte, count int) ([]Element, error) { const L = 16 + Bytes lenInBytes := count * L - pseudoRandomBytes, err := hash_utils.ExpandMsgXmd(msg, dst, lenInBytes) + pseudoRandomBytes, err := hashutils.ExpandMsgXmd(msg, dst, lenInBytes) if err != nil { return nil, err } diff --git a/ecc/bw6-761/fr/element.go b/ecc/bw6-761/fr/element.go index 1ca6ee1b7..1b604580e 100644 --- a/ecc/bw6-761/fr/element.go +++ b/ecc/bw6-761/fr/element.go @@ -20,7 +20,7 @@ import ( "crypto/rand" "encoding/binary" "errors" - "github.com/consensys/gnark-crypto/internal/hash_utils" //TODO: Make sure gnark-crypto dependence is okay + "github.com/consensys/gnark-crypto/internal/hashutils" "io" "math/big" "math/bits" @@ -926,7 +926,7 @@ func Hash(msg, dst []byte, count int) ([]Element, error) { const L = 16 + Bytes lenInBytes := count * L - pseudoRandomBytes, err := hash_utils.ExpandMsgXmd(msg, dst, lenInBytes) + pseudoRandomBytes, err := hashutils.ExpandMsgXmd(msg, dst, lenInBytes) if err != nil { return nil, err } diff --git a/field/goldilocks/element.go b/field/goldilocks/element.go index 9f2ef23b6..25973e8af 100644 --- a/field/goldilocks/element.go +++ b/field/goldilocks/element.go @@ -20,7 +20,7 @@ import ( "crypto/rand" "encoding/binary" "errors" - "github.com/consensys/gnark-crypto/internal/hash_utils" //TODO: Make sure gnark-crypto dependence is okay + "github.com/consensys/gnark-crypto/internal/hashutils" "io" "math/big" "math/bits" @@ -573,7 +573,7 @@ func Hash(msg, dst []byte, count int) ([]Element, error) { const L = 16 + Bytes lenInBytes := count * L - pseudoRandomBytes, err := hash_utils.ExpandMsgXmd(msg, dst, lenInBytes) + pseudoRandomBytes, err := hashutils.ExpandMsgXmd(msg, dst, lenInBytes) if err != nil { return nil, err } diff --git a/internal/field/internal/templates/element/base.go b/internal/field/internal/templates/element/base.go index 86a62ca66..c89e9297c 100644 --- a/internal/field/internal/templates/element/base.go +++ b/internal/field/internal/templates/element/base.go @@ -3,7 +3,7 @@ package element const Base = ` import ( - "github.com/consensys/gnark-crypto/internal/hash_utils" //TODO: Make sure gnark-crypto dependence is okay + "github.com/consensys/gnark-crypto/internal/hashutils" "math/big" "math/bits" "io" @@ -636,7 +636,7 @@ func Hash(msg, dst []byte, count int) ([]{{.ElementName}}, error) { const L = 16 + Bytes lenInBytes := count * L - pseudoRandomBytes, err := hash_utils.ExpandMsgXmd(msg, dst, lenInBytes) + pseudoRandomBytes, err := hashutils.ExpandMsgXmd(msg, dst, lenInBytes) if err != nil { return nil, err } diff --git a/internal/hash_utils/hash_utils.go b/internal/hashutils/hashutils.go similarity index 99% rename from internal/hash_utils/hash_utils.go rename to internal/hashutils/hashutils.go index aab72ee3f..bf2a2cc2d 100644 --- a/internal/hash_utils/hash_utils.go +++ b/internal/hashutils/hashutils.go @@ -1,4 +1,4 @@ -package hash_utils +package hashutils import ( "crypto/sha256" diff --git a/internal/hash_utils/hash_utils_test.go b/internal/hashutils/hashutils_test.go similarity index 99% rename from internal/hash_utils/hash_utils_test.go rename to internal/hashutils/hashutils_test.go index dc43fd2ed..60dd75e80 100644 --- a/internal/hash_utils/hash_utils_test.go +++ b/internal/hashutils/hashutils_test.go @@ -1,4 +1,4 @@ -package hash_utils +package hashutils import ( "bytes" From 2d8cae0701982e07ef0062d3d70720f2315b4a30 Mon Sep 17 00:00:00 2001 From: Gautam Botrel Date: Mon, 21 Nov 2022 14:43:30 -0600 Subject: [PATCH 6/6] fix: fix #267 Inverse -> Exp -> Inverse --- ecc/bls12-377/fp/element.go | 21 ++++++++++++++----- ecc/bls12-377/fr/element.go | 21 ++++++++++++++----- ecc/bls12-378/fp/element.go | 21 ++++++++++++++----- ecc/bls12-378/fr/element.go | 21 ++++++++++++++----- ecc/bls12-381/fp/element.go | 21 ++++++++++++++----- ecc/bls12-381/fr/element.go | 21 ++++++++++++++----- ecc/bls24-315/fp/element.go | 21 ++++++++++++++----- ecc/bls24-315/fr/element.go | 21 ++++++++++++++----- ecc/bls24-317/fp/element.go | 21 ++++++++++++++----- ecc/bls24-317/fr/element.go | 21 ++++++++++++++----- ecc/bn254/fp/element.go | 21 ++++++++++++++----- ecc/bn254/fr/element.go | 21 ++++++++++++++----- ecc/bw6-633/fp/element.go | 21 ++++++++++++++----- ecc/bw6-633/fr/element.go | 21 ++++++++++++++----- ecc/bw6-756/fp/element.go | 21 ++++++++++++++----- ecc/bw6-756/fr/element.go | 21 ++++++++++++++----- ecc/bw6-761/fp/element.go | 21 ++++++++++++++----- ecc/bw6-761/fr/element.go | 21 ++++++++++++++----- .../internal/templates/element/inverse.go | 21 ++++++++++++++----- 19 files changed, 304 insertions(+), 95 deletions(-) diff --git a/ecc/bls12-377/fp/element.go b/ecc/bls12-377/fp/element.go index 776ea9614..b5fe73bef 100644 --- a/ecc/bls12-377/fp/element.go +++ b/ecc/bls12-377/fp/element.go @@ -1481,17 +1481,28 @@ func (z *Element) Inverse(x *Element) *Element { // correctness check v.Mul(&u, z) if !v.IsOne() && !u.IsZero() { - return z.inverseExp(&u) + return z.inverseExp(u) } return z } // inverseExp computes z = x⁻¹ (mod q) = x**(q-2) (mod q) -func (z *Element) inverseExp(x *Element) *Element { - qMinusTwo := Modulus() - qMinusTwo.Sub(qMinusTwo, big.NewInt(2)) - return z.Exp(*x, qMinusTwo) +func (z *Element) inverseExp(x Element) *Element { + // e == q-2 + e := Modulus() + e.Sub(e, big.NewInt(2)) + + z.Set(&x) + + for i := e.BitLen() - 2; i >= 0; i-- { + z.Square(z) + if e.Bit(i) == 1 { + z.Mul(z, &x) + } + } + + return z } // approximate a big number x into a single 64 bit word using its uppermost and lowermost bits diff --git a/ecc/bls12-377/fr/element.go b/ecc/bls12-377/fr/element.go index fd50cdfa2..2bf699030 100644 --- a/ecc/bls12-377/fr/element.go +++ b/ecc/bls12-377/fr/element.go @@ -1305,17 +1305,28 @@ func (z *Element) Inverse(x *Element) *Element { // correctness check v.Mul(&u, z) if !v.IsOne() && !u.IsZero() { - return z.inverseExp(&u) + return z.inverseExp(u) } return z } // inverseExp computes z = x⁻¹ (mod q) = x**(q-2) (mod q) -func (z *Element) inverseExp(x *Element) *Element { - qMinusTwo := Modulus() - qMinusTwo.Sub(qMinusTwo, big.NewInt(2)) - return z.Exp(*x, qMinusTwo) +func (z *Element) inverseExp(x Element) *Element { + // e == q-2 + e := Modulus() + e.Sub(e, big.NewInt(2)) + + z.Set(&x) + + for i := e.BitLen() - 2; i >= 0; i-- { + z.Square(z) + if e.Bit(i) == 1 { + z.Mul(z, &x) + } + } + + return z } // approximate a big number x into a single 64 bit word using its uppermost and lowermost bits diff --git a/ecc/bls12-378/fp/element.go b/ecc/bls12-378/fp/element.go index 72f70ab35..cdbdafe64 100644 --- a/ecc/bls12-378/fp/element.go +++ b/ecc/bls12-378/fp/element.go @@ -1481,17 +1481,28 @@ func (z *Element) Inverse(x *Element) *Element { // correctness check v.Mul(&u, z) if !v.IsOne() && !u.IsZero() { - return z.inverseExp(&u) + return z.inverseExp(u) } return z } // inverseExp computes z = x⁻¹ (mod q) = x**(q-2) (mod q) -func (z *Element) inverseExp(x *Element) *Element { - qMinusTwo := Modulus() - qMinusTwo.Sub(qMinusTwo, big.NewInt(2)) - return z.Exp(*x, qMinusTwo) +func (z *Element) inverseExp(x Element) *Element { + // e == q-2 + e := Modulus() + e.Sub(e, big.NewInt(2)) + + z.Set(&x) + + for i := e.BitLen() - 2; i >= 0; i-- { + z.Square(z) + if e.Bit(i) == 1 { + z.Mul(z, &x) + } + } + + return z } // approximate a big number x into a single 64 bit word using its uppermost and lowermost bits diff --git a/ecc/bls12-378/fr/element.go b/ecc/bls12-378/fr/element.go index c0643cbc3..00a8ffc7a 100644 --- a/ecc/bls12-378/fr/element.go +++ b/ecc/bls12-378/fr/element.go @@ -1305,17 +1305,28 @@ func (z *Element) Inverse(x *Element) *Element { // correctness check v.Mul(&u, z) if !v.IsOne() && !u.IsZero() { - return z.inverseExp(&u) + return z.inverseExp(u) } return z } // inverseExp computes z = x⁻¹ (mod q) = x**(q-2) (mod q) -func (z *Element) inverseExp(x *Element) *Element { - qMinusTwo := Modulus() - qMinusTwo.Sub(qMinusTwo, big.NewInt(2)) - return z.Exp(*x, qMinusTwo) +func (z *Element) inverseExp(x Element) *Element { + // e == q-2 + e := Modulus() + e.Sub(e, big.NewInt(2)) + + z.Set(&x) + + for i := e.BitLen() - 2; i >= 0; i-- { + z.Square(z) + if e.Bit(i) == 1 { + z.Mul(z, &x) + } + } + + return z } // approximate a big number x into a single 64 bit word using its uppermost and lowermost bits diff --git a/ecc/bls12-381/fp/element.go b/ecc/bls12-381/fp/element.go index e5355ad98..37fa12bce 100644 --- a/ecc/bls12-381/fp/element.go +++ b/ecc/bls12-381/fp/element.go @@ -1427,17 +1427,28 @@ func (z *Element) Inverse(x *Element) *Element { // correctness check v.Mul(&u, z) if !v.IsOne() && !u.IsZero() { - return z.inverseExp(&u) + return z.inverseExp(u) } return z } // inverseExp computes z = x⁻¹ (mod q) = x**(q-2) (mod q) -func (z *Element) inverseExp(x *Element) *Element { - qMinusTwo := Modulus() - qMinusTwo.Sub(qMinusTwo, big.NewInt(2)) - return z.Exp(*x, qMinusTwo) +func (z *Element) inverseExp(x Element) *Element { + // e == q-2 + e := Modulus() + e.Sub(e, big.NewInt(2)) + + z.Set(&x) + + for i := e.BitLen() - 2; i >= 0; i-- { + z.Square(z) + if e.Bit(i) == 1 { + z.Mul(z, &x) + } + } + + return z } // approximate a big number x into a single 64 bit word using its uppermost and lowermost bits diff --git a/ecc/bls12-381/fr/element.go b/ecc/bls12-381/fr/element.go index 38e5aafb8..f5e77559c 100644 --- a/ecc/bls12-381/fr/element.go +++ b/ecc/bls12-381/fr/element.go @@ -1305,17 +1305,28 @@ func (z *Element) Inverse(x *Element) *Element { // correctness check v.Mul(&u, z) if !v.IsOne() && !u.IsZero() { - return z.inverseExp(&u) + return z.inverseExp(u) } return z } // inverseExp computes z = x⁻¹ (mod q) = x**(q-2) (mod q) -func (z *Element) inverseExp(x *Element) *Element { - qMinusTwo := Modulus() - qMinusTwo.Sub(qMinusTwo, big.NewInt(2)) - return z.Exp(*x, qMinusTwo) +func (z *Element) inverseExp(x Element) *Element { + // e == q-2 + e := Modulus() + e.Sub(e, big.NewInt(2)) + + z.Set(&x) + + for i := e.BitLen() - 2; i >= 0; i-- { + z.Square(z) + if e.Bit(i) == 1 { + z.Mul(z, &x) + } + } + + return z } // approximate a big number x into a single 64 bit word using its uppermost and lowermost bits diff --git a/ecc/bls24-315/fp/element.go b/ecc/bls24-315/fp/element.go index fe2e480fa..a536fdf72 100644 --- a/ecc/bls24-315/fp/element.go +++ b/ecc/bls24-315/fp/element.go @@ -1390,17 +1390,28 @@ func (z *Element) Inverse(x *Element) *Element { // correctness check v.Mul(&u, z) if !v.IsOne() && !u.IsZero() { - return z.inverseExp(&u) + return z.inverseExp(u) } return z } // inverseExp computes z = x⁻¹ (mod q) = x**(q-2) (mod q) -func (z *Element) inverseExp(x *Element) *Element { - qMinusTwo := Modulus() - qMinusTwo.Sub(qMinusTwo, big.NewInt(2)) - return z.Exp(*x, qMinusTwo) +func (z *Element) inverseExp(x Element) *Element { + // e == q-2 + e := Modulus() + e.Sub(e, big.NewInt(2)) + + z.Set(&x) + + for i := e.BitLen() - 2; i >= 0; i-- { + z.Square(z) + if e.Bit(i) == 1 { + z.Mul(z, &x) + } + } + + return z } // approximate a big number x into a single 64 bit word using its uppermost and lowermost bits diff --git a/ecc/bls24-315/fr/element.go b/ecc/bls24-315/fr/element.go index e51bab6fe..61737f63d 100644 --- a/ecc/bls24-315/fr/element.go +++ b/ecc/bls24-315/fr/element.go @@ -1305,17 +1305,28 @@ func (z *Element) Inverse(x *Element) *Element { // correctness check v.Mul(&u, z) if !v.IsOne() && !u.IsZero() { - return z.inverseExp(&u) + return z.inverseExp(u) } return z } // inverseExp computes z = x⁻¹ (mod q) = x**(q-2) (mod q) -func (z *Element) inverseExp(x *Element) *Element { - qMinusTwo := Modulus() - qMinusTwo.Sub(qMinusTwo, big.NewInt(2)) - return z.Exp(*x, qMinusTwo) +func (z *Element) inverseExp(x Element) *Element { + // e == q-2 + e := Modulus() + e.Sub(e, big.NewInt(2)) + + z.Set(&x) + + for i := e.BitLen() - 2; i >= 0; i-- { + z.Square(z) + if e.Bit(i) == 1 { + z.Mul(z, &x) + } + } + + return z } // approximate a big number x into a single 64 bit word using its uppermost and lowermost bits diff --git a/ecc/bls24-317/fp/element.go b/ecc/bls24-317/fp/element.go index cb30cd66d..c7c2fcfdb 100644 --- a/ecc/bls24-317/fp/element.go +++ b/ecc/bls24-317/fp/element.go @@ -1337,17 +1337,28 @@ func (z *Element) Inverse(x *Element) *Element { // correctness check v.Mul(&u, z) if !v.IsOne() && !u.IsZero() { - return z.inverseExp(&u) + return z.inverseExp(u) } return z } // inverseExp computes z = x⁻¹ (mod q) = x**(q-2) (mod q) -func (z *Element) inverseExp(x *Element) *Element { - qMinusTwo := Modulus() - qMinusTwo.Sub(qMinusTwo, big.NewInt(2)) - return z.Exp(*x, qMinusTwo) +func (z *Element) inverseExp(x Element) *Element { + // e == q-2 + e := Modulus() + e.Sub(e, big.NewInt(2)) + + z.Set(&x) + + for i := e.BitLen() - 2; i >= 0; i-- { + z.Square(z) + if e.Bit(i) == 1 { + z.Mul(z, &x) + } + } + + return z } // approximate a big number x into a single 64 bit word using its uppermost and lowermost bits diff --git a/ecc/bls24-317/fr/element.go b/ecc/bls24-317/fr/element.go index 599a4777e..d0cb9e66b 100644 --- a/ecc/bls24-317/fr/element.go +++ b/ecc/bls24-317/fr/element.go @@ -1305,17 +1305,28 @@ func (z *Element) Inverse(x *Element) *Element { // correctness check v.Mul(&u, z) if !v.IsOne() && !u.IsZero() { - return z.inverseExp(&u) + return z.inverseExp(u) } return z } // inverseExp computes z = x⁻¹ (mod q) = x**(q-2) (mod q) -func (z *Element) inverseExp(x *Element) *Element { - qMinusTwo := Modulus() - qMinusTwo.Sub(qMinusTwo, big.NewInt(2)) - return z.Exp(*x, qMinusTwo) +func (z *Element) inverseExp(x Element) *Element { + // e == q-2 + e := Modulus() + e.Sub(e, big.NewInt(2)) + + z.Set(&x) + + for i := e.BitLen() - 2; i >= 0; i-- { + z.Square(z) + if e.Bit(i) == 1 { + z.Mul(z, &x) + } + } + + return z } // approximate a big number x into a single 64 bit word using its uppermost and lowermost bits diff --git a/ecc/bn254/fp/element.go b/ecc/bn254/fp/element.go index 818277289..72c6ef170 100644 --- a/ecc/bn254/fp/element.go +++ b/ecc/bn254/fp/element.go @@ -1253,17 +1253,28 @@ func (z *Element) Inverse(x *Element) *Element { // correctness check v.Mul(&u, z) if !v.IsOne() && !u.IsZero() { - return z.inverseExp(&u) + return z.inverseExp(u) } return z } // inverseExp computes z = x⁻¹ (mod q) = x**(q-2) (mod q) -func (z *Element) inverseExp(x *Element) *Element { - qMinusTwo := Modulus() - qMinusTwo.Sub(qMinusTwo, big.NewInt(2)) - return z.Exp(*x, qMinusTwo) +func (z *Element) inverseExp(x Element) *Element { + // e == q-2 + e := Modulus() + e.Sub(e, big.NewInt(2)) + + z.Set(&x) + + for i := e.BitLen() - 2; i >= 0; i-- { + z.Square(z) + if e.Bit(i) == 1 { + z.Mul(z, &x) + } + } + + return z } // approximate a big number x into a single 64 bit word using its uppermost and lowermost bits diff --git a/ecc/bn254/fr/element.go b/ecc/bn254/fr/element.go index add971c1c..a5a21b3a8 100644 --- a/ecc/bn254/fr/element.go +++ b/ecc/bn254/fr/element.go @@ -1305,17 +1305,28 @@ func (z *Element) Inverse(x *Element) *Element { // correctness check v.Mul(&u, z) if !v.IsOne() && !u.IsZero() { - return z.inverseExp(&u) + return z.inverseExp(u) } return z } // inverseExp computes z = x⁻¹ (mod q) = x**(q-2) (mod q) -func (z *Element) inverseExp(x *Element) *Element { - qMinusTwo := Modulus() - qMinusTwo.Sub(qMinusTwo, big.NewInt(2)) - return z.Exp(*x, qMinusTwo) +func (z *Element) inverseExp(x Element) *Element { + // e == q-2 + e := Modulus() + e.Sub(e, big.NewInt(2)) + + z.Set(&x) + + for i := e.BitLen() - 2; i >= 0; i-- { + z.Square(z) + if e.Bit(i) == 1 { + z.Mul(z, &x) + } + } + + return z } // approximate a big number x into a single 64 bit word using its uppermost and lowermost bits diff --git a/ecc/bw6-633/fp/element.go b/ecc/bw6-633/fp/element.go index 5ad593286..b982c9658 100644 --- a/ecc/bw6-633/fp/element.go +++ b/ecc/bw6-633/fp/element.go @@ -1856,17 +1856,28 @@ func (z *Element) Inverse(x *Element) *Element { // correctness check v.Mul(&u, z) if !v.IsOne() && !u.IsZero() { - return z.inverseExp(&u) + return z.inverseExp(u) } return z } // inverseExp computes z = x⁻¹ (mod q) = x**(q-2) (mod q) -func (z *Element) inverseExp(x *Element) *Element { - qMinusTwo := Modulus() - qMinusTwo.Sub(qMinusTwo, big.NewInt(2)) - return z.Exp(*x, qMinusTwo) +func (z *Element) inverseExp(x Element) *Element { + // e == q-2 + e := Modulus() + e.Sub(e, big.NewInt(2)) + + z.Set(&x) + + for i := e.BitLen() - 2; i >= 0; i-- { + z.Square(z) + if e.Bit(i) == 1 { + z.Mul(z, &x) + } + } + + return z } // approximate a big number x into a single 64 bit word using its uppermost and lowermost bits diff --git a/ecc/bw6-633/fr/element.go b/ecc/bw6-633/fr/element.go index 9c69cf520..be2130642 100644 --- a/ecc/bw6-633/fr/element.go +++ b/ecc/bw6-633/fr/element.go @@ -1390,17 +1390,28 @@ func (z *Element) Inverse(x *Element) *Element { // correctness check v.Mul(&u, z) if !v.IsOne() && !u.IsZero() { - return z.inverseExp(&u) + return z.inverseExp(u) } return z } // inverseExp computes z = x⁻¹ (mod q) = x**(q-2) (mod q) -func (z *Element) inverseExp(x *Element) *Element { - qMinusTwo := Modulus() - qMinusTwo.Sub(qMinusTwo, big.NewInt(2)) - return z.Exp(*x, qMinusTwo) +func (z *Element) inverseExp(x Element) *Element { + // e == q-2 + e := Modulus() + e.Sub(e, big.NewInt(2)) + + z.Set(&x) + + for i := e.BitLen() - 2; i >= 0; i-- { + z.Square(z) + if e.Bit(i) == 1 { + z.Mul(z, &x) + } + } + + return z } // approximate a big number x into a single 64 bit word using its uppermost and lowermost bits diff --git a/ecc/bw6-756/fp/element.go b/ecc/bw6-756/fp/element.go index 71e3fcc00..6258eabb3 100644 --- a/ecc/bw6-756/fp/element.go +++ b/ecc/bw6-756/fp/element.go @@ -2153,17 +2153,28 @@ func (z *Element) Inverse(x *Element) *Element { // correctness check v.Mul(&u, z) if !v.IsOne() && !u.IsZero() { - return z.inverseExp(&u) + return z.inverseExp(u) } return z } // inverseExp computes z = x⁻¹ (mod q) = x**(q-2) (mod q) -func (z *Element) inverseExp(x *Element) *Element { - qMinusTwo := Modulus() - qMinusTwo.Sub(qMinusTwo, big.NewInt(2)) - return z.Exp(*x, qMinusTwo) +func (z *Element) inverseExp(x Element) *Element { + // e == q-2 + e := Modulus() + e.Sub(e, big.NewInt(2)) + + z.Set(&x) + + for i := e.BitLen() - 2; i >= 0; i-- { + z.Square(z) + if e.Bit(i) == 1 { + z.Mul(z, &x) + } + } + + return z } // approximate a big number x into a single 64 bit word using its uppermost and lowermost bits diff --git a/ecc/bw6-756/fr/element.go b/ecc/bw6-756/fr/element.go index b32a0bcdc..54f0108ca 100644 --- a/ecc/bw6-756/fr/element.go +++ b/ecc/bw6-756/fr/element.go @@ -1481,17 +1481,28 @@ func (z *Element) Inverse(x *Element) *Element { // correctness check v.Mul(&u, z) if !v.IsOne() && !u.IsZero() { - return z.inverseExp(&u) + return z.inverseExp(u) } return z } // inverseExp computes z = x⁻¹ (mod q) = x**(q-2) (mod q) -func (z *Element) inverseExp(x *Element) *Element { - qMinusTwo := Modulus() - qMinusTwo.Sub(qMinusTwo, big.NewInt(2)) - return z.Exp(*x, qMinusTwo) +func (z *Element) inverseExp(x Element) *Element { + // e == q-2 + e := Modulus() + e.Sub(e, big.NewInt(2)) + + z.Set(&x) + + for i := e.BitLen() - 2; i >= 0; i-- { + z.Square(z) + if e.Bit(i) == 1 { + z.Mul(z, &x) + } + } + + return z } // approximate a big number x into a single 64 bit word using its uppermost and lowermost bits diff --git a/ecc/bw6-761/fp/element.go b/ecc/bw6-761/fp/element.go index a24131825..dd9a5f980 100644 --- a/ecc/bw6-761/fp/element.go +++ b/ecc/bw6-761/fp/element.go @@ -2093,17 +2093,28 @@ func (z *Element) Inverse(x *Element) *Element { // correctness check v.Mul(&u, z) if !v.IsOne() && !u.IsZero() { - return z.inverseExp(&u) + return z.inverseExp(u) } return z } // inverseExp computes z = x⁻¹ (mod q) = x**(q-2) (mod q) -func (z *Element) inverseExp(x *Element) *Element { - qMinusTwo := Modulus() - qMinusTwo.Sub(qMinusTwo, big.NewInt(2)) - return z.Exp(*x, qMinusTwo) +func (z *Element) inverseExp(x Element) *Element { + // e == q-2 + e := Modulus() + e.Sub(e, big.NewInt(2)) + + z.Set(&x) + + for i := e.BitLen() - 2; i >= 0; i-- { + z.Square(z) + if e.Bit(i) == 1 { + z.Mul(z, &x) + } + } + + return z } // approximate a big number x into a single 64 bit word using its uppermost and lowermost bits diff --git a/ecc/bw6-761/fr/element.go b/ecc/bw6-761/fr/element.go index 1b604580e..eceef0cd7 100644 --- a/ecc/bw6-761/fr/element.go +++ b/ecc/bw6-761/fr/element.go @@ -1481,17 +1481,28 @@ func (z *Element) Inverse(x *Element) *Element { // correctness check v.Mul(&u, z) if !v.IsOne() && !u.IsZero() { - return z.inverseExp(&u) + return z.inverseExp(u) } return z } // inverseExp computes z = x⁻¹ (mod q) = x**(q-2) (mod q) -func (z *Element) inverseExp(x *Element) *Element { - qMinusTwo := Modulus() - qMinusTwo.Sub(qMinusTwo, big.NewInt(2)) - return z.Exp(*x, qMinusTwo) +func (z *Element) inverseExp(x Element) *Element { + // e == q-2 + e := Modulus() + e.Sub(e, big.NewInt(2)) + + z.Set(&x) + + for i := e.BitLen() - 2; i >= 0; i-- { + z.Square(z) + if e.Bit(i) == 1 { + z.Mul(z, &x) + } + } + + return z } // approximate a big number x into a single 64 bit word using its uppermost and lowermost bits diff --git a/internal/field/internal/templates/element/inverse.go b/internal/field/internal/templates/element/inverse.go index 30826e74d..4a02aaa99 100644 --- a/internal/field/internal/templates/element/inverse.go +++ b/internal/field/internal/templates/element/inverse.go @@ -272,17 +272,28 @@ func (z *{{.ElementName}}) Inverse(x *{{.ElementName}}) *{{.ElementName}} { // correctness check v.Mul(&u, z) if !v.IsOne() && !u.IsZero() { - return z.inverseExp(&u) + return z.inverseExp(u) } return z } // inverseExp computes z = x⁻¹ (mod q) = x**(q-2) (mod q) -func (z *{{.ElementName}}) inverseExp(x *{{.ElementName}}) *{{.ElementName}} { - qMinusTwo := Modulus() - qMinusTwo.Sub(qMinusTwo, big.NewInt(2)) - return z.Exp(*x, qMinusTwo) +func (z *{{.ElementName}}) inverseExp(x {{.ElementName}}) *{{.ElementName}} { + // e == q-2 + e := Modulus() + e.Sub(e, big.NewInt(2)) + + z.Set(&x) + + for i := e.BitLen() - 2; i >= 0; i-- { + z.Square(z) + if e.Bit(i) == 1 { + z.Mul(z, &x) + } + } + + return z } // approximate a big number x into a single 64 bit word using its uppermost and lowermost bits