86 lines
1.8 KiB
Go
86 lines
1.8 KiB
Go
package algos
|
|
|
|
// getBit 获取指定位的值
|
|
func getBit(val uint64, pos int) uint64 {
|
|
if val&(1<<pos) != 0 {
|
|
return 1
|
|
}
|
|
return 0
|
|
}
|
|
|
|
// rotateLeft64 64位左循环移位
|
|
func rotateLeft64(v uint64, n int) uint64 {
|
|
r := (v << n) | (v >> (64 - n))
|
|
return r & 0xFFFFFFFFFFFFFFFF
|
|
}
|
|
|
|
// rotateRight64 64位右循环移位
|
|
func rotateRight64(v uint64, n int) uint64 {
|
|
r := (v << (64 - n)) | (v >> n)
|
|
return r & 0xFFFFFFFFFFFFFFFF
|
|
}
|
|
|
|
// keyExpansion 密钥扩展
|
|
func keyExpansion(key []uint64) []uint64 {
|
|
expandedKey := make([]uint64, 72)
|
|
copy(expandedKey, key[:4])
|
|
|
|
var tmp uint64
|
|
for i := 4; i < 72; i++ {
|
|
tmp = rotateRight64(expandedKey[i-1], 3)
|
|
tmp = tmp ^ expandedKey[i-3]
|
|
tmp = tmp ^ rotateRight64(tmp, 1)
|
|
expandedKey[i] = (^expandedKey[i-4]) ^ tmp ^ getBit(0x3DC94C3A046D678B, (i-4)%62) ^ 3
|
|
}
|
|
return expandedKey
|
|
}
|
|
|
|
// SimonEnc Simon加密
|
|
func SimonEnc(pt []uint64, k []uint64, c int) []uint64 {
|
|
key := make([]uint64, 72)
|
|
copy(key[:4], k[:4])
|
|
key = keyExpansion(key)
|
|
|
|
xi := pt[0]
|
|
xi1 := pt[1]
|
|
|
|
var tmp, f uint64
|
|
for i := 0; i < 72; i++ {
|
|
tmp = xi1
|
|
if c == 1 {
|
|
f = rotateLeft64(xi1, 1)
|
|
} else {
|
|
f = rotateLeft64(xi1, 1) & rotateLeft64(xi1, 8)
|
|
}
|
|
xi1 = xi ^ f ^ rotateLeft64(xi1, 2) ^ key[i]
|
|
xi = tmp
|
|
}
|
|
|
|
return []uint64{xi, xi1}
|
|
}
|
|
|
|
// SimonDec Simon解密
|
|
func SimonDec(ct []uint64, k []uint64, c int) []uint64 {
|
|
key := make([]uint64, 72)
|
|
copy(key[:4], k[:4])
|
|
key = keyExpansion(key)
|
|
|
|
xi := ct[0]
|
|
xi1 := ct[1]
|
|
|
|
var tmp, f uint64
|
|
for i := 71; i >= 0; i-- {
|
|
tmp = xi
|
|
if c == 1 {
|
|
f = rotateLeft64(xi, 1)
|
|
} else {
|
|
f = rotateLeft64(xi, 1) & rotateLeft64(xi, 8)
|
|
}
|
|
xi = xi1 ^ f ^ rotateLeft64(xi, 2) ^ key[i]
|
|
xi1 = tmp
|
|
}
|
|
|
|
return []uint64{xi, xi1}
|
|
}
|
|
|