Replace addc64,subc64,mul64 in SIKE Go code with functions from math/bits

* math/bits in Go 1.12 offers Add64,Sub64 and Mul64 which can replace
  handwritten functions in SIKE Go

Change-Id: Ie92aa2b2b5183e3588a4ab02fb9b3ea111fa8a33
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/36384
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
diff --git a/ssl/test/runner/sike/arith.go b/ssl/test/runner/sike/arith.go
index 0b9b5c0..338a714 100644
--- a/ssl/test/runner/sike/arith.go
+++ b/ssl/test/runner/sike/arith.go
@@ -14,76 +14,9 @@
 
 package sike
 
-// Helpers
-
-// uint128 representation
-type uint128 struct {
-	H, L uint64
-}
-
-func addc64(cin, a, b uint64) (ret, cout uint64) {
-	ret = cin
-	ret = ret + a
-	if ret < a {
-		cout = 1
-	}
-	ret = ret + b
-	if ret < b {
-		cout = 1
-	}
-
-	return
-}
-
-func subc64(bIn, a, b uint64) (ret, bOut uint64) {
-	tmp := a - bIn
-	if tmp > a {
-		bOut = 1
-	}
-	ret = tmp - b
-	if ret > tmp {
-		bOut = 1
-	}
-	return
-}
-
-func mul64(a, b uint64) (res uint128) {
-	var al, bl, ah, bh, albl, albh, ahbl, ahbh uint64
-	var res1, res2, res3 uint64
-	var carry, maskL, maskH, temp uint64
-
-	maskL = (^maskL) >> 32
-	maskH = ^maskL
-
-	al = a & maskL
-	ah = a >> 32
-	bl = b & maskL
-	bh = b >> 32
-
-	albl = al * bl
-	albh = al * bh
-	ahbl = ah * bl
-	ahbh = ah * bh
-	res.L = albl & maskL
-
-	res1 = albl >> 32
-	res2 = ahbl & maskL
-	res3 = albh & maskL
-	temp = res1 + res2 + res3
-	carry = temp >> 32
-	res.L ^= temp << 32
-
-	res1 = ahbl >> 32
-	res2 = albh >> 32
-	res3 = ahbh & maskL
-	temp = res1 + res2 + res3 + carry
-	res.H = temp & maskL
-	carry = temp & maskH
-	res.H ^= (ahbh & maskH) + carry
-	return
-}
-
-// Fp implementation
+import (
+	"math/bits"
+)
 
 // Compute z = x + y (mod 2*p).
 func fpAddRdc(z, x, y *Fp) {
@@ -91,20 +24,20 @@
 
 	// z=x+y % p503
 	for i := 0; i < FP_WORDS; i++ {
-		z[i], carry = addc64(carry, x[i], y[i])
+		z[i], carry = bits.Add64(x[i], y[i], carry)
 	}
 
 	// z = z - p503x2
 	carry = 0
 	for i := 0; i < FP_WORDS; i++ {
-		z[i], carry = subc64(carry, z[i], p503x2[i])
+		z[i], carry = bits.Sub64(z[i], p503x2[i], carry)
 	}
 
 	// if z<0 add p503x2 back
 	mask := uint64(0 - carry)
 	carry = 0
 	for i := 0; i < FP_WORDS; i++ {
-		z[i], carry = addc64(carry, z[i], p503x2[i]&mask)
+		z[i], carry = bits.Add64(z[i], p503x2[i]&mask, carry)
 	}
 }
 
@@ -114,14 +47,14 @@
 
 	// z = z - p503x2
 	for i := 0; i < FP_WORDS; i++ {
-		z[i], borrow = subc64(borrow, x[i], y[i])
+		z[i], borrow = bits.Sub64(x[i], y[i], borrow)
 	}
 
 	// if z<0 add p503x2 back
 	mask := uint64(0 - borrow)
 	borrow = 0
 	for i := 0; i < FP_WORDS; i++ {
-		z[i], borrow = addc64(borrow, z[i], p503x2[i]&mask)
+		z[i], borrow = bits.Add64(z[i], p503x2[i]&mask, borrow)
 	}
 }
 
@@ -129,14 +62,14 @@
 func fpRdcP(x *Fp) {
 	var borrow, mask uint64
 	for i := 0; i < FP_WORDS; i++ {
-		x[i], borrow = subc64(borrow, x[i], p503[i])
+		x[i], borrow = bits.Sub64(x[i], p503[i], borrow)
 	}
 
 	// Sets all bits if borrow = 1
 	mask = 0 - borrow
 	borrow = 0
 	for i := 0; i < FP_WORDS; i++ {
-		x[i], borrow = addc64(borrow, x[i], p503[i]&mask)
+		x[i], borrow = bits.Add64(x[i], p503[i]&mask, borrow)
 	}
 }
 
@@ -152,15 +85,14 @@
 
 // Compute z = x * y.
 func fpMul(z *FpX2, x, y *Fp) {
-	var u, v, t uint64
-	var carry uint64
-	var uv uint128
+	var carry, t, u, v uint64
+	var hi, lo uint64
 
 	for i := uint64(0); i < FP_WORDS; i++ {
 		for j := uint64(0); j <= i; j++ {
-			uv = mul64(x[j], y[i-j])
-			v, carry = addc64(0, uv.L, v)
-			u, carry = addc64(carry, uv.H, u)
+			hi, lo = bits.Mul64(x[j], y[i-j])
+			v, carry = bits.Add64(lo, v, 0)
+			u, carry = bits.Add64(hi, u, carry)
 			t += carry
 		}
 		z[i] = v
@@ -171,9 +103,9 @@
 
 	for i := FP_WORDS; i < (2*FP_WORDS)-1; i++ {
 		for j := i - FP_WORDS + 1; j < FP_WORDS; j++ {
-			uv = mul64(x[j], y[i-j])
-			v, carry = addc64(0, uv.L, v)
-			u, carry = addc64(carry, uv.H, u)
+			hi, lo = bits.Mul64(x[j], y[i-j])
+			v, carry = bits.Add64(lo, v, 0)
+			u, carry = bits.Add64(hi, u, carry)
 			t += carry
 		}
 		z[i] = v
@@ -188,7 +120,7 @@
 // with R=2^512. Destroys the input value.
 func fpMontRdc(z *Fp, x *FpX2) {
 	var carry, t, u, v uint64
-	var uv uint128
+	var hi, lo uint64
 	var count int
 
 	count = 3 // number of 0 digits in the least significat part of p503 + 1
@@ -196,14 +128,14 @@
 	for i := 0; i < FP_WORDS; i++ {
 		for j := 0; j < i; j++ {
 			if j < (i - count + 1) {
-				uv = mul64(z[j], p503p1[i-j])
-				v, carry = addc64(0, uv.L, v)
-				u, carry = addc64(carry, uv.H, u)
+				hi, lo = bits.Mul64(z[j], p503p1[i-j])
+				v, carry = bits.Add64(lo, v, 0)
+				u, carry = bits.Add64(hi, u, carry)
 				t += carry
 			}
 		}
-		v, carry = addc64(0, v, x[i])
-		u, carry = addc64(carry, u, 0)
+		v, carry = bits.Add64(v, x[i], 0)
+		u, carry = bits.Add64(u, 0, carry)
 		t += carry
 
 		z[i] = v
@@ -218,14 +150,14 @@
 		}
 		for j := i - FP_WORDS + 1; j < FP_WORDS; j++ {
 			if j < (FP_WORDS - count) {
-				uv = mul64(z[j], p503p1[i-j])
-				v, carry = addc64(0, uv.L, v)
-				u, carry = addc64(carry, uv.H, u)
+				hi, lo = bits.Mul64(z[j], p503p1[i-j])
+				v, carry = bits.Add64(lo, v, 0)
+				u, carry = bits.Add64(hi, u, carry)
 				t += carry
 			}
 		}
-		v, carry = addc64(0, v, x[i])
-		u, carry = addc64(carry, u, 0)
+		v, carry = bits.Add64(v, x[i], 0)
+		u, carry = bits.Add64(u, 0, carry)
 
 		t += carry
 		z[i-FP_WORDS] = v
@@ -233,7 +165,7 @@
 		u = t
 		t = 0
 	}
-	v, carry = addc64(0, v, x[2*FP_WORDS-1])
+	v, carry = bits.Add64(v, x[2*FP_WORDS-1], 0)
 	z[FP_WORDS-1] = v
 }
 
@@ -241,7 +173,7 @@
 func fp2Add(z, x, y *FpX2) {
 	var carry uint64
 	for i := 0; i < 2*FP_WORDS; i++ {
-		z[i], carry = addc64(carry, x[i], y[i])
+		z[i], carry = bits.Add64(x[i], y[i], carry)
 	}
 }
 
@@ -249,14 +181,14 @@
 func fp2Sub(z, x, y *FpX2) {
 	var borrow, mask uint64
 	for i := 0; i < 2*FP_WORDS; i++ {
-		z[i], borrow = subc64(borrow, x[i], y[i])
+		z[i], borrow = bits.Sub64(x[i], y[i], borrow)
 	}
 
 	// Sets all bits if borrow = 1
 	mask = 0 - borrow
 	borrow = 0
 	for i := FP_WORDS; i < 2*FP_WORDS; i++ {
-		z[i], borrow = addc64(borrow, z[i], p503[i-FP_WORDS]&mask)
+		z[i], borrow = bits.Add64(z[i], p503[i-FP_WORDS]&mask, borrow)
 	}
 }