# SD-JWT Library

> An implementation of the SD-JWT specification for selective disclosure when sharing data.

[
        Apache 2.0 License 
    ](https://github.com/affinidi/affinidi-sdjwt-dart/blob/main/LICENSE)

    [
        Contribution Guidelines 
    ](https://github.com/affinidi/affinidi-sdjwt-dart/blob/main/CONTRIBUTING.md)

    [
        Repository 
    ](https://github.com/affinidi/affinidi-sdjwt-dart)

The SD-JWT for Dart package provides libraries and tools to enable selective disclosure, enhancing security and privacy in the data-sharing process. It implements the IETF’s [Selective Disclosure for JWTs (SD-JWT)](https://datatracker.ietf.org/doc/draft-ietf-oauth-selective-disclosure-jwt/) specification.

The SD-JWT for Dart package enables:

- Issuer to create JWTs with selectively disclosable claims.

- Holder to present only specific claims to verifiers.

- Verifier to validate the authenticity of the presented claims.

- Key binding to prevent unauthorized presentations.

## Core Concepts

SD-JWT introduces several key concepts:

- Selective Disclosure: Claims can be selectively disclosed based on need

- Cryptographic Binding: Claims are cryptographically bound to the JWT

- Key Binding: Ensures only the intended holder can present the SD-JWT

- Disclosures: Individual pieces of information that can be selectively shared

## Supported Algorithms

The package supports the following signing algorithms:

- ES256 - ECDSA using P-256 curve and SHA-256

- ES256K - ECDSA using secp256k1 curve and SHA-256

- RS256 - RSASSA-PKCS1-v1_5 using SHA-256

- HS256 - HMAC using SHA-256

- EdDSA (Ed25519) - Edwards-curve Digital Signature Algorithm using Ed25519

- Additional algorithms: RS384, RS512, ES384, ES512, HS384, and HS512

For hash calculation in disclosures:

- SHA-256 (default)

- SHA-384

- SHA-512

You can create your custom signer, hasher, and verifier to extend support for other algorithms. Refer to [this example](example/code_snippets/custom_algorithm.dart) on how to do this.

## Get Started

### Prerequisite

- Dart SDK version ^3.6.0

### Installation

Run:

```bash
dart pub add selective_disclosure_jwt
```

or manually, add the package into your pubspec.yaml file:

```yaml
dependencies:
  selective_disclosure_jwt: ^
```

and then run the command below to install the package:

```bash
dart pub get
```

### Sample Usage

After successfully installing the package, import it into your Dart code.

```dart
import 'package:selective_disclosure_jwt/selective_disclosure_jwt.dart';

void main() async {
  // Always generate and use your own secure keys for real-world use.
  final issuerPrivateKey = SdPrivateKey("""
...
""", SdJwtSignAlgorithm.es256k);

  final issuerPublicKey = SdPublicKey("""
...
""", SdJwtSignAlgorithm.es256k);

  // 1. Create SD-JWT with selective disclosures
  final SdJwtHandlerV1 handler = SdJwtHandlerV1();

  final Map claims = {
    'given_name': 'Alice',
    'family_name': 'Smith',
    'email': 'alice@example.com',
  };

  // Specify which claims should be selectively disclosable
  final disclosureFrame = {
    '_sd': ['given_name', 'email'],
  };

  // Sign the claims to produce the SD-JWT
  final SdJwt sdJwt = await handler.sign(
    claims: claims,
    disclosureFrame: disclosureFrame,
    signer: SDKeySigner(issuerPrivateKey),
  );

  print('SD-JWT: ${sdJwt.serialized}');

  // 2. Decode and verify the SD-JWT
  final SdJwt verified = handler.decodeAndVerify(
    sdJwtToken: sdJwt.serialized,
    verifier: SDKeyVerifier(issuerPublicKey),
  );

  print('Verified claims: ${verified.claims}');
  // Output: {family_name: Smith, given_name: Alice, email: alice@example.com}
}
```

For more examples, go to the [example folder](https://github.com/affinidi/affinidi-sdjwt-dart/tree/main/example/).

## API Reference

For the available operations, go to the [API reference page](https://github.com/affinidi/affinidi-sdjwt-dart/tree/main/doc/api_reference.md).
