go-sike/arith_utils.go
2019-05-04 23:29:36 +01:00

71 lines
1.0 KiB
Go

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
}