/
/
/
/
在代码中使用 LOG 宏打印消息
/
/
__android_log_print(ANDROID_LOG_DEBUG, TAG,
"Your message"
);
/
/
/
/
/
/
打印带有格式化字符串的消息
/
/
__android_log_print(ANDROID_LOG_DEBUG, TAG,
"Formatted message: %s"
, yourStringVariable);
const uint8_t SM4_SBOX_TABLE[
16
][
16
]
=
{
{
0xd6
,
0x90
,
0xe9
,
0xfe
,
0xcc
,
0xe1
,
0x3d
,
0xb7
,
0x16
,
0xb6
,
0x14
,
0xc2
,
0x28
,
0xfb
,
0x2c
,
0x05
},
{
0x2b
,
0x67
,
0x9a
,
0x76
,
0x2a
,
0xbe
,
0x04
,
0xc3
,
0xaa
,
0x44
,
0x13
,
0x26
,
0x49
,
0x86
,
0x06
,
0x99
},
{
0x9c
,
0x42
,
0x50
,
0xf4
,
0x91
,
0xef
,
0x98
,
0x7a
,
0x33
,
0x54
,
0x0b
,
0x43
,
0xed
,
0xcf
,
0xac
,
0x62
},
{
0xe4
,
0xb3
,
0x1c
,
0xa9
,
0xc9
,
0x08
,
0xe8
,
0x95
,
0x80
,
0xdf
,
0x94
,
0xfa
,
0x75
,
0x8f
,
0x3f
,
0xa6
},
{
0x47
,
0x07
,
0xa7
,
0xfc
,
0xf3
,
0x73
,
0x17
,
0xba
,
0x83
,
0x59
,
0x3c
,
0x19
,
0xe6
,
0x85
,
0x4f
,
0xa8
},
{
0x68
,
0x6b
,
0x81
,
0xb2
,
0x71
,
0x64
,
0xda
,
0x8b
,
0xf8
,
0xeb
,
0x0f
,
0x4b
,
0x70
,
0x56
,
0x9d
,
0x35
},
{
0x1e
,
0x24
,
0x0e
,
0x5e
,
0x63
,
0x58
,
0xd1
,
0xa2
,
0x25
,
0x22
,
0x7c
,
0x3b
,
0x01
,
0x21
,
0x78
,
0x87
},
{
0xd4
,
0x00
,
0x46
,
0x57
,
0x9f
,
0xd3
,
0x27
,
0x52
,
0x4c
,
0x36
,
0x02
,
0xe7
,
0xa0
,
0xc4
,
0xc8
,
0x9e
},
{
0xea
,
0xbf
,
0x8a
,
0xd2
,
0x40
,
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
},
{
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
},
{
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
},
{
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
},
{
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
},
{
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
},
{
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
,
0x0f
},
};
const uint32_t SM4_ROUND_CONSTANTS[
32
]
=
{
0x000000C0
,
0x000000D8
,
0x000000F0
,
0x00000108
,
0x00000120
,
0x00000138
,
0x00000150
,
0x00000168
,
0x00000180
,
0x00000198
,
0x000001B0
,
0x000001C8
,
0x000001E0
,
0x000001F8
,
0x00000210
,
0x00000228
,
0x00000240
,
0x00000258
,
0x00000270
,
0x00000288
,
0x000002A0
,
0x000002B8
,
0x000002D0
,
0x000002E8
,
0x00000300
,
0x00000318
,
0x00000330
,
0x00000348
,
0x00000360
,
0x00000378
,
0x00000390
,
0x000003A8
};
/
/
32
-
bit left rotation
/
/
S
-
box substitution
(SM4_SBOX_TABLE[((t) >>
4
) &
0x0F
][(t) &
0x0F
])
/
/
Linear transformation L
((t) ^ SM4_LEFT_ROTATE((t),
2
) ^ SM4_LEFT_ROTATE((t),
10
) ^ \
SM4_LEFT_ROTATE((t),
18
) ^ SM4_LEFT_ROTATE((t),
24
))
/
/
Key expansion
void sm4_key_schedule(const uint8_t
*
key, uint32_t
*
rk) {
uint32_t k[
4
];
memcpy(k, key, sizeof(uint32_t)
*
4
);
for
(
int
i
=
0
; i <
32
;
+
+
i) {
uint32_t temp
=
k[
0
] ^ SM4_SBOX(k[
1
] ^ k[
2
] ^ k[
3
] ^ SM4_ROUND_CONSTANTS[i]);
k[
0
]
=
k[
1
];
k[
1
]
=
k[
2
];
k[
2
]
=
k[
3
];
k[
3
]
=
temp;
rk[i]
=
temp;
}
}
/
/
Encryption
/
/
void sm4_encrypt(const uint32_t
*
rk, const uint8_t
*
input
, uint8_t
*
output) {
/
/
uint32_t x[
36
];
/
/
memcpy(x,
input
, sizeof(uint32_t)
*
4
);
/
/
/
/
for
(
int
i
=
0
; i <
32
;
+
+
i) {
/
/
uint32_t t
=
x[i
+
1
] ^ x[i
+
2
] ^ x[i
+
3
] ^ rk[i];
/
/
uint32_t y
=
SM4_SBOX(t);
/
/
x[i
+
4
]
=
x[i] ^ SM4_LTRANSFORM(y);
/
/
}
/
/
/
/
memcpy(output, x
+
32
, sizeof(uint32_t)
*
4
);
/
/
}
void sm4_encrypt(const uint32_t
*
rk, const uint8_t
*
input
, const uint8_t
*
iv, uint8_t
*
output) {
uint32_t x[
36
];
for
(
int
i
=
0
; i <
4
; i
+
+
) {
x[i]
=
(
input
[i
*
4
] <<
24
) | (
input
[i
*
4
+
1
] <<
16
) | (
input
[i
*
4
+
2
] <<
8
) |
input
[i
*
4
+
3
];
}
/
/
XOR with IV
for
(
int
i
=
0
; i <
4
;
+
+
i) {
uint32_t iv_tmp
=
(iv[i
*
4
] <<
24
) | (iv[i
*
4
+
1
] <<
16
) | (iv[i
*
4
+
2
] <<
8
) | iv[i
*
4
+
3
];
x[i] ^
=
iv_tmp;
}
for
(
int
i
=
0
; i <
32
;
+
+
i) {
uint32_t t
=
x[i
+
1
] ^ x[i
+
2
] ^ x[i
+
3
] ^ rk[i];
uint32_t y
=
SM4_SBOX(t);
x[i
+
4
]
=
x[i] ^ SM4_LTRANSFORM(y);
}
for
(
int
i
=
0
; i <
4
; i
+
+
) {
output[i
*
4
]
=
(x[
35
-
i] >>
24
) &
0xFF
;
output[i
*
4
+
1
]
=
(x[
35
-
i] >>
16
) &
0xFF
;
output[i
*
4
+
2
]
=
(x[
35
-
i] >>
8
) &
0xFF
;
output[i
*
4
+
3
]
=
x[
35
-
i] &
0xFF
;
}
}
void sm4_decrypt(const uint32_t
*
rk, const uint8_t
*
input
, const uint8_t
*
iv, uint8_t
*
output) {
uint32_t x[
36
];
for
(
int
i
=
0
; i <
4
; i
+
+
) {
x[i]
=
(
input
[i
*
4
] <<
24
) | (
input
[i
*
4
+
1
] <<
16
) | (
input
[i
*
4
+
2
] <<
8
) |
input
[i
*
4
+
3
];
}
for
(
int
i
=
0
; i <
32
;
+
+
i) {
uint32_t t
=
x[i
+
1
] ^ x[i
+
2
] ^ x[i
+
3
] ^ rk[
31
-
i];
uint32_t y
=
SM4_SBOX(t);
x[i
+
4
]
=
x[i] ^ SM4_LTRANSFORM(y);
}
/
/
XOR with IV
for
(
int
i
=
0
; i <
4
;
+
+
i) {
uint32_t iv_tmp
=
(iv[i
*
4
] <<
24
) | (iv[i
*
4
+
1
] <<
16
) | (iv[i
*
4
+
2
] <<
8
) | iv[i
*
4
+
3
];
x[
35
-
i] ^
=
iv_tmp;
}
for
(
int
i
=
0
; i <
4
; i
+
+
) {
output[i
*
4
]
=
(x[
35
-
i] >>
24
) &
0xFF
;
output[i
*
4
+
1
]
=
(x[
35
-
i] >>
16
) &
0xFF
;
output[i
*
4
+
2
]
=
(x[
35
-
i] >>
8
) &
0xFF
;
output[i
*
4
+
3
]
=
x[
35
-
i] &
0xFF
;
}
}
/
/
Padding
void sm4_pad(uint8_t
*
data, size_t size) {
size_t remainder
=
size
%
16
;
size_t paddingSize
=
(remainder
=
=
0
) ?
16
: (
16
-
remainder);
for
(size_t i
=
0
; i < paddingSize;
+
+
i) {
data[size
+
i]
=
static_cast<uint8_t>(paddingSize);
}
}
/
/
Remove padding
void sm4_unpad(uint8_t
*
data, size_t size) {
size_t paddingSize
=
static_cast<size_t>(data[size
-
1
]);
if
(paddingSize <
=
size) {
for
(size_t i
=
0
; i < paddingSize;
+
+
i) {
if
(data[size
-
i
-
1
] !
=
paddingSize) {
return
;
}
}
memset(data
+
size
-
paddingSize,
0
, paddingSize);
}
}
int
main() {
/
/
Test encryption
and
decryption
std::string key
=
"0123456789ABCDEFFEDCBA9876543210"
;
uint8_t value
=
0123456701234567
;
const uint8_t
*
iv
=
&value;
std::string plaintext
=
"asd"
;
std::vector<uint8_t> encrypted(plaintext.size());
std::vector<uint8_t> decrypted(plaintext.size());
/
/
Key expansion
uint32_t rk[
32
];
sm4_key_schedule(reinterpret_cast<const uint8_t
*
>(key.data()), rk);
/
/
Encryption
sm4_encrypt(rk, reinterpret_cast<const uint8_t
*
>(plaintext.data()),iv, encrypted.data());
__android_log_print(ANDROID_LOG_DEBUG, TAG,
"明 文:%s"
,plaintext.data());
__android_log_print(ANDROID_LOG_DEBUG, TAG,
"密 文:%s"
,encrypted.data());
/
/
Decryption
sm4_decrypt(rk, encrypted.data(), iv,decrypted.data());
__android_log_print(ANDROID_LOG_DEBUG, TAG,
"解密明 文:%s"
,decrypted.data());
return
0
;
}
extern
"C"
JNIEXPORT jstring JNICALL
Java_com_yyf_sm_MainActivity_stringFromJNI(
JNIEnv
*
env,
jobject
/
*
this
*
/
) {
std::string hello
=
"Hello from C++"
;
int
a
=
main();
std::cout <<
"Decrypted: "
<< a << std::endl;
return
env
-
>NewStringUTF(hello.c_str());
}