Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
135 commits
Select commit Hold shift + click to select a range
840a867
added circuit implementation of ExpandMsgXmd
weijiguo Jan 8, 2024
7fb1b95
implemented HashToG2 for bls12-381
weijiguo Jan 27, 2024
620585f
Merge branch 'Consensys:master' into feat/Hash2G2
weijiguo Jan 27, 2024
b0b11d2
revised G2.addUnified function based on the Brier and Joye algorithm
weijiguo Jan 28, 2024
3cf48fd
Merge pull request #2 from lightec-xyz/feat/Hash2G2
weijiguo Jan 28, 2024
b4da768
fixed G2.sgn0 function and associated unit tests for BLS12-381
weijiguo Jan 29, 2024
b6574fc
Merge pull request #4 from lightec-xyz/feat/Hash2G2
weijiguo Jan 29, 2024
86d12ce
implemented BLS signature verification for BLS12-381/G2
weijiguo Jan 29, 2024
78bdcf6
added benchmarks for HashToG2/BLS12-381
weijiguo Jan 30, 2024
04c1677
Merge branch 'master' into feat/BLSSigAndHashToG2
weijiguo Feb 10, 2024
8e2fc0e
gofmt
weijiguo Feb 10, 2024
bae5ff4
Merge branch 'master' into feat/BLSSigAndHashToG2
weijiguo Feb 14, 2024
4a2f9b0
golangci-lint
weijiguo Feb 19, 2024
50cca4b
Merge branch 'master' into feat/BLSSigAndHashToG2
weijiguo Feb 20, 2024
17fc881
Merge branch 'master' into feat/BLSSigAndHashToG2
weijiguo Feb 23, 2024
c60b775
Merge branch 'master' into feat/BLSSigAndHashToG2
weijiguo Mar 10, 2024
5719545
Merge branch 'master' into feat/BLSSigAndHashToG2
weijiguo Mar 12, 2024
3f6bbef
Merge branch 'master' into feat/BLSSigAndHashToG2
weijiguo Mar 21, 2024
8f38fba
Merge branch 'master' into feat/BLSSigAndHashToG2
weijiguo Mar 24, 2024
f0856e9
Merge branch 'master' into feat/BLSSigAndHashToG2
weijiguo May 4, 2024
34a664c
Merge branch 'master' into feat/BLSSigAndHashToG2
weijiguo May 16, 2024
a25777f
Merge branch 'master' into feat/BLSSigAndHashToG2
weijiguo Sep 27, 2024
99c819d
Merge branch 'master' into feat/BLSSigAndHashToG2
weijiguo Jan 10, 2025
89847e8
Merge branch 'master' into feat/BLSSigAndHashToG2
weijiguo Jan 23, 2025
a012086
Merge pull request #9 from Consensys/master
weijiguo Jan 24, 2025
8921270
fixed spacing issue introduced during merging
weijiguo Jan 24, 2025
d179d71
feat(pectra/precompiles): BLS12_G1ADD and BLS12_PAIRING_CHECK
yelhousni Mar 13, 2025
5c58de3
feat(pectra/precompiles): BLS12_G2ADD
yelhousni Mar 13, 2025
90ad595
perf(pectra/precompiles): include G2 membership in BLS12_PAIR
yelhousni Mar 13, 2025
b8f9004
test: update stats
yelhousni Mar 14, 2025
e748c1f
feat: add G2 memebrship to BLS12_G2ADD
yelhousni Mar 14, 2025
e5886ea
feat(pectra/precompiles): BLS12_G1MSM
yelhousni Mar 14, 2025
13f23c3
refactor: BLS12 precompiles to include G1/2 membership checks
yelhousni Mar 17, 2025
225d6f6
perf(pectra): optimize MSM G1
yelhousni Mar 17, 2025
ee8f46a
feat: constants isogeny ok
ThomasPiellard Mar 18, 2025
f8eef37
feat(pectra): add BLS12_G2MSM
yelhousni Mar 18, 2025
7ea03d5
refactor: clean code
yelhousni Mar 18, 2025
b9e729e
feat: mul by z ok
ThomasPiellard Mar 18, 2025
c9f6df4
style(pectra): rename methods
yelhousni Mar 18, 2025
0cd0f62
feat: hint ok
ThomasPiellard Mar 19, 2025
efe3928
Merge branch 'pectra/precompiles' of github.com:Consensys/gnark into …
ThomasPiellard Mar 19, 2025
61d3d5f
feat: move map-to-g1 to swbls12381 package
ThomasPiellard Mar 20, 2025
f215ee1
feat: main function ok
ThomasPiellard Mar 20, 2025
c2dcd18
feat: isogeny ok
ThomasPiellard Mar 20, 2025
f1566ea
feat: fixed api
ThomasPiellard Mar 21, 2025
8a072b8
fix: missing addAssign clear cofactor
ThomasPiellard Mar 21, 2025
0001898
fix: Clear cofactor ok
ThomasPiellard Mar 21, 2025
16ba968
feat: correct values, but test fails
ThomasPiellard Mar 23, 2025
28fed0b
bug: nonnative limb checking fails
ThomasPiellard Mar 24, 2025
d1bdd70
clean: removed some dereferencing
ThomasPiellard Mar 24, 2025
1e61775
perf(pectra): optimize G2 scalar mul with GLV
yelhousni Mar 24, 2025
5f36147
fix(pectra): make linter happy
yelhousni Mar 24, 2025
b32c12d
Merge branch 'master' into pectra/precompiles
yelhousni Mar 24, 2025
581ddb4
fix(pectra): make linter happier
yelhousni Mar 24, 2025
97aeba5
fix(pectra): make linter much happier
yelhousni Mar 24, 2025
506a359
fix: avoid dereferencing non-native values
ivokub Mar 25, 2025
fb37104
feat: hint is constrained
ThomasPiellard Mar 25, 2025
abe3cbb
feat: added full precompile
ThomasPiellard Mar 25, 2025
a7ef40d
feat: corrected name
ThomasPiellard Mar 25, 2025
c36c352
fix: replace OR with XOR
ThomasPiellard Mar 25, 2025
6cd996a
refactor: address some of the review comments
yelhousni Apr 4, 2025
dcada5c
GKR Gate Registry (#1442)
Tabaie Apr 2, 2025
b1ba425
chore: go.mod update
ivokub Apr 7, 2025
ebe3b99
refactor: use sqrt from gnark-crypto
ivokub Apr 7, 2025
6e6246a
chore: go.mod update
ivokub Apr 7, 2025
3730ea9
refactor: use isogeny map from gnark-crypto
ivokub Apr 7, 2025
e5c9a42
chore: do not redefine base element
ivokub Apr 7, 2025
4ab6383
chore: remove unneeded error handling
ivokub Apr 7, 2025
c7b8845
chore: cleanup unused definition
ivokub Apr 7, 2025
85091e7
Merge branch 'pr/weijiguo/1040' into feat/map_to_g2
ivokub Apr 7, 2025
31c9648
chore: fix some merge issues
ivokub Apr 7, 2025
b6dccf1
chore: rename g2sqrtratiohint
ivokub Apr 7, 2025
2f1273d
chore: remove unused const
ivokub Apr 7, 2025
e558d23
fix: address PR review
yelhousni Apr 8, 2025
c1d6169
Merge branch 'pectra/precompiles' of github.com:consensys/gnark into …
yelhousni Apr 8, 2025
b2c738b
XXX: work refactor hash to g2
ivokub Apr 9, 2025
c1d02d5
XXX: work refactor
ivokub Apr 9, 2025
e6f9b6d
refactor: do not need error
ivokub Apr 9, 2025
79bc1ee
chore: go.mod update
ivokub Apr 9, 2025
ba58e1d
refactor: use z value from gnark-crypto
ivokub Apr 9, 2025
16e24ef
chore: use constant 1 (on one limb)
ivokub Apr 9, 2025
875c591
Merge branch 'pectra/precompiles' into feat/map_to_g2
ivokub Apr 9, 2025
6ee8bd3
chore: remove done todo
ivokub Apr 9, 2025
8499ee6
feat: added file
ThomasPiellard Apr 9, 2025
193791d
refactor: use NewElement instead of ValueOf
ivokub Apr 9, 2025
e999177
Merge branch 'pectra/precompiles' into feat/map_to_g2
ivokub Apr 9, 2025
118ff6c
Merge branch 'pectra/precompiles' of github.com:Consensys/gnark into …
ThomasPiellard Apr 9, 2025
2346fc6
feat: add test map_to_g1 precompile
ThomasPiellard Apr 9, 2025
6396084
refactor: embed sswu map info in G2
ivokub Apr 9, 2025
7ee3b91
refactor: map to g2
ivokub Apr 9, 2025
51e08f3
fix: BLS signature api
ivokub Apr 9, 2025
5526e69
test: add isogeny and map to curve test
ivokub Apr 9, 2025
4647ef6
refactor: dont need return error
ivokub Apr 9, 2025
24e8f78
test: add G1 isogeny test
ivokub Apr 9, 2025
5e4582d
Merge branch 'pectra/precompiles' into feat/map_to_g2
ivokub Apr 9, 2025
2aa451b
refactor: use NewElement instead of ValueOf
ivokub Apr 9, 2025
8d46753
fix: monix fixed poly eval
ivokub Apr 9, 2025
fc4267f
test: remove benchmarking
ivokub Apr 9, 2025
35df500
chore: rename hash to g2 file
ivokub Apr 9, 2025
5e9ead6
Merge branch 'master' into pectra/precompiles
ivokub Apr 13, 2025
cc3d534
chore: go mod update
ivokub Apr 13, 2025
f965e8c
chore: revert unrelated changes
ivokub Apr 13, 2025
8460c3f
docs: fix typo for staticcehck
ivokub Apr 13, 2025
5cedec3
chore: stats
ivokub Apr 13, 2025
fa55f7d
Merge branch 'pectra/precompiles' into feat/map_to_g2
ivokub Apr 14, 2025
69a391c
fix: use correct input for g2 sgn0 zero0
ivokub Apr 14, 2025
4ed2847
fix: use xor instead of diff and iszero
ivokub Apr 14, 2025
e99790c
fix: select order
ivokub Apr 14, 2025
1f135d5
Merge branch 'master' into feat/map_to_g2
ivokub Jul 7, 2025
aa85b61
fix: duplicate declaration
ivokub Jul 7, 2025
b34438e
feat: implement BLS signature package with test
ivokub Jul 7, 2025
e947f1b
feat: implement BlockSize for binary hashers
ivokub Jul 7, 2025
0af1c02
feat: refactor expandMsgXmd to expand package
ivokub Jul 7, 2025
81fc763
docs: add TODOs for now
ivokub Jul 8, 2025
f38a57b
feat: refactor g2 hash to curve
ivokub Jul 8, 2025
6f7316d
feat: implement encode and hash to G1
ivokub Jul 8, 2025
5b3c254
refactor: global const for secure base element sampling len
ivokub Jul 8, 2025
78c37dc
test: implement encode/hash to G2 tests
ivokub Jul 8, 2025
d7c7fe6
refactor: rename BLS sig test
ivokub Jul 8, 2025
c3f287c
test: use single conditional circuit for unified add
ivokub Jul 8, 2025
0a192e7
fix: infinity point check
ivokub Jul 8, 2025
5154b23
fix: error message coordinate
ivokub Jul 8, 2025
5ae6e4c
test: rename G1 to G2 in G2 tests
ivokub Jul 8, 2025
82d14a1
docs: cleanup and explicit mention
ivokub Jul 8, 2025
9cf0c0d
refactor: separate bytes from Long API
ivokub May 23, 2025
2251097
refactor: use bytes api
ivokub Jul 14, 2025
4c3cb24
feat: handle edge cases directly in rangechecker
ivokub Jul 14, 2025
57ef0ff
test: test kvstore
ivokub May 23, 2025
617c7ee
chore: include all hints automatic registration
ivokub Jul 3, 2025
7866081
feat: implement conversion package
ivokub Jul 14, 2025
b8b0cfb
Merge branch 'feat/bytes-conversion' into feat/map_to_g2
ivokub Jul 15, 2025
48c07eb
refactor: use conversion package for mapping to field
ivokub Jul 15, 2025
1718561
refactor: use xor directly
ivokub Jul 15, 2025
f53e220
Merge branch 'master' into feat/map_to_g2
ivokub Sep 4, 2025
44ab405
test: add all test cases from eth
ivokub Sep 4, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
122 changes: 118 additions & 4 deletions std/algebra/emulated/sw_bls12381/g2_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,16 +51,22 @@ func TestScalarMulG2TestSolve(t *testing.T) {
}

type addG2Circuit struct {
In1, In2 G2Affine
Res G2Affine
In1, In2 G2Affine
Res G2Affine
unifiedAdd bool // if true, use the unified addition method
}

func (c *addG2Circuit) Define(api frontend.API) error {
g2, err := NewG2(api)
if err != nil {
return fmt.Errorf("new G2 struct: %w", err)
}
res := g2.add(&c.In1, &c.In2)
var res *G2Affine
if c.unifiedAdd {
res = g2.AddUnified(&c.In1, &c.In2)
} else {
res = g2.add(&c.In1, &c.In2)
}
g2.AssertIsEqual(res, &c.Res)
return nil
}
Expand All @@ -76,10 +82,118 @@ func TestAddG2TestSolve(t *testing.T) {
In2: NewG2Affine(in2),
Res: NewG2Affine(res),
}
err := test.IsSolved(&addG2Circuit{}, &witness, ecc.BN254.ScalarField())
err := test.IsSolved(&addG2Circuit{unifiedAdd: false}, &witness, ecc.BN254.ScalarField())
assert.NoError(err, "expected success for random inputs")
}

func TestAddG2FailureCaseTestSolve(t *testing.T) {
assert := test.NewAssert(t)
_, in1 := randomG1G2Affines()
var res bls12381.G2Affine
res.Double(&in1)
witness := addG2Circuit{
In1: NewG2Affine(in1),
In2: NewG2Affine(in1),
Res: NewG2Affine(res),
}
err := test.IsSolved(&addG2Circuit{unifiedAdd: false}, &witness, ecc.BN254.ScalarField())
// the add() function cannot handle identical inputs
assert.Error(err, "expected solver error for identical inputs")
}

func TestAddG2UnifiedTestSolveAdd(t *testing.T) {
assert := test.NewAssert(t)
_, in1 := randomG1G2Affines()
_, in2 := randomG1G2Affines()
var res bls12381.G2Affine
res.Add(&in1, &in2)
witness := addG2Circuit{
In1: NewG2Affine(in1),
In2: NewG2Affine(in2),
Res: NewG2Affine(res),
}
err := test.IsSolved(&addG2Circuit{unifiedAdd: true}, &witness, ecc.BN254.ScalarField())
assert.NoError(err)
}

func TestAddG2UnifiedTestSolveDbl(t *testing.T) {
assert := test.NewAssert(t)
_, in1 := randomG1G2Affines()
var res bls12381.G2Affine
res.Double(&in1)
witness := addG2Circuit{
In1: NewG2Affine(in1),
In2: NewG2Affine(in1),
Res: NewG2Affine(res),
}
err := test.IsSolved(&addG2Circuit{unifiedAdd: true}, &witness, ecc.BN254.ScalarField())
assert.NoError(err)
}

func TestAddG2UnifiedTestSolveEdgeCases(t *testing.T) {
assert := test.NewAssert(t)
_, p := randomG1G2Affines()
var np, zero bls12381.G2Affine
np.Neg(&p)
zero.Sub(&p, &p)

assert.Run(func(assert *test.Assert) {
// p + (-p) == (0, 0)
witness := addG2Circuit{
In1: NewG2Affine(p),
In2: NewG2Affine(np),
Res: NewG2Affine(zero),
}
err := test.IsSolved(&addG2Circuit{unifiedAdd: true}, &witness, ecc.BN254.ScalarField())
assert.NoError(err)
}, "case=inverse")

assert.Run(func(assert *test.Assert) {
// (-p) + p == (0, 0)
witness2 := addG2Circuit{
In1: NewG2Affine(np),
In2: NewG2Affine(p),
Res: NewG2Affine(zero),
}
err := test.IsSolved(&addG2Circuit{unifiedAdd: true}, &witness2, ecc.BN254.ScalarField())
assert.NoError(err)
}, "case=inverse2")

assert.Run(func(assert *test.Assert) {
// p + (0, 0) == p
witness3 := addG2Circuit{
In1: NewG2Affine(p),
In2: NewG2Affine(zero),
Res: NewG2Affine(p),
}
err := test.IsSolved(&addG2Circuit{unifiedAdd: true}, &witness3, ecc.BN254.ScalarField())
assert.NoError(err)
}, "case=zero")

assert.Run(func(assert *test.Assert) {
// (0, 0) + p == p
witness4 := addG2Circuit{
In1: NewG2Affine(zero),
In2: NewG2Affine(p),
Res: NewG2Affine(p),
}
err := test.IsSolved(&addG2Circuit{unifiedAdd: true}, &witness4, ecc.BN254.ScalarField())
assert.NoError(err)
}, "case=zero2")

assert.Run(func(assert *test.Assert) {
// (0, 0) + (0, 0) == (0, 0)
witness5 := addG2Circuit{
In1: NewG2Affine(zero),
In2: NewG2Affine(zero),
Res: NewG2Affine(zero),
}
err5 := test.IsSolved(&addG2Circuit{unifiedAdd: true}, &witness5, ecc.BN254.ScalarField())
assert.NoError(err5)
}, "case=zero3")

}

type doubleG2Circuit struct {
In1 G2Affine
Res G2Affine
Expand Down
96 changes: 96 additions & 0 deletions std/algebra/emulated/sw_bls12381/map_to_g1.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ import (
"github.com/consensys/gnark-crypto/ecc/bls12-381/fp"
"github.com/consensys/gnark-crypto/ecc/bls12-381/hash_to_curve"
"github.com/consensys/gnark/frontend"
"github.com/consensys/gnark/std/conversion"
"github.com/consensys/gnark/std/hash/expand"
"github.com/consensys/gnark/std/math/emulated"
"github.com/consensys/gnark/std/math/uints"
)

func (g1 *G1) evalFixedPolynomial(monic bool, coefficients []fp.Element, x *baseEl) *baseEl {
Expand Down Expand Up @@ -180,3 +184,95 @@ func (g1 *G1) MapToG1(u *baseEl) (*G1Affine, error) {
z = g1.ClearCofactor(z)
return z, nil
}

// EncodeToG1 hashes a message to a point on the G1 curve using the SSWU map as
// defined in [RFC9380]. It is faster than [G1.HashToG1], but the result is not
// uniformly distributed. Unsuitable as a random oracle.
//
// dst stands for "domain separation tag", a string unique to the construction
// using the hash function
//
// // This method corresponds to the [bls12381.EncodeToG1] method in gnark-crypto.
//
// [RFC9380]: https://www.rfc-editor.org/rfc/rfc9380.html#roadmap
func (g1 *G1) EncodeToG1(msg []uints.U8, dst []byte) (*G1Affine, error) {
uniformBytes, err := expand.ExpandMsgXmd(g1.api, msg, dst, secureBaseElementLen)
if err != nil {
return nil, fmt.Errorf("expand msg: %w", err)
}
el, err := secureBytesToElement(g1.api, g1.curveF, uniformBytes)
if err != nil {
return nil, fmt.Errorf("bytes to element: %w", err)
}
R, err := g1.MapToCurve1(el)
if err != nil {
return nil, fmt.Errorf("map to curve: %w", err)
}
R = g1.isogeny(R)
R = g1.ClearCofactor(R)
return R, nil
}

// HashToG1 hashes a message to a point on the G1 curve using the SSWU map as
// defined in [RFC9380]. It is slower than [G1.EncodeToG1], but usable as a
// random oracle.
//
// dst stands for "domain separation tag", a string unique to the construction
// using the hash function.
//
// This method corresponds to the [bls12381.HashToG1] method in gnark-crypto.
//
// [RFC9380]: https://www.rfc-editor.org/rfc/rfc9380.html#roadmap
func (g1 *G1) HashToG1(msg []uints.U8, dst []byte) (*G1Affine, error) {
els := make([]*baseEl, 2)
uniformBytes, err := expand.ExpandMsgXmd(g1.api, msg, dst, len(els)*secureBaseElementLen)
if err != nil {
return nil, fmt.Errorf("expand msg: %w", err)
}
for i := range els {
els[i], err = secureBytesToElement(g1.api, g1.curveF, uniformBytes[i*secureBaseElementLen:(i+1)*secureBaseElementLen])
if err != nil {
return nil, fmt.Errorf("bytes to element: %w", err)
}
}
Q0, err := g1.MapToCurve1(els[0])
if err != nil {
return nil, fmt.Errorf("map to curve Q0: %w", err)
}
Q1, err := g1.MapToCurve1(els[1])
if err != nil {
return nil, fmt.Errorf("map to curve Q1: %w", err)
}
R0 := g1.isogeny(Q0)
R1 := g1.isogeny(Q1)
R := g1.add(R0, R1)
R = g1.ClearCofactor(R)
return R, nil
}

func secureBytesToElement(api frontend.API, f *emulated.Field[BaseField], data []uints.U8) (*emulated.Element[BaseField], error) {
// we have sampled more bytes than is needed to serialize to field element.
// The goal is to have more uniform distribution of the output.
//
// However, we cannot easily initialize non-native elements with more than 48 bytes. So we instead look at
// x * 2^376 + y, where x are first 17 bytes and y are the last 47 bytes.
if len(data) != secureBaseElementLen {
return nil, fmt.Errorf("expected %d bytes, got %d", secureBaseElementLen, len(data))
}

hib := data[:secureBaseElementLen-fp.Bytes+1]
lob := data[secureBaseElementLen-fp.Bytes+1 : secureBaseElementLen]
// coeff is 2^376 % Fp
coeff := f.NewElement("153914086704665934422965000391185991426092731525255651046673021110334850669910978950836977558144201721900890587136")
hi, err := conversion.BytesToEmulated[BaseField](api, hib, conversion.WithAllowOverflow())
if err != nil {
return nil, fmt.Errorf("convert hi bytes to emulated element: %w", err)
}
lo, err := conversion.BytesToEmulated[BaseField](api, lob, conversion.WithAllowOverflow())
if err != nil {
return nil, fmt.Errorf("convert lo bytes to emulated element: %w", err)
}
res := f.Mul(hi, coeff)
res = f.Add(res, lo)
return res, nil
}
78 changes: 78 additions & 0 deletions std/algebra/emulated/sw_bls12381/map_to_g1_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package sw_bls12381

import (
"crypto/rand"
"fmt"
"testing"

Expand All @@ -10,6 +11,7 @@ import (
"github.com/consensys/gnark-crypto/ecc/bls12-381/hash_to_curve"
"github.com/consensys/gnark/frontend"
"github.com/consensys/gnark/std/math/emulated"
"github.com/consensys/gnark/std/math/uints"
"github.com/consensys/gnark/test"
)

Expand Down Expand Up @@ -145,3 +147,79 @@ func TestIsogenyG1(t *testing.T) {
err := test.IsSolved(&IsogenyG1Circuit{}, &witness, ecc.BN254.ScalarField())
assert.NoError(err)
}

type EncodeToG1Circuit struct {
Msg []uints.U8
Res G1Affine
Dst []byte
}

func (c *EncodeToG1Circuit) Define(api frontend.API) error {
g, err := NewG1(api)
if err != nil {
return fmt.Errorf("new G1: %w", err)
}
res, err := g.EncodeToG1(c.Msg, []byte(c.Dst))
if err != nil {
return fmt.Errorf("encode to G1: %w", err)
}

g.AssertIsEqual(res, &c.Res)
return nil
}

func TestEncodeToG1(t *testing.T) {
assert := test.NewAssert(t)
dst := []byte("BLS12381G1Test")
for _, msgLen := range []int{0, 1, 31, 32, 33, 63, 64, 65} {
assert.Run(func(assert *test.Assert) {
msg := make([]byte, msgLen)
_, err := rand.Reader.Read(msg)
assert.NoError(err, "failed to generate random message")
res, err := bls12381.EncodeToG1(msg, dst)
assert.NoError(err, "failed to encode message to G1")
circuit := EncodeToG1Circuit{Msg: make([]uints.U8, msgLen), Dst: dst}
witness := EncodeToG1Circuit{Msg: uints.NewU8Array(msg), Res: NewG1Affine(res)}
err = test.IsSolved(&circuit, &witness, ecc.BN254.ScalarField())
assert.NoError(err, "solving failed")
}, fmt.Sprintf("msgLen=%d", msgLen))
}
}

type HashToG1Circuit struct {
Msg []uints.U8
Res G1Affine
Dst []byte
}

func (c *HashToG1Circuit) Define(api frontend.API) error {
g, err := NewG1(api)
if err != nil {
return fmt.Errorf("new G1: %w", err)
}
res, err := g.HashToG1(c.Msg, []byte(c.Dst))
if err != nil {
return fmt.Errorf("hash to G1: %w", err)
}

g.AssertIsEqual(res, &c.Res)
return nil
}

func TestHashToG1(t *testing.T) {
assert := test.NewAssert(t)
dst := []byte("BLS12381G1Test")
for _, msgLen := range []int{0, 1, 31, 32, 33, 63, 64, 65} {
assert.Run(func(assert *test.Assert) {
msg := make([]byte, msgLen)
_, err := rand.Reader.Read(msg)
assert.NoError(err, "failed to generate random message")
res, err := bls12381.HashToG1(msg, dst)
assert.NoError(err, "failed to hash message to G1")
circuit := HashToG1Circuit{Msg: make([]uints.U8, msgLen), Dst: dst}
witness := HashToG1Circuit{Msg: uints.NewU8Array(msg), Res: NewG1Affine(res)}
err = test.IsSolved(&circuit, &witness, ecc.BN254.ScalarField())
assert.NoError(err, "solving failed")
}, fmt.Sprintf("msgLen=%d", msgLen))
}
}
Loading
Loading