125 lines
1.9 KiB
Go
125 lines
1.9 KiB
Go
package experiment
|
|
|
|
// ffe stands for finite field elements
|
|
type ffe struct {
|
|
v [8]byte
|
|
}
|
|
|
|
func NewFFE(in byte) *ffe {
|
|
r := new(ffe)
|
|
for i := 0; i < 8; i++ {
|
|
r.v[i] = (in >> i) & 1
|
|
}
|
|
return r
|
|
}
|
|
|
|
type gf256 struct {
|
|
f [9]byte
|
|
invertTable [256]byte
|
|
}
|
|
|
|
var sm4Field = &gf256{
|
|
f: [9]byte{1, 0, 1, 0, 1, 1, 1, 1, 1},
|
|
}
|
|
|
|
var aesField = &gf256{
|
|
f: [9]byte{1, 1, 0, 1, 1, 0, 0, 0, 1},
|
|
}
|
|
|
|
func (g *gf256) _add(u, v []byte) []byte {
|
|
l := len(u)
|
|
if l < len(v) {
|
|
l = len(v)
|
|
}
|
|
r := make([]byte, l)
|
|
copy(r, u)
|
|
for i := 0; i < len(v); i++ {
|
|
r[i] = r[i] ^ v[i]
|
|
}
|
|
return r
|
|
}
|
|
|
|
func (g *gf256) Add(u, v *ffe) *ffe {
|
|
r := new(ffe)
|
|
for i := 0; i < 8; i++ {
|
|
r.v[i] = u.v[i] ^ v.v[i]
|
|
}
|
|
return r
|
|
}
|
|
|
|
// return v*x^n
|
|
func (g *gf256) _mulxn(v []byte, n int) []byte {
|
|
buf := make([]byte, n, len(v)+n)
|
|
buf = append(buf, v[:]...)
|
|
return buf
|
|
}
|
|
|
|
func (g *gf256) reduce(v []byte) *ffe {
|
|
buf := append([]byte{}, v...)
|
|
for i := len(buf) - 1; i >= 8; i-- {
|
|
if buf[i] == 1 {
|
|
buf = g._add(buf, g._mulxn(g.f[:], i-8))
|
|
}
|
|
}
|
|
|
|
r := new(ffe)
|
|
copy(r.v[:], buf)
|
|
return r
|
|
}
|
|
|
|
// vmul return v1*v2 mod m
|
|
func (g *gf256) Mul(u, v *ffe) *ffe {
|
|
r := make([]byte, 16)
|
|
// copy(r, u.v[:])
|
|
for i := 0; i < 8; i++ {
|
|
if v.v[i] == 1 {
|
|
r = g._add(r, g._mulxn(u.v[:], i))
|
|
}
|
|
}
|
|
|
|
return g.reduce(r)
|
|
}
|
|
|
|
func (g *gf256) IsOne(v *ffe) bool {
|
|
if v.v[0] == 0 {
|
|
return false
|
|
}
|
|
for i := 1; i < len(v.v); i++ {
|
|
if v.v[i] != 0 {
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
func (g *gf256) makeInverseTable() {
|
|
g.invertTable[0] = 0
|
|
for i := 1; i < 256; i++ {
|
|
u := NewFFE(byte(i))
|
|
for j := 1; j < 256; j++ {
|
|
if g.IsOne(g.Mul(u, NewFFE(byte(j)))) {
|
|
g.invertTable[i] = byte(j)
|
|
break
|
|
}
|
|
}
|
|
}
|
|
}
|
|
func init() {
|
|
aesField.makeInverseTable()
|
|
sm4Field.makeInverseTable()
|
|
|
|
}
|
|
|
|
func (g *gf256) Invert(v *ffe) *ffe {
|
|
return NewFFE(g.invertTable[v.Byte()])
|
|
}
|
|
|
|
func (e *ffe) Byte() byte {
|
|
r := byte(0)
|
|
for i := 0; i < len(e.v); i++ {
|
|
r = r << 1
|
|
r = r | e.v[len(e.v)-1-i]
|
|
}
|
|
return r
|
|
}
|