import 'dart:convert'; import 'dart:ffi'; import 'dart:io'; import 'dart:math'; import 'package:ffi/ffi.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/foundation.dart'; import 'package:path_provider/path_provider.dart'; import 'package:prime_chat/screens/ChatScreen.dart'; import 'package:tuple/tuple.dart'; import 'Encrypt.dart'; void testPrint(bool x, String name) { print("test $name: $x"); } Uint8List randomVector(int length) { final random = Random.secure(); final values = List.generate(length, (i) => random.nextInt(255)); return Uint8List.fromList(values); } void testSM2(Pointer key) { const plaintext = "Hello, GmSSL!"; var plain = Uint8List.fromList(plaintext.codeUnits); plain = randomVector(255); try { final encrypted = sm2Encrypt(key, plain); final decrypted = sm2Decrypt(key, encrypted); testPrint(listEquals(decrypted, plain), "sm2 encrypt & decrypt"); } on Error catch(e) { debugPrint(e.toString()); return; } } Future testSM2PrivateKeyPem(Pointer key) async { final pass = "123456".toNativeUtf8(); final private = key.privateKey.list; final tempDirPath = (await getTemporaryDirectory()).path; final path = "$tempDirPath/private.pem"; sm2PrivateKeyInfoEncryptToPEM(key, pass, path); sm2PrivateKeyInfoDecryptFromPEM(key, pass, path); testPrint(listEquals(private, key.privateKey.list), "private key <-> PEM"); } void testSM2PublicKeyDER(Pointer key) { final public = Tuple2(key.publicKey.x.list, key.publicKey.y.list); try { final der = sm2PublicKeyInfoToDER(key); debugPrint("der.length = ${der.length}"); debugPrint("der = $der"); final encoded = base64Encode(der); debugPrint("pem = $encoded"); final res = sm2PublicKeyInfoFromDER(key, der); // assert(res>=0, "sm2PublicKeyInfoFromDER error"); if (res != 1) { debugPrint("sm2PublicKeyInfoFromDER error! res == $res"); } } on Error catch(e) { debugPrint(e.toString()); return; } testPrint(listEquals(public.item1, key.publicKey.x.list) && listEquals(public.item2, key.publicKey.y.list), "public key <-> DER"); } void testSM4() { final plain = randomVector(1<<16); // debugPrint("plain="); // debugPrint(base64Encode(plain)); final sm4key = randomVector(16); final iv = randomVector(16); final sm4enc = sm4cbcEncrypt(plain, sm4key, iv); // debugPrint("sm4enc="); // debugPrint(base64Encode(sm4enc)); final sm4dec = sm4cbcDecrypt(sm4enc, sm4key, iv); // debugPrint("sm4dec="); // debugPrint(base64Encode(sm4dec)); testPrint(listEquals(plain, sm4dec), "sm4 encrypt & decrypt"); } void testPemToDerToKey(Pointer key, String tempPath) { final public = Tuple2(key.publicKey.x.list, key.publicKey.y.list); final private = key.privateKey.list; assert(sm2PublicKeyInfoToPEM(key, tempPath) == 1); File pemFile = File(tempPath); final lines = pemFile.readAsLinesSync(); lines.remove("-----BEGIN PUBLIC KEY-----"); lines.remove("-----END PUBLIC KEY-----"); final content = lines.join(); debugPrint("pem=$content"); final der = base64Decode(content); debugPrint("der.length=${der.length} der=$der"); assert(sm2PublicKeyInfoFromDER(key, der)==1); testPrint(listEquals(public.item1, key.publicKey.x.list) && listEquals(public.item2, key.publicKey.y.list), "der -> publicKey"); final equals = listEquals(private, key.privateKey.list); debugPrint("privateKey equals : $equals"); } void encryptTest() async { final tempDirPath = (await getTemporaryDirectory()).path; final errorPath = "$tempDirPath/error.txt"; final tempPath = "$tempDirPath/temp.pem"; final pf = freopen(errorPath, "w", stderrAddress); debugPrint("==========encrypt test start==========="); try { // int s = add(1, 5); // debugPrint("test libadd sum = $s"); final key = gm.newSM2Key(); key.generate(); testPemToDerToKey(key, tempPath); final key1 = gm.newSM2Key(); testSM2(key); // testSM2(key); // testSM2(key); // testSM2(key); await testSM2PrivateKeyPem(key); testSM2(key); testSM2PublicKeyDER(key); // testSM2PublicKeyDER(key); // testSM2PublicKeyDER(key); // testSM2PublicKeyDER(key); // testSM2(key); // testSM2(key); // testSM2(key); // testSM2(key); // TODO: ERROR sm2PublicKeyInfoToDER // final private = sm2PrivateKeyInfoDecryptFromPEMString(key, pass); // final publicPem = await sm2PublicKeyInfoToPEMString(key); // debugPrint(privatePem); // debugPrint(publicPem); testSM4(); } on Error catch (e) { debugPrint(e.toString()); } debugPrint("==========encrypt test end==========="); gm.fclose(pf); File errorFile = File(errorPath); final errorInfo = errorFile.readAsStringSync(); debugPrint("error info = "); debugPrint(errorInfo); }