Example #1
0
        public void Extkey_derivation()
        {
            // TODO More test vectors
            var s       = Secp256K1.New();
            var seed    = HexUtil.from_hex("000102030405060708090a0b0c0d0e0f");
            var extk    = ExtendedKey.from_seed(s, seed);
            var derived = extk.Derive(s, 0);
            var sec     = HexUtil.from_hex("d75f70beb2bd3b56f9b064087934bdedee98e4b5aae6280c58b4eff38847888f"
                                           );
            var        secretKey  = SecretKey.From_slice(s, sec);
            var        chaincode  = HexUtil.from_hex("243cb881e1549e714db31d23af45540b13ad07941f64a786bbf3313b4de1df52");
            var        rootKeyId  = HexUtil.from_hex("83e59c48297b78b34b73");
            var        identifier = HexUtil.from_hex("0185adb4d8b730099c93");
            const int  depth      = 1;
            const uint nChild     = 0;

            Assert.Equal(derived.Key.Value, secretKey.Value);
            Assert.Equal(
                derived.Identifier(s).Value,
                Identifier.From_bytes(identifier).Value
                );
            Assert.Equal(
                derived.RootKeyId.Value,
                Identifier.From_bytes(rootKeyId).Value
                );
            Assert.Equal(derived.Chaincode, chaincode);
            Assert.Equal(derived.Depth, depth);
            Assert.Equal(derived.NChild, nChild);
        }
Example #2
0
        public void Test_debug_output()
        {
            var s   = Secp256K1.New();
            var sig = RecoverableSigniture.From_compact(s, new byte[] {
                0x66, 0x73, 0xff, 0xad, 0x21, 0x47, 0x74, 0x1f,
                0x04, 0x77, 0x2b, 0x6f, 0x92, 0x1f, 0x0b, 0xa6,
                0xaf, 0x0c, 0x1e, 0x77, 0xfc, 0x43, 0x9e, 0x65,
                0xc3, 0x6d, 0xed, 0xf4, 0x09, 0x2e, 0x88, 0x98,
                0x4c, 0x1a, 0x97, 0x16, 0x52, 0xe0, 0xad, 0xa8,
                0x80, 0x12, 0x0e, 0xf8, 0x02, 0x5e, 0x70, 0x9f,
                0xff, 0x20, 0x80, 0xc4, 0xa3, 0x9a, 0xae, 0x06,
                0x8d, 0x12, 0xee, 0xd0, 0x09, 0xb6, 0x8c, 0x89
            },
                                                        RecoveryId.from_i32(1));

            //TODO: Finish here
            Assert.Equal("RecoverableSignature(98882e09f4ed6dc3659e43fc771e0cafa60b1f926f2b77041f744721adff7366898cb609d0ee128d06ae9aa3c48020ff9f705e02f80e1280a8ade05216971a4c01)", $"{sig}");

            var msg = Message.from_slice(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8,
                                                      9, 10, 11, 12, 13, 14, 15, 16,
                                                      17, 18, 19, 20, 21, 22, 23, 24,
                                                      25, 26, 27, 28, 29, 30, 31, 255 });

            //TODO: Finish here
            Assert.Equal("Message(0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1fff)", $"{msg}");
        }
Example #3
0
        public void Sign_and_verify_extreme()
        {
            var s = Secp256K1.New();

            s.Randomize(RandomNumberGenerator.Create());

            // Wild keys: 1, CURVE_ORDER - 1
            // Wild msgs: 0, 1, CURVE_ORDER - 1, CURVE_ORDER
            var wildKeys = new byte[32, 2]; // [[0; 32]; 2];
            var wildMsgs = new byte[32, 4]; // [[0; 32]; 4];

            wildKeys[0, 0] = 1;
            wildMsgs[1, 0] = 1;

            //TODO: Finish here
            //use constants;
            //wild_keys[1][..].copy_from_slice(&constants::CURVE_ORDER[..]);
            //wild_msgs[1][..].copy_from_slice(&constants::CURVE_ORDER[..]);
            //wild_msgs[2][..].copy_from_slice(&constants::CURVE_ORDER[..]);

            //wild_keys[1][0] -= 1;
            //wild_msgs[1][0] -= 1;

            //for key in wild_keys.iter().map(| k | SecretKey::from_slice(&s, &k[..]).unwrap()) {
            //    for msg in wild_msgs.iter().map(| m | Message::from_slice(&m[..]).unwrap()) {
            //        var sig = s.sign(&msg, &key).unwrap();
            //        var pk = PublicKey::from_secret_key(&s, &key).unwrap();
            //        assert_eq!(s.verify(&msg, &sig, &pk), Ok(()));
            //    }
            //}
        }
Example #4
0
        public void Sign_and_verify_fail()
        {
            var s = Secp256K1.New();

            s.Randomize(RandomNumberGenerator.Create());

            var msgBytes = ByteUtil.Get_random_bytes(RandomNumberGenerator.Create(), 32);
            var msg      = Message.from_slice(msgBytes);

            var(sk, pk) = s.generate_keypair(RandomNumberGenerator.Create());

            var sigr = s.sign_recoverable(msg, sk);
            var sig  = sigr.To_standard(s);

            var msgBytes2 = ByteUtil.Get_random_bytes(RandomNumberGenerator.Create(), 32);
            var msg2      = Message.from_slice(msgBytes2);

            var ex = Assert.Throws <Exception>(() => { s.Verify(msg2, sig, pk); });

            Assert.Equal("IncorrectSignature", ex.Message);

            var recoveredKey = s.Recover(msg2, sigr);

            Assert.NotEqual(recoveredKey.Value, pk.Value);
        }
Example #5
0
        public void Pubkey_from_slice()
        {
            var secp256K1 = Secp256K1.New();

            var ex = Assert.Throws <Exception>(() => { PublicKey.from_slice(secp256K1, null); });

            Assert.Equal("InvalidPublicKey", ex.Message);

            ex = Assert.Throws <Exception>(() => { PublicKey.from_slice(secp256K1, new byte[] { 1, 2, 3 }); });
            Assert.Equal("InvalidPublicKey", ex.Message);


            var uncompressed = PublicKey.from_slice(secp256K1, new byte[]
            {
                4, 54, 57, 149, 239, 162, 148, 175, 246, 254, 239, 75, 154, 152, 10, 82, 234, 224, 85, 220, 40, 100, 57,
                121, 30, 162, 94, 156, 135, 67, 74, 49, 179, 57, 236, 53, 162, 124, 149, 144, 168, 77, 74, 30, 72, 211,
                229, 110, 111, 55, 96, 193, 86, 227, 183, 152, 195, 155, 51, 247, 123, 113, 60, 228, 188
            });

            Assert.NotEmpty(uncompressed.Value);


            var compressed = PublicKey.from_slice(secp256K1, new byte[]
            {
                3, 23, 183, 225, 206, 31, 159, 148, 195, 42, 67, 115, 146, 41, 248, 140, 11, 3, 51, 41, 111, 180, 110,
                143, 114, 134, 88, 73, 198, 174, 52, 184, 78
            });

            Assert.NotEmpty(compressed.Value);
        }
Example #6
0
        public void Invalid_secret_key()
        {
            var s = Secp256K1.New();

            // Zero
            var ex = Assert.Throws <Exception>(() => { SecretKey.From_slice(s, ByteUtil.Get_bytes(0, 32)); });

            Assert.Equal("InvalidSecretKey", ex.Message);
            // -1
            ex = Assert.Throws <Exception>(() => { SecretKey.From_slice(s, ByteUtil.Get_bytes(0xff, 32)); });
            Assert.Equal("InvalidSecretKey", ex.Message);

            // Top of range
            var sk1 = SecretKey.From_slice(s, new byte[]
            {
                0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE,
                0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B,
                0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x40
            });

            Assert.NotEmpty(sk1.Value);

            // One past top of range
            Assert.Throws <Exception>(() =>
            {
                SecretKey.From_slice(s, new byte[]
                {
                    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE,
                    0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B,
                    0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x41
                });
            });
        }
Example #7
0
        public void Sign()
        {
            var s = Secp256K1.New();

            s.Randomize(RandomNumberGenerator.Create());

            var one = new byte[]
            {
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1
            };

            var sk  = SecretKey.From_slice(s, one);
            var msg = Message.from_slice(one);

            var sig  = s.sign_recoverable(msg, sk);
            var rsig = RecoverableSigniture.From_compact(s, new byte[]
            {
                0x66, 0x73, 0xff, 0xad, 0x21, 0x47, 0x74, 0x1f,
                0x04, 0x77, 0x2b, 0x6f, 0x92, 0x1f, 0x0b, 0xa6,
                0xaf, 0x0c, 0x1e, 0x77, 0xfc, 0x43, 0x9e, 0x65,
                0xc3, 0x6d, 0xed, 0xf4, 0x09, 0x2e, 0x88, 0x98,
                0x4c, 0x1a, 0x97, 0x16, 0x52, 0xe0, 0xad, 0xa8,
                0x80, 0x12, 0x0e, 0xf8, 0x02, 0x5e, 0x70, 0x9f,
                0xff, 0x20, 0x80, 0xc4, 0xa3, 0x9a, 0xae, 0x06,
                0x8d, 0x12, 0xee, 0xd0, 0x09, 0xb6, 0x8c, 0x89
            },
                                                         RecoveryId.from_i32(1));

            Assert.Equal(sig.Value, rsig.Value);
        }
Example #8
0
        public void Invalid_pubkey()
        {
            var s        = Secp256K1.New();
            var sig      = RecoverableSigniture.From_compact(s, ByteUtil.Get_bytes(1, 64), RecoveryId.from_i32(0));
            var pk       = PublicKey.New();
            var msgBytes = ByteUtil.Get_random_bytes(RandomNumberGenerator.Create(), 32);
            var msg      = Message.from_slice(msgBytes);
            var ex       = Assert.Throws <Exception>(() => { s.Verify(msg, sig.To_standard(s), pk); });

            Assert.Equal("InvalidPublicKey", ex.Message);
        }
Example #9
0
        public void Sign_with_recovery()
        {
            var s = Secp256K1.New();

            s.Randomize(RandomNumberGenerator.Create());

            var msgBytes = ByteUtil.Get_random_bytes(RandomNumberGenerator.Create(), 32);
            var msg      = Message.from_slice(msgBytes);

            var(sk, pk) = s.generate_keypair(RandomNumberGenerator.Create());

            var sig = s.sign_recoverable(msg, sk);

            Assert.Equal(s.Recover(msg, sig).Value, pk.Value);
        }
Example #10
0
        public void Keypair_slice_round_trip()
        {
            var secp256K1 = Secp256K1.New();

            // ReSharper disable once JoinDeclarationAndInitializer
            SecretKey sk;

            var ex = Assert.Throws <Exception>(
                () => { sk = SecretKey.From_slice(secp256K1, ByteUtil.Get_bytes(1, 31)); });

            Assert.Equal("InvalidSecretKey", ex.Message);

            sk = SecretKey.From_slice(secp256K1, ByteUtil.Get_bytes(1, 32));

            Assert.NotEmpty(sk.Value);
        }
Example #11
0
        public void Test_addition()
        {
            var s = Secp256K1.New();

            var(sk1, pk1) = s.generate_keypair(RandomNumberGenerator.Create());
            var(sk2, pk2) = s.generate_keypair(RandomNumberGenerator.Create());

            Assert.Equal(PublicKey.from_secret_key(s, sk1).Value, pk1.Value);
            sk1.Add_assign(s, sk2);
            pk1.add_exp_assign(s, sk2);
            Assert.Equal(PublicKey.from_secret_key(s, sk1).Value, pk1.Value);

            Assert.Equal(PublicKey.from_secret_key(s, sk2).Value, pk2.Value);
            sk2.Add_assign(s, sk1);
            pk2.add_exp_assign(s, sk1);
            Assert.Equal(PublicKey.from_secret_key(s, sk2).Value, pk2.Value);
        }
Example #12
0
        public void Pubkey_hash()
        {
            var s   = Secp256K1.New();
            var set = new HashSet <byte[]>();

            const int usize = 1024;

            for (var i = 0; i <= usize; i++)
            {
                var kp = s.generate_keypair(RandomNumberGenerator.Create());

                var hash = Hash(kp.publicKey.Value);

                Assert.DoesNotContain(hash, set);

                set.Add(hash);
            }
        }
Example #13
0
        public void Test_pubkey_from_bad_slice()
        {
            var s = Secp256K1.New();

            // Bad sizes
            Assert.Throws <Exception>(() =>
            {
                PublicKey.from_slice(s, ByteUtil.Get_bytes(0, Constants.Constants.PublicKeySize - 1));
            });

            Assert.Throws <Exception>(() =>
            {
                PublicKey.from_slice(s, ByteUtil.Get_bytes(0, Constants.Constants.PublicKeySize + 1));
            });

            Assert.Throws <Exception>(() =>
            {
                PublicKey.from_slice(s, ByteUtil.Get_bytes(0, Constants.Constants.CompressedPublicKeySize + 1));
            });

            Assert.Throws <Exception>(() =>
            {
                PublicKey.from_slice(s,
                                     ByteUtil.Get_bytes(0, Constants.Constants.UncompressedPublicKeySize - 1));
            });

            Assert.Throws <Exception>(() =>
            {
                PublicKey.from_slice(s,
                                     ByteUtil.Get_bytes(0, Constants.Constants.UncompressedPublicKeySize + 1));
            });

            //// Bad parse

            Assert.Throws <Exception>(() =>
            {
                PublicKey.from_slice(s, ByteUtil.Get_bytes(0xff, Constants.Constants.UncompressedPublicKeySize));
            });

            Assert.Throws <Exception>(() =>
            {
                PublicKey.from_slice(s, ByteUtil.Get_bytes(0x55, Constants.Constants.CompressedPublicKeySize));
            });
        }
Example #14
0
        public void Test_bad_slice()
        {
            var s = Secp256K1.New();

            var ex = Assert.Throws <Exception>(() => { Signiture.from_der(s, new byte[Constants.Constants.MaxSignatureSize + 1]); });

            Assert.Equal("InvalidSignature", ex.Message);

            ex = Assert.Throws <Exception>(() => { Signiture.from_der(s, new byte[Constants.Constants.MaxSignatureSize]); });
            Assert.Equal("InvalidSignature", ex.Message);

            ex = Assert.Throws <Exception>(() => { Message.from_slice(new byte[Constants.Constants.MessageSize - 1]); });
            Assert.Equal("InvalidMessage", ex.Message);

            ex = Assert.Throws <Exception>(() => { Message.from_slice(new byte[Constants.Constants.MessageSize + 1]); });
            Assert.Equal("InvalidMessage", ex.Message);

            Message.from_slice(new byte[Constants.Constants.MessageSize]);
        }
Example #15
0
        public void Sign_and_verify()
        {
            var s = Secp256K1.New();

            s.Randomize(RandomNumberGenerator.Create());

            for (var i = 0; i <= 100; i++)
            {
                var msgBytes = ByteUtil.Get_random_bytes(RandomNumberGenerator.Create(), 32);
                var msg      = Message.from_slice(msgBytes);

                var(sk, pk) = s.generate_keypair(RandomNumberGenerator.Create());


                var sig = s.Sign(msg, sk);

                s.Verify(msg, sig, pk);
            }
        }
Example #16
0
        public void Test_multiplication()
        {
            var s = Secp256K1.New();

            var(sk1, pk1) = s.generate_keypair(RandomNumberGenerator.Create());
            var(sk2, pk2) = s.generate_keypair(RandomNumberGenerator.Create());

            Assert.Equal(PublicKey.from_secret_key(s, sk1).Value, pk1.Value);
            sk1.Mul_assign(s, sk2);
            pk1.mul_assign(s, sk2);
            Assert.Equal(PublicKey.from_secret_key(s, sk1).Value, pk1.Value);

            var pp = PublicKey.from_secret_key(s, sk2);

            Assert.Equal(pp.Value, pk2.Value);
            sk2.Mul_assign(s, sk1);
            pk2.mul_assign(s, sk1);
            Assert.Equal(PublicKey.from_secret_key(s, sk2).Value, pk2.Value);
        }
Example #17
0
        public void Signature_serialize_roundtrip()
        {
            var s = Secp256K1.New();

            s.Randomize(RandomNumberGenerator.Create());


            for (var i = 0; i <= 100; i++)
            {
                var msgBytes = ByteUtil.Get_random_bytes(RandomNumberGenerator.Create(), 32);
                var msg      = Message.from_slice(msgBytes);

                var kp = s.generate_keypair(RandomNumberGenerator.Create());
                var sk = kp.secretKey;

                var sig1 = s.Sign(msg, sk);
                var der  = sig1.serialize_der(s);
                var sig2 = Signiture.from_der(s, der);
                Assert.Equal(sig1.Value, sig2.Value);

                var compact = sig1.serialize_compact(s);
                var sig3    = Signiture.from_compact(s, compact);

                Assert.Equal(sig1.Value, sig3.Value);

                //round_trip_serde!(sig1);

                var ex = Assert.Throws <Exception>(() => { Signiture.from_compact(s, der); });
                Assert.Equal("InvalidSignature", ex.Message);

                ex = Assert.Throws <Exception>(() => { Signiture.from_compact(s, compact.Take(5).ToArray()); });
                Assert.Equal("InvalidSignature", ex.Message);


                ex = Assert.Throws <Exception>(() => { Signiture.from_der(s, compact); });
                Assert.Equal("InvalidSignature", ex.Message);


                ex = Assert.Throws <Exception>(() => { Signiture.from_der(s, der.Take(5).ToArray()); });
                Assert.Equal("InvalidSignature", ex.Message);
            }
        }
Example #18
0
        public void Bad_recovery()
        {
            var s = Secp256K1.New();

            s.Randomize(RandomNumberGenerator.Create());

            var msgBytes = ByteUtil.Get_bytes(0x55, 32);
            var msg      = Message.from_slice(msgBytes);

            // Zero is not a valid sig
            var sig = RecoverableSigniture.From_compact(s, new byte[64], RecoveryId.from_i32(0));
            var ex  = Assert.Throws <Exception>(() => { s.Recover(msg, sig); });

            Assert.Equal("InvalidSignature", ex.Message);

            // ...but 111..111 is
            var sig2 = RecoverableSigniture.From_compact(s, ByteUtil.Get_bytes(1, 64), RecoveryId.from_i32(0));

            s.Recover(msg, sig2);
        }
Example #19
0
        public void Test_low_s()
        {
            // nb this is a transaction on testnet
            // txid 8ccc87b72d766ab3128f03176bb1c98293f2d1f85ebfaf07b82cc81ea6891fa9
            // input number 3
            var sigBytes = HexUtil.from_hex("3046022100839c1fbc5304de944f697c9f4b1d01d1faeba32d751c0f7acb21ac8a0f436a72022100e89bd46bb3a5a62adc679f659b7ce876d83ee297c7a5587b2011c4fcc72eab45");
            var pkBytes  = HexUtil.from_hex("031ee99d2b786ab3b0991325f2de8489246a6a3fdb700f6d0511b1d80cf5f4cd43");
            var msgBytes = HexUtil.from_hex("a4965ca63b7d8562736ceec36dfa5a11bf426eb65be8ea3f7a49ae363032da0d");

            var secp = Secp256K1.New();
            var sig  = Signiture.from_der(secp, sigBytes);
            var pk   = PublicKey.from_slice(secp, pkBytes);
            var msg  = Message.from_slice(msgBytes);

            // without normalization we expect this will fail
            var ex = Assert.Throws <Exception>(() => { secp.Verify(msg, sig, pk); });

            Assert.Equal("IncorrectSignature", ex.Message);
            // after normalization it should pass
            sig.normalize_s(secp);
            secp.Verify(msg, sig, pk);
        }
Example #20
0
        public void Extkey_from_seed()
        {
            // TODO More test vectors
            var s         = Secp256K1.New();
            var seed      = HexUtil.from_hex("000102030405060708090a0b0c0d0e0f");
            var extk      = ExtendedKey.from_seed(s, seed);
            var sec       = HexUtil.from_hex("c3f5ae520f474b390a637de4669c84d0ed9bbc21742577fac930834d3c3083dd");
            var secretKey = SecretKey.From_slice(s, sec);
            var chaincode = HexUtil.from_hex("e7298e68452b0c6d54837670896e1aee76b118075150d90d4ee416ece106ae72");


            var        identifier = HexUtil.from_hex("83e59c48297b78b34b73");
            const int  depth      = 0;
            const uint nChild     = 0;

            Assert.Equal(extk.Key.Value, secretKey.Value);
            Assert.Equal(extk.Identifier(s).Value, Identifier.From_bytes(identifier).Value);
            Assert.Equal(extk.RootKeyId.Value, Identifier.From_bytes(identifier).Value);
            Assert.Equal(extk.Chaincode, chaincode);
            Assert.Equal(extk.Depth, depth);
            Assert.Equal(extk.NChild, nChild);
        }
Example #21
0
        public void Test_recov_sig_serialize_compact()
        {
            var s = Secp256K1.New();

            var recidIn = RecoveryId.from_i32(1);
            var bytesIn = new byte[]
            {
                0x66, 0x73, 0xff, 0xad, 0x21, 0x47, 0x74, 0x1f,
                0x04, 0x77, 0x2b, 0x6f, 0x92, 0x1f, 0x0b, 0xa6,
                0xaf, 0x0c, 0x1e, 0x77, 0xfc, 0x43, 0x9e, 0x65,
                0xc3, 0x6d, 0xed, 0xf4, 0x09, 0x2e, 0x88, 0x98,
                0x4c, 0x1a, 0x97, 0x16, 0x52, 0xe0, 0xad, 0xa8,
                0x80, 0x12, 0x0e, 0xf8, 0x02, 0x5e, 0x70, 0x9f,
                0xff, 0x20, 0x80, 0xc4, 0xa3, 0x9a, 0xae, 0x06,
                0x8d, 0x12, 0xee, 0xd0, 0x09, 0xb6, 0x8c, 0x89
            };
            var sig = RecoverableSigniture.From_compact(
                s, bytesIn, recidIn);

            var(recidOut, bytesOut) = sig.Serialize_compact(s);
            Assert.Equal(recidIn.Value, recidOut.Value);
            Assert.Equal(bytesIn, bytesOut);
        }