init: v1.0.0
This commit is contained in:
@@ -0,0 +1,124 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user