Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Probably too much #29

Merged
merged 7 commits into from
Jan 11, 2024
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
1 change: 1 addition & 0 deletions packages/web5/analysis_options.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ linter:
- prefer_final_locals
- require_trailing_commas
- unnecessary_late
- prefer_single_quotes
10 changes: 4 additions & 6 deletions packages/web5/example/web5_example.dart
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
import 'dart:convert';

import 'package:web5/web5.dart';

void main() async {
final keyManager = InMemoryKeyManager();

final did = await DidJwk.create(keyManager: keyManager);
print(did.uri);
// LOAD PRE-EXISTING
// final did = DidJwk(uri: "some_uri", keyManager: keyManager);

final didResolutionResult = DidJwk.resolve(did.uri);
print(jsonEncode(didResolutionResult));
// CREATE
// final did = DidJwk.create(keyManager: keyManager);
}
9 changes: 9 additions & 0 deletions packages/web5/lib/src/crypto.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export './crypto/jwk.dart';
export './crypto/dsa.dart';
export './crypto/ed25519.dart';
export './crypto/dsa_name.dart';
export './crypto/dsa_alias.dart';
export './crypto/secp256k1.dart';
export './crypto/key_manager.dart';
export './crypto/dsa_algorithms.dart';
export './crypto/in_memory_key_manager.dart';
Comment on lines +1 to +9
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice!

45 changes: 1 addition & 44 deletions packages/web5/lib/src/crypto/dsa.dart
Original file line number Diff line number Diff line change
@@ -1,50 +1,7 @@
import 'dart:typed_data';

import 'package:web5/src/crypto/jwk.dart';

/// Enum [DsaName] representing supported Digital Signature Algorithm (DSA) names.
enum DsaName {
secp256k1('ES256K', 'secp256k1', 'EC'),
ed25519('EdDSA', 'Ed25519', 'OKP');

static final _aliases = {
DsaAlias(algorithm: 'EdDSA', curve: 'Ed25519'): DsaName.ed25519,
DsaAlias(algorithm: null, curve: 'Ed25519'): DsaName.ed25519,
DsaAlias(algorithm: 'ES256K', curve: 'secp256k1'): DsaName.secp256k1,
DsaAlias(algorithm: 'ES256K', curve: null): DsaName.secp256k1,
DsaAlias(algorithm: null, curve: 'secp256k1'): DsaName.secp256k1,
};

final String algorithm;
final String curve;
final String kty;

const DsaName(this.algorithm, this.curve, this.kty);

/// method that can be used to find [DsaName] using
/// [JWA](https://datatracker.ietf.org/doc/html/rfc7518.html) algorithm and
/// curve names
static DsaName? findByAlias({String? algorithm, String? curve}) =>
_aliases[DsaAlias(algorithm: algorithm, curve: curve)];
}

class DsaAlias {
String? algorithm;
String? curve;

DsaAlias({this.algorithm, this.curve});

@override
bool operator ==(Object other) {
if (identical(this, other)) return true;
return other is DsaAlias &&
other.algorithm == algorithm &&
other.curve == curve;
}

@override
int get hashCode => algorithm.hashCode ^ curve.hashCode;
}
import 'package:web5/src/crypto/dsa_name.dart';

/// Abstract interface for Digital Signature Algorithms.
///
Expand Down
26 changes: 23 additions & 3 deletions packages/web5/lib/src/crypto/dsa_algorithms.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import 'dart:typed_data';

import 'package:web5/web5.dart';
import 'package:web5/src/crypto/jwk.dart';
import 'package:web5/src/crypto/dsa.dart';
import 'package:web5/src/crypto/ed25519.dart';
import 'package:web5/src/crypto/dsa_name.dart';
import 'package:web5/src/crypto/secp256k1.dart';

class DsaAlgorithms {
static final _supportedAlgorithms = {
Expand All @@ -12,7 +16,7 @@ class DsaAlgorithms {
final dsa = _supportedAlgorithms[alg];

if (dsa == null) {
throw Exception("${alg.name} not supported");
throw Exception('${alg.name} not supported');
}

return dsa.generatePrivateKey();
Expand All @@ -26,6 +30,22 @@ class DsaAlgorithms {
return _getDsa(privateKeyJwk).sign(privateKeyJwk, payload);
}

static Future<void> verify({
required DsaName algName,
required Jwk publicKey,
required Uint8List payload,
required Uint8List signature,
}) {
final dsa = _supportedAlgorithms[algName];
if (dsa == null) {
throw Exception(
'DSA ${algName.algorithm}:${algName.curve} not supported.',
);
}

return dsa.verify(publicKey, payload, signature);
}

static Dsa _getDsa(Jwk privateKeyJwk) {
final dsa = _supportedAlgorithms[DsaName.findByAlias(
algorithm: privateKeyJwk.alg,
Expand All @@ -34,7 +54,7 @@ class DsaAlgorithms {

if (dsa == null) {
throw Exception(
"DSA ${privateKeyJwk.alg}:${privateKeyJwk.crv} not supported.",
'DSA ${privateKeyJwk.alg}:${privateKeyJwk.crv} not supported.',
);
}
return dsa;
Expand Down
17 changes: 17 additions & 0 deletions packages/web5/lib/src/crypto/dsa_alias.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
class DsaAlias {
String? algorithm;
String? curve;

DsaAlias({this.algorithm, this.curve});

@override
bool operator ==(Object other) {
if (identical(this, other)) return true;
return other is DsaAlias &&
other.algorithm == algorithm &&
other.curve == curve;
}

@override
int get hashCode => algorithm.hashCode ^ curve.hashCode;
}
27 changes: 27 additions & 0 deletions packages/web5/lib/src/crypto/dsa_name.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import 'package:web5/src/crypto/dsa_alias.dart';

/// Enum [DsaName] representing supported Digital Signature Algorithm (DSA) names.
enum DsaName {
secp256k1('ES256K', 'secp256k1', 'EC'),
ed25519('EdDSA', 'Ed25519', 'OKP');

static final _aliases = {
DsaAlias(algorithm: 'EdDSA', curve: 'Ed25519'): DsaName.ed25519,
DsaAlias(algorithm: null, curve: 'Ed25519'): DsaName.ed25519,
DsaAlias(algorithm: 'ES256K', curve: 'secp256k1'): DsaName.secp256k1,
DsaAlias(algorithm: 'ES256K', curve: null): DsaName.secp256k1,
DsaAlias(algorithm: null, curve: 'secp256k1'): DsaName.secp256k1,
};

final String algorithm;
final String curve;
final String kty;

const DsaName(this.algorithm, this.curve, this.kty);

/// method that can be used to find [DsaName] using
/// [JWA](https://datatracker.ietf.org/doc/html/rfc7518.html) algorithm and
/// curve names
static DsaName? findByAlias({String? algorithm, String? curve}) =>
_aliases[DsaAlias(algorithm: algorithm, curve: curve)];
}
5 changes: 3 additions & 2 deletions packages/web5/lib/src/crypto/ed25519.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ import 'dart:typed_data';

import 'package:cryptography/cryptography.dart' as crypto;

import 'package:web5/src/extensions/base64url.dart';
import 'package:web5/src/extensions.dart';
import 'package:web5/src/crypto/dsa.dart';
import 'package:web5/src/crypto/jwk.dart';
import 'package:web5/src/crypto/dsa_name.dart';

final ed25519 = crypto.Ed25519();
final _base64UrlCodec = Base64Codec.urlSafe();
Expand Down Expand Up @@ -107,7 +108,7 @@ class Ed25519 implements Dsa {
final isLegit = await ed25519.verify(payload, signature: signature);

if (isLegit == false) {
throw Exception("Integrity check failed");
throw Exception('Integrity check failed');
}
}

Expand Down
6 changes: 3 additions & 3 deletions packages/web5/lib/src/crypto/in_memory_key_manager.dart
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import 'dart:typed_data';

import 'package:web5/src/crypto/dsa.dart';
import 'package:web5/src/crypto/dsa_algorithms.dart';
import 'package:web5/src/crypto/jwk.dart';
import 'package:web5/src/crypto/dsa_name.dart';
import 'package:web5/src/crypto/key_manager.dart';
import 'package:web5/src/crypto/dsa_algorithms.dart';

/// A class for managing cryptographic keys in-memory.
///
Expand Down Expand Up @@ -46,7 +46,7 @@ class InMemoryKeyManager implements KeyManager {
Jwk _retrievePrivateKeyJwk(String keyAlias) {
final privateKeyJwk = _keyStore[keyAlias];
if (privateKeyJwk == null) {
throw Exception("key with alias $keyAlias not found.");
throw Exception('key with alias $keyAlias not found.');
}

return privateKeyJwk;
Expand Down
11 changes: 6 additions & 5 deletions packages/web5/lib/src/crypto/jwk.dart
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import 'dart:convert';
import 'package:cryptography/dart.dart';
import 'package:web5/src/extensions/base64url.dart';
import 'package:web5/src/extensions/json.dart';
import 'package:web5/src/extensions.dart';

// TODO: refactor into PrivateJwk PublicJwk classes

const dartSha256 = DartSha256();
const _dartSha256 = DartSha256();
final _base64UrlEncoder = Base64Codec.urlSafe().encoder;

/// Represents a [JSON Web Key (JWK)](https://datatracker.ietf.org/doc/html/rfc7517).
///
Expand Down Expand Up @@ -135,10 +135,11 @@ class Jwk {
thumbprintPayload.removeWhere((key, value) => value == null);

final thumbprintPayloadBytes = utf8.encode(jsonEncode(thumbprintPayload));
final thumbprintPayloadDigest = dartSha256.hashSync(thumbprintPayloadBytes);
final thumbprintPayloadDigest =
_dartSha256.hashSync(thumbprintPayloadBytes);

final thumbprint =
base64UrlEncoder.convertNoPadding(thumbprintPayloadDigest.bytes);
_base64UrlEncoder.convertNoPadding(thumbprintPayloadDigest.bytes);

return thumbprint;
}
Expand Down
2 changes: 1 addition & 1 deletion packages/web5/lib/src/crypto/key_manager.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import 'dart:typed_data';

import 'package:web5/src/crypto/jwk.dart';
import 'package:web5/src/crypto/dsa.dart';
import 'package:web5/src/crypto/dsa_name.dart';

/// A key management interface that provides functionality for generating,
/// storing, and utilizing private keys and their associated public keys.
Expand Down
14 changes: 7 additions & 7 deletions packages/web5/lib/src/crypto/secp256k1.dart
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import "dart:convert";
import "dart:math";
import 'dart:math';
import 'dart:convert';
import 'dart:typed_data';

import "package:pointycastle/export.dart";
import 'package:pointycastle/export.dart';
import 'package:web5/src/crypto/dsa.dart';
import 'package:web5/src/crypto/jwk.dart';
import "package:web5/src/extensions/base64url.dart";
import 'package:web5/src/extensions/bigint.dart';
import 'package:web5/src/extensions.dart';
import 'package:web5/src/crypto/dsa_name.dart';

final _base64UrlCodec = Base64Codec.urlSafe();
final _base64UrlEncoder = _base64UrlCodec.encoder;
Expand Down Expand Up @@ -47,7 +47,7 @@ class Secp256k1 implements Dsa {
final y = Q.y!.toBigInteger();

if (x == null || y == null) {
throw Exception("Failed to generate public key from private key");
throw Exception('Failed to generate public key from private key');
}

final publicKeyJwk = Jwk(
Expand Down Expand Up @@ -166,7 +166,7 @@ class Secp256k1 implements Dsa {
final isLegit = verifier.verifySignature(payload, ecSignature);

if (!isLegit) {
throw Exception("Integrity check failed");
throw Exception('Integrity check failed');
}

return Future.value();
Expand Down
7 changes: 7 additions & 0 deletions packages/web5/lib/src/dids.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export './dids/did.dart';
export './dids/did_uri.dart';
export './dids/data_models.dart';
export './dids/did_resolver.dart';
export './dids/did_dht/did_dht.dart';
export './dids/did_jwk/did_jwk.dart';
export './dids/did_method_resolver.dart';
11 changes: 11 additions & 0 deletions packages/web5/lib/src/dids/data_models.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export 'structures/service.dart';
export 'structures/did_resource.dart';
export 'structures/did_document.dart';
export 'structures/resolution_result.dart';
export 'structures/dereference_result.dart';
export 'structures/verification_method.dart';
export 'structures/resolution_metadata.dart';
export 'structures/dereference_options.dart';
export 'structures/dereference_metadata.dart';
export 'structures/did_document_metadata.dart';
export 'structures/verification_relationship.dart';
2 changes: 1 addition & 1 deletion packages/web5/lib/src/dids/did.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import 'package:web5/src/crypto/key_manager.dart';
import 'package:web5/src/crypto.dart';

abstract class Did {
String get uri;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,13 @@
import 'dart:convert';
import 'dart:io';

import 'package:web5/src/crypto/dsa.dart';
import 'package:web5/src/crypto/ed25519.dart';
import 'package:web5/src/crypto/secp256k1.dart';
import 'package:web5/src/crypto.dart';
import 'package:web5/src/dids/did.dart';
import 'package:web5/src/dids/did_document.dart';
import 'package:web5/src/dids/did_service.dart';
import 'package:web5/src/extensions.dart';
import 'package:web5/src/dids/did_uri.dart';
import 'package:web5/src/dids/did_verification_method.dart';
import 'package:web5/src/dns_packet/packet.dart';
import 'package:web5/src/crypto/key_manager.dart';
import 'package:web5/src/dids/did_resolution_result.dart';
import 'package:web5/src/dns_packet/txt_data.dart';
import 'package:web5/src/dns_packet/type.dart';
import 'package:web5/src/extensions/base64url.dart';
import 'package:web5/src/dids/data_models.dart';
import 'package:web5/src/dids/did_dht/dns_packet.dart';
import 'package:web5/src/dids/did_method_resolver.dart';

final Set<String> txtEntryNames = {'vm', 'auth', 'asm', 'agm', 'inv', 'del'};
final _base64UrlCodec = Base64Codec.urlSafe();
Expand All @@ -31,7 +24,7 @@ class DidDht implements Did {

static const String methodName = 'dht';

// static final resolver = DidMethodResolver(name: methodName, resolve: resolve);
static final resolver = DidMethodResolver(name: methodName, resolve: resolve);

static Future<DidResolutionResult> resolve(
String didUri, {
Expand Down Expand Up @@ -140,7 +133,7 @@ class DidDht implements Did {
}

if (dsa == null) {
throw Exception("idk rn");
throw Exception('idk rn');
}

final publicKeyBytes =
Expand Down
14 changes: 14 additions & 0 deletions packages/web5/lib/src/dids/did_dht/dns_packet.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export './dns_packet/answer.dart';
export './dns_packet/class.dart';
export './dns_packet/consts.dart';
export './dns_packet/header.dart';
export './dns_packet/name.dart';
export './dns_packet/opcode.dart';
export './dns_packet/opt_data.dart';
export './dns_packet/option_code.dart';
export './dns_packet/packet.dart';
export './dns_packet/question.dart';
export './dns_packet/rcode.dart';
export './dns_packet/rdata.dart';
export './dns_packet/txt_data.dart';
export './dns_packet/type.dart';
Loading