save [skip ci]

This commit is contained in:
Matthew Fosse 2024-04-11 12:48:00 -07:00
parent 04fccb8e7b
commit 2fe5236f04
4 changed files with 139 additions and 13 deletions

View file

@ -6,6 +6,12 @@ import 'dart:math';
import 'package:bitcoin_base/bitcoin_base.dart';
import 'package:bitcoin_flutter/bitcoin_flutter.dart' as bitcoin;
import 'package:bitcoin_base/bitcoin_base.dart' as bitcoin_base;
import 'package:blockchain_utils/base58/base58_base.dart';
import 'package:blockchain_utils/blockchain_utils.dart';
import 'package:blockchain_utils/crypto/crypto/cdsa/curve/curves.dart';
import 'package:blockchain_utils/crypto/crypto/cdsa/ecdsa/signature.dart';
import 'package:blockchain_utils/signer/bitcoin_signer.dart';
import 'package:blockchain_utils/string/string.dart';
import 'package:collection/collection.dart';
import 'package:cw_bitcoin/address_from_output.dart';
import 'package:cw_bitcoin/bitcoin_address_record.dart';
@ -40,6 +46,9 @@ import 'package:hive/hive.dart';
import 'package:mobx/mobx.dart';
import 'package:rxdart/subjects.dart';
import 'package:http/http.dart' as http;
import 'package:bip32/bip32.dart' as bip32;
import 'package:bitcoin_base/bitcoin_base.dart';
import 'package:hex/hex.dart';
part 'electrum_wallet.g.dart';
@ -1222,20 +1231,110 @@ abstract class ElectrumWalletBase
@override
Future<String> signMessage(String message, {String? address = null}) async {
final index = address != null
? walletAddresses.allAddresses.firstWhere((element) => element.address == address).index
: null;
final HD = index == null ? hd : hd.derive(index);
return base64Encode(HD.sign(message));
// final index = address != null
// ? walletAddresses.allAddresses.firstWhere((element) => element.address == address).index
// : null;
// final HD = index == null ? hd : hd.derive(index);
// final HD = hd.derive(0);
// return base64Encode(HD.signMessage(message));
// hd.privKey
final priv = ECPrivate.fromHex(hd.privKey!);
String messagePrefix = '\x18Bitcoin Signed Message:\n';
return priv.signMessage(utf8.encode(message), messagePrefix: messagePrefix);
}
// Uint8List? recoverPublicKey(String signature, String messageHash) {
// try {
// // Convert the signature from hex to bytes
// final signatureBytes = HEX.decode(signature);
// // Convert the message hash from hex to bytes
// final messageHashBytes = HEX.decode(messageHash);
// // Create a BitcoinSignature object from the signature bytes
// final bitcoinSignature = BitcoinSignatures.fromCompact(signatureBytes);
// // Recover the public key using the signature and message hash
// final recoveredPublicKey = bitcoinSignature.recoverPublicKey(messageHashBytes);
// // Convert the recovered public key to compressed format
// final compressedPublicKey = recoveredPublicKey.compressed;
// return compressedPublicKey;
// } catch (e) {
// // Return null if an error occurs during the recovery process
// return null;
// }
// }
@override
Future<bool> verifyMessage(String message, String signature, {String? address = null}) async {
final index = address != null
? walletAddresses.allAddresses.firstWhere((element) => element.address == address).index
: null;
final HD = index == null ? hd : hd.derive(index);
return HD.verify(message: message, signature: base64Decode(signature));
if (address == null) {
return false;
}
// final decode = List<int>.unmodifiable(Base58Decoder.decode(address));
// /// Extract script bytes excluding version and checksum.
// final List<int> scriptBytes = decode.sublist(1, decode.length - Base58Const.checksumByteLen);
// scriptBytes == hash160 (public key)
String messagePrefix = '\x18Bitcoin Signed Message:\n';
// ECDSASignature signature = ECDSASignature.fromBytes(ascii.encode(signature), generator)
// final btcSigner = BitcoinVerifier.fromKeyBytes([]);
// btcSigner.verifyKey.verify(signature, digest)
print("@@@@@@@@@111111111111");
// final messageHash = QuickCrypto.sha256Hash(
// BitcoinSignerUtils.magicMessage(utf8.encode(message), messagePrefix));
final messageHash = BitcoinSignerUtils.magicMessage(utf8.encode(message), messagePrefix);
// final generator = ProjectiveECCPoint.infinity(Curves.curveSecp256k1);
final generator = Curves.generatorSecp256k1;
print("@@@@@@@@@@@@@@@@@@@@@");
print(signature);
final sig = ECDSASignature.fromBytes(utf8.encode(signature), generator);
print("######################");
final sigBytes = utf8.encode(signature);
print(sigBytes[0]);
final pubKey = sig.recoverPublicKey(messageHash, generator, sigBytes[0]);
final recoveredPub = ECPublic.fromBytes(pubKey!.toBytes());
final recoveredAddress = recoveredPub.toP2pkhInP2sh();
print("$address $recoveredAddress");
if (recoveredAddress.toAddress(network) == address) {
return true;
}
// ECPublic pub = ECPublic.fromBytes(pubKey!.toBytes());
// return pub.verify(
// utf8.encode(message),
// sigBytes,
// messagePrefix: messagePrefix,
// );
// final index = address != null
// ? walletAddresses.allAddresses.firstWhere((element) => element.address == address).index
// : null;
// final HD = index == null ? hd : hd.derive(index);
// final HD = hd.derive(0);
// return HD.verify(message: message, signature: base64Decode(signature));
return false;
}
static BasedUtxoNetwork _getNetwork(bitcoin.NetworkType networkType, CryptoCurrency? currency) {

View file

@ -26,6 +26,7 @@ import 'package:cw_nano/nano_wallet_addresses.dart';
import 'package:cw_core/wallet_base.dart';
import 'package:bip39/bip39.dart' as bip39;
import 'package:nanoutil/nanoutil.dart';
import 'package:nanodart/nanodart.dart' as nd;
part 'nano_wallet.g.dart';
@ -489,9 +490,24 @@ abstract class NanoWalletBase
await Directory(currentDirPath).delete(recursive: true);
}
String hash(String message) {
return nd.NanoHelpers.byteToHex(
nd.Blake2b.digest256([nd.NanoHelpers.stringToBytesUtf8(message)]),
).toUpperCase();
}
@override
Future<String> signMessage(String message, {String? address = null}) async {
return NanoSignatures.sign(message, privateKey!);
// return NanoSignatures.sign(message, privateKey!);
// return nd.NanoHelpers.byteToHex(
// nd.Signature.detached(
// nd.NanoHelpers.hexToBytes(hash(message)),
// nd.NanoHelpers.hexToBytes(privateKey!),
// ),
// );
// return nd.NanoSignatures.signBlock(hash(message), privateKey!);
return nd.NanoSignatures.signBlock(
"AEC75F807DCE45AFA787DE7B395BE498A885525569DD614162E0C80FD4F27EE9", privateKey!);
}
@override
@ -500,6 +516,17 @@ abstract class NanoWalletBase
return false;
}
String publicKey = NanoDerivations.addressToPublicKey(address);
return NanoSignatures.verify(message, signature, publicKey);
// return NanoSignatures.verify(message, signature, publicKey);
print(publicKey);
print("adasdasdadaadadada");
var msg = "AEC75F807DCE45AFA787DE7B395BE498A885525569DD614162E0C80FD4F27EE9";
return nd.Signature.detachedVerify(
// nd.NanoHelpers.hexToBytes(hash(message)),
nd.NanoHelpers.hexToBytes(msg),
nd.NanoHelpers.hexToBytes(signature),
nd.NanoHelpers.hexToBytes(publicKey),
);
}
}

View file

@ -82,6 +82,7 @@ class VerifyFormState extends State<VerifyForm> {
controller: signatureController,
placeholder: S.current.signature,
options: [AddressTextFieldOption.paste],
buttonColor: Theme.of(context).hintColor,
),
],
),

View file

@ -374,7 +374,6 @@ abstract class DashboardViewModelBase with Store {
bool get hasSignMessages => [
WalletType.monero,
WalletType.haven,
WalletType.solana,
WalletType.litecoin,
WalletType.bitcoin,
WalletType.bitcoinCash,