init: v1.0.0
This commit is contained in:
+202
@@ -0,0 +1,202 @@
|
||||
package sm1
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
)
|
||||
|
||||
// type roundKey = [4 * (numOfRound + 1)]uint32
|
||||
type roundKey []uint32
|
||||
|
||||
// // func newRoundKey() AC_SM1_KEY {
|
||||
// // return make([]uint32, 4*(numOfRound+1))
|
||||
// // }
|
||||
// func (k AC_SM1_KEY) clear() {
|
||||
// for i := range k {
|
||||
// k[i] = 0
|
||||
// }
|
||||
// }
|
||||
|
||||
func sbox2(sbox1, sbox2 []byte, x byte) byte {
|
||||
return ((sbox1[(x>>4)&0x0f] << 4) | sbox2[x&0x0f])
|
||||
}
|
||||
|
||||
func g(out, inX, inY []uint32) {
|
||||
var sbox = [][]byte{
|
||||
{0x5, 0xd, 0x9, 0x1, 0x0, 0x2, 0xa, 0xf, 0x6, 0x7, 0xc, 0x8, 0xe, 0x3, 0xb, 0x4},
|
||||
{0x2, 0x4, 0xf, 0x6, 0x8, 0xb, 0xe, 0x5, 0xa, 0xd, 0x3, 0xc, 0x9, 0x7, 0x1, 0x0},
|
||||
{0x4, 0x3, 0x5, 0xd, 0xf, 0x0, 0x8, 0x9, 0xb, 0x2, 0x6, 0xe, 0xa, 0x1, 0xc, 0x7},
|
||||
{0xf, 0xe, 0x0, 0xa, 0x1, 0x7, 0x3, 0xd, 0x4, 0xc, 0x8, 0x5, 0xb, 0x9, 0x6, 0x2},
|
||||
{0x4, 0xc, 0x8, 0x0, 0x1, 0x3, 0xb, 0xe, 0x7, 0x6, 0xd, 0x9, 0xf, 0x2, 0xa, 0x5},
|
||||
{0x1, 0x7, 0xc, 0x5, 0xb, 0x8, 0xd, 0x6, 0x9, 0xe, 0x0, 0xf, 0xa, 0x4, 0x2, 0x3},
|
||||
{0xd, 0xa, 0xc, 0x4, 0x6, 0x9, 0x1, 0x0, 0x2, 0xb, 0xf, 0x7, 0x3, 0x8, 0x5, 0xe},
|
||||
{0x9, 0x8, 0x6, 0xc, 0x7, 0x1, 0x5, 0xb, 0x2, 0xa, 0xe, 0x3, 0xd, 0xf, 0x0, 0x4}}
|
||||
xx := make([]uint32, 4)
|
||||
xxx := make([]uint32, 4)
|
||||
xx[0] = inX[0] ^ inX[2] ^ inX[3]
|
||||
xx[1] = inX[0] ^ inX[1] ^ inX[3]
|
||||
xx[2] = inX[0] ^ inX[2] ^ inX[1]
|
||||
xx[3] = inX[0] ^ inX[1] ^ inX[2] ^ inX[3]
|
||||
|
||||
xxx[0] = xx[0] ^ inY[0]
|
||||
xxx[1] = xx[1] ^ inY[1]
|
||||
xxx[2] = xx[2] ^ inY[2]
|
||||
s := make([]byte, 4)
|
||||
// int2bytes(s, xx[3])
|
||||
binary.BigEndian.PutUint32(s, xx[3])
|
||||
// printf("s[0-3]=%02x%02x%02x%02x\n", s[0], s[1], s[2], s[3]);
|
||||
s[0] = sbox2(sbox[0], sbox[1], s[0])
|
||||
s[1] = sbox2(sbox[2], sbox[3], s[1])
|
||||
// printf("s[0-3]=%02x%02x%02x%02x\n", s[0], s[1], s[2], s[3]);
|
||||
s[2] = sbox2(sbox[4], sbox[5], s[2])
|
||||
// printf("s[0-3]=%02x%02x%02x%02x\n", s[0], s[1], s[2], s[3]);
|
||||
s[3] = sbox2(sbox[6], sbox[7], s[3])
|
||||
// printf("s[0-3]=%02x%02x%02x%02x\n", s[0], s[1], s[2], s[3]);
|
||||
xxx[3] = binary.BigEndian.Uint32(s) // bytes2int(s);
|
||||
|
||||
out[0] = rol(xxx[3], 1) ^ inY[3]
|
||||
out[1] = rol(xxx[0], 8) ^ rol(xxx[3], 17)
|
||||
out[2] = rol(xxx[1], 7) ^ rol(xxx[3], 25)
|
||||
out[3] = rol(xxx[2], 1) ^ rol(xxx[3], 9)
|
||||
}
|
||||
|
||||
func gg(out, inX, inY []uint32) {
|
||||
var sbox = [][]byte{
|
||||
{0x4, 0x3, 0x5, 0xd, 0xf, 0x0, 0x8, 0x9, 0xb, 0x2, 0x6, 0xe, 0xa, 0x1, 0xc, 0x7},
|
||||
{0xf, 0xe, 0x0, 0xa, 0x1, 0x7, 0x3, 0xd, 0x4, 0xc, 0x8, 0x5, 0xb, 0x9, 0x6, 0x2},
|
||||
{0x5, 0xd, 0x9, 0x1, 0x0, 0x2, 0xa, 0xf, 0x6, 0x7, 0xc, 0x8, 0xe, 0x3, 0xb, 0x4},
|
||||
{0x2, 0x4, 0xf, 0x6, 0x8, 0xb, 0xe, 0x5, 0xa, 0xd, 0x3, 0xc, 0x9, 0x7, 0x1, 0x0},
|
||||
{0x3, 0x4, 0xd, 0x5, 0x0, 0xf, 0x9, 0x8, 0x2, 0xb, 0xe, 0x6, 0x1, 0xa, 0x7, 0xc},
|
||||
{0xa, 0x0, 0xe, 0xf, 0xd, 0x3, 0x7, 0x1, 0x5, 0x8, 0xc, 0x4, 0x2, 0x6, 0x9, 0xb},
|
||||
{0x7, 0x6, 0x8, 0xc, 0x3, 0xe, 0x4, 0xb, 0xd, 0x5, 0x1, 0x9, 0x2, 0x0, 0xf, 0xa},
|
||||
{0xe, 0x5, 0x8, 0xb, 0xf, 0x6, 0x2, 0x4, 0x1, 0x0, 0x9, 0x7, 0x3, 0xc, 0xa, 0xd},
|
||||
}
|
||||
xx := make([]uint32, 4)
|
||||
xxx := make([]uint32, 4)
|
||||
xx[3] = ror(inX[0]^inY[3], 1)
|
||||
xx[2] = ror(rol(xx[3], 9)^inX[3], 1)
|
||||
xx[1] = ror(rol(xx[3], 25)^inX[2], 7)
|
||||
xx[0] = ror(rol(xx[3], 17)^inX[1], 8)
|
||||
|
||||
xxx[0] = xx[0] ^ inY[0]
|
||||
xxx[1] = xx[1] ^ inY[1]
|
||||
xxx[2] = xx[2] ^ inY[2]
|
||||
s := make([]byte, 4)
|
||||
binary.BigEndian.PutUint32(s, xx[3])
|
||||
s[0] = sbox2(sbox[0], sbox[1], s[0])
|
||||
s[1] = sbox2(sbox[2], sbox[3], s[1])
|
||||
s[2] = sbox2(sbox[4], sbox[5], s[2])
|
||||
s[3] = sbox2(sbox[6], sbox[7], s[3])
|
||||
xxx[3] = binary.BigEndian.Uint32(s)
|
||||
|
||||
out[0] = xxx[0] ^ xxx[1] ^ xxx[2]
|
||||
out[1] = xxx[0] ^ xxx[3]
|
||||
out[2] = xxx[3] ^ xxx[1]
|
||||
out[3] = xxx[2] ^ xxx[3]
|
||||
}
|
||||
|
||||
func xor(c, a, b []uint32) {
|
||||
for i := range a {
|
||||
c[i] = a[i] ^ b[i]
|
||||
}
|
||||
}
|
||||
|
||||
func keyexpand(A, B [][]uint32, ek []byte) {
|
||||
// static const unsigned char sk[AC_SM1_KEY_LENGTH_IN_BYTE] = {0x19, 0x1a, 0x4e, 0xf3, 0x67, 0xec, 0xe2, 0x81, 0xc9, 0x03, 0xc4, 0x6c, 0x23, 0x33, 0x3c, 0x2a};
|
||||
// static const unsigned char ak[AC_SM1_KEY_LENGTH_IN_BYTE] = {0};
|
||||
EK := make([]uint32, 4)
|
||||
|
||||
// 辅助密钥AK为全0
|
||||
// uint32_t AK[4] = {0};
|
||||
|
||||
// 系统密钥
|
||||
SK := []uint32{0x191a4ef3, 0x67ece281, 0xc903c46c, 0x23333c2a}
|
||||
|
||||
bytes2ints(EK, ek)
|
||||
a := make([]uint32, 4)
|
||||
b := make([]uint32, 4)
|
||||
xor(SK, EK, SK)
|
||||
a[0] = SK[1] ^ SK[2] ^ SK[3]
|
||||
a[1] = SK[1] ^ SK[2] ^ SK[0]
|
||||
a[2] = SK[1] ^ SK[0] ^ SK[3]
|
||||
a[3] = SK[0] ^ SK[2] ^ SK[3]
|
||||
// a[0] = a[0];
|
||||
a[1] = rol(a[1], 8)
|
||||
a[2] = rol(a[2], 16)
|
||||
a[3] = rol(a[3], 23)
|
||||
|
||||
// xor(i, EK, AK, 4);
|
||||
b[0] = EK[1] ^ EK[2] ^ EK[3]
|
||||
b[1] = EK[1] ^ EK[2] ^ EK[0]
|
||||
b[2] = EK[1] ^ EK[0] ^ EK[3]
|
||||
b[3] = EK[0] ^ EK[2] ^ EK[3]
|
||||
b[0] = rol(b[0], 8)
|
||||
b[1] = rol(b[1], 16)
|
||||
b[2] = rol(b[2], 24)
|
||||
// b[3] = b[3];
|
||||
|
||||
g(A[0], a, b)
|
||||
gg(B[0], b, a)
|
||||
for i := 1; i < numOfRound/2+1; i++ {
|
||||
g(A[i], A[i-1], b)
|
||||
gg(B[i], B[i-1], a)
|
||||
}
|
||||
for i := numOfRound/2 + 1; i < numOfRound+1; i++ {
|
||||
gg(A[i], A[i-1], b)
|
||||
g(B[i], B[i-1], a)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func keyexpand_enc(rkey []uint32, ek []byte) {
|
||||
A := make([][]uint32, numOfRound+1)
|
||||
for i := range A {
|
||||
A[i] = make([]uint32, 4)
|
||||
}
|
||||
B := make([][]uint32, numOfRound+1)
|
||||
for i := range B {
|
||||
B[i] = make([]uint32, 4)
|
||||
}
|
||||
|
||||
keyexpand(A, B, ek)
|
||||
j := 0
|
||||
for ; j < numOfRound/2+1; j++ {
|
||||
rkey[4*j+0] = A[j][0]
|
||||
rkey[4*j+1] = A[j][1]
|
||||
rkey[4*j+2] = A[j][2]
|
||||
rkey[4*j+3] = A[j][3]
|
||||
}
|
||||
for ; j < numOfRound+1; j++ {
|
||||
rkey[4*j+0] = B[j][0]
|
||||
rkey[4*j+1] = B[j][1]
|
||||
rkey[4*j+2] = B[j][2]
|
||||
rkey[4*j+3] = B[j][3]
|
||||
}
|
||||
}
|
||||
func keyexpand_dec(rkey []uint32, ek []byte) {
|
||||
A := make([][]uint32, numOfRound+1)
|
||||
for i := range A {
|
||||
A[i] = make([]uint32, 4)
|
||||
}
|
||||
B := make([][]uint32, numOfRound+1)
|
||||
for i := range B {
|
||||
B[i] = make([]uint32, 4)
|
||||
}
|
||||
|
||||
keyexpand(A, B, ek)
|
||||
j := 0
|
||||
for ; j < numOfRound/2; j++ {
|
||||
rkey[4*j+0] = B[j][0]
|
||||
rkey[4*j+1] = B[j][1]
|
||||
rkey[4*j+2] = B[j][2]
|
||||
rkey[4*j+3] = B[j][3]
|
||||
}
|
||||
for ; j < numOfRound+1; j++ {
|
||||
rkey[4*j+0] = A[j][0]
|
||||
rkey[4*j+1] = A[j][1]
|
||||
rkey[4*j+2] = A[j][2]
|
||||
rkey[4*j+3] = A[j][3]
|
||||
}
|
||||
for j = 0; j < numOfRound+1; j++ {
|
||||
rr(rkey[4*j:], rkey[4*j:])
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user