/// <summary> /// Computes the commitment Hash /// </summary> /// <param name="commitment">Commitment the commitment as a byte array.</param> /// <returns>Commitment hash as a byte array</returns> public virtual byte[] ComputeCommitmentHash(byte[] commitment) { Guard.NotNull(commitment, nameof(commitment)); Guard.NotLessThanOrEqualTo(commitment.Length, 0, nameof(commitment)); return(Digests.Sha256(commitment)); }
/// <summary> /// Verifies the commitmentHash is resulted from commitment /// </summary> /// <param name="commitment">Commitment as a byte array</param> /// <param name="commitmentHash">CommitmentHash the commitment hash as a byte array</param> /// <returns>true if commitmentHash is the Hash of commitment, false otherwise</returns> public bool ValidateCommitment(byte[] commitment, byte[] commitmentHash) { Guard.NotNull(commitment, nameof(commitment)); Guard.NotLessThanOrEqualTo(commitment.Length, 0, nameof(commitment)); Guard.NotNull(commitmentHash, nameof(commitmentHash)); Guard.NotLessThanOrEqualTo(commitmentHash.Length, 0, nameof(commitmentHash)); var computedHash = Digests.Sha256(commitment); return(computedHash.SequenceEqual(commitmentHash)); }
/// <summary> /// Computes the challenge according to Belare Naveen multi-signature algorithm: /// - H1( /// <L'>||Xi||R||m), where H1 is a Hashing function, e.g Sha3, Xi is the public key, /// - R is the aggregated commitment, and m is the message. /// /// /// </summary> /// <param name="signers">the listToTable of signee's (consensus group's) public keys</param> /// <param name="publicKey">own public key</param> /// <param name="aggregatedCommitment">the aggregated commitment from all signers as a byte array</param> /// <param name="message">the message to be signed</param> /// <param name="bitmapCommitments"> /// commitment mask (byte), bit is 1 if corresponding signer participates in signing or 0 /// otherwise /// </param> /// <returns>the challenge as a byte array</returns> public byte[] ComputeChallenge(List <byte[]> signers, byte[] publicKey, byte[] aggregatedCommitment, byte[] message, long bitmapCommitments) { Guard.NotNull(signers, nameof(signers)); Guard.NotLessThanOrEqualTo(signers.Count, 0, nameof(signers)); Guard.NotNull(publicKey, nameof(publicKey)); Guard.NotLessThanOrEqualTo(publicKey.Length, 0, nameof(publicKey)); Guard.NotNull(aggregatedCommitment, nameof(aggregatedCommitment)); Guard.NotLessThanOrEqualTo(aggregatedCommitment.Length, 0, nameof(aggregatedCommitment)); Guard.NotNull(message, nameof(message)); Guard.NotLessThanOrEqualTo(message.Length, 0, nameof(message)); var challenge = new byte[0]; if (0 == bitmapCommitments) { return(challenge); } // compute <L'> as concatenation of participating signers public keys challenge = ConcatenatePublicKeys(signers, bitmapCommitments); // do rest of concatenation <L'> || public key challenge = Concat(challenge, publicKey); // do <L'> || public key || R challenge = Concat(challenge, aggregatedCommitment); // do <L'> || public key || R || m challenge = Concat(challenge, message); // do computing hash as BigInteger var challengeInt = new BigInteger(1, Digests.Sha3(challenge)); // reduce the challenge modulo curve order return(challengeInt.Mod(_secp256k1.Parameters.N).ToByteArray()); }