public void ShouldPassBatchVerifycation() { var vectors = new string[][] { new [] { "0279BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", "0000000000000000000000000000000000000000000000000000000000000000", "787A848E71043D280C50470E8E1532B2DD5D20EE912A45DBDD2BD1DFBF187EF67031A98831859DC34DFFEEDDA86831842CCD0079E1F92AF177F7F22CC1DCED05" }, new [] { "02DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659", "243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89", "2A298DACAE57395A15D0795DDBFD1DCB564DA82B0F269BC70A74F8220429BA1D1E51A22CCEC35599B8F266912281F8365FFC2D035A230434A1A64DC59F7013FD" }, new [] { "03FAC2114C2FBB091527EB7C64ECB11F8021CB45E8E7809D3C0938E4B8C0E5F84B", "5E2D58D8B3BCDF1ABADEC7829054F90DDA9805AAB56C77333024B9D0A508B75C", "00DA9B08172A9B6F0466A2DEFD817F2D7AB437E0D253CB5395A963866B3574BE00880371D01766935B92D2AB4CD5C8A2A5837EC57FED7660773A05F0DE142380" } }; var messages = vectors.Select(v => uint256.Parse(v[1])).ToArray(); var pubkeys = vectors.Select(v => new PubKey(Encoders.Hex.DecodeData(v[0]))).ToArray(); var signatures = vectors.Select(v => SchnorrSignature.Parse(v[2])).ToArray(); var randoms = Enumerable.Range(0, 2).Select(x => BigInteger.Arbitrary(256)).ToArray(); var ok = SchnorrSigner.BatchVerify(messages, pubkeys, signatures, randoms); Assert.True(ok); }
public void SingningTest() { var vectors = new string[][] { new [] { "Test vector 1", "0000000000000000000000000000000000000000000000000000000000000001", "0279BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", "0000000000000000000000000000000000000000000000000000000000000000", "787A848E71043D280C50470E8E1532B2DD5D20EE912A45DBDD2BD1DFBF187EF67031A98831859DC34DFFEEDDA86831842CCD0079E1F92AF177F7F22CC1DCED05" }, new [] { "Test vector 2", "B7E151628AED2A6ABF7158809CF4F3C762E7160F38B4DA56A784D9045190CFEF", "02DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659", "243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89", "2A298DACAE57395A15D0795DDBFD1DCB564DA82B0F269BC70A74F8220429BA1D1E51A22CCEC35599B8F266912281F8365FFC2D035A230434A1A64DC59F7013FD" }, new [] { "Test vector 3", "C90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B14E5C7", "03FAC2114C2FBB091527EB7C64ECB11F8021CB45E8E7809D3C0938E4B8C0E5F84B", "5E2D58D8B3BCDF1ABADEC7829054F90DDA9805AAB56C77333024B9D0A508B75C", "00DA9B08172A9B6F0466A2DEFD817F2D7AB437E0D253CB5395A963866B3574BE00880371D01766935B92D2AB4CD5C8A2A5837EC57FED7660773A05F0DE142380" } }; var signer = new SchnorrSigner(); foreach (var vector in vectors) { var privatekey = new Key(Encoders.Hex.DecodeData(vector[1])); var publicKey = new PubKey(Encoders.Hex.DecodeData(vector[2])); var message = uint256.Parse(vector[3]); var expectedSignature = SchnorrSignature.Parse(vector[4]); var signature = signer.Sign(message, privatekey); Assert.Equal(expectedSignature.ToBytes(), signature.ToBytes()); Assert.True(signer.Verify(message, publicKey, signature)); Assert.True(signer.Verify(message, privatekey.PubKey, signature)); } }
public void ShouldFailVerifycation() { var vectors = new string[][] { new [] { "Test vector 5", "02DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659", "243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89", "2A298DACAE57395A15D0795DDBFD1DCB564DA82B0F269BC70A74F8220429BA1DFA16AEE06609280A19B67A24E1977E4697712B5FD2943914ECD5F730901B4AB7", "incorrect R residuosity" }, new [] { "Test vector 6", "03FAC2114C2FBB091527EB7C64ECB11F8021CB45E8E7809D3C0938E4B8C0E5F84B", "5E2D58D8B3BCDF1ABADEC7829054F90DDA9805AAB56C77333024B9D0A508B75C", "00DA9B08172A9B6F0466A2DEFD817F2D7AB437E0D253CB5395A963866B3574BED092F9D860F1776A1F7412AD8A1EB50DACCC222BC8C0E26B2056DF2F273EFDEC", "negated message hash" }, new [] { "Test vector 7", "0279BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", "0000000000000000000000000000000000000000000000000000000000000000", "787A848E71043D280C50470E8E1532B2DD5D20EE912A45DBDD2BD1DFBF187EF68FCE5677CE7A623CB20011225797CE7A8DE1DC6CCD4F754A47DA6C600E59543C", "negated s value" }, new [] { "Test vector 8", "03DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659", "243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89", "2A298DACAE57395A15D0795DDBFD1DCB564DA82B0F269BC70A74F8220429BA1D1E51A22CCEC35599B8F266912281F8365FFC2D035A230434A1A64DC59F7013FD", "negated public key" } }; foreach (var vector in vectors) { var publicKey = new PubKey(Encoders.Hex.DecodeData(vector[1])); var message = uint256.Parse(vector[2]); var expectedSignature = SchnorrSignature.Parse(vector[3]); var reason = vector[4]; Assert.False(publicKey.Verify(message, expectedSignature), reason); } }
public void ShouldPassVerifycation() { var publicKey = new PubKey(Encoders.Hex.DecodeData("03DEFDEA4CDB677750A420FEE807EACF21EB9898AE79B9768766E4FAA04A2D4A34")); var message = Parseuint256("4DF3C3F68FCC83B27E9D42C90431A72499F17875C81A599B566C9889B9696703"); var signature = SchnorrSignature.Parse("00000000000000000000003B78CE563F89A0ED9414F5AA28AD0D96D6795F9C6302A8DC32E64E86A333F20EF56EAC9BA30B7246D6D25E22ADB8C6BE1AEB08D49D"); Assert.True(publicKey.Verify(message, signature)); }
public bool VerifySignature(uint256 hash, SchnorrSignature signature) { if (hash == null) { throw new ArgumentNullException(nameof(hash)); } if (signature == null) { throw new ArgumentNullException(nameof(signature)); } return(this.pubkey.SigVerifyBIP340(signature.secpShnorr, hash.ToBytes())); }
public TaprootSignature(SchnorrSignature schnorrSignature, TaprootSigHash sigHash) { if (!TaprootExecutionData.IsValidSigHash((byte)sigHash)) { throw new ArgumentException("Invalid hash_type", nameof(sigHash)); } if (schnorrSignature == null) { throw new ArgumentNullException(nameof(schnorrSignature)); } SigHash = sigHash; SchnorrSignature = schnorrSignature; }
public static bool TryParse(byte[] bytes, [MaybeNullWhen(false)] out TaprootSignature signature) { if (bytes == null) { throw new ArgumentNullException(nameof(bytes)); } #if HAS_SPAN return(TryParse(bytes.AsSpan(), out signature)); #else if (bytes.Length == 64) { if (!SchnorrSignature.TryParse(bytes, out var sig)) { signature = null; return(false); } signature = new TaprootSignature(sig); return(true); } else if (bytes.Length == 65) { if (!TaprootExecutionData.IsValidSigHash(bytes[64]) || bytes[64] == 0) { signature = null; return(false); } var sighash = (TaprootSigHash)bytes[64]; if (sighash == TaprootSigHash.Default) { signature = null; return(false); } var buff = new byte[64]; Array.Copy(bytes, 0, buff, 0, 64); if (!SchnorrSignature.TryParse(buff, out var sig)) { signature = null; return(false); } signature = new TaprootSignature(sig, sighash); return(true); } else { signature = null; return(false); } #endif }
public bool Verify(uint256 hash, SchnorrSignature sig) { if (sig == null) { throw new ArgumentNullException(nameof(sig)); } if (hash == null) { throw new ArgumentNullException(nameof(hash)); } SchnorrSigner signer = new SchnorrSigner(); return(signer.Verify(hash, this, sig)); }
public bool Verify(uint256 hash, SchnorrSignature sig) { if (sig == null) { throw new ArgumentNullException(nameof(sig)); } if (hash == null) { throw new ArgumentNullException(nameof(hash)); } #if HAS_SPAN Span <byte> msg = stackalloc byte[32]; hash.ToBytes(msg); return(ECKey.SigVerifySchnorr(sig.secpShnorr, msg)); #else SchnorrSigner signer = new SchnorrSigner(); return(signer.Verify(hash, this, sig)); #endif }
public static bool TryParse(ReadOnlySpan <byte> bytes, [MaybeNullWhen(false)] out TaprootSignature signature) { if (bytes.Length == 64) { if (!SchnorrSignature.TryParse(bytes, out var sig)) { signature = null; return(false); } signature = new TaprootSignature(sig); return(true); } else if (bytes.Length == 65) { if (!TaprootExecutionData.IsValidSigHash(bytes[64])) { signature = null; return(false); } var sighash = (TaprootSigHash)bytes[64]; if (sighash == TaprootSigHash.Default) { signature = null; return(false); } if (!SchnorrSignature.TryParse(bytes.Slice(0, 64), out var sig)) { signature = null; return(false); } signature = new TaprootSignature(sig, sighash); return(true); } else { signature = null; return(false); } }
public void SchnorrUtilTest() { var msg = new ByteData("e48441762fb75010b2aa31a512b62b4148aa3fb08eb0765d76b252559064a614"); var sk = new Privkey("688c77bc2d5aaff5491cf309d4753b732135470d05b7b2cd21add0744fe97bef"); var pubkey = new SchnorrPubkey("b33cc9edc096d0a83416964bd3c6247b8fecd256e4efa7870d2c854bdeb33390"); var auxRand = new ByteData("02cce08e913f22a36c5648d6405a2c7c50106e7aa2f1649e381c7f09d16b80ab"); var nonce = new ByteData("8c8ca771d3c25eb38de7401818eeda281ac5446f5c1396148f8d9d67592440fe"); var schnorrNonce = new SchnorrPubkey("f14d7e54ff58c5d019ce9986be4a0e8b7d643bd08ef2cdf1099e1a457865b547"); var signature = new SchnorrSignature("6470fd1303dda4fda717b9837153c24a6eab377183fc438f939e0ed2b620e9ee5077c4a8b8dca28963d772a94f5f0ddf598e1c47c137f91933274c7c3edadce8"); var sig = SchnorrUtil.Sign(msg, sk, auxRand); Assert.Equal(signature.ToHexString(), sig.ToHexString()); var expectedSig = "5da618c1936ec728e5ccff29207f1680dcf4146370bdcfab0039951b91e3637a958e91d68537d1f6f19687cec1fd5db1d83da56ef3ade1f3c611babd7d08af42"; var sig2 = SchnorrUtil.SignWithNonce(msg, sk, nonce); Assert.Equal(expectedSig, sig2.ToHexString()); string expectedSigPoint = "03735acf82eef9da1540efb07a68251d5476dabb11ac77054924eccbb4121885e8"; var sigPoint = SchnorrUtil.ComputeSigPoint(msg, schnorrNonce, pubkey); Assert.Equal(expectedSigPoint, sigPoint.ToHexString()); var isVerify = SchnorrUtil.Verify(signature, msg, pubkey); Assert.True(isVerify); var expectedNonce = "6470fd1303dda4fda717b9837153c24a6eab377183fc438f939e0ed2b620e9ee"; var expectedPrivkey = "5077c4a8b8dca28963d772a94f5f0ddf598e1c47c137f91933274c7c3edadce8"; Assert.Equal(expectedNonce, sig.GetNonce().ToHexString()); Assert.Equal(expectedPrivkey, sig.GetKey().ToHexString()); }
public bool VerifyTaproot(uint256 hash, uint256?merkleRoot, SchnorrSignature signature) { return(this.GetTaprootFullPubKey(merkleRoot).OutputKey.VerifySignature(hash, signature)); }
public TaprootSignature(SchnorrSignature schnorrSignature) : this(schnorrSignature, TaprootSigHash.Default) { }