Skip to content

Commit

Permalink
feat: ✨ Add a method to verify archethic keys
Browse files Browse the repository at this point in the history
  • Loading branch information
redDwarf03 committed Jan 21, 2025
1 parent 7ba0faf commit eaff7f2
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 1 deletion.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# 7.3.0
- Add a method to verify archethic keys

# 7.2.0
- Implementation of GraphQL method: `chainUnspentOutputs`

Expand Down
1 change: 1 addition & 0 deletions lib/archethic_lib_dart.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ library archethic;
export 'src/model/address.dart';
export 'src/model/authorized_key.dart';
export 'src/model/balance.dart';
export 'src/model/consumed_inputs.dart';
export 'src/model/contract.dart';
export 'src/model/cross_validation_stamp.dart';
export 'src/model/crypto/aes_auth_encrypt_infos.dart';
Expand Down
46 changes: 46 additions & 0 deletions lib/src/utils/utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,52 @@ Map<String, dynamic> removeNullValues(Map<String, dynamic> json) {
.toMap();
}

bool verifyArchethicKey(String key) {
if (!isHex(key)) {
return false;
}

// Convert the hexadecimal public key to a byte list
final pubKeyBytes = hexToUint8List(key);

// Check that the total length of the public key is sufficient to contain curve and origin information
if (pubKeyBytes.length < 2) {
return false;
}

final pubKeyBuf = pubKeyBytes.sublist(2, pubKeyBytes.length);

// Determine the expected length of the public key based on the curve
int lengthBytes;
switch (pubKeyBytes[0]) {
case 0:
lengthBytes = 32;
break;
case 1:
case 2:
lengthBytes = 65;
break;
case 3:
lengthBytes = 48;
break;
default:
lengthBytes = -1;
}

// Check that the length of the public key matches the expected length
if (lengthBytes == -1 || pubKeyBuf.lengthInBytes != lengthBytes) {
return false;
}

// Check that the origin is either 0 or 1
if (pubKeyBytes[1] != 0 && pubKeyBytes[1] != 1) {
return false;
}

// If all checks pass, the public key is valid
return true;
}

extension MapExtension<K, V> on Iterable<MapEntry<K, V>> {
Map<K, V> toMap() => {for (final entry in this) entry.key: entry.value};
}
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: archethic_lib_dart
description: Archethic dart library for Flutter for Node and Browser. This library aims to provide a easy way to create Archethic transaction and to send them over the network
homepage: https://github.com/archethic-foundation/libdart

version: 7.2.0
version: 7.3.0

environment:
sdk: ">=3.5.3 <4.0.0"
Expand Down
59 changes: 59 additions & 0 deletions test/utils_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -208,4 +208,63 @@ void main() {
expect(obj['a']['b'][0]['b'].keys, equals(['a', 'b', 'c']));
});
});

group('verifyPubKey', () {
test('should return true for a valid pubKey with curve 0', () {
const pubKey =
'00017EB361D06C3CB2A0102F664422542E9AB6E88C9867A4EAE082C86274B83AD041';
final result = verifyArchethicKey(pubKey);
expect(result, true);
});

test('should return true for a valid pubKey with curve 3', () {
const pubKey =
'0301A7BB0712AFBCB6345B4C5282F82538F979D9E88FB4F3B3DE7A708D224DA18ACDD53F3DFFB9D597A9D8537A85119B0123';
final result = verifyArchethicKey(pubKey);
expect(result, true);
});

test(
'should return false for an invalid pubKey with incorrect length for curve 0',
() {
const pubKey =
'00017EB361D06C3CB2A0102F664422542E9AB6E88C9867A4EAE082C86274B83AD0413433'; // Too long
final result = verifyArchethicKey(pubKey);
expect(result, false);
});

test('should return false for an invalid pubKey with unknown curve', () {
const pubKey =
'0401A7BB0712AFBCB6345B4C5282F82538F979D9E88FB4F3B3DE7A708D224DA18ACDD53F3DFFB9D597A9D8537A85119B0123'; // Curve 4 does not exist
final result = verifyArchethicKey(pubKey);
expect(result, false);
});

test('should return false for an invalid pubKey with invalid origin', () {
const pubKey =
'00047EB361D06C3CB2A0102F664422542E9AB6E88C9867A4EAE082C86274B83AD041'; // Origin 2 is invalid
final result = verifyArchethicKey(pubKey);
expect(result, false);
});

test('should return false for an invalid pubKey with insufficient length',
() {
const pubKey = '0001'; // Too short to contain a valid public key
final result = verifyArchethicKey(pubKey);
expect(result, false);
});

test('should return false for an empty pubKey', () {
const pubKey = '';
final result = verifyArchethicKey(pubKey);
expect(result, false);
});

test('should return false for a pubKey with non-hex characters', () {
const pubKey =
'00017EB361D06C3CB2A0102F664422542E9AB6E88C9867A4EAE082C86274B83AD0ZZ'; // Contains non-hex characters
final result = verifyArchethicKey(pubKey);
expect(result, false);
});
});
}

0 comments on commit eaff7f2

Please sign in to comment.