Flutter数字签名插件schnorr的使用

Flutter 数字签名插件 schnorr 的使用

dart-schnorr 插件实现了 Schnorr 签名算法,这是一种由 Claus Schnorr 描述的数字签名。

该代码基于 Pieter Wuille 最初提出的提案,在还没有分配 BIP 编号时。

当前版本通过了所有提供的测试向量。但是作者不保证该算法在每个边缘情况下都正确实现!

支持 elliptic 包中的所有曲线。

使用

以下是一个简单的使用示例:

import 'package:elliptic/elliptic.dart';
import 'package:schnorr/schnorr.dart';

void main() {
  // 获取 secp256k1 曲线
  var ec = getS256();

  // 生成私钥
  var priv = ec.generatePrivateKey();
  // 生成公钥
  var pub = priv.publicKey;

  // 打印私钥和公钥
  print(priv);
  print(pub);

  // 定义一个哈希值(十六进制字符串)
  var hashHex = 
      'b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9';
  
  // 将哈希值从十六进制字符串转换为整数列表
  var hash = List<int>.generate(hashHex.length ~/ 2,
      (i) => int.parse(hashHex.substring(i * 2, i * 2 + 2), radix: 16));

  // 使用私钥对哈希进行确定性签名
  var sig = deterministicSign(priv, hash);

  // 验证签名
  var result = verify(pub, hash, sig);

  // 断言验证结果为真
  assert(result);

  // 生成另一个私钥和公钥
  var priv2 = ec.generatePrivateKey();
  var pub2 = priv2.publicKey;

  // 对多个私钥进行聚合签名
  var sig2 = aggregateSign([priv, priv2], hash);

  // 结合多个公钥
  var combinedPub = combinePublicKeys([pub, pub2]);

  // 验证聚合签名
  var result2 = verify(combinedPub, hash, sig2);

  // 断言验证结果为真
  assert(result2);
}

更多关于Flutter数字签名插件schnorr的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter数字签名插件schnorr的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter中使用Schnorr数字签名算法,你可以使用现有的插件或库来实现。目前,Flutter社区中并没有专门为Schnorr签名算法设计的插件,但你可以使用Dart的加密库或通过原生代码来实现。

以下是一个使用Dart的加密库 pointycastle 来实现Schnorr签名的示例:

1. 添加依赖

首先,在 pubspec.yaml 文件中添加 pointycastle 依赖:

dependencies:
  flutter:
    sdk: flutter
  pointycastle: ^3.4.0

2. 实现Schnorr签名

以下是一个简单的Schnorr签名实现示例:

import 'dart:typed_data';
import 'package:pointycastle/export.dart';

class Schnorr {
  final ECDomainParameters _params = ECCurve_secp256k1();
  final SecureRandom _secureRandom = FortunaRandom();

  Schnorr() {
    _secureRandom.seed(KeyParameter(Uint8List.fromList(List.generate(32, (i) => i))));
  }

  Uint8List generatePrivateKey() {
    var key = _params.n ~/ BigInt.two;
    var privateKey = _secureRandom.nextBigInteger(key.bitLength);
    return Uint8List.fromList(privateKey.toByteArray());
  }

  ECPoint generatePublicKey(Uint8List privateKey) {
    var d = BigInt.parse(privateKey.toHexString(), radix: 16);
    return _params.G * d;
  }

  Uint8List sign(Uint8List privateKey, Uint8List message) {
    var d = BigInt.parse(privateKey.toHexString(), radix: 16);
    var k = _secureRandom.nextBigInteger(_params.n.bitLength);
    var R = _params.G * k;
    var e = BigInt.parse(sha256(R.getEncoded(true) + message).toHexString(), radix: 16);
    var s = (k + (d * e)) % _params.n;
    return Uint8List.fromList(s.toByteArray() + e.toByteArray());
  }

  bool verify(Uint8List publicKey, Uint8List message, Uint8List signature) {
    var s = BigInt.parse(signature.sublist(0, 32).toHexString(), radix: 16);
    var e = BigInt.parse(signature.sublist(32).toHexString(), radix: 16);
    var R = _params.G * s - (ECPoint.fromBytes(_params.curve, publicKey) * e);
    var ePrime = BigInt.parse(sha256(R.getEncoded(true) + message).toHexString(), radix: 16);
    return e == ePrime;
  }

  Uint8List sha256(Uint8List data) {
    var digest = SHA256Digest();
    return digest.process(data);
  }
}

void main() {
  var schnorr = Schnorr();
  var privateKey = schnorr.generatePrivateKey();
  var publicKey = schnorr.generatePublicKey(privateKey).getEncoded(true);
  var message = Uint8List.fromList('Hello, Schnorr!'.codeUnits);
  var signature = schnorr.sign(privateKey, message);
  var isValid = schnorr.verify(publicKey, message, signature);
  print('Signature is valid: $isValid');
}
回到顶部