github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/crypto/bn256/cloudflare/lattice.go (about)

     1  
     2  //此源码被清华学神尹成大魔王专业翻译分析并修改
     3  //尹成QQ77025077
     4  //尹成微信18510341407
     5  //尹成所在QQ群721929980
     6  //尹成邮箱 yinc13@mails.tsinghua.edu.cn
     7  //尹成毕业于清华大学,微软区块链领域全球最有价值专家
     8  //https://mvp.microsoft.com/zh-cn/PublicProfile/4033620
     9  package bn256
    10  
    11  import (
    12  	"math/big"
    13  )
    14  
    15  var half = new(big.Int).Rsh(Order, 1)
    16  
    17  var curveLattice = &lattice{
    18  	vectors: [][]*big.Int{
    19  		{bigFromBase10("147946756881789319000765030803803410728"), bigFromBase10("147946756881789319010696353538189108491")},
    20  		{bigFromBase10("147946756881789319020627676272574806254"), bigFromBase10("-147946756881789318990833708069417712965")},
    21  	},
    22  	inverse: []*big.Int{
    23  		bigFromBase10("147946756881789318990833708069417712965"),
    24  		bigFromBase10("147946756881789319010696353538189108491"),
    25  	},
    26  	det: bigFromBase10("43776485743678550444492811490514550177096728800832068687396408373151616991234"),
    27  }
    28  
    29  var targetLattice = &lattice{
    30  	vectors: [][]*big.Int{
    31  		{bigFromBase10("9931322734385697761"), bigFromBase10("9931322734385697761"), bigFromBase10("9931322734385697763"), bigFromBase10("9931322734385697764")},
    32  		{bigFromBase10("4965661367192848881"), bigFromBase10("4965661367192848881"), bigFromBase10("4965661367192848882"), bigFromBase10("-9931322734385697762")},
    33  		{bigFromBase10("-9931322734385697762"), bigFromBase10("-4965661367192848881"), bigFromBase10("4965661367192848881"), bigFromBase10("-4965661367192848882")},
    34  		{bigFromBase10("9931322734385697763"), bigFromBase10("-4965661367192848881"), bigFromBase10("-4965661367192848881"), bigFromBase10("-4965661367192848881")},
    35  	},
    36  	inverse: []*big.Int{
    37  		bigFromBase10("734653495049373973658254490726798021314063399421879442165"),
    38  		bigFromBase10("147946756881789319000765030803803410728"),
    39  		bigFromBase10("-147946756881789319005730692170996259609"),
    40  		bigFromBase10("1469306990098747947464455738335385361643788813749140841702"),
    41  	},
    42  	det: new(big.Int).Set(Order),
    43  }
    44  
    45  type lattice struct {
    46  	vectors [][]*big.Int
    47  	inverse []*big.Int
    48  	det     *big.Int
    49  }
    50  
    51  //分解以一个标量mod阶作为输入,并找到一个简短的正分解,它与格的基础。
    52  func (l *lattice) decompose(k *big.Int) []*big.Int {
    53  	n := len(l.inverse)
    54  
    55  //用babai的四舍五入法计算晶格中最接近的向量<k,0,0,…>。
    56  	c := make([]*big.Int, n)
    57  	for i := 0; i < n; i++ {
    58  		c[i] = new(big.Int).Mul(k, l.inverse[i])
    59  		round(c[i], l.det)
    60  	}
    61  
    62  //根据c变换向量并减去<k,0,0,…>。
    63  	out := make([]*big.Int, n)
    64  	temp := new(big.Int)
    65  
    66  	for i := 0; i < n; i++ {
    67  		out[i] = new(big.Int)
    68  
    69  		for j := 0; j < n; j++ {
    70  			temp.Mul(c[j], l.vectors[j][i])
    71  			out[i].Add(out[i], temp)
    72  		}
    73  
    74  		out[i].Neg(out[i])
    75  		out[i].Add(out[i], l.vectors[0][i]).Add(out[i], l.vectors[0][i])
    76  	}
    77  	out[0].Add(out[0], k)
    78  
    79  	return out
    80  }
    81  
    82  func (l *lattice) Precompute(add func(i, j uint)) {
    83  	n := uint(len(l.vectors))
    84  	total := uint(1) << n
    85  
    86  	for i := uint(0); i < n; i++ {
    87  		for j := uint(0); j < total; j++ {
    88  			if (j>>i)&1 == 1 {
    89  				add(i, j)
    90  			}
    91  		}
    92  	}
    93  }
    94  
    95  func (l *lattice) Multi(scalar *big.Int) []uint8 {
    96  	decomp := l.decompose(scalar)
    97  
    98  	maxLen := 0
    99  	for _, x := range decomp {
   100  		if x.BitLen() > maxLen {
   101  			maxLen = x.BitLen()
   102  		}
   103  	}
   104  
   105  	out := make([]uint8, maxLen)
   106  	for j, x := range decomp {
   107  		for i := 0; i < maxLen; i++ {
   108  			out[i] += uint8(x.Bit(i)) << uint(j)
   109  		}
   110  	}
   111  
   112  	return out
   113  }
   114  
   115  //round将num设置为num/denom,四舍五入到最接近的整数。
   116  func round(num, denom *big.Int) {
   117  	r := new(big.Int)
   118  	num.DivMod(num, denom, r)
   119  
   120  	if r.Cmp(half) == 1 {
   121  		num.Add(num, big.NewInt(1))
   122  	}
   123  }