github.com/consensys/gnark-crypto@v0.14.0/ecc/utils.go (about)

     1  package ecc
     2  
     3  import (
     4  	"math/big"
     5  	"math/bits"
     6  )
     7  
     8  //-------------------------------------------------------
     9  // Ate loop counter (not used for each curve)
    10  
    11  // NafDecomposition gets the naf decomposition of a big number
    12  func NafDecomposition(a *big.Int, result []int8) int {
    13  
    14  	var zero, one, two, three big.Int
    15  
    16  	one.SetUint64(1)
    17  	two.SetUint64(2)
    18  	three.SetUint64(3)
    19  
    20  	length := 0
    21  
    22  	// some buffers
    23  	var buf, aCopy big.Int
    24  	aCopy.Set(a)
    25  
    26  	for aCopy.Cmp(&zero) != 0 {
    27  
    28  		// if aCopy % 2 == 0
    29  		buf.And(&aCopy, &one)
    30  
    31  		// aCopy even
    32  		if buf.Cmp(&zero) == 0 {
    33  			result[length] = 0
    34  		} else { // aCopy odd
    35  			buf.And(&aCopy, &three)
    36  			if buf.Cmp(&three) == 0 {
    37  				result[length] = -1
    38  				aCopy.Add(&aCopy, &one)
    39  			} else {
    40  				result[length] = 1
    41  			}
    42  		}
    43  		aCopy.Rsh(&aCopy, 1)
    44  		length++
    45  	}
    46  	return length
    47  }
    48  
    49  //-------------------------------------------------------
    50  // GLV utils
    51  
    52  // Lattice represents a Z module spanned by V1, V2.
    53  // det is the associated determinant.
    54  type Lattice struct {
    55  	V1, V2      [2]big.Int
    56  	Det, b1, b2 big.Int
    57  }
    58  
    59  // PrecomputeLattice res such that res.V1, res.V2
    60  // are short vectors satisfying v11+v12.λ=v21+v22.λ=0[r].
    61  // cf https://www.iacr.org/archive/crypto2001/21390189.pdf
    62  func PrecomputeLattice(r, lambda *big.Int, res *Lattice) {
    63  
    64  	var rst [2][3]big.Int
    65  	var tmp [3]big.Int
    66  	var quotient, remainder, sqroot, _r, _t big.Int
    67  
    68  	rst[0][0].Set(r)
    69  	rst[0][1].SetUint64(1)
    70  	rst[0][2].SetUint64(0)
    71  
    72  	rst[1][0].Set(lambda)
    73  	rst[1][1].SetUint64(0)
    74  	rst[1][2].SetUint64(1)
    75  
    76  	sqroot.Sqrt(r)
    77  
    78  	var one big.Int
    79  	one.SetUint64(1)
    80  
    81  	// r_i+1 = r_i-1 - q_i.r_i
    82  	// s_i+1 = s_i-1 - q_i.s_i
    83  	// t_i+1 = t_i-1 - q_i.s_i
    84  	for rst[1][0].Cmp(&sqroot) >= 1 {
    85  
    86  		quotient.Div(&rst[0][0], &rst[1][0])
    87  		remainder.Mod(&rst[0][0], &rst[1][0])
    88  
    89  		tmp[0].Set(&rst[1][0])
    90  		tmp[1].Set(&rst[1][1])
    91  		tmp[2].Set(&rst[1][2])
    92  
    93  		rst[1][0].Set(&remainder)
    94  		rst[1][1].Mul(&rst[1][1], &quotient).Sub(&rst[0][1], &rst[1][1])
    95  		rst[1][2].Mul(&rst[1][2], &quotient).Sub(&rst[0][2], &rst[1][2])
    96  
    97  		rst[0][0].Set(&tmp[0])
    98  		rst[0][1].Set(&tmp[1])
    99  		rst[0][2].Set(&tmp[2])
   100  	}
   101  
   102  	quotient.Div(&rst[0][0], &rst[1][0])
   103  	remainder.Mod(&rst[0][0], &rst[1][0])
   104  	_r.Set(&remainder)
   105  	_t.Mul(&rst[1][2], &quotient).Sub(&rst[0][2], &_t)
   106  
   107  	res.V1[0].Set(&rst[1][0])
   108  	res.V1[1].Neg(&rst[1][2])
   109  
   110  	// take the shorter of [rst[0][0], rst[0][2]], [_r, _t]
   111  	tmp[1].Mul(&rst[0][2], &rst[0][2])
   112  	tmp[0].Mul(&rst[0][0], &rst[0][0]).Add(&tmp[1], &tmp[0])
   113  	tmp[2].Mul(&_r, &_r)
   114  	tmp[1].Mul(&_t, &_t).Add(&tmp[2], &tmp[1])
   115  	if tmp[0].Cmp(&tmp[1]) == 1 {
   116  		res.V2[0].Set(&_r)
   117  		res.V2[1].Neg(&_t)
   118  	} else {
   119  		res.V2[0].Set(&rst[0][0])
   120  		res.V2[1].Neg(&rst[0][2])
   121  	}
   122  
   123  	// sets determinant
   124  	tmp[0].Mul(&res.V1[1], &res.V2[0])
   125  	res.Det.Mul(&res.V1[0], &res.V2[1]).Sub(&res.Det, &tmp[0])
   126  
   127  	// sets roundings of 2^n*v21/d and 2^n*v11/d (where 2ⁿ > d)
   128  	n := 2 * uint(((res.Det.BitLen()+32)>>6)<<6)
   129  	res.b1.Lsh(&res.V2[1], n)
   130  	rounding(&res.b1, &res.Det, &res.b1)
   131  	res.b2.Lsh(&res.V1[1], n)
   132  	rounding(&res.b2, &res.Det, &res.b2)
   133  }
   134  
   135  // SplitScalar outputs u,v such that u+vlambda=s[r].
   136  // The method is to view s as (s,0) in ZxZ, and find a close
   137  // vector w of (s,0) in <l>, where l is a sub Z-module of
   138  // ker((a,b) → a+b.λ[r]): then (u,v)=w-(s,0), and
   139  // u+v.λ=s[r].
   140  // cf https://www.iacr.org/archive/crypto2001/21390189.pdf
   141  func SplitScalar(s *big.Int, l *Lattice) [2]big.Int {
   142  
   143  	var k1, k2 big.Int
   144  	k1.Mul(s, &l.b1)
   145  	k2.Mul(s, &l.b2).Neg(&k2)
   146  	// right-shift instead of division by lattice determinant
   147  	// this increases the bounds on k1 and k2 by 1
   148  	// but we check this ScalarMultiplication alg. (not constant-time)
   149  	n := 2 * uint(((l.Det.BitLen()+32)>>6)<<6)
   150  	k1.Rsh(&k1, n)
   151  	k2.Rsh(&k2, n)
   152  	v := getVector(l, &k1, &k2)
   153  	v[0].Sub(s, &v[0])
   154  	v[1].Neg(&v[1])
   155  	return v
   156  }
   157  
   158  // sets res to the closest integer from n/d
   159  func rounding(n, d, res *big.Int) {
   160  	var dshift, r, one big.Int
   161  	one.SetUint64(1)
   162  	dshift.Rsh(d, 1)
   163  	r.Mod(n, d)
   164  	res.Div(n, d)
   165  	if r.Cmp(&dshift) == 1 {
   166  		res.Add(res, &one)
   167  	}
   168  }
   169  
   170  // getVector returns aV1 + bV2
   171  func getVector(l *Lattice, a, b *big.Int) [2]big.Int {
   172  	var res [2]big.Int
   173  	var tmp big.Int
   174  	tmp.Mul(b, &l.V2[0])
   175  	res[0].Mul(a, &l.V1[0]).Add(&res[0], &tmp)
   176  	tmp.Mul(b, &l.V2[1])
   177  	res[1].Mul(a, &l.V1[1]).Add(&res[1], &tmp)
   178  	return res
   179  }
   180  
   181  // NextPowerOfTwo returns the next power of 2 of n
   182  func NextPowerOfTwo(n uint64) uint64 {
   183  	c := bits.OnesCount64(n)
   184  	if c == 0 {
   185  		return 1
   186  	}
   187  	if c == 1 {
   188  		return n
   189  	}
   190  	t := bits.LeadingZeros64(n)
   191  	if t == 0 {
   192  		panic("next power of 2 overflows uint64")
   193  	}
   194  	return uint64(1) << (64 - t)
   195  }