Skip to content

Commit

Permalink
refactor knowncredentials and private funcs
Browse files Browse the repository at this point in the history
  • Loading branch information
code-z2 committed Jun 17, 2024
1 parent 92b3cfd commit 9181f82
Show file tree
Hide file tree
Showing 7 changed files with 62 additions and 41 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## 0.0.13

- returned raw credential from Passkey Signature
- made random challenge generator public

## 0.0.12

- register function requires display name
Expand Down
3 changes: 2 additions & 1 deletion lib/src/interfaces/interfaces.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ library interfaces;

import 'dart:typed_data';

import 'package:blockchain_utils/tuple/tuple.dart';
import 'package:blockchain_utils/utils/utils.dart';
import 'package:passkeys/types.dart';
import 'package:web3dart/crypto.dart';
import 'package:web3dart/web3dart.dart';

Expand Down
10 changes: 7 additions & 3 deletions lib/src/interfaces/passkey_signer_interface.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ abstract class PasskeySignerInterface extends MultiSignerInterface {
PassKeysOptions get opts;

/// Gets the credential IDs used by the passkey signer.
Set<String> get credentialIds;
Set<Uint8List> get credentialIds;

/// Generates the 32-byte client data hash for the given [PassKeysOptions] and optional challenge.
///
Expand Down Expand Up @@ -77,7 +77,7 @@ abstract class PasskeySignerInterface extends MultiSignerInterface {
///
/// Parameters:
/// - [hash]: The hash to be signed.
/// - [index]: Optional index of the credentialId associated with the PassKeyPair.
/// - [knownCredentials]: Optional credentials to be used for signing.
///
/// Returns a Future<PassKeySignature> representing the PassKeySignature of the signed hash.
///
Expand All @@ -88,5 +88,9 @@ abstract class PasskeySignerInterface extends MultiSignerInterface {
/// final pkps = PassKeySigner("example", "example.com", "https://example.com");
/// final passKeySignature = await pkps.signToPasskeySignature(hash);
/// ```
Future<PassKeySignature> signToPasskeySignature(Uint8List hash, {int? index});
Future<PassKeySignature> signToPasskeySignature(Uint8List hash,
{List<CredentialType>? knownCredentials});

/// Generates a random base64 string.
String randomBase64String();
}
80 changes: 46 additions & 34 deletions lib/src/signers/passkey_signer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class PassKeyPair {

final String username;
final String? displayname;
final DateTime registrationTime;
final DateTime? registrationTime;
PassKeyPair(
this.authData, this.username, this.displayname, this.registrationTime);

Expand All @@ -38,7 +38,9 @@ class PassKeyPair {
),
map['username'],
map['displayname'],
DateTime.fromMillisecondsSinceEpoch(map['registrationTime']),
map['registrationTime'] != null
? DateTime.fromMillisecondsSinceEpoch(map['registrationTime'])
: null,
);
}

Expand All @@ -53,13 +55,14 @@ class PassKeyPair {
'username': username,
'displayname': displayname,
'aaGUID': authData.aaGUID,
'registrationTime': registrationTime.millisecondsSinceEpoch,
'registrationTime': registrationTime?.millisecondsSinceEpoch,
};
}
}

class PassKeySignature {
final Hex credentialHex;
final Hex hexCredential;
final Bytes rawCredential;

/// r and s values of the signature.
final Tuple<Uint256, Uint256> signature;
Expand All @@ -70,8 +73,8 @@ class PassKeySignature {
/// not decodable.
final String userId;

PassKeySignature(this.credentialHex, this.signature, this.authData,
this.clientDataPrefix, this.clientDataSuffix, this.userId);
PassKeySignature(this.hexCredential, this.rawCredential, this.signature,
this.authData, this.clientDataPrefix, this.clientDataSuffix, this.userId);

/// Converts the `PassKeySignature` to a `Uint8List` using the specified ABI encoding.
///
Expand Down Expand Up @@ -103,7 +106,7 @@ class PassKeySigner implements PasskeySignerInterface {

final PasskeyAuthenticator _auth;

final Set<Hex> _knownCredentials;
final Set<Bytes> _knownCredentials;

@override
String dummySignature =
Expand All @@ -114,7 +117,7 @@ class PassKeySigner implements PasskeySignerInterface {
/// - [origin] : the relying party entity origin. e.g "https://variance.space"
/// - [knownCredentials] : a set of known credentials. Defaults to an empty set.
PassKeySigner(String namespace, String name, String origin,
{Set<Hex> knownCredentials = const {}})
{Set<Bytes> knownCredentials = const {}})
: _opts = PassKeysOptions(
namespace: namespace,
name: name,
Expand All @@ -124,14 +127,14 @@ class PassKeySigner implements PasskeySignerInterface {
_knownCredentials = knownCredentials;

@override
Set<Hex> get credentialIds => _knownCredentials;
Set<Bytes> get credentialIds => _knownCredentials;

@override
PassKeysOptions get opts => _opts;

@override
Uint8List clientDataHash(PassKeysOptions options, [String? challenge]) {
options.challenge = challenge ?? _randomBase64String();
options.challenge = challenge ?? randomBase64String();
final clientDataJson = jsonEncode({
"type": options.type,
"challenge": options.challenge,
Expand All @@ -157,8 +160,7 @@ class PassKeySigner implements PasskeySignerInterface {

@override
String getAddress({int? index}) {
return base64Url
.encode(hexToCredentialId(_knownCredentials.elementAt(index ?? 0)));
return base64Url.encode(_knownCredentials.elementAt(index ?? 0));
}

@override
Expand All @@ -177,10 +179,32 @@ class PassKeySigner implements PasskeySignerInterface {

@override
Future<Uint8List> personalSign(Uint8List hash, {int? index}) async {
final signature = await signToPasskeySignature(hash, index: index);
final knownCredentials = _getKnownCredentials(index);
final signature =
await signToPasskeySignature(hash, knownCredentials: knownCredentials);
return signature.toUint8List();
}

List<CredentialType> _getKnownCredentials([int? index]) {
// Retrive known credentials if any
final List<Bytes> credentialIds;
if (index != null) {
credentialIds = _knownCredentials.elementAtOrNull(index) != null
? [_knownCredentials.elementAt(index)]
: _knownCredentials.toList();
} else {
credentialIds = _knownCredentials.toList();
}

// convert credentialIds to CredentialType
final List<CredentialType> credentials = credentialIds
.map((e) =>
CredentialType(type: "public-key", id: b64e(e), transports: []))
.toList();

return credentials;
}

@override
Future<PassKeyPair> register(String username, String displayname,
{String? challenge,
Expand All @@ -205,35 +229,21 @@ class PassKeySigner implements PasskeySignerInterface {

@override
Future<MsgSignature> signToEc(Uint8List hash, {int? index}) async {
final signature = await signToPasskeySignature(hash, index: index);
final knownCredentials = _getKnownCredentials(index);
final signature =
await signToPasskeySignature(hash, knownCredentials: knownCredentials);
return MsgSignature(
signature.signature.item1.value, signature.signature.item2.value, 0);
}

@override
Future<PassKeySignature> signToPasskeySignature(Uint8List hash,
{int? index}) async {
{List<CredentialType>? knownCredentials}) async {
// Prepare hash
final hashBase64 = b64e(hash);

// Retrive known credentials if any
final List<Hex> credentialIds;
if (index != null) {
credentialIds = _knownCredentials.elementAtOrNull(index) != null
? [_knownCredentials.elementAt(index)]
: _knownCredentials.toList();
} else {
credentialIds = _knownCredentials.toList();
}

// convert credentialIds to CredentialType
final List<CredentialType> credentials = credentialIds
.map((e) => CredentialType(
type: "public-key", id: b64e(hexToCredentialId(e)), transports: []))
.toList();

// Authenticate with passkey
final assertion = await _authenticate(hashBase64, credentials, true);
final assertion = await _authenticate(hashBase64, knownCredentials, true);

// Extract signature from response
final sig = getMessagingSignature(b64d(assertion.signature));
Expand All @@ -247,6 +257,7 @@ class PassKeySigner implements PasskeySignerInterface {

return PassKeySignature(
credentialIdToHex(b64d(assertion.id).toList()),
b64d(assertion.rawId),
sig,
b64d(assertion.authenticatorData),
challengePrefix,
Expand Down Expand Up @@ -316,7 +327,8 @@ class PassKeySigner implements PasskeySignerInterface {
return _decode(authData);
}

String _randomBase64String() {
@override
String randomBase64String() {
final uuid = UUID.generateUUIDv4();
return b64e(UUID.toBuffer(uuid));
}
Expand All @@ -334,7 +346,7 @@ class PassKeySigner implements PasskeySignerInterface {
name: options.name,
),
user: UserType(
id: _randomBase64String(),
id: randomBase64String(),
displayName: displayname,
name: username,
),
Expand Down
2 changes: 1 addition & 1 deletion lib/src/vendor/vendor.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import 'dart:math';
import 'dart:typed_data';

import 'package:blockchain_utils/tuple/tuple.dart';
import 'package:blockchain_utils/utils/utils.dart';
import 'package:web3dart/crypto.dart';

import '../utils/utils.dart' show hexToU8a;
Expand Down
1 change: 0 additions & 1 deletion lib/src/web3_signers_base.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import 'dart:convert';
import 'dart:math';
import 'dart:typed_data';

import 'package:blockchain_utils/bip/mnemonic/mnemonic.dart';
import 'package:blockchain_utils/blockchain_utils.dart';
import 'package:passkeys/authenticator.dart';
import 'package:passkeys/types.dart';
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: web3_signers
description: Web3 signers provides a uniform interface for signing EIP-1271 messages with different EC algorithms.
version: 0.0.12
version: 0.0.13
homepage: https://variance.space
repository: https://github.com/vaariance/web3-signers
issue_tracker: https://github.com/vaariance/web3-signers/issues
Expand Down

0 comments on commit 9181f82

Please sign in to comment.