import 'dart:convert'; import 'dart:typed_data'; import 'package:dart_spectre/src/scope.dart'; import 'package:dart_spectre/src/template.dart'; import "package:pointycastle/export.dart"; final scrypt = Scrypt(); final hmac = HMac(SHA256Digest(), 64); class Spectre { final String _name; final String _secret; late Scoper _scoper; late Uint8List _key; Spectre(this._name, this._secret, [Scoper? scoper]) { _scoper = scoper ?? defaultScoper; _key = _userKey(); } Uint8List _userKey() { var nameBytes = utf8.encode(_name); var secretBytes = utf8.encode(_secret); var keyScope = utf8.encode(_scoper.scope(Scope.authentication)); var nameBytesLen = nameBytes.length; var keySalt = keyScope + List.from([ nameBytesLen >> 24, nameBytesLen >> 16, nameBytesLen >> 8, nameBytesLen, ]) + nameBytes; scrypt.init(ScryptParameters(32768, 8, 2, 64, Uint8List.fromList(keySalt))); return scrypt.process(Uint8List.fromList(secretBytes)); } Uint8List _siteKey(String name, int counter, Scope scope) { var nameBytes = utf8.encode(name); var scopeBytes = utf8.encode(_scoper.scope(scope)); var nameBytesLen = nameBytes.length; var keySalt = scopeBytes + List.from([ nameBytesLen >> 24, nameBytesLen >> 16, nameBytesLen >> 8, nameBytesLen, ]) + nameBytes + List.from([ counter >> 24, counter >> 16, counter >> 8, counter, ]); hmac.init(KeyParameter(_key)); return hmac.process(Uint8List.fromList(keySalt)); } String site(String siteName, {Template? templateType, int counter = 1, Scope scope = Scope.authentication}) { templateType = templateType ?? scopeDefaultTemplate(scope); var siteKey = _siteKey(siteName, counter, scope); var templateSet = templates[templateType]!; var template = templateSet[siteKey[0] % templateSet.length]; var out = StringBuffer(); var idx = 0; for (var rune in template.runes) { var chars = characters[String.fromCharCode(rune)]!; var char = chars[siteKey[++idx] % chars.length]; out.write(char); } return out.toString(); } }