| 1 | import 'dart:typed_data'; |
| 2 | |
| 3 | import 'package:bip32/bip32.dart' as bip32; |
| 4 | import 'package:bip39/bip39.dart' as bip39; |
| 5 | import 'package:polyseed/polyseed.dart'; |
| 6 | |
| 7 | bool isBip39Seed(String mnemonic) => bip39.validateMnemonic(mnemonic); |
| 8 | |
| 9 | String getBip39Seed() => bip39.generateMnemonic(); |
| 10 | |
| 11 | String getLegacySeedFromBip39(String mnemonic, {int accountIndex = 0, String passphrase = ""}) { |
| 12 | final seed = bip39.mnemonicToSeed(mnemonic, passphrase: passphrase); |
| 13 | |
| 14 | final bip32KeyPair = bip32.BIP32.fromSeed(seed).derivePath("m/44'/128'/$accountIndex'/0/0"); |
| 15 | |
| 16 | final spendKey = _reduceECKey(bip32KeyPair.privateKey!); |
| 17 | |
| 18 | return LegacySeedLang.getByEnglishName("English").encodePhrase(spendKey.toHexString()); |
| 19 | } |
| 20 | |
| 21 | const _ed25519CurveOrder = "1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED"; |
| 22 | |
| 23 | Uint8List _reduceECKey(Uint8List buffer) { |
| 24 | final curveOrder = BigInt.parse(_ed25519CurveOrder, radix: 16); |
| 25 | final bigNumber = _readBytes(buffer); |
| 26 | |
| 27 | var result = bigNumber % curveOrder; |
| 28 | |
| 29 | final resultBuffer = Uint8List(32); |
| 30 | for (var i = 0; i < 32; i++) { |
| 31 | resultBuffer[i] = (result & BigInt.from(0xff)).toInt(); |
| 32 | result = result >> 8; |
| 33 | } |
| 34 | |
| 35 | return resultBuffer; |
| 36 | } |
| 37 | |
| 38 | /// Read BigInt from a little-endian Uint8List |
| 39 | /// From https://github.com/dart-lang/sdk/issues/32803#issuecomment-387405784 |
| 40 | BigInt _readBytes(Uint8List bytes) { |
| 41 | BigInt read(int start, int end) { |
| 42 | if (end - start <= 4) { |
| 43 | var result = 0; |
| 44 | for (int i = end - 1; i >= start; i--) { |
| 45 | result = result * 256 + bytes[i]; |
| 46 | } |
| 47 | return BigInt.from(result); |
| 48 | } |
| 49 | final mid = start + ((end - start) >> 1); |
| 50 | return read(start, mid) + read(mid, end) * (BigInt.one << ((mid - start) * 8)); |
| 51 | } |
| 52 | |
| 53 | return read(0, bytes.length); |
| 54 | } |