github.com/cloudflare/circl@v1.5.0/dh/sidh/internal/p751/arith_generic.go (about) 1 // Code generated by go generate; DO NOT EDIT. 2 // This file was generated by robots. 3 4 //go:build purego || (!amd64 && !arm64) 5 // +build purego !amd64,!arm64 6 7 package p751 8 9 import ( 10 "math/bits" 11 12 "github.com/cloudflare/circl/dh/sidh/internal/common" 13 ) 14 15 // Compute z = x + y (mod p). 16 func addP751(z, x, y *common.Fp) { 17 var carry uint64 18 19 // z=x+y % P751 20 for i := 0; i < FpWords; i++ { 21 z[i], carry = bits.Add64(x[i], y[i], carry) 22 } 23 24 // z = z - P751x2 25 carry = 0 26 for i := 0; i < FpWords; i++ { 27 z[i], carry = bits.Sub64(z[i], P751x2[i], carry) 28 } 29 30 // if z<0 add P751x2 back 31 mask := uint64(0 - carry) 32 carry = 0 33 for i := 0; i < FpWords; i++ { 34 z[i], carry = bits.Add64(z[i], P751x2[i]&mask, carry) 35 } 36 } 37 38 // Compute z = x - y (mod p). 39 func subP751(z, x, y *common.Fp) { 40 var borrow uint64 41 42 for i := 0; i < FpWords; i++ { 43 z[i], borrow = bits.Sub64(x[i], y[i], borrow) 44 } 45 46 mask := uint64(0 - borrow) 47 borrow = 0 48 49 for i := 0; i < FpWords; i++ { 50 z[i], borrow = bits.Add64(z[i], P751x2[i]&mask, borrow) 51 } 52 } 53 54 // If choice = 0, leave x unchanged. If choice = 1, sets x to y. 55 // If choice is neither 0 nor 1 then behaviour is undefined. 56 // This function executes in constant time. 57 func cmovP751(x, y *common.Fp, choice uint8) { 58 mask := 0 - uint64(choice) 59 for i := 0; i < FpWords; i++ { 60 x[i] ^= mask & (x[i] ^ y[i]) 61 } 62 } 63 64 // Conditionally swaps bits in x and y in constant time. 65 // mask indicates bits to be swapped (set bits are swapped) 66 // For details see "Hackers Delight, 2.20" 67 // 68 // Implementation doesn't actually depend on a prime field. 69 func cswapP751(x, y *common.Fp, mask uint8) { 70 var tmp, mask64 uint64 71 72 mask64 = 0 - uint64(mask) 73 for i := 0; i < FpWords; i++ { 74 tmp = mask64 & (x[i] ^ y[i]) 75 x[i] = tmp ^ x[i] 76 y[i] = tmp ^ y[i] 77 } 78 } 79 80 // Perform Montgomery reduction: set z = x R^{-1} (mod 2*p) 81 // with R=2^(FpWords*64). Destroys the input value. 82 func rdcP751(z *common.Fp, x *common.FpX2) { 83 var carry, t, u, v uint64 84 var hi, lo uint64 85 var count int 86 87 count = P751p1Zeros 88 89 for i := 0; i < FpWords; i++ { 90 for j := 0; j < i; j++ { 91 if j < (i - count + 1) { 92 hi, lo = bits.Mul64(z[j], P751p1[i-j]) 93 v, carry = bits.Add64(lo, v, 0) 94 u, carry = bits.Add64(hi, u, carry) 95 t += carry 96 } 97 } 98 v, carry = bits.Add64(v, x[i], 0) 99 u, carry = bits.Add64(u, 0, carry) 100 t += carry 101 102 z[i] = v 103 v = u 104 u = t 105 t = 0 106 } 107 108 for i := FpWords; i < 2*FpWords-1; i++ { 109 if count > 0 { 110 count-- 111 } 112 for j := i - FpWords + 1; j < FpWords; j++ { 113 if j < (FpWords - count) { 114 hi, lo = bits.Mul64(z[j], P751p1[i-j]) 115 v, carry = bits.Add64(lo, v, 0) 116 u, carry = bits.Add64(hi, u, carry) 117 t += carry 118 } 119 } 120 v, carry = bits.Add64(v, x[i], 0) 121 u, carry = bits.Add64(u, 0, carry) 122 123 t += carry 124 z[i-FpWords] = v 125 v = u 126 u = t 127 t = 0 128 } 129 v, _ = bits.Add64(v, x[2*FpWords-1], 0) 130 z[FpWords-1] = v 131 } 132 133 // Compute z = x * y. 134 func mulP751(z *common.FpX2, x, y *common.Fp) { 135 var u, v, t uint64 136 var hi, lo uint64 137 var carry uint64 138 139 for i := uint64(0); i < FpWords; i++ { 140 for j := uint64(0); j <= i; j++ { 141 hi, lo = bits.Mul64(x[j], y[i-j]) 142 v, carry = bits.Add64(lo, v, 0) 143 u, carry = bits.Add64(hi, u, carry) 144 t += carry 145 } 146 z[i] = v 147 v = u 148 u = t 149 t = 0 150 } 151 152 for i := FpWords; i < (2*FpWords)-1; i++ { 153 for j := i - FpWords + 1; j < FpWords; j++ { 154 hi, lo = bits.Mul64(x[j], y[i-j]) 155 v, carry = bits.Add64(lo, v, 0) 156 u, carry = bits.Add64(hi, u, carry) 157 t += carry 158 } 159 z[i] = v 160 v = u 161 u = t 162 t = 0 163 } 164 z[2*FpWords-1] = v 165 } 166 167 // Compute z = x + y, without reducing mod p. 168 func adlP751(z, x, y *common.FpX2) { 169 var carry uint64 170 for i := 0; i < 2*FpWords; i++ { 171 z[i], carry = bits.Add64(x[i], y[i], carry) 172 } 173 } 174 175 // Reduce a field element in [0, 2*p) to one in [0,p). 176 func modP751(x *common.Fp) { 177 var borrow, mask uint64 178 for i := 0; i < FpWords; i++ { 179 x[i], borrow = bits.Sub64(x[i], P751[i], borrow) 180 } 181 182 // Sets all bits if borrow = 1 183 mask = 0 - borrow 184 borrow = 0 185 for i := 0; i < FpWords; i++ { 186 x[i], borrow = bits.Add64(x[i], P751[i]&mask, borrow) 187 } 188 } 189 190 // Compute z = x - y, without reducing mod p. 191 func sulP751(z, x, y *common.FpX2) { 192 var borrow, mask uint64 193 for i := 0; i < 2*FpWords; i++ { 194 z[i], borrow = bits.Sub64(x[i], y[i], borrow) 195 } 196 197 // Sets all bits if borrow = 1 198 mask = 0 - borrow 199 borrow = 0 200 for i := FpWords; i < 2*FpWords; i++ { 201 z[i], borrow = bits.Add64(z[i], P751[i-FpWords]&mask, borrow) 202 } 203 }