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:]) } }