|
| 1 | +using System; |
| 2 | +using System.Collections.Generic; |
| 3 | +using System.IO; |
| 4 | +using System.Linq; |
| 5 | +using NBitcoin.BouncyCastle.Math; |
| 6 | +using NBitcoin.Crypto; |
| 7 | +using NBitcoin.DataEncoders; |
| 8 | +#if HAS_SPAN |
| 9 | +using NBitcoin.Secp256k1; |
| 10 | +#endif |
| 11 | +using Xunit; |
| 12 | + |
| 13 | +namespace NBitcoin.Tests |
| 14 | +{ |
| 15 | + public class SchnorrSignerTests |
| 16 | + { |
| 17 | + [Fact] |
| 18 | + public void SingningTest() |
| 19 | + { |
| 20 | + var vectors = new string[][]{ |
| 21 | + new []{"Test vector 1", |
| 22 | + "0000000000000000000000000000000000000000000000000000000000000001", |
| 23 | + "0279BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", |
| 24 | + "0000000000000000000000000000000000000000000000000000000000000000", |
| 25 | + "787A848E71043D280C50470E8E1532B2DD5D20EE912A45DBDD2BD1DFBF187EF67031A98831859DC34DFFEEDDA86831842CCD0079E1F92AF177F7F22CC1DCED05"}, |
| 26 | + new []{"Test vector 2", |
| 27 | + "B7E151628AED2A6ABF7158809CF4F3C762E7160F38B4DA56A784D9045190CFEF", |
| 28 | + "02DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659", |
| 29 | + "243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89", |
| 30 | + "2A298DACAE57395A15D0795DDBFD1DCB564DA82B0F269BC70A74F8220429BA1D1E51A22CCEC35599B8F266912281F8365FFC2D035A230434A1A64DC59F7013FD"}, |
| 31 | + new []{"Test vector 3", |
| 32 | + "C90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B14E5C7", |
| 33 | + "03FAC2114C2FBB091527EB7C64ECB11F8021CB45E8E7809D3C0938E4B8C0E5F84B", |
| 34 | + "5E2D58D8B3BCDF1ABADEC7829054F90DDA9805AAB56C77333024B9D0A508B75C", |
| 35 | + "00DA9B08172A9B6F0466A2DEFD817F2D7AB437E0D253CB5395A963866B3574BE00880371D01766935B92D2AB4CD5C8A2A5837EC57FED7660773A05F0DE142380"} |
| 36 | + }; |
| 37 | + |
| 38 | + foreach (var vector in vectors) |
| 39 | + { |
| 40 | + var privatekey = new Key(Encoders.Hex.DecodeData(vector[1])); |
| 41 | + var publicKey = new PubKey(Encoders.Hex.DecodeData(vector[2])); |
| 42 | + var message = Parseuint256(vector[3]); |
| 43 | + var expectedSignature = SchnorrSignature.Parse(vector[4]); |
| 44 | + |
| 45 | + var signature = privatekey.SignSchnorr(message); |
| 46 | + Assert.Equal(expectedSignature.ToBytes(), signature.ToBytes()); |
| 47 | + |
| 48 | + Assert.True(publicKey.Verify(message, expectedSignature)); |
| 49 | + Assert.True(privatekey.PubKey.Verify(message, expectedSignature)); |
| 50 | + } |
| 51 | + } |
| 52 | + |
| 53 | + [Fact] |
| 54 | + public void ShouldPassVerifycation() |
| 55 | + { |
| 56 | + var publicKey = new PubKey(Encoders.Hex.DecodeData("03DEFDEA4CDB677750A420FEE807EACF21EB9898AE79B9768766E4FAA04A2D4A34")); |
| 57 | + var message = Parseuint256("4DF3C3F68FCC83B27E9D42C90431A72499F17875C81A599B566C9889B9696703"); |
| 58 | + var signature = SchnorrSignature.Parse("00000000000000000000003B78CE563F89A0ED9414F5AA28AD0D96D6795F9C6302A8DC32E64E86A333F20EF56EAC9BA30B7246D6D25E22ADB8C6BE1AEB08D49D"); |
| 59 | + Assert.True(publicKey.Verify(message, signature)); |
| 60 | + } |
| 61 | + |
| 62 | + private uint256 Parseuint256(string hex) |
| 63 | + { |
| 64 | + var message = uint256.Parse(hex); |
| 65 | + return new uint256(message.ToBytes(false)); |
| 66 | + } |
| 67 | + |
| 68 | + [Fact] |
| 69 | + public void ShouldFailVerifycation() |
| 70 | + { |
| 71 | + var vectors = new string[][]{ |
| 72 | + new []{"Test vector 5", |
| 73 | + "02DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659", |
| 74 | + "243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89", |
| 75 | + "2A298DACAE57395A15D0795DDBFD1DCB564DA82B0F269BC70A74F8220429BA1DFA16AEE06609280A19B67A24E1977E4697712B5FD2943914ECD5F730901B4AB7", |
| 76 | + "incorrect R residuosity"}, |
| 77 | + new []{"Test vector 6", |
| 78 | + "03FAC2114C2FBB091527EB7C64ECB11F8021CB45E8E7809D3C0938E4B8C0E5F84B", |
| 79 | + "5E2D58D8B3BCDF1ABADEC7829054F90DDA9805AAB56C77333024B9D0A508B75C", |
| 80 | + "00DA9B08172A9B6F0466A2DEFD817F2D7AB437E0D253CB5395A963866B3574BED092F9D860F1776A1F7412AD8A1EB50DACCC222BC8C0E26B2056DF2F273EFDEC", |
| 81 | + "negated message hash"}, |
| 82 | + new []{"Test vector 7", |
| 83 | + "0279BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", |
| 84 | + "0000000000000000000000000000000000000000000000000000000000000000", |
| 85 | + "787A848E71043D280C50470E8E1532B2DD5D20EE912A45DBDD2BD1DFBF187EF68FCE5677CE7A623CB20011225797CE7A8DE1DC6CCD4F754A47DA6C600E59543C", |
| 86 | + "negated s value"}, |
| 87 | + new []{"Test vector 8", |
| 88 | + "03DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659", |
| 89 | + "243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89", |
| 90 | + "2A298DACAE57395A15D0795DDBFD1DCB564DA82B0F269BC70A74F8220429BA1D1E51A22CCEC35599B8F266912281F8365FFC2D035A230434A1A64DC59F7013FD", |
| 91 | + "negated public key"} |
| 92 | + }; |
| 93 | + |
| 94 | + foreach (var vector in vectors) |
| 95 | + { |
| 96 | + var publicKey = new PubKey(Encoders.Hex.DecodeData(vector[1])); |
| 97 | + var message = uint256.Parse(vector[2]); |
| 98 | + var expectedSignature = SchnorrSignature.Parse(vector[3]); |
| 99 | + var reason = vector[4]; |
| 100 | + |
| 101 | + Assert.False(publicKey.Verify(message, expectedSignature), reason); |
| 102 | + } |
| 103 | + } |
| 104 | + |
| 105 | + [Fact] |
| 106 | + public void ShouldPassBatchVerifycation() |
| 107 | + { |
| 108 | + var vectors = new string[][]{ |
| 109 | + new []{ |
| 110 | + "0279BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", |
| 111 | + "0000000000000000000000000000000000000000000000000000000000000000", |
| 112 | + "787A848E71043D280C50470E8E1532B2DD5D20EE912A45DBDD2BD1DFBF187EF67031A98831859DC34DFFEEDDA86831842CCD0079E1F92AF177F7F22CC1DCED05"}, |
| 113 | + new []{ |
| 114 | + "02DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659", |
| 115 | + "243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89", |
| 116 | + "2A298DACAE57395A15D0795DDBFD1DCB564DA82B0F269BC70A74F8220429BA1D1E51A22CCEC35599B8F266912281F8365FFC2D035A230434A1A64DC59F7013FD"}, |
| 117 | + new []{ |
| 118 | + "03FAC2114C2FBB091527EB7C64ECB11F8021CB45E8E7809D3C0938E4B8C0E5F84B", |
| 119 | + "5E2D58D8B3BCDF1ABADEC7829054F90DDA9805AAB56C77333024B9D0A508B75C", |
| 120 | + "00DA9B08172A9B6F0466A2DEFD817F2D7AB437E0D253CB5395A963866B3574BE00880371D01766935B92D2AB4CD5C8A2A5837EC57FED7660773A05F0DE142380"} |
| 121 | + }; |
| 122 | + |
| 123 | + var messages = vectors.Select(v => Parseuint256(v[1])).ToArray(); |
| 124 | + var pubkeys = vectors.Select(v => new PubKey(Encoders.Hex.DecodeData(v[0]))).ToArray(); |
| 125 | + var signatures = vectors.Select(v => SchnorrSignature.Parse(v[2])).ToArray(); |
| 126 | + |
| 127 | + var randoms = Enumerable.Range(0, 2).Select(x => BigInteger.Arbitrary(256)).ToArray(); |
| 128 | + var ok = SchnorrSigner.BatchVerify(messages, pubkeys, signatures, randoms); |
| 129 | + Assert.True(ok); |
| 130 | + } |
| 131 | + } |
| 132 | +} |
0 commit comments