github.com/cloudflare/circl@v1.5.0/math/fp448/fp_generic.go (about) 1 package fp448 2 3 import ( 4 "encoding/binary" 5 "math/bits" 6 ) 7 8 func cmovGeneric(x, y *Elt, n uint) { 9 m := -uint64(n & 0x1) 10 x0 := binary.LittleEndian.Uint64(x[0*8 : 1*8]) 11 x1 := binary.LittleEndian.Uint64(x[1*8 : 2*8]) 12 x2 := binary.LittleEndian.Uint64(x[2*8 : 3*8]) 13 x3 := binary.LittleEndian.Uint64(x[3*8 : 4*8]) 14 x4 := binary.LittleEndian.Uint64(x[4*8 : 5*8]) 15 x5 := binary.LittleEndian.Uint64(x[5*8 : 6*8]) 16 x6 := binary.LittleEndian.Uint64(x[6*8 : 7*8]) 17 18 y0 := binary.LittleEndian.Uint64(y[0*8 : 1*8]) 19 y1 := binary.LittleEndian.Uint64(y[1*8 : 2*8]) 20 y2 := binary.LittleEndian.Uint64(y[2*8 : 3*8]) 21 y3 := binary.LittleEndian.Uint64(y[3*8 : 4*8]) 22 y4 := binary.LittleEndian.Uint64(y[4*8 : 5*8]) 23 y5 := binary.LittleEndian.Uint64(y[5*8 : 6*8]) 24 y6 := binary.LittleEndian.Uint64(y[6*8 : 7*8]) 25 26 x0 = (x0 &^ m) | (y0 & m) 27 x1 = (x1 &^ m) | (y1 & m) 28 x2 = (x2 &^ m) | (y2 & m) 29 x3 = (x3 &^ m) | (y3 & m) 30 x4 = (x4 &^ m) | (y4 & m) 31 x5 = (x5 &^ m) | (y5 & m) 32 x6 = (x6 &^ m) | (y6 & m) 33 34 binary.LittleEndian.PutUint64(x[0*8:1*8], x0) 35 binary.LittleEndian.PutUint64(x[1*8:2*8], x1) 36 binary.LittleEndian.PutUint64(x[2*8:3*8], x2) 37 binary.LittleEndian.PutUint64(x[3*8:4*8], x3) 38 binary.LittleEndian.PutUint64(x[4*8:5*8], x4) 39 binary.LittleEndian.PutUint64(x[5*8:6*8], x5) 40 binary.LittleEndian.PutUint64(x[6*8:7*8], x6) 41 } 42 43 func cswapGeneric(x, y *Elt, n uint) { 44 m := -uint64(n & 0x1) 45 x0 := binary.LittleEndian.Uint64(x[0*8 : 1*8]) 46 x1 := binary.LittleEndian.Uint64(x[1*8 : 2*8]) 47 x2 := binary.LittleEndian.Uint64(x[2*8 : 3*8]) 48 x3 := binary.LittleEndian.Uint64(x[3*8 : 4*8]) 49 x4 := binary.LittleEndian.Uint64(x[4*8 : 5*8]) 50 x5 := binary.LittleEndian.Uint64(x[5*8 : 6*8]) 51 x6 := binary.LittleEndian.Uint64(x[6*8 : 7*8]) 52 53 y0 := binary.LittleEndian.Uint64(y[0*8 : 1*8]) 54 y1 := binary.LittleEndian.Uint64(y[1*8 : 2*8]) 55 y2 := binary.LittleEndian.Uint64(y[2*8 : 3*8]) 56 y3 := binary.LittleEndian.Uint64(y[3*8 : 4*8]) 57 y4 := binary.LittleEndian.Uint64(y[4*8 : 5*8]) 58 y5 := binary.LittleEndian.Uint64(y[5*8 : 6*8]) 59 y6 := binary.LittleEndian.Uint64(y[6*8 : 7*8]) 60 61 t0 := m & (x0 ^ y0) 62 t1 := m & (x1 ^ y1) 63 t2 := m & (x2 ^ y2) 64 t3 := m & (x3 ^ y3) 65 t4 := m & (x4 ^ y4) 66 t5 := m & (x5 ^ y5) 67 t6 := m & (x6 ^ y6) 68 x0 ^= t0 69 x1 ^= t1 70 x2 ^= t2 71 x3 ^= t3 72 x4 ^= t4 73 x5 ^= t5 74 x6 ^= t6 75 y0 ^= t0 76 y1 ^= t1 77 y2 ^= t2 78 y3 ^= t3 79 y4 ^= t4 80 y5 ^= t5 81 y6 ^= t6 82 83 binary.LittleEndian.PutUint64(x[0*8:1*8], x0) 84 binary.LittleEndian.PutUint64(x[1*8:2*8], x1) 85 binary.LittleEndian.PutUint64(x[2*8:3*8], x2) 86 binary.LittleEndian.PutUint64(x[3*8:4*8], x3) 87 binary.LittleEndian.PutUint64(x[4*8:5*8], x4) 88 binary.LittleEndian.PutUint64(x[5*8:6*8], x5) 89 binary.LittleEndian.PutUint64(x[6*8:7*8], x6) 90 91 binary.LittleEndian.PutUint64(y[0*8:1*8], y0) 92 binary.LittleEndian.PutUint64(y[1*8:2*8], y1) 93 binary.LittleEndian.PutUint64(y[2*8:3*8], y2) 94 binary.LittleEndian.PutUint64(y[3*8:4*8], y3) 95 binary.LittleEndian.PutUint64(y[4*8:5*8], y4) 96 binary.LittleEndian.PutUint64(y[5*8:6*8], y5) 97 binary.LittleEndian.PutUint64(y[6*8:7*8], y6) 98 } 99 100 func addGeneric(z, x, y *Elt) { 101 x0 := binary.LittleEndian.Uint64(x[0*8 : 1*8]) 102 x1 := binary.LittleEndian.Uint64(x[1*8 : 2*8]) 103 x2 := binary.LittleEndian.Uint64(x[2*8 : 3*8]) 104 x3 := binary.LittleEndian.Uint64(x[3*8 : 4*8]) 105 x4 := binary.LittleEndian.Uint64(x[4*8 : 5*8]) 106 x5 := binary.LittleEndian.Uint64(x[5*8 : 6*8]) 107 x6 := binary.LittleEndian.Uint64(x[6*8 : 7*8]) 108 109 y0 := binary.LittleEndian.Uint64(y[0*8 : 1*8]) 110 y1 := binary.LittleEndian.Uint64(y[1*8 : 2*8]) 111 y2 := binary.LittleEndian.Uint64(y[2*8 : 3*8]) 112 y3 := binary.LittleEndian.Uint64(y[3*8 : 4*8]) 113 y4 := binary.LittleEndian.Uint64(y[4*8 : 5*8]) 114 y5 := binary.LittleEndian.Uint64(y[5*8 : 6*8]) 115 y6 := binary.LittleEndian.Uint64(y[6*8 : 7*8]) 116 117 z0, c0 := bits.Add64(x0, y0, 0) 118 z1, c1 := bits.Add64(x1, y1, c0) 119 z2, c2 := bits.Add64(x2, y2, c1) 120 z3, c3 := bits.Add64(x3, y3, c2) 121 z4, c4 := bits.Add64(x4, y4, c3) 122 z5, c5 := bits.Add64(x5, y5, c4) 123 z6, z7 := bits.Add64(x6, y6, c5) 124 125 z0, c0 = bits.Add64(z0, z7, 0) 126 z1, c1 = bits.Add64(z1, 0, c0) 127 z2, c2 = bits.Add64(z2, 0, c1) 128 z3, c3 = bits.Add64(z3, z7<<32, c2) 129 z4, c4 = bits.Add64(z4, 0, c3) 130 z5, c5 = bits.Add64(z5, 0, c4) 131 z6, z7 = bits.Add64(z6, 0, c5) 132 133 z0, c0 = bits.Add64(z0, z7, 0) 134 z1, c1 = bits.Add64(z1, 0, c0) 135 z2, c2 = bits.Add64(z2, 0, c1) 136 z3, c3 = bits.Add64(z3, z7<<32, c2) 137 z4, c4 = bits.Add64(z4, 0, c3) 138 z5, c5 = bits.Add64(z5, 0, c4) 139 z6, _ = bits.Add64(z6, 0, c5) 140 141 binary.LittleEndian.PutUint64(z[0*8:1*8], z0) 142 binary.LittleEndian.PutUint64(z[1*8:2*8], z1) 143 binary.LittleEndian.PutUint64(z[2*8:3*8], z2) 144 binary.LittleEndian.PutUint64(z[3*8:4*8], z3) 145 binary.LittleEndian.PutUint64(z[4*8:5*8], z4) 146 binary.LittleEndian.PutUint64(z[5*8:6*8], z5) 147 binary.LittleEndian.PutUint64(z[6*8:7*8], z6) 148 } 149 150 func subGeneric(z, x, y *Elt) { 151 x0 := binary.LittleEndian.Uint64(x[0*8 : 1*8]) 152 x1 := binary.LittleEndian.Uint64(x[1*8 : 2*8]) 153 x2 := binary.LittleEndian.Uint64(x[2*8 : 3*8]) 154 x3 := binary.LittleEndian.Uint64(x[3*8 : 4*8]) 155 x4 := binary.LittleEndian.Uint64(x[4*8 : 5*8]) 156 x5 := binary.LittleEndian.Uint64(x[5*8 : 6*8]) 157 x6 := binary.LittleEndian.Uint64(x[6*8 : 7*8]) 158 159 y0 := binary.LittleEndian.Uint64(y[0*8 : 1*8]) 160 y1 := binary.LittleEndian.Uint64(y[1*8 : 2*8]) 161 y2 := binary.LittleEndian.Uint64(y[2*8 : 3*8]) 162 y3 := binary.LittleEndian.Uint64(y[3*8 : 4*8]) 163 y4 := binary.LittleEndian.Uint64(y[4*8 : 5*8]) 164 y5 := binary.LittleEndian.Uint64(y[5*8 : 6*8]) 165 y6 := binary.LittleEndian.Uint64(y[6*8 : 7*8]) 166 167 z0, c0 := bits.Sub64(x0, y0, 0) 168 z1, c1 := bits.Sub64(x1, y1, c0) 169 z2, c2 := bits.Sub64(x2, y2, c1) 170 z3, c3 := bits.Sub64(x3, y3, c2) 171 z4, c4 := bits.Sub64(x4, y4, c3) 172 z5, c5 := bits.Sub64(x5, y5, c4) 173 z6, z7 := bits.Sub64(x6, y6, c5) 174 175 z0, c0 = bits.Sub64(z0, z7, 0) 176 z1, c1 = bits.Sub64(z1, 0, c0) 177 z2, c2 = bits.Sub64(z2, 0, c1) 178 z3, c3 = bits.Sub64(z3, z7<<32, c2) 179 z4, c4 = bits.Sub64(z4, 0, c3) 180 z5, c5 = bits.Sub64(z5, 0, c4) 181 z6, z7 = bits.Sub64(z6, 0, c5) 182 183 z0, c0 = bits.Sub64(z0, z7, 0) 184 z1, c1 = bits.Sub64(z1, 0, c0) 185 z2, c2 = bits.Sub64(z2, 0, c1) 186 z3, c3 = bits.Sub64(z3, z7<<32, c2) 187 z4, c4 = bits.Sub64(z4, 0, c3) 188 z5, c5 = bits.Sub64(z5, 0, c4) 189 z6, _ = bits.Sub64(z6, 0, c5) 190 191 binary.LittleEndian.PutUint64(z[0*8:1*8], z0) 192 binary.LittleEndian.PutUint64(z[1*8:2*8], z1) 193 binary.LittleEndian.PutUint64(z[2*8:3*8], z2) 194 binary.LittleEndian.PutUint64(z[3*8:4*8], z3) 195 binary.LittleEndian.PutUint64(z[4*8:5*8], z4) 196 binary.LittleEndian.PutUint64(z[5*8:6*8], z5) 197 binary.LittleEndian.PutUint64(z[6*8:7*8], z6) 198 } 199 200 func addsubGeneric(x, y *Elt) { 201 z := &Elt{} 202 addGeneric(z, x, y) 203 subGeneric(y, x, y) 204 *x = *z 205 } 206 207 func mulGeneric(z, x, y *Elt) { 208 x0 := binary.LittleEndian.Uint64(x[0*8 : 1*8]) 209 x1 := binary.LittleEndian.Uint64(x[1*8 : 2*8]) 210 x2 := binary.LittleEndian.Uint64(x[2*8 : 3*8]) 211 x3 := binary.LittleEndian.Uint64(x[3*8 : 4*8]) 212 x4 := binary.LittleEndian.Uint64(x[4*8 : 5*8]) 213 x5 := binary.LittleEndian.Uint64(x[5*8 : 6*8]) 214 x6 := binary.LittleEndian.Uint64(x[6*8 : 7*8]) 215 216 y0 := binary.LittleEndian.Uint64(y[0*8 : 1*8]) 217 y1 := binary.LittleEndian.Uint64(y[1*8 : 2*8]) 218 y2 := binary.LittleEndian.Uint64(y[2*8 : 3*8]) 219 y3 := binary.LittleEndian.Uint64(y[3*8 : 4*8]) 220 y4 := binary.LittleEndian.Uint64(y[4*8 : 5*8]) 221 y5 := binary.LittleEndian.Uint64(y[5*8 : 6*8]) 222 y6 := binary.LittleEndian.Uint64(y[6*8 : 7*8]) 223 224 yy := [7]uint64{y0, y1, y2, y3, y4, y5, y6} 225 zz := [7]uint64{} 226 227 yi := yy[0] 228 h0, l0 := bits.Mul64(x0, yi) 229 h1, l1 := bits.Mul64(x1, yi) 230 h2, l2 := bits.Mul64(x2, yi) 231 h3, l3 := bits.Mul64(x3, yi) 232 h4, l4 := bits.Mul64(x4, yi) 233 h5, l5 := bits.Mul64(x5, yi) 234 h6, l6 := bits.Mul64(x6, yi) 235 236 zz[0] = l0 237 a0, c0 := bits.Add64(h0, l1, 0) 238 a1, c1 := bits.Add64(h1, l2, c0) 239 a2, c2 := bits.Add64(h2, l3, c1) 240 a3, c3 := bits.Add64(h3, l4, c2) 241 a4, c4 := bits.Add64(h4, l5, c3) 242 a5, c5 := bits.Add64(h5, l6, c4) 243 a6, _ := bits.Add64(h6, 0, c5) 244 245 for i := 1; i < 7; i++ { 246 yi = yy[i] 247 h0, l0 = bits.Mul64(x0, yi) 248 h1, l1 = bits.Mul64(x1, yi) 249 h2, l2 = bits.Mul64(x2, yi) 250 h3, l3 = bits.Mul64(x3, yi) 251 h4, l4 = bits.Mul64(x4, yi) 252 h5, l5 = bits.Mul64(x5, yi) 253 h6, l6 = bits.Mul64(x6, yi) 254 255 zz[i], c0 = bits.Add64(a0, l0, 0) 256 a0, c1 = bits.Add64(a1, l1, c0) 257 a1, c2 = bits.Add64(a2, l2, c1) 258 a2, c3 = bits.Add64(a3, l3, c2) 259 a3, c4 = bits.Add64(a4, l4, c3) 260 a4, c5 = bits.Add64(a5, l5, c4) 261 a5, a6 = bits.Add64(a6, l6, c5) 262 263 a0, c0 = bits.Add64(a0, h0, 0) 264 a1, c1 = bits.Add64(a1, h1, c0) 265 a2, c2 = bits.Add64(a2, h2, c1) 266 a3, c3 = bits.Add64(a3, h3, c2) 267 a4, c4 = bits.Add64(a4, h4, c3) 268 a5, c5 = bits.Add64(a5, h5, c4) 269 a6, _ = bits.Add64(a6, h6, c5) 270 } 271 red64(z, &zz, &[7]uint64{a0, a1, a2, a3, a4, a5, a6}) 272 } 273 274 func sqrGeneric(z, x *Elt) { mulGeneric(z, x, x) } 275 276 func red64(z *Elt, l, h *[7]uint64) { 277 /* (2C13, 2C12, 2C11, 2C10|C10, C9, C8, C7) + (C6,...,C0) */ 278 h0 := h[0] 279 h1 := h[1] 280 h2 := h[2] 281 h3 := ((h[3] & (0xFFFFFFFF << 32)) << 1) | (h[3] & 0xFFFFFFFF) 282 h4 := (h[3] >> 63) | (h[4] << 1) 283 h5 := (h[4] >> 63) | (h[5] << 1) 284 h6 := (h[5] >> 63) | (h[6] << 1) 285 h7 := (h[6] >> 63) 286 287 l0, c0 := bits.Add64(h0, l[0], 0) 288 l1, c1 := bits.Add64(h1, l[1], c0) 289 l2, c2 := bits.Add64(h2, l[2], c1) 290 l3, c3 := bits.Add64(h3, l[3], c2) 291 l4, c4 := bits.Add64(h4, l[4], c3) 292 l5, c5 := bits.Add64(h5, l[5], c4) 293 l6, c6 := bits.Add64(h6, l[6], c5) 294 l7, _ := bits.Add64(h7, 0, c6) 295 296 /* (C10C9, C9C8,C8C7,C7C13,C13C12,C12C11,C11C10) + (C6,...,C0) */ 297 h0 = (h[3] >> 32) | (h[4] << 32) 298 h1 = (h[4] >> 32) | (h[5] << 32) 299 h2 = (h[5] >> 32) | (h[6] << 32) 300 h3 = (h[6] >> 32) | (h[0] << 32) 301 h4 = (h[0] >> 32) | (h[1] << 32) 302 h5 = (h[1] >> 32) | (h[2] << 32) 303 h6 = (h[2] >> 32) | (h[3] << 32) 304 305 l0, c0 = bits.Add64(l0, h0, 0) 306 l1, c1 = bits.Add64(l1, h1, c0) 307 l2, c2 = bits.Add64(l2, h2, c1) 308 l3, c3 = bits.Add64(l3, h3, c2) 309 l4, c4 = bits.Add64(l4, h4, c3) 310 l5, c5 = bits.Add64(l5, h5, c4) 311 l6, c6 = bits.Add64(l6, h6, c5) 312 l7, _ = bits.Add64(l7, 0, c6) 313 314 /* (C7) + (C6,...,C0) */ 315 l0, c0 = bits.Add64(l0, l7, 0) 316 l1, c1 = bits.Add64(l1, 0, c0) 317 l2, c2 = bits.Add64(l2, 0, c1) 318 l3, c3 = bits.Add64(l3, l7<<32, c2) 319 l4, c4 = bits.Add64(l4, 0, c3) 320 l5, c5 = bits.Add64(l5, 0, c4) 321 l6, l7 = bits.Add64(l6, 0, c5) 322 323 /* (C7) + (C6,...,C0) */ 324 l0, c0 = bits.Add64(l0, l7, 0) 325 l1, c1 = bits.Add64(l1, 0, c0) 326 l2, c2 = bits.Add64(l2, 0, c1) 327 l3, c3 = bits.Add64(l3, l7<<32, c2) 328 l4, c4 = bits.Add64(l4, 0, c3) 329 l5, c5 = bits.Add64(l5, 0, c4) 330 l6, _ = bits.Add64(l6, 0, c5) 331 332 binary.LittleEndian.PutUint64(z[0*8:1*8], l0) 333 binary.LittleEndian.PutUint64(z[1*8:2*8], l1) 334 binary.LittleEndian.PutUint64(z[2*8:3*8], l2) 335 binary.LittleEndian.PutUint64(z[3*8:4*8], l3) 336 binary.LittleEndian.PutUint64(z[4*8:5*8], l4) 337 binary.LittleEndian.PutUint64(z[5*8:6*8], l5) 338 binary.LittleEndian.PutUint64(z[6*8:7*8], l6) 339 }