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