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