github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/crypto/bn256/cloudflare/gfp_generic.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 //+建设!AMD64!ARM64通用 10 11 package bn256 12 13 func gfpCarry(a *gfP, head uint64) { 14 b := &gfP{} 15 16 var carry uint64 17 for i, pi := range p2 { 18 ai := a[i] 19 bi := ai - pi - carry 20 b[i] = bi 21 carry = (pi&^ai | (pi|^ai)&bi) >> 63 22 } 23 carry = carry &^ head 24 25 //如果b为负,则返回a。 26 //否则返回B。 27 carry = -carry 28 ncarry := ^carry 29 for i := 0; i < 4; i++ { 30 a[i] = (a[i] & carry) | (b[i] & ncarry) 31 } 32 } 33 34 func gfpNeg(c, a *gfP) { 35 var carry uint64 36 for i, pi := range p2 { 37 ai := a[i] 38 ci := pi - ai - carry 39 c[i] = ci 40 carry = (ai&^pi | (ai|^pi)&ci) >> 63 41 } 42 gfpCarry(c, 0) 43 } 44 45 func gfpAdd(c, a, b *gfP) { 46 var carry uint64 47 for i, ai := range a { 48 bi := b[i] 49 ci := ai + bi + carry 50 c[i] = ci 51 carry = (ai&bi | (ai|bi)&^ci) >> 63 52 } 53 gfpCarry(c, carry) 54 } 55 56 func gfpSub(c, a, b *gfP) { 57 t := &gfP{} 58 59 var carry uint64 60 for i, pi := range p2 { 61 bi := b[i] 62 ti := pi - bi - carry 63 t[i] = ti 64 carry = (bi&^pi | (bi|^pi)&ti) >> 63 65 } 66 67 carry = 0 68 for i, ai := range a { 69 ti := t[i] 70 ci := ai + ti + carry 71 c[i] = ci 72 carry = (ai&ti | (ai|ti)&^ci) >> 63 73 } 74 gfpCarry(c, carry) 75 } 76 77 func mul(a, b [4]uint64) [8]uint64 { 78 const ( 79 mask16 uint64 = 0x0000ffff 80 mask32 uint64 = 0xffffffff 81 ) 82 83 var buff [32]uint64 84 for i, ai := range a { 85 a0, a1, a2, a3 := ai&mask16, (ai>>16)&mask16, (ai>>32)&mask16, ai>>48 86 87 for j, bj := range b { 88 b0, b2 := bj&mask32, bj>>32 89 90 off := 4 * (i + j) 91 buff[off+0] += a0 * b0 92 buff[off+1] += a1 * b0 93 buff[off+2] += a2*b0 + a0*b2 94 buff[off+3] += a3*b0 + a1*b2 95 buff[off+4] += a2 * b2 96 buff[off+5] += a3 * b2 97 } 98 } 99 100 for i := uint(1); i < 4; i++ { 101 shift := 16 * i 102 103 var head, carry uint64 104 for j := uint(0); j < 8; j++ { 105 block := 4 * j 106 107 xi := buff[block] 108 yi := (buff[block+i] << shift) + head 109 zi := xi + yi + carry 110 buff[block] = zi 111 carry = (xi&yi | (xi|yi)&^zi) >> 63 112 113 head = buff[block+i] >> (64 - shift) 114 } 115 } 116 117 return [8]uint64{buff[0], buff[4], buff[8], buff[12], buff[16], buff[20], buff[24], buff[28]} 118 } 119 120 func halfMul(a, b [4]uint64) [4]uint64 { 121 const ( 122 mask16 uint64 = 0x0000ffff 123 mask32 uint64 = 0xffffffff 124 ) 125 126 var buff [18]uint64 127 for i, ai := range a { 128 a0, a1, a2, a3 := ai&mask16, (ai>>16)&mask16, (ai>>32)&mask16, ai>>48 129 130 for j, bj := range b { 131 if i+j > 3 { 132 break 133 } 134 b0, b2 := bj&mask32, bj>>32 135 136 off := 4 * (i + j) 137 buff[off+0] += a0 * b0 138 buff[off+1] += a1 * b0 139 buff[off+2] += a2*b0 + a0*b2 140 buff[off+3] += a3*b0 + a1*b2 141 buff[off+4] += a2 * b2 142 buff[off+5] += a3 * b2 143 } 144 } 145 146 for i := uint(1); i < 4; i++ { 147 shift := 16 * i 148 149 var head, carry uint64 150 for j := uint(0); j < 4; j++ { 151 block := 4 * j 152 153 xi := buff[block] 154 yi := (buff[block+i] << shift) + head 155 zi := xi + yi + carry 156 buff[block] = zi 157 carry = (xi&yi | (xi|yi)&^zi) >> 63 158 159 head = buff[block+i] >> (64 - shift) 160 } 161 } 162 163 return [4]uint64{buff[0], buff[4], buff[8], buff[12]} 164 } 165 166 func gfpMul(c, a, b *gfP) { 167 T := mul(*a, *b) 168 m := halfMul([4]uint64{T[0], T[1], T[2], T[3]}, np) 169 t := mul([4]uint64{m[0], m[1], m[2], m[3]}, p2) 170 171 var carry uint64 172 for i, Ti := range T { 173 ti := t[i] 174 zi := Ti + ti + carry 175 T[i] = zi 176 carry = (Ti&ti | (Ti|ti)&^zi) >> 63 177 } 178 179 *c = gfP{T[4], T[5], T[6], T[7]} 180 gfpCarry(c, carry) 181 }