mirror of
https://github.com/FlourishingWorld/hk4e.git
synced 2026-03-01 00:35:36 +08:00
协议加密密钥生成算法
This commit is contained in:
179
pkg/random/hk4e_ec2b.go
Normal file
179
pkg/random/hk4e_ec2b.go
Normal file
@@ -0,0 +1,179 @@
|
||||
package random
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type Ec2b struct {
|
||||
key []byte
|
||||
data []byte
|
||||
seed uint64
|
||||
temp []byte
|
||||
}
|
||||
|
||||
func LoadKey(b []byte) (*Ec2b, error) {
|
||||
if len(b) < 4+4+16+4+2048 {
|
||||
return nil, fmt.Errorf("invalid ec2b key")
|
||||
}
|
||||
if string(b[0:4]) != "Ec2b" {
|
||||
return nil, fmt.Errorf("invalid ec2b key")
|
||||
}
|
||||
keyLen := binary.LittleEndian.Uint32(b[4:])
|
||||
if keyLen != 16 {
|
||||
return nil, fmt.Errorf("invalid ec2b key")
|
||||
}
|
||||
dataLen := binary.LittleEndian.Uint32(b[24:])
|
||||
if dataLen != 2048 {
|
||||
return nil, fmt.Errorf("invalid ec2b key")
|
||||
}
|
||||
e := &Ec2b{
|
||||
key: b[8:24],
|
||||
data: b[28 : 28+2048],
|
||||
}
|
||||
e.init()
|
||||
return e, nil
|
||||
}
|
||||
|
||||
func NewEc2b() *Ec2b {
|
||||
e := &Ec2b{
|
||||
key: make([]byte, 16),
|
||||
data: make([]byte, 2048),
|
||||
}
|
||||
rand.Read(e.key)
|
||||
rand.Read(e.data)
|
||||
e.init()
|
||||
return e
|
||||
}
|
||||
|
||||
func (e *Ec2b) init() {
|
||||
k := make([]byte, 16)
|
||||
copy(k[:], e.key)
|
||||
keyScramble(k)
|
||||
e.SetSeed(getSeed(k, e.data))
|
||||
}
|
||||
|
||||
func (e *Ec2b) Bytes() []byte {
|
||||
b := make([]byte, 4+4+16+4+2048)
|
||||
copy(b[0:4], []byte("Ec2b"))
|
||||
binary.LittleEndian.PutUint32(b[4:], 16)
|
||||
copy(b[8:], e.key)
|
||||
binary.LittleEndian.PutUint32(b[24:], 2048)
|
||||
copy(b[28:], e.data)
|
||||
return b
|
||||
}
|
||||
|
||||
func (e *Ec2b) SetSeed(seed uint64) {
|
||||
e.seed = seed
|
||||
r := NewRand64()
|
||||
r.Seed(int64(e.seed))
|
||||
e.temp = make([]byte, 4096)
|
||||
for i := 0; i < 4096>>3; i++ {
|
||||
binary.LittleEndian.PutUint64(e.temp[i<<3:], r.Uint64())
|
||||
}
|
||||
}
|
||||
|
||||
func (e *Ec2b) Seed() uint64 {
|
||||
return e.seed
|
||||
}
|
||||
|
||||
func (e *Ec2b) Key() []byte {
|
||||
b := make([]byte, 4+4+16+4+2048)
|
||||
copy(b[0:4], []byte("Ec2b"))
|
||||
binary.LittleEndian.PutUint32(b[4:], 16)
|
||||
copy(b[8:], e.key)
|
||||
binary.LittleEndian.PutUint32(b[24:], 2048)
|
||||
copy(b[28:], e.data)
|
||||
return b
|
||||
}
|
||||
|
||||
func (e *Ec2b) Xor(data []byte) {
|
||||
for i := 0; i < len(data); i++ {
|
||||
data[i] ^= e.temp[i%4096]
|
||||
}
|
||||
}
|
||||
|
||||
func keyScramble(key []byte) {
|
||||
var roundKeys [11][16]byte
|
||||
for r := 0; r < 11; r++ {
|
||||
for i := 0; i < 16; i++ {
|
||||
for j := 0; j < 16; j++ {
|
||||
idx := (r << 8) + (i << 4) + j
|
||||
roundKeys[r][i] ^= aesXorTable[1][idx] ^ aesXorTable[0][idx]
|
||||
}
|
||||
}
|
||||
}
|
||||
xorRoundKey(key, roundKeys[0][:])
|
||||
for r := 1; r < 10; r++ {
|
||||
subBytesInv(key)
|
||||
shiftRowsInv(key)
|
||||
mixColsInv(key)
|
||||
xorRoundKey(key, roundKeys[r][:])
|
||||
}
|
||||
subBytesInv(key)
|
||||
shiftRowsInv(key)
|
||||
xorRoundKey(key, roundKeys[10][:])
|
||||
for i := 0; i < 16; i++ {
|
||||
key[i] ^= keyXorTable[i]
|
||||
}
|
||||
}
|
||||
|
||||
func xorRoundKey(key, roundKey []byte) {
|
||||
for i := 0; i < 16; i++ {
|
||||
key[i] ^= roundKey[i]
|
||||
}
|
||||
}
|
||||
|
||||
func subBytes(key []byte) {
|
||||
for i := 0; i < 16; i++ {
|
||||
key[i] = lookupSbox[key[i]]
|
||||
}
|
||||
}
|
||||
|
||||
func subBytesInv(key []byte) {
|
||||
for i := 0; i < 16; i++ {
|
||||
key[i] = lookupSboxInv[key[i]]
|
||||
}
|
||||
}
|
||||
|
||||
func shiftRows(key []byte) {
|
||||
var temp [16]byte
|
||||
copy(temp[:], key[:])
|
||||
for i := 0; i < 16; i++ {
|
||||
key[i] = temp[shiftRowsTable[i]]
|
||||
}
|
||||
}
|
||||
|
||||
func shiftRowsInv(key []byte) {
|
||||
var temp [16]byte
|
||||
copy(temp[:], key[:])
|
||||
for i := 0; i < 16; i++ {
|
||||
key[i] = temp[shiftRowsTableInv[i]]
|
||||
}
|
||||
}
|
||||
|
||||
func mixColInv(key []byte) {
|
||||
a0, a1, a2, a3 := key[0], key[1], key[2], key[3]
|
||||
key[0] = lookupG14[a0] ^ lookupG9[a3] ^ lookupG13[a2] ^ lookupG11[a1]
|
||||
key[1] = lookupG14[a1] ^ lookupG9[a0] ^ lookupG13[a3] ^ lookupG11[a2]
|
||||
key[2] = lookupG14[a2] ^ lookupG9[a1] ^ lookupG13[a0] ^ lookupG11[a3]
|
||||
key[3] = lookupG14[a3] ^ lookupG9[a2] ^ lookupG13[a1] ^ lookupG11[a0]
|
||||
}
|
||||
|
||||
func mixColsInv(key []byte) {
|
||||
mixColInv(key[0:])
|
||||
mixColInv(key[4:])
|
||||
mixColInv(key[8:])
|
||||
mixColInv(key[12:])
|
||||
}
|
||||
|
||||
func getSeed(key, data []byte) uint64 {
|
||||
v := ^uint64(0xCEAC3B5A867837AC)
|
||||
v ^= binary.LittleEndian.Uint64(key[0:])
|
||||
v ^= binary.LittleEndian.Uint64(key[8:])
|
||||
for i := 0; i < len(data)>>3; i++ {
|
||||
v ^= binary.LittleEndian.Uint64(data[i<<3:])
|
||||
}
|
||||
return v
|
||||
}
|
||||
Reference in New Issue
Block a user