Flutter电子签名插件bls_signatures_ffi的使用
Flutter电子签名插件bls_signatures_ffi的使用
使用方法
要使用此插件,你需要在pubspec.yaml
文件中添加bls_signatures_ffi
作为依赖项。
dependencies:
bls_signatures_ffi: ^版本号
需求
Android
构建bls-signatures
需要cmake版本3.14.0+
。但大多数最近版本的Android Studio默认安装的是cmake版本3.10.2
,因此你需要通过Android Studio的SDK管理器更新cmake版本。
iOS
iOS构建C/C++代码使用XCode而不是cmake。但你仍然需要下载cmake来构建bls-signatures
,确保其版本高于3.14.0
。
创建密钥和签名
以下是一个创建密钥和签名的示例:
import 'dart:typed_data';
import 'package:bls_signatures_ffi/bls_signatures_ffi.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
Uint8List? _seed;
PrivateKey? _sk;
G1Element? _pk;
int? _fingerprint;
Exception? _exception;
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('BLS example app'),
),
body: Container(
width: double.infinity,
padding: const EdgeInsets.symmetric(horizontal: 15),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () async {
await genKey();
},
child: const Text('Generate Key'),
),
const SizedBox(height: 5),
if (_exception != null) Text(_exception.toString()),
const SizedBox(height: 5),
const SizedBox(height: 10),
const Text('Seed'),
const SizedBox(height: 5),
Text(_seed == null ? 'Press Generate Key' : _seed.toString()),
const SizedBox(height: 10),
const Text('Secret Key'),
const SizedBox(height: 5),
Text(_sk == null ? 'Press Generate Key' : _sk!.hexString()),
const SizedBox(height: 10),
const Text('Public Key'),
const SizedBox(height: 5),
Text(_pk == null ? 'Press Generate Key' : _pk!.hexString()),
const SizedBox(height: 10),
const Text('Fingerprint'),
const SizedBox(height: 5),
Text(
_fingerprint == null
? 'Press Generate Key'
: _fingerprint.toString(),
),
],
),
),
),
);
}
Future<void> genKey() async {
setState(() {
_exception = null;
});
final seed = genSeed();
final scheme = AugSchemeMPL();
try {
final sk = scheme.keyGen(seed);
final pk = sk.g1Element();
final fingerprint = pk.fingerprint();
setState(() {
_seed = seed;
_sk = sk;
_pk = pk;
_fingerprint = fingerprint;
});
} on Exception catch (e) {
setState(() {
_exception = e;
});
} finally {
scheme.free();
}
}
Uint8List genSeed() {
final data = [];
final random = Random();
for (var i = 0; i < 32; i++) {
data.add(random.nextInt(255));
}
return Uint8List.fromList(data);
}
@override
void dispose() {
_sk?.free();
_pk?.free();
super.dispose();
}
}
序列化密钥和签名到字节
你可以将密钥和签名序列化为字节列表,以便于存储或传输。
final skBytes = sk.serialize();
final pkBytes = pk.serialize();
final sigBytes = sig.serialize();
从字节加载密钥和签名
你可以从字节列表重新加载密钥和签名。
final sk = PrivateKey.fromBytes(data: skBytes);
final pk = G1Element.fromBytes(data: pkBytes);
final sig = G2Element.fromBytes(data: sigBytes);
print(sk.hexString()); // 32 bytes printed in hex
print(pk.hexString()); // 48 bytes printed in hex
print(sig.hexString()); // 96 bytes printed in hex
创建聚合签名
你可以组合多个签名以创建聚合签名。
final sk1 = scheme.keyGen(Uint8List.fromList(seed)..[0] = 1);
final sk2 = scheme.keyGen(Uint8List.fromList(seed)..[0] = 2);
final message2 = Uint8List.fromList([1, 2, 3, 4, 5]);
final pk1 = sk1.g1Element();
final sig1 = scheme.sign(sk1, message);
final pk2 = sk2.g1Element();
final sig2 = scheme.sign(sk2, message2);
final aggSig = scheme.aggregateSigs([sig1, sig2]);
print('Verification result: ${scheme.aggregateVerify([pk1, pk2], [message, message2], aggSig)}');
创建任意树形结构的聚合签名
你可以创建更复杂的树形结构的聚合签名。
final sk3 = scheme.keyGen(Uint8List.fromList(seed)..[0] = 3);
final pk3 = sk3.g1Element();
final message3 = Uint8List.fromList([100, 2, 254, 88, 90, 45, 23]);
final sig3 = scheme.sign(sk3, message3);
final aggSigFinal = scheme.aggregateSigs([aggSig, sig3]);
print('Verification result: ${scheme.aggregateVerify([pk1, pk2, pk3], [message, message2, message3], aggSigFinal)}');
使用证明所有权方案进行快速验证
如果你对相同的消息进行签名,可以使用证明所有权(Proof of Possession, PopScheme)以提高效率。
final popScheme = PopSchemeMPL();
final popSig1 = popScheme.sign(sk1, message);
final popSig2 = popScheme.sign(sk2, message);
final popSig3 = popScheme.sign(sk3, message);
final pop1 = popScheme.popProve(sk1);
final pop2 = popScheme.popProve(sk2);
final pop3 = popScheme.popProve(sk3);
print('Verification result: ${popScheme.popVerify(pk1, pop1)}');
print('Verification result: ${popScheme.popVerify(pk2, pop2)}');
print('Verification result: ${popScheme.popVerify(pk3, pop3)}');
final popSigAgg = popScheme.aggregateSigs([popSig1, popSig2, popSig3]);
print('Verification result: ${popScheme.fastAggregateVerify([pk1, pk2, pk3], message, popSigAgg)}');
final popAggPk = pk1 + pk2 + pk3;
print('Verification result: ${popScheme.verify(popAggPk, message, popSigAgg)}');
final aggSk = PrivateKey.aggregate([sk1, sk2, sk3]);
print('Verification result: ${popScheme.sign(aggSk, message) == popSigAgg}');
使用EIP-2333创建分层密钥
你可以从任何密钥派生出“子”密钥,以创建任意树形结构。
final masterSk = scheme.keyGen(seed);
final child = scheme.deriveChildSk(masterSk, 152);
final grandChild = scheme.deriveChildSk(child, 952);
final masterPk = masterSk.g1Element();
final childU = scheme.deriveChildSkUnhardened(masterSk, 22);
final grandChildU = scheme.deriveChildSkUnhardened(childU, 0);
final childUPk = scheme.deriveChildPkUnhardened(masterPk, 22);
final grandChildUPk = scheme.deriveChildPkUnhardened(childUPk, 0);
print('Verification result: ${grandChildUPk == grandChildU.g1Element()}');
重要提示
任何由该库创建的实例不会被Dart垃圾回收机制清理。因此,你需要手动调用free()
方法来释放资源。未来可能会实现终结器。相关问题参见Dart SDK Issue和Dart Language Issue。
运行测试
运行测试需要连接设备(物理设备或模拟器),然后进入example
目录并运行flutter驱动程序。
cd example
flutter drive --driver=test_driver/integration_test.dart --target=test_driver/main.dart
更多关于Flutter电子签名插件bls_signatures_ffi的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter电子签名插件bls_signatures_ffi的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
bls_signatures_ffi
是一个用于在 Flutter 中实现 BLS(Boneh–Lynn–Shacham)签名的插件。BLS 签名是一种基于椭圆曲线的数字签名方案,通常用于区块链技术和分布式系统中。
以下是如何在 Flutter 项目中使用 bls_signatures_ffi
插件的基本步骤:
1. 添加依赖
首先,在 pubspec.yaml
文件中添加 bls_signatures_ffi
依赖:
dependencies:
flutter:
sdk: flutter
bls_signatures_ffi: ^1.0.0 # 请检查最新版本
然后运行 flutter pub get
来获取依赖。
2. 导入包
在你的 Dart 文件中导入 bls_signatures_ffi
包:
import 'package:bls_signatures_ffi/bls_signatures_ffi.dart';
3. 初始化 BLS
在使用 BLS 签名之前,你需要初始化 BLS 库:
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await BLS.init();
runApp(MyApp());
}
4. 生成密钥对
你可以生成一个 BLS 密钥对:
final privateKey = PrivateKey.generate();
final publicKey = privateKey.getPublicKey();
5. 签名和验证
使用私钥对消息进行签名,然后使用公钥验证签名:
final message = 'Hello, BLS!';
final signature = privateKey.sign(message);
final isValid = publicKey.verify(message, signature);
print('Signature is valid: $isValid');
6. 聚合签名
BLS 签名的一个强大特性是支持签名聚合。你可以将多个签名聚合为一个签名,并使用聚合的公钥进行验证:
final privateKey1 = PrivateKey.generate();
final privateKey2 = PrivateKey.generate();
final publicKey1 = privateKey1.getPublicKey();
final publicKey2 = privateKey2.getPublicKey();
final message = 'Aggregated BLS signature';
final signature1 = privateKey1.sign(message);
final signature2 = privateKey2.sign(message);
final aggregatedSignature = Signature.aggregate([signature1, signature2]);
final aggregatedPublicKey = PublicKey.aggregate([publicKey1, publicKey2]);
final isValid = aggregatedPublicKey.verify(message, aggregatedSignature);
print('Aggregated signature is valid: $isValid');
7. 清理资源
在应用程序退出时,释放 BLS 库的资源:
void dispose() {
BLS.dispose();
}
8. 处理错误
在使用过程中,可能会遇到各种错误,例如无效的签名或密钥。确保在使用时进行适当的错误处理。
try {
final isValid = publicKey.verify(message, signature);
print('Signature is valid: $isValid');
} catch (e) {
print('Error verifying signature: $e');
}
9. 其他功能
bls_signatures_ffi
还提供了其他功能,如从字节数组生成密钥、序列化和反序列化密钥和签名等。你可以查阅官方文档以获取更多信息。
10. 示例代码
以下是一个完整的示例代码:
import 'package:flutter/material.dart';
import 'package:bls_signatures_ffi/bls_signatures_ffi.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await BLS.init();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('BLS Signatures Example')),
body: Center(
child: BLSExample(),
),
),
);
}
}
class BLSExample extends StatefulWidget {
[@override](/user/override)
_BLSExampleState createState() => _BLSExampleState();
}
class _BLSExampleState extends State<BLSExample> {
String _result = '';
[@override](/user/override)
void initState() {
super.initState();
_testBLSSignature();
}
void _testBLSSignature() async {
final privateKey = PrivateKey.generate();
final publicKey = privateKey.getPublicKey();
final message = 'Hello, BLS!';
final signature = privateKey.sign(message);
final isValid = publicKey.verify(message, signature);
setState(() {
_result = 'Signature is valid: $isValid';
});
}
[@override](/user/override)
Widget build(BuildContext context) {
return Text(_result);
}
[@override](/user/override)
void dispose() {
BLS.dispose();
super.dispose();
}
}