Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
## 0.0.5
## 0.0.7

- Improve compatibility with japanese strings using U+0020 separators

## 0.0.6

- Make getters less strict
- Support up-to-date dependencies
Expand Down
12 changes: 9 additions & 3 deletions lib/src/mnemonics/polyseed_lang.dart
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,15 @@ class PolyseedLang {

/// Get the [PolyseedLang] by it's english name eg. "Chinese (Simplified)"
static PolyseedLang getByEnglishName(String englishName) =>
languages.firstWhere((e) => e.nameEnglish.toLowerCase() == englishName.toLowerCase());
languages.firstWhere(
(e) => e.nameEnglish.toLowerCase() == englishName.toLowerCase());

/// Get the [PolyseedLang] using the words of [phrase]
static PolyseedLang getByPhrase(String phrase) {
for (var language in languages) {
phrase = language.hasAccents ? unorm.nfkd(phrase) : phrase;
final phraseWords = phrase.split(language.separator);
final phraseWords =
language.normalizeSeparator(phrase).split(language.separator);
if (language.words.containsAll(phraseWords)) {
return language;
}
Expand All @@ -85,12 +87,16 @@ class PolyseedLang {
}

/// Decode a valid seed [phrase] into it's coefficients
List<int> decodePhrase(String phrase) => phrase
List<int> decodePhrase(String phrase) => normalizeSeparator(phrase)
.split(separator)
.map((e) => words.indexOf(hasAccents ? unorm.nfkd(e) : e))
.toList();

/// Encode a seed [coefficients] into a valid seed phrase
String encodePhrase(List<int> coefficients) =>
coefficients.map((e) => words[e]).join(separator);

/// Replace space with the expected [separator] to improve compatibility
String normalizeSeparator(String phrase) =>
separator != '\u0020' ? phrase.replaceAll("\u0020", separator) : phrase;
}
17 changes: 11 additions & 6 deletions lib/src/polyseed.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,15 @@ class Polyseed {
late PolyseedData _data;

/// Check if a seed is a valid Polyseed
static bool isValidSeed(String phrase) {
if (!PolyseedLang.isValidPhrase(phrase)) return false;
final lang = PolyseedLang.getByPhrase(phrase);

return phrase.split(lang.separator).length == numberOfWords;
static bool isValidSeed(String phrase, [PolyseedLang? lang]) {
if (lang != null && !PolyseedLang.isValidPhrase(phrase)) return false;
final polyseedLang = lang ?? PolyseedLang.getByPhrase(phrase);

return polyseedLang
.normalizeSeparator(phrase)
.split(polyseedLang.separator)
.length ==
numberOfWords;
}

/// Create a random [Polyseed]
Expand Down Expand Up @@ -66,9 +70,10 @@ class Polyseed {
Polyseed.decode(String str, PolyseedLang lang, PolyseedCoin coin) {
assert(coin.index < GFPoly.size);

final words = str.split(lang.separator);
final words = lang.normalizeSeparator(str).split(lang.separator);
final poly = GFPoly();


// split into words
if (words.length != numberOfWords) {
throw WordNumberException();
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: polyseed
description: A pure dart implementation of the 16-word seed scheme for monero
version: 0.0.6
version: 0.0.7
homepage: https://cakelabs.com
repository: https://github.com/cake-tech/polyseed_dart
issue_tracker: https://github.com/cake-tech/polyseed_dart/issues
Expand Down
19 changes: 19 additions & 0 deletions test/polyseed_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import 'dart:convert';

import 'package:polyseed/polyseed.dart';
import 'package:polyseed/src/mnemonics/es_lang.dart';
import 'package:polyseed/src/mnemonics/jp_lang.dart';
import 'package:test/test.dart';

void main() {
Expand Down Expand Up @@ -118,6 +119,24 @@ void main() {
expect(legacySeed,
"remedio haz ébano lobo orden celda pezuña regreso ardilla estar acelga fallo punto nación hada quitar ancla obeso piedra pausa helio fuente joroba pista quitar");
});

test('Edge Case: Japanese seed with normal space separator', () {
final seed =
"せつぶん いせい てはい けんか たてる ねんきん くたびれる いよく やたい あいこくしん ちきゅう きたえる せたけ あひる かのう げつれい";

final detectedLang = PolyseedLang.getByPhrase(seed);
expect(detectedLang, jpLang);

final isValidSeed = Polyseed.isValidSeed(seed);
expect(isValidSeed, true);

final key = Polyseed.decode(seed, jpLang, coin)
.generateKey(coin, 32)
.toHexString();

expect(key,
"340593b3fd0b2670b4727b6a9b64f3f817e2b97fcb26ea3ae8467234eb857f95");
});
});
});
}
Expand Down