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
|
||
|
}
|