LCOV - code coverage report
Current view: top level - crypto/evm/entities/raw_transaction - signature.dart (source / functions) Coverage Total Hit
Test: lcov.info Lines: 60.4 % 48 29
Test Date: 2025-01-30 01:10:00 Functions: - 0 0

            Line data    Source code
       1              : import 'dart:convert';
       2              : import 'dart:typed_data';
       3              : import 'package:pointycastle/export.dart';
       4              : import 'package:sec/sec.dart';
       5              : import 'package:walletkit_dart/src/utils/keccak.dart';
       6              : import 'package:walletkit_dart/walletkit_dart.dart';
       7              : import 'package:pointycastle/src/utils.dart' as p_utils;
       8              : 
       9              : class Signature {
      10              :   final BigInt r;
      11              :   final BigInt s;
      12              :   final int v;
      13              : 
      14            0 :   Uint8List get rBytes => padUint8ListTo32(p_utils.encodeBigIntAsUnsigned(r));
      15            0 :   Uint8List get sBytes => padUint8ListTo32(p_utils.encodeBigIntAsUnsigned(s));
      16              : 
      17            4 :   const Signature(this.r, this.s, this.v);
      18              : 
      19            0 :   @override
      20              :   String toString() {
      21            0 :     return 'Signature{r: $r, s: $s, v: $v}';
      22              :   }
      23              : 
      24            3 :   factory Signature.fromHex(String hex) => Signature.fromBytes(hex.hexToBytes);
      25              : 
      26            2 :   factory Signature.fromBytes(Uint8List bytes) {
      27            4 :     final r = bytes.sublist(0, 32).toUBigInt;
      28            4 :     final s = bytes.sublist(32, 64).toUBigInt;
      29            2 :     final v = bytes[64];
      30              : 
      31            2 :     return Signature(r, s, v);
      32              :   }
      33              : 
      34            1 :   factory Signature.fromRSV(BigInt r, BigInt s, int v) {
      35            1 :     return Signature(r, s, v);
      36              :   }
      37              : 
      38            3 :   factory Signature.createSignature(
      39              :     Uint8List payload,
      40              :     Uint8List privateKey, {
      41              :     TransactionType txType = TransactionType.Legacy,
      42              :     int? chainId,
      43              :     bool hashPayload = true,
      44              :   }) {
      45            3 :     final digest = SHA256Digest();
      46            6 :     final signer = ECDSASigner(null, HMac(digest, 64));
      47            3 :     final params = ECCurve_secp256k1();
      48            6 :     final key = ECPrivateKey(bytesToUnsignedInt(privateKey), params);
      49            6 :     signer.init(true, PrivateKeyParameter(key));
      50              : 
      51              :     if (hashPayload) {
      52            2 :       payload = keccak256(payload);
      53              :     }
      54            3 :     var sig = signer.generateSignature(payload) as ECSignature;
      55              : 
      56           15 :     if (sig.s.compareTo(params.n >> 1) > 0) {
      57            0 :       final canonicalS = params.n - sig.s;
      58            0 :       sig = ECSignature(sig.r, canonicalS);
      59              :     }
      60              : 
      61              :     final publickey =
      62            9 :         bytesToUnsignedInt(privateKeyToPublic(bytesToUnsignedInt(privateKey)));
      63              : 
      64            6 :     final rcID = EC.secp256k1.calculateRecoveryId(publickey, sig, payload);
      65              : 
      66              :     if (rcID == null) {
      67            0 :       throw Exception('Failed to calculate recovery id');
      68              :     }
      69              : 
      70              :     final int v = switch (txType) {
      71            3 :       TransactionType.Legacy =>
      72            6 :         chainId != null ? (rcID + (chainId * 2 + 35)) : (rcID + 27),
      73            0 :       TransactionType.Type1 || TransactionType.Type2 => rcID,
      74              :     };
      75              : 
      76            9 :     return Signature(sig.r, sig.s, v);
      77              :   }
      78              : 
      79            0 :   int get yParity => v % 2;
      80              : 
      81              :   static const _messagePrefix = '\u0019Ethereum Signed Message:\n';
      82              : 
      83            0 :   static Uint8List signPersonalMessageToUint8List(
      84              :       Uint8List payload, Uint8List privateKey) {
      85            0 :     final prefix = _messagePrefix + payload.length.toString();
      86            0 :     final prefixBytes = ascii.encode(prefix);
      87              : 
      88            0 :     final concat = uint8ListFromList(prefixBytes + payload);
      89              : 
      90            0 :     final signature = Signature.createSignature(concat, privateKey);
      91            0 :     return signature.bytes;
      92              :   }
      93              : 
      94            0 :   bool isValidETHSignature(
      95              :     Uint8List payload,
      96              :     Uint8List publicKey,
      97              :   ) {
      98            0 :     payload = keccak256(payload);
      99            0 :     final recoverdPublicKey = recoverPublicKey(payload, this);
     100              : 
     101            0 :     return recoverdPublicKey.toHex == publicKey.toHex;
     102              :   }
     103              : 
     104            1 :   Uint8List get bytes {
     105            3 :     final rBytes = padUint8ListTo32(p_utils.encodeBigIntAsUnsigned(r));
     106            3 :     final sBytes = padUint8ListTo32(p_utils.encodeBigIntAsUnsigned(s));
     107              : 
     108            4 :     return Uint8List.fromList([...rBytes, ...sBytes, v]);
     109              :   }
     110              : 
     111            1 :   String get hex {
     112            2 :     return bytes.toHex;
     113              :   }
     114              : }
        

Generated by: LCOV version 2.0-1