public void ShouldValidateSignaturesCorrectly(Curve curveEnum, string dHex, string qHex, string msgHex, string sigHex, bool expectedResult) { var d = LoadValue(dHex); var q = LoadValue(qHex); var msg = new BitString(msgHex); var expectedSig = LoadValue(sigHex); var factory = new EdwardsCurveFactory(); var curve = factory.GetCurve(curveEnum); var domainParams = new EdDomainParameters(curve, new NativeShaFactory()); var keyPair = new EdKeyPair(q); var signature = new EdSignature(expectedSig); var subject = new EdDsa(); var result = subject.Verify(domainParams, keyPair, msg, signature); Assert.AreEqual(expectedResult, result.Success); }
public static (EdPoint R, BigInteger s) DecodeSig(EdDomainParameters domainParameters, EdSignature sig) { var rBits = sig.Sig.MSBSubstring(0, domainParameters.CurveE.VariableB); var sBits = sig.Sig.Substring(0, domainParameters.CurveE.VariableB); var R = domainParameters.CurveE.Decode(rBits); var s = BitString.ReverseByteOrder(sBits).ToPositiveBigInteger(); return(R, s); }
public EdVerificationResult Verify(EdDomainParameters domainParameters, EdKeyPair keyPair, BitString message, EdSignature signature, BitString context, bool preHash = false) { Sha = domainParameters.Hash; // If preHash version, then the message becomes the hash of the message if (preHash) { message = Sha.HashMessage(message, 512).Digest; } // 1. Decode R, s, and Q EdPoint R; BigInteger s; EdPoint Q; try { var sigDecoded = SignatureDecoderHelper.DecodeSig(domainParameters, signature); R = sigDecoded.R; s = sigDecoded.s; Q = domainParameters.CurveE.Decode(keyPair.PublicQ); } catch (Exception e) { return new EdVerificationResult(e.Message); } // 2. Concatenate R || Q || M var hashData = BitString.ConcatenateBits(domainParameters.CurveE.Encode(R), BitString.ConcatenateBits(keyPair.PublicQ, message)); // 3. Compute t // Determine dom. Empty if ed25519. Different for preHash function BitString dom; if (preHash) { dom = domainParameters.CurveE.CurveName == Curve.Ed448 ? Dom4(1, context) : Dom2(1, context); } else { dom = domainParameters.CurveE.CurveName == Curve.Ed448 ? Dom4(0, context) : new BitString(""); } // Compute Hash(dom4 || HashData) var hash = Sha.HashMessage(BitString.ConcatenateBits(dom, hashData), 912).Digest; // Interpret hash as a little endian integer var t = BitString.ReverseByteOrder(hash).ToPositiveBigInteger(); // 4. Check the verification equation [2^c * s]G = [2^c]R + [2^c * t]Q // 2^c var powC = NumberTheory.Pow2(domainParameters.CurveE.VariableC); // [2^c * s]G var lhs = domainParameters.CurveE.Multiply(domainParameters.CurveE.BasePointG, (powC * s).PosMod(domainParameters.CurveE.OrderN)); // [2^c]R var rhs1 = domainParameters.CurveE.Multiply(R, powC); // [2^c * t]Q var rhs2 = domainParameters.CurveE.Multiply(Q, (powC * t).PosMod(domainParameters.CurveE.OrderN)); // [2^c]R + [2^c * t]Q var rhs = domainParameters.CurveE.Add(rhs1, rhs2); if (lhs.Equals(rhs)) { return new EdVerificationResult(); } return new EdVerificationResult("The verification equation is not satisfied. Signature not valid"); }
public EdSignatureResult(EdSignature signature) { Signature = signature; }
public EdVerificationResult Verify(EdDomainParameters domainParameters, EdKeyPair keyPair, BitString message, EdSignature signature, bool preHash = false) { return Verify(domainParameters, keyPair, message, signature, null, preHash); }