verifyProof method

  1. @override
FutureOr<bool> verifyProof(
  1. dynamic proof,
  2. dynamic data,
  3. String did, {
  4. String? challenge,
  5. Map<String, dynamic>? jwk,
  6. Future<DidDocument> didResolver(
    1. String
    ) = resolveDidDocument,
})
override

Verifies a LinkedDataProof / DataIntegrityProof

Implementation

@override
FutureOr<bool> verifyProof(proof, data, String did,
    {String? challenge,
    Map<String, dynamic>? jwk,
    Future<DidDocument> Function(String) didResolver =
        resolveDidDocument}) async {
  //compare challenge
  if (challenge != null) {
    var containedChallenge = proof['challenge'];
    if (containedChallenge == null) {
      throw Exception('Expected challenge in this credential');
    }
    if (containedChallenge != challenge) {
      throw Exception('a challenge do not match expected challenge');
    }
  }

  List<int> hash = await _dataToHash(data);

  String jws = proof.remove('jws');
  proof['@context'] = jsonWebSignature2020ContextIri;

  var proofHash = sha256
      .convert(utf8.encode(await JsonLdProcessor.normalize(proof,
          options:
              JsonLdOptions(safeMode: true, documentLoader: loadDocument))))
      .bytes;
  var payload = proofHash + hash;

  proof['jws'] = jws;
  proof.remove('@context');

  var verificationMethod = proof['verificationMethod'];
  dynamic usedJwk;

  if (jwk != null) {
    usedJwk = jwk;
  } else {
    var ddo = await didResolver(did);
    ddo = ddo.resolveKeyIds().convertAllKeysToJwk();

    for (var k in ddo.verificationMethod!) {
      if (k.id == verificationMethod) {
        usedJwk = k.publicKeyJwk!;
        break;
      }
    }
  }

  if (usedJwk == null) {
    throw Exception(
        'Can\'t find public key for id $verificationMethod in did document');
  }

  var header = jws.split('.').first;
  var decodedHeader =
      jsonDecode(utf8.decode(base64Decode(addPaddingToBase64(header))));
  var alg = decodedHeader['alg'];
  if (alg == null || alg is! String) {
    throw Exception('alg Header missing in jws-header');
  }

  var hashToSign = ascii.encode('$header.') + payload;

  var signature = Uint8List.fromList(
      base64Decode(addPaddingToBase64(jws.split('.').last)));

  if (alg == 'EdDSA') {
    if (usedJwk['crv'] != 'Ed25519') {
      throw Exception(
          'Wrong crv value ${usedJwk['crv']} for this signature suite (ed25519 needed)');
    }
    var decodedKey = base64Decode(addPaddingToBase64(usedJwk['x']));
    return ed.verify(
        ed.PublicKey(decodedKey), Uint8List.fromList(hashToSign), signature);
  } else if (alg.startsWith('ES256K')) {
    var pubKey = EcPublicKey(
        xCoordinate: web3_crypto.bytesToUnsignedInt(
            base64Decode(addPaddingToBase64(usedJwk['x']))),
        yCoordinate: web3_crypto.bytesToUnsignedInt(
            base64Decode(addPaddingToBase64(usedJwk['y']))),
        curve: curves.p256k);
    var verifier = pubKey.createVerifier(algorithms.signing.ecdsa.sha256);

    return verifier.verify(
        Uint8List.fromList(hashToSign), Signature(signature));
  } else if (alg.startsWith('ES256')) {
    print('ES256');
    var pubKey = EcPublicKey(
        xCoordinate: web3_crypto.bytesToUnsignedInt(
            base64Decode(addPaddingToBase64(usedJwk['x']))),
        yCoordinate: web3_crypto
            .bytesToInt(base64Decode(addPaddingToBase64(usedJwk['y']))),
        curve: curves.p256);
    var verifier = pubKey.createVerifier(algorithms.signing.ecdsa.sha256);

    return verifier.verify(
        Uint8List.fromList(hashToSign), Signature(signature));
  } else if (alg.startsWith('ES384')) {
    var pubKey = EcPublicKey(
        xCoordinate: web3_crypto.bytesToUnsignedInt(
            base64Decode(addPaddingToBase64(usedJwk['x']))),
        yCoordinate: web3_crypto.bytesToUnsignedInt(
            base64Decode(addPaddingToBase64(usedJwk['y']))),
        curve: curves.p384);
    var verifier = pubKey.createVerifier(algorithms.signing.ecdsa.sha384);

    return verifier.verify(
        Uint8List.fromList(hashToSign), Signature(signature));
  } else if (alg.startsWith('ES512')) {
    var pubKey = EcPublicKey(
        xCoordinate: web3_crypto.bytesToUnsignedInt(
            base64Decode(addPaddingToBase64(usedJwk['x']))),
        yCoordinate: web3_crypto.bytesToUnsignedInt(
            base64Decode(addPaddingToBase64(usedJwk['y']))),
        curve: curves.p521);
    var verifier = pubKey.createVerifier(algorithms.signing.ecdsa.sha512);

    return verifier.verify(
        Uint8List.fromList(hashToSign), Signature(signature));
  } else {
    throw Exception('Unknown Signature algorithm');
  }
}