github.com/linapex/ethereum-dpos-chinese@v0.0.0-20190316121959-b78b3a4a1ece/crypto/bn256/cloudflare/lattice.go (about)

     1  
     2  //<developer>
     3  //    <name>linapex 曹一峰</name>
     4  //    <email>linapex@163.com</email>
     5  //    <wx>superexc</wx>
     6  //    <qqgroup>128148617</qqgroup>
     7  //    <url>https://jsq.ink</url>
     8  //    <role>pku engineer</role>
     9  //    <date>2019-03-16 12:09:36</date>
    10  //</624342625368936448>
    11  
    12  package bn256
    13  
    14  import (
    15  	"math/big"
    16  )
    17  
    18  var half = new(big.Int).Rsh(Order, 1)
    19  
    20  var curveLattice = &lattice{
    21  	vectors: [][]*big.Int{
    22  		{bigFromBase10("147946756881789319000765030803803410728"), bigFromBase10("147946756881789319010696353538189108491")},
    23  		{bigFromBase10("147946756881789319020627676272574806254"), bigFromBase10("-147946756881789318990833708069417712965")},
    24  	},
    25  	inverse: []*big.Int{
    26  		bigFromBase10("147946756881789318990833708069417712965"),
    27  		bigFromBase10("147946756881789319010696353538189108491"),
    28  	},
    29  	det: bigFromBase10("43776485743678550444492811490514550177096728800832068687396408373151616991234"),
    30  }
    31  
    32  var targetLattice = &lattice{
    33  	vectors: [][]*big.Int{
    34  		{bigFromBase10("9931322734385697761"), bigFromBase10("9931322734385697761"), bigFromBase10("9931322734385697763"), bigFromBase10("9931322734385697764")},
    35  		{bigFromBase10("4965661367192848881"), bigFromBase10("4965661367192848881"), bigFromBase10("4965661367192848882"), bigFromBase10("-9931322734385697762")},
    36  		{bigFromBase10("-9931322734385697762"), bigFromBase10("-4965661367192848881"), bigFromBase10("4965661367192848881"), bigFromBase10("-4965661367192848882")},
    37  		{bigFromBase10("9931322734385697763"), bigFromBase10("-4965661367192848881"), bigFromBase10("-4965661367192848881"), bigFromBase10("-4965661367192848881")},
    38  	},
    39  	inverse: []*big.Int{
    40  		bigFromBase10("734653495049373973658254490726798021314063399421879442165"),
    41  		bigFromBase10("147946756881789319000765030803803410728"),
    42  		bigFromBase10("-147946756881789319005730692170996259609"),
    43  		bigFromBase10("1469306990098747947464455738335385361643788813749140841702"),
    44  	},
    45  	det: new(big.Int).Set(Order),
    46  }
    47  
    48  type lattice struct {
    49  	vectors [][]*big.Int
    50  	inverse []*big.Int
    51  	det     *big.Int
    52  }
    53  
    54  //分解以一个标量mod阶作为输入,并找到一个简短的正分解,它与格的基础。
    55  func (l *lattice) decompose(k *big.Int) []*big.Int {
    56  	n := len(l.inverse)
    57  
    58  //用babai的四舍五入法计算晶格中最接近的向量<k,0,0,…>。
    59  	c := make([]*big.Int, n)
    60  	for i := 0; i < n; i++ {
    61  		c[i] = new(big.Int).Mul(k, l.inverse[i])
    62  		round(c[i], l.det)
    63  	}
    64  
    65  //根据c变换向量并减去<k,0,0,…>。
    66  	out := make([]*big.Int, n)
    67  	temp := new(big.Int)
    68  
    69  	for i := 0; i < n; i++ {
    70  		out[i] = new(big.Int)
    71  
    72  		for j := 0; j < n; j++ {
    73  			temp.Mul(c[j], l.vectors[j][i])
    74  			out[i].Add(out[i], temp)
    75  		}
    76  
    77  		out[i].Neg(out[i])
    78  		out[i].Add(out[i], l.vectors[0][i]).Add(out[i], l.vectors[0][i])
    79  	}
    80  	out[0].Add(out[0], k)
    81  
    82  	return out
    83  }
    84  
    85  func (l *lattice) Precompute(add func(i, j uint)) {
    86  	n := uint(len(l.vectors))
    87  	total := uint(1) << n
    88  
    89  	for i := uint(0); i < n; i++ {
    90  		for j := uint(0); j < total; j++ {
    91  			if (j>>i)&1 == 1 {
    92  				add(i, j)
    93  			}
    94  		}
    95  	}
    96  }
    97  
    98  func (l *lattice) Multi(scalar *big.Int) []uint8 {
    99  	decomp := l.decompose(scalar)
   100  
   101  	maxLen := 0
   102  	for _, x := range decomp {
   103  		if x.BitLen() > maxLen {
   104  			maxLen = x.BitLen()
   105  		}
   106  	}
   107  
   108  	out := make([]uint8, maxLen)
   109  	for j, x := range decomp {
   110  		for i := 0; i < maxLen; i++ {
   111  			out[i] += uint8(x.Bit(i)) << uint(j)
   112  		}
   113  	}
   114  
   115  	return out
   116  }
   117  
   118  //round将num设置为num/denom,四舍五入到最接近的整数。
   119  func round(num, denom *big.Int) {
   120  	r := new(big.Int)
   121  	num.DivMod(num, denom, r)
   122  
   123  	if r.Cmp(half) == 1 {
   124  		num.Add(num, big.NewInt(1))
   125  	}
   126  }
   127