Skip to content

Commit

Permalink
fix eosdart serialize/deserialize of public keys (#1935)
Browse files Browse the repository at this point in the history
* fix eosdart serialize/deserialize of public keys

* eosdart: serialize/deserialize methods for all key types; add unit test

* eosdart deserialize: fix bug in signature type (note: not in unit test)

* eosdart deserialize signature oops!

---------

Co-authored-by: NIK <[email protected]>
  • Loading branch information
chuck-h and n13 authored Apr 26, 2024
1 parent 8bcbe1e commit 3eedd13
Show file tree
Hide file tree
Showing 3 changed files with 185 additions and 6 deletions.
25 changes: 22 additions & 3 deletions lib/crypto/eosdart/src/numeric.dart
Original file line number Diff line number Diff line change
Expand Up @@ -234,10 +234,25 @@ Uint8List digestSuffixRipemd160(Uint8List data, String suffix) {
return dg.process(d);
}

Uint8List digestSha256X2(Uint8List data) {
var dg = Digest("SHA-256");
var d1 = dg.process(data);
dg.reset();
return dg.process(d1);
}

IKey stringToKey(String s, KeyType type, int size, String suffix) {
var whole = base58ToBinary(size + 4, s);
var result = IKey(type, whole);
var digest = digestSuffixRipemd160(result.data, suffix);

var result;
var digest;
if (suffix == '') {
result = IKey(type, whole.sublist(1,size));
digest = digestSha256X2(whole.sublist(0,size));
} else {
result = IKey(type, whole.sublist(0,size));
digest = digestSuffixRipemd160(result.data, suffix).toList();
}
if (digest[0] != whole[size + 0] ||
digest[1] != whole[size + 1] ||
digest[2] != whole[size + 2] ||
Expand Down Expand Up @@ -314,15 +329,19 @@ List<String> convertLegacyPublicKeys(List<String> keys) =>
IKey stringToPrivateKey(String s) {
if (s.substring(0, 7) == 'PVT_R1_') {
return stringToKey(s.substring(7), KeyType.r1, privateKeyDataSize, 'R1');
} else if (s.substring(0, 7) == 'PVT_K1_') {
return stringToKey(s.substring(7), KeyType.k1, privateKeyDataSize, 'K1');
} else {
throw 'unrecognized private key format';
return stringToKey(s, KeyType.k1, privateKeyDataSize+1, '');
}
}

/// Convert `key` to string (base-58) form */
String privateKeyToString(IKey key) {
if (key.type == KeyType.r1) {
return keyToString(key, 'R1', 'PVT_R1_');
} else if (key.type == KeyType.k1) {
return keyToString(key, 'K1', 'PVT_K1_');
} else {
throw 'unrecognized private key format';
}
Expand Down
6 changes: 3 additions & 3 deletions lib/crypto/eosdart/src/serialize.dart
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,7 @@ class SerialBuffer {
String getPublicKey() {
var type = get();
var data = getUint8List(numeric.publicKeyDataSize);
return numeric.publicKeyToString(numeric.IKey(type as numeric.KeyType, data));
return numeric.publicKeyToString(numeric.IKey(numeric.KeyType.values[type], data));
}

/// Append a private key */
Expand All @@ -420,7 +420,7 @@ class SerialBuffer {
String getPrivateKey() {
var type = get();
var data = getUint8List(numeric.privateKeyDataSize);
return numeric.privateKeyToString(numeric.IKey(type as numeric.KeyType, data));
return numeric.privateKeyToString(numeric.IKey(numeric.KeyType.values[type], data));
}

/// Append a signature */
Expand All @@ -434,7 +434,7 @@ class SerialBuffer {
String getSignature() {
var type = get();
var data = getUint8List(numeric.signatureDataSize);
return numeric.signatureToString(numeric.IKey(type as numeric.KeyType, data));
return numeric.signatureToString(numeric.IKey(numeric.KeyType.values[type], data));
}
} // SerialBuffer

Expand Down
160 changes: 160 additions & 0 deletions test/utils/serialize_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
import 'dart:typed_data';
import 'package:flutter_test/flutter_test.dart';
import 'package:seeds/crypto/eosdart/src/serialize.dart';

const verbose = false;
void main() {

group('public keys', () {
test('serialize k1 old style', () {
final keystring = 'EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV';
final sb = new SerialBuffer(new Uint8List(0));
sb.pushPublicKey(keystring);
final serialized = sb.asUint8List();

if(verbose) {
print("keystring: $keystring");
print("serialized: $serialized\n"+" ${arrayToHex(serialized)}");
}
expect(serialized,
[0, 2, 192, 222, 210, 188, 31, 19, 5, 251, 15, 170, 197, 230, 192, 62,
227, 161, 146, 66, 52, 152, 84, 39, 182, 22, 124, 165, 105, 209, 61,
244, 53, 207]);
});
test('serialize k1 new style', () {
final keystring = 'PUB_K1_6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5BoDq63';
final sb = new SerialBuffer(new Uint8List(0));
sb.pushPublicKey(keystring);
final serialized = sb.asUint8List();

if(verbose) {
print("keystring: $keystring");
print("serialized: $serialized\n"+" ${arrayToHex(serialized)}");
}
expect(serialized,
[0, 2, 192, 222, 210, 188, 31, 19, 5, 251, 15, 170, 197, 230, 192, 62,
227, 161, 146, 66, 52, 152, 84, 39, 182, 22, 124, 165, 105, 209, 61,
244, 53, 207]);
});
test('deserialize k1 new style', () {
final serialized = Uint8List.fromList([0, 2, 192, 222, 210, 188, 31, 19,
5, 251, 15, 170, 197, 230, 192, 62, 227, 161, 146, 66, 52, 152, 84, 39,
182, 22, 124, 165, 105, 209, 61, 244, 53, 207]);
final sb = new SerialBuffer(serialized);
final keystring = sb.getPublicKey();

if(verbose) {
print("keystring: $keystring");
print("serialized: $serialized\n"+" ${arrayToHex(serialized)}");
}
expect(keystring, 'PUB_K1_6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5BoDq63');
});
test('serialize r1 new style', () {
final keystring = 'PUB_R1_6eMzJfDVWvzMTYAUWQ95JcpoY8vFL62pTFm6spim25n5wqtVWP';
final sb = new SerialBuffer(new Uint8List(0));
sb.pushPublicKey(keystring);
final serialized = sb.asUint8List();

if(verbose) {
print("keystring: $keystring");
print("serialized: $serialized\n"+" ${arrayToHex(serialized)}");
}
expect(serialized,
[1, 2, 231, 80, 174, 4, 190, 33, 189, 1, 48, 165, 223, 203, 242,
125, 16, 95, 97, 223, 20, 206, 120, 17, 207, 107, 49, 24, 30,
7, 140, 39, 8, 36]);
});
test('deserialize r1 new style', () {
final serialized = Uint8List.fromList(
[1, 2, 231, 80, 174, 4, 190, 33, 189, 1, 48, 165, 223, 203, 242,
125, 16, 95, 97, 223, 20, 206, 120, 17, 207, 107, 49, 24, 30,
7, 140, 39, 8, 36]);
final sb = new SerialBuffer(serialized);
final keystring = sb.getPublicKey();

if(verbose) {
print("keystring: $keystring");
print("serialized: $serialized\n"+" ${arrayToHex(serialized)}");
}
expect(keystring, 'PUB_R1_6eMzJfDVWvzMTYAUWQ95JcpoY8vFL62pTFm6spim25n5wqtVWP');
});

});

group('private keys', () {
test('serialize k1 old style', () {
final keystring = '5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3';
final sb = new SerialBuffer(new Uint8List(0));
sb.pushPrivateKey(keystring);
final serialized = sb.asUint8List();

if(verbose) {
print("keystring: $keystring");
print("serialized: $serialized\n"+" ${arrayToHex(serialized)}");
}
expect(serialized,
[0, 210, 101, 63, 247, 203, 178, 216, 255, 18, 154, 194, 126, 245,
120, 28, 230, 139, 37, 88, 196, 26, 116, 175, 31, 45, 220, 166, 53,
203, 238, 240, 125]);
});
test('serialize k1 new style', () {
final keystring = 'PVT_K1_2bfGi9rYsXQSXXTvJbDAPhHLQUojjaNLomdm3cEJ1XTzMqUt3V';
final sb = new SerialBuffer(new Uint8List(0));
sb.pushPrivateKey(keystring);
final serialized = sb.asUint8List();

if(verbose) {
print("keystring: $keystring");
print("serialized: $serialized\n"+" ${arrayToHex(serialized)}");
}
expect(serialized,
[0, 210, 101, 63, 247, 203, 178, 216, 255, 18, 154, 194, 126, 245,
120, 28, 230, 139, 37, 88, 196, 26, 116, 175, 31, 45, 220, 166, 53,
203, 238, 240, 125]);
});
test('deserialize k1 new style', () {
final serialized = Uint8List.fromList([0, 210, 101, 63, 247, 203, 178,
216, 255, 18, 154, 194, 126, 245, 120, 28, 230, 139, 37, 88, 196,
26, 116, 175, 31, 45, 220, 166, 53, 203, 238, 240, 125]);
final sb = new SerialBuffer(serialized);
final keystring = sb.getPrivateKey();

if(verbose) {
print("keystring: $keystring");
print("serialized: $serialized\n"+" ${arrayToHex(serialized)}");
}
expect(keystring, 'PVT_K1_2bfGi9rYsXQSXXTvJbDAPhHLQUojjaNLomdm3cEJ1XTzMqUt3V');
});
test('serialize r1 new style', () {
final keystring = 'PVT_R1_2JrJRQXEagWobhJbHWtP11muTWi5pgCJ6uXWhGKd2KcFBGF7mT';
final sb = new SerialBuffer(new Uint8List(0));
sb.pushPrivateKey(keystring);
final serialized = sb.asUint8List();

if(verbose) {
print("keystring: $keystring");
print("serialized: $serialized\n"+" ${arrayToHex(serialized)}");
}
expect(serialized,
[1, 172, 58, 10, 48, 178, 188, 37, 15, 234, 129, 216, 243, 182,
68, 115, 41, 18, 206, 91, 223, 230, 199, 84, 66, 41, 110, 159,
117, 45, 189, 67, 43]);
});
test('deserialize r1 new style', () {
final serialized = Uint8List.fromList(
[1, 172, 58, 10, 48, 178, 188, 37, 15, 234, 129, 216, 243, 182,
68, 115, 41, 18, 206, 91, 223, 230, 199, 84, 66, 41, 110, 159,
117, 45, 189, 67, 43]);
final sb = new SerialBuffer(serialized);
final keystring = sb.getPrivateKey();

if(verbose) {
print("keystring: $keystring");
print("serialized: $serialized\n"+" ${arrayToHex(serialized)}");
}
expect(keystring, 'PVT_R1_2JrJRQXEagWobhJbHWtP11muTWi5pgCJ6uXWhGKd2KcFBGF7mT');
});

});

}

0 comments on commit 3eedd13

Please sign in to comment.