/// <inheritdoc /> protected override Task <JObject> SignAsync(IVerifyData verifyData, JObject proof, ProofOptions options) { var verifyDataArray = verifyData as StringArray ?? throw new Exception("Unsupported verify data type"); var derivedProof = new JObject { { "@context", Constants.SECURITY_CONTEXT_V3_URL } }; var originalProof = options.AdditonalData["originalDocument"]["proof"]; var signature = Convert.FromBase64String(originalProof["proofValue"].ToString()); var keyPair = new Bls12381G2Key2020(GetVerificationMethod(originalProof as JObject, options)); var bbsKey = keyPair.ToBlsKeyPair().GetBbsKey((uint)verifyDataArray.Data.Length); var nonce = Nonce ?? Encoding.UTF8.GetBytes(Guid.NewGuid().ToString()); var proofMessages = GetProofMessages( allInputStatements: verifyDataArray.Data, revealIndicies: options.AdditonalData["revealIndicies"].ToObject <int[]>()); var outputProof = Service.CreateProof(new CreateProofRequest( publicKey: bbsKey, messages: proofMessages.ToArray(), signature: signature, blindingFactor: null, nonce: nonce)); // Set the proof value on the derived proof derivedProof["proofValue"] = Convert.ToBase64String(outputProof); derivedProof["nonce"] = Convert.ToBase64String(nonce); derivedProof["created"] = originalProof["created"]; derivedProof["proofPurpose"] = originalProof["proofPurpose"]; derivedProof["verificationMethod"] = originalProof["verificationMethod"]; derivedProof["type"] = "BbsBlsSignatureProof2020"; return(Task.FromResult(derivedProof)); }
protected override Task VerifyAsync(IVerifyData payload, JToken proof, JToken verificationMethod, ProofOptions options) { var verifyData = payload as ByteArray ?? throw new ArgumentException("Invalid data type"); if (proof["jws"] == null || !proof["jws"].ToString().Contains("..")) { throw new Exception("The proof does not include a valid 'jws' property."); } var parts = proof["jws"].ToString().Split(".."); var(encodedHeader, encodedSignature) = (parts.First(), parts.Last()); var header = JObject.Parse(Encoding.UTF8.GetString(Helpers.FromBase64String(encodedHeader))); if (header["alg"]?.ToString() != Algorithm) { throw new Exception($"Invalid JWS header parameters for ${TypeName}."); } var signature = Helpers.FromBase64String(encodedSignature); var data = (ByteArray)Encoding.ASCII.GetBytes($"{encodedHeader}.") .Concat(verifyData.Data) .ToArray(); var signer = GetSigner(verificationMethod); var valid = signer.Verify(signature, data); if (!valid) { throw new Exception("Invalid signature"); } return(Task.CompletedTask); }
protected override Task <JObject> SignAsync(IVerifyData verifyData, JObject proof, ProofOptions options) { var data = verifyData as ByteArray ?? throw new Exception("Invalid verify data type"); var signature = Signer.Sign(data); proof["signatureValue"] = Multibase.Base58.Encode(signature); return(Task.FromResult(proof)); }
protected override Task VerifyAsync(IVerifyData verifyData, JToken proof, JToken verificationMethod, ProofOptions options) { var data = verifyData as ByteArray ?? throw new Exception("Invalid verify data type"); var signature = Multibase.Base58.Decode(proof["signatureValue"].ToString()); var valid = Signer.Verify(signature, data); if (!valid) { throw new Exception("Invalid signature"); } return(Task.CompletedTask); }
protected override Task <JObject> SignAsync(IVerifyData payload, JObject proof, ProofOptions options) { var verifyData = payload as StringArray ?? throw new ArgumentException("Invalid data type"); if (KeyPair?.SecretKey == null) { throw new Exception("Private key not found."); } var proofValue = SignatureService.Sign(new SignRequest(KeyPair, verifyData.Data)); proof["proofValue"] = Convert.ToBase64String(proofValue); proof["type"] = "BbsBlsSignature2020"; return(Task.FromResult(proof)); }
protected override Task VerifyAsync(IVerifyData payload, JToken proof, JToken verificationMethod, ProofOptions options) { var verifyData = payload as StringArray ?? throw new ArgumentException("Invalid data type"); var blsVerificationMethod = new Bls12381G2Key2020(verificationMethod as JObject); var key = new BlsKeyPair(Multibase.Base58.Decode(blsVerificationMethod.PublicKeyBase58)); var signature = Helpers.FromBase64String(proof["proofValue"]?.ToString() ?? throw new Exception("Proof value not found")); var valid = SignatureService.Verify(new VerifyRequest(key, signature, verifyData.Data)); if (!valid) { throw new Exception("Invalid signature"); } return(Task.CompletedTask); }
/// <inheritdoc /> protected override Task VerifyAsync(IVerifyData verifyData, JToken proof, JToken verificationMethod, ProofOptions options) { var stringArray = verifyData as StringArray ?? throw new Exception("Unsupported verify data type"); var proofData = Helpers.FromBase64String(proof["proofValue"]?.ToString() ?? throw new Exception("Proof value not found")); var nonce = Helpers.FromBase64String(proof["nonce"]?.ToString() ?? throw new Exception("Nonce not found")); var keyPair = new Bls12381G2Key2020(GetVerificationMethod(proof as JObject, options)); var messageCount = Service.GetTotalMessageCount(proofData); var verifyResult = Service.VerifyProof(new VerifyProofRequest( publicKey: keyPair.ToBlsKeyPair().GetBbsKey((uint)messageCount), proof: proofData, messages: stringArray.Data, nonce: nonce)); if (!verifyResult) { throw new Exception("Invalid signature proof"); } return(Task.CompletedTask); }
/// <inheritdoc /> protected override Task <JObject> SignAsync(IVerifyData payload, JObject proof, ProofOptions options) { var verifyData = payload as ByteArray ?? throw new ArgumentException("Invalid data type"); // JWS header var header = new JObject { { "alg", Algorithm }, { "b64", false }, { "crit", JArray.Parse("[\"b64\"]") } }; /* +-------+-----------------------------------------------------------+ | "b64" | JWS Signing Input Formula | +-------+-----------------------------------------------------------+ | true | ASCII(BASE64URL(UTF8(JWS Protected Header)) || '.' || | | | BASE64URL(JWS Payload)) | | | | | false | ASCII(BASE64URL(UTF8(JWS Protected Header)) || '.') || | | | JWS Payload | +-------+-----------------------------------------------------------+ */ // create JWS data and sign var encodedHeader = Convert.ToBase64String(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(header))); var data = (ByteArray)Encoding.ASCII.GetBytes($"{encodedHeader}.") .Concat(verifyData.Data) .ToArray(); var signature = Signer.Sign(data); // create detached content signature var encodedSignature = Convert.ToBase64String(signature); proof["jws"] = $"{encodedHeader}..{encodedSignature}"; return(Task.FromResult(proof)); }
protected override Task VerifyAsync(IVerifyData verifyData, JToken proof, JToken verificationMethod, ProofOptions options) { throw new NotImplementedException(); }
protected override Task <JObject> SignAsync(IVerifyData verifyData, JObject proof, ProofOptions options) { proof["proofValue"] = Convert.ToBase64String((verifyData as ByteArray).Data); return(Task.FromResult(proof)); }
/// <summary> /// Verifies the verification data for the current proof /// </summary> /// <param name="verifyData"></param> /// <param name="proof"></param> /// <param name="verificationMethod"></param> /// <param name="options"></param> /// <returns></returns> protected abstract Task VerifyAsync(IVerifyData verifyData, JToken proof, JToken verificationMethod, ProofOptions options);
/// <summary> /// Signs the verification data for the current proof /// </summary> /// <param name="verifyData"></param> /// <param name="proof"></param> /// <param name="options"></param> /// <returns></returns> protected abstract Task <JObject> SignAsync(IVerifyData verifyData, JObject proof, ProofOptions options);