71 lines
1.0 KiB
Go
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
|
|
}
|