github.com/cloudflare/circl@v1.5.0/ecc/fourq/fp_generic.go (about) 1 //go:build go1.12 2 // +build go1.12 3 4 package fourq 5 6 import ( 7 "encoding/binary" 8 "math/bits" 9 ) 10 11 func fpModGeneric(c *Fp) { fpSubGeneric(c, c, &modulusP) } 12 13 func fpAddGeneric(c, a, b *Fp) { 14 a0 := binary.LittleEndian.Uint64(a[0*8 : 1*8]) 15 a1 := binary.LittleEndian.Uint64(a[1*8 : 2*8]) 16 17 b0 := binary.LittleEndian.Uint64(b[0*8 : 1*8]) 18 b1 := binary.LittleEndian.Uint64(b[1*8 : 2*8]) 19 20 c0, x := bits.Add64(a0, b0, 0) 21 c1, _ := bits.Add64(a1, b1, x) 22 c1, x = bits.Add64(c1, c1, 0) 23 c0, x = bits.Add64(c0, 0, x) 24 c1, _ = bits.Add64(c1>>1, 0, x) 25 26 binary.LittleEndian.PutUint64(c[0*8:1*8], c0) 27 binary.LittleEndian.PutUint64(c[1*8:2*8], c1) 28 } 29 30 func fpSubGeneric(c, a, b *Fp) { 31 a0 := binary.LittleEndian.Uint64(a[0*8 : 1*8]) 32 a1 := binary.LittleEndian.Uint64(a[1*8 : 2*8]) 33 34 b0 := binary.LittleEndian.Uint64(b[0*8 : 1*8]) 35 b1 := binary.LittleEndian.Uint64(b[1*8 : 2*8]) 36 37 c0, x := bits.Sub64(a0, b0, 0) 38 c1, _ := bits.Sub64(a1, b1, x) 39 c1, x = bits.Add64(c1, c1, 0) 40 c0, x = bits.Sub64(c0, 0, x) 41 c1, _ = bits.Sub64(c1>>1, 0, x) 42 43 binary.LittleEndian.PutUint64(c[0*8:1*8], c0) 44 binary.LittleEndian.PutUint64(c[1*8:2*8], c1) 45 } 46 47 func fpMulGeneric(c, a, b *Fp) { 48 a0 := binary.LittleEndian.Uint64(a[0*8 : 1*8]) 49 a1 := binary.LittleEndian.Uint64(a[1*8 : 2*8]) 50 51 b0 := binary.LittleEndian.Uint64(b[0*8 : 1*8]) 52 b1 := binary.LittleEndian.Uint64(b[1*8 : 2*8]) 53 54 c1, c0 := bits.Mul64(a0, b0) 55 hi, lo := bits.Mul64(a0, b1) 56 c0, x := bits.Add64(c0, hi<<1, 0) 57 c1, x = bits.Add64(c1, lo, x) 58 c2, _ := bits.Add64(0, 0, x) 59 60 hi, lo = bits.Mul64(a1, b0) 61 c0, x = bits.Add64(c0, hi<<1, 0) 62 c1, x = bits.Add64(c1, lo, x) 63 c2, _ = bits.Add64(c2, 0, x) 64 65 hi, lo = bits.Mul64(a1, b1) 66 lo, x = bits.Add64(lo, lo, 0) 67 hi, _ = bits.Add64(hi, hi, x) 68 69 c0, x = bits.Add64(c0, lo, 0) 70 c1, x = bits.Add64(c1, hi, x) 71 c2, _ = bits.Add64(c2, 0, x) 72 73 c1, x = bits.Add64(c1, c1, 0) 74 c0, x = bits.Add64(c0, c2<<1, x) 75 c1, _ = bits.Add64(c1>>1, 0, x) 76 77 c1, x = bits.Add64(c1, c1, 0) 78 c0, x = bits.Add64(c0, 0, x) 79 c1, _ = bits.Add64(c1>>1, 0, x) 80 81 binary.LittleEndian.PutUint64(c[0*8:1*8], c0) 82 binary.LittleEndian.PutUint64(c[1*8:2*8], c1) 83 } 84 85 func fpSqrGeneric(c, a *Fp) { fpMulGeneric(c, a, a) } 86 87 func fpHlfGeneric(c, a *Fp) { 88 a0 := binary.LittleEndian.Uint64(a[0*8 : 1*8]) 89 a1 := binary.LittleEndian.Uint64(a[1*8 : 2*8]) 90 91 hlf := a0 & 0x1 92 c0 := (a1 << 63) | (a0 >> 1) 93 c1 := (hlf << 62) | (a1 >> 1) 94 95 binary.LittleEndian.PutUint64(c[0*8:1*8], c0) 96 binary.LittleEndian.PutUint64(c[1*8:2*8], c1) 97 }