github.com/consensys/gnark@v0.11.0/backend/groth16/bn254/mpcsetup/utils.go (about)

     1  // Copyright 2020 ConsenSys Software Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  // Code generated by gnark DO NOT EDIT
    16  
    17  package mpcsetup
    18  
    19  import (
    20  	"bytes"
    21  	"math/big"
    22  	"math/bits"
    23  	"runtime"
    24  
    25  	"github.com/consensys/gnark-crypto/ecc"
    26  	curve "github.com/consensys/gnark-crypto/ecc/bn254"
    27  	"github.com/consensys/gnark-crypto/ecc/bn254/fr"
    28  	"github.com/consensys/gnark/internal/utils"
    29  )
    30  
    31  type PublicKey struct {
    32  	SG  curve.G1Affine
    33  	SXG curve.G1Affine
    34  	XR  curve.G2Affine
    35  }
    36  
    37  func newPublicKey(x fr.Element, challenge []byte, dst byte) PublicKey {
    38  	var pk PublicKey
    39  	_, _, g1, _ := curve.Generators()
    40  
    41  	var s fr.Element
    42  	var sBi big.Int
    43  	s.SetRandom()
    44  	s.BigInt(&sBi)
    45  	pk.SG.ScalarMultiplication(&g1, &sBi)
    46  
    47  	// compute x*sG1
    48  	var xBi big.Int
    49  	x.BigInt(&xBi)
    50  	pk.SXG.ScalarMultiplication(&pk.SG, &xBi)
    51  
    52  	// generate R based on sG1, sxG1, challenge, and domain separation tag (tau, alpha or beta)
    53  	R := genR(pk.SG, pk.SXG, challenge, dst)
    54  
    55  	// compute x*spG2
    56  	pk.XR.ScalarMultiplication(&R, &xBi)
    57  	return pk
    58  }
    59  
    60  func bitReverse[T any](a []T) {
    61  	n := uint64(len(a))
    62  	nn := uint64(64 - bits.TrailingZeros64(n))
    63  
    64  	for i := uint64(0); i < n; i++ {
    65  		irev := bits.Reverse64(i) >> nn
    66  		if irev > i {
    67  			a[i], a[irev] = a[irev], a[i]
    68  		}
    69  	}
    70  }
    71  
    72  // Returns [1, a, a², ..., aⁿ⁻¹ ] in Montgomery form
    73  func powers(a fr.Element, n int) []fr.Element {
    74  	result := make([]fr.Element, n)
    75  	result[0] = fr.NewElement(1)
    76  	for i := 1; i < n; i++ {
    77  		result[i].Mul(&result[i-1], &a)
    78  	}
    79  	return result
    80  }
    81  
    82  // Returns [aᵢAᵢ, ...] in G1
    83  func scaleG1InPlace(A []curve.G1Affine, a []fr.Element) {
    84  	utils.Parallelize(len(A), func(start, end int) {
    85  		var tmp big.Int
    86  		for i := start; i < end; i++ {
    87  			a[i].BigInt(&tmp)
    88  			A[i].ScalarMultiplication(&A[i], &tmp)
    89  		}
    90  	})
    91  }
    92  
    93  // Returns [aᵢAᵢ, ...] in G2
    94  func scaleG2InPlace(A []curve.G2Affine, a []fr.Element) {
    95  	utils.Parallelize(len(A), func(start, end int) {
    96  		var tmp big.Int
    97  		for i := start; i < end; i++ {
    98  			a[i].BigInt(&tmp)
    99  			A[i].ScalarMultiplication(&A[i], &tmp)
   100  		}
   101  	})
   102  }
   103  
   104  // Check e(a₁, a₂) = e(b₁, b₂)
   105  func sameRatio(a1, b1 curve.G1Affine, a2, b2 curve.G2Affine) bool {
   106  	if !a1.IsInSubGroup() || !b1.IsInSubGroup() || !a2.IsInSubGroup() || !b2.IsInSubGroup() {
   107  		panic("invalid point not in subgroup")
   108  	}
   109  	var na2 curve.G2Affine
   110  	na2.Neg(&a2)
   111  	res, err := curve.PairingCheck(
   112  		[]curve.G1Affine{a1, b1},
   113  		[]curve.G2Affine{na2, b2})
   114  	if err != nil {
   115  		panic(err)
   116  	}
   117  	return res
   118  }
   119  
   120  // returns a = ∑ rᵢAᵢ, b = ∑ rᵢBᵢ
   121  func merge(A, B []curve.G1Affine) (a, b curve.G1Affine) {
   122  	nc := runtime.NumCPU()
   123  	r := make([]fr.Element, len(A))
   124  	for i := 0; i < len(A); i++ {
   125  		r[i].SetRandom()
   126  	}
   127  	a.MultiExp(A, r, ecc.MultiExpConfig{NbTasks: nc / 2})
   128  	b.MultiExp(B, r, ecc.MultiExpConfig{NbTasks: nc / 2})
   129  	return
   130  }
   131  
   132  // L1 = ∑ rᵢAᵢ, L2 = ∑ rᵢAᵢ₊₁ in G1
   133  func linearCombinationG1(A []curve.G1Affine) (L1, L2 curve.G1Affine) {
   134  	nc := runtime.NumCPU()
   135  	n := len(A)
   136  	r := make([]fr.Element, n-1)
   137  	for i := 0; i < n-1; i++ {
   138  		r[i].SetRandom()
   139  	}
   140  	L1.MultiExp(A[:n-1], r, ecc.MultiExpConfig{NbTasks: nc / 2})
   141  	L2.MultiExp(A[1:], r, ecc.MultiExpConfig{NbTasks: nc / 2})
   142  	return
   143  }
   144  
   145  // L1 = ∑ rᵢAᵢ, L2 = ∑ rᵢAᵢ₊₁ in G2
   146  func linearCombinationG2(A []curve.G2Affine) (L1, L2 curve.G2Affine) {
   147  	nc := runtime.NumCPU()
   148  	n := len(A)
   149  	r := make([]fr.Element, n-1)
   150  	for i := 0; i < n-1; i++ {
   151  		r[i].SetRandom()
   152  	}
   153  	L1.MultiExp(A[:n-1], r, ecc.MultiExpConfig{NbTasks: nc / 2})
   154  	L2.MultiExp(A[1:], r, ecc.MultiExpConfig{NbTasks: nc / 2})
   155  	return
   156  }
   157  
   158  // Generate R in G₂ as Hash(gˢ, gˢˣ, challenge, dst)
   159  func genR(sG1, sxG1 curve.G1Affine, challenge []byte, dst byte) curve.G2Affine {
   160  	var buf bytes.Buffer
   161  	buf.Grow(len(challenge) + curve.SizeOfG1AffineUncompressed*2)
   162  	buf.Write(sG1.Marshal())
   163  	buf.Write(sxG1.Marshal())
   164  	buf.Write(challenge)
   165  	spG2, err := curve.HashToG2(buf.Bytes(), []byte{dst})
   166  	if err != nil {
   167  		panic(err)
   168  	}
   169  	return spG2
   170  }