text:
package org.bitcoinj.core;

import org.bitcoinj.core.ECKey.ECDSASignature;
import org.bitcoinj.crypto.EncryptedData;
import org.bitcoinj.crypto.KeyCrypter;
import org.bitcoinj.crypto.KeyCrypterScrypt;
import org.bitcoinj.crypto.TransactionSignature;
import org.bitcoinj.params.MainNetParams;
import org.bitcoinj.params.TestNet3Params;
import org.bitcoinj.params.UnitTestParams;
import com.google.common.collect.Lists;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
import org.junit.Before;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.bouncycastle.crypto.params.KeyParameter;

import java.io.InputStream;
import java.math.BigInteger;
import java.security.SignatureException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;

import static org.bitcoinj.core.Utils.HEX;
import static org.bitcoinj.core.Utils.reverseBytes;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.junit.Assert.*;

public class ECKeyTest {
    private static final Logger log = LoggerFactory.getLogger(ECKeyTest.class);

    private KeyCrypter keyCrypter;

    private static final int SCRYPT_ITERATIONS = 256;
    private static CharSequence PASSWORD1 = "my hovercraft has eels";
    private static CharSequence WRONG_PASSWORD = "it is a snowy day today";
    private static final NetworkParameters TESTNET = TestNet3Params.get();
    private static final NetworkParameters MAINNET = MainNetParams.get();
    private static final NetworkParameters UNITTEST = UnitTestParams.get();

    @Before
    public void setUp() throws Exception {
        keyCrypter = new KeyCrypterScrypt(SCRYPT_ITERATIONS);
    }

    @Test
    public void sValue() throws Exception {
        // Check that we never generate an S value that is larger than half the curve order. This avoids a malleability
        // issue that can allow someone to change a transaction [hash] without invalidating the signature.
        final int ITERATIONS = 10;
        ListeningExecutorService executor = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(ITERATIONS));
        List<ListenableFuture<ECKey.ECDSASignature>> sigFutures = new ArrayList<>();
        final ECKey key = new ECKey();
        for (byte i = 0; i < ITERATIONS; i++) {
            final Sha256Hash hash = Sha256Hash.of(new byte[]{i});
            sigFutures.add(executor.submit(new Callable<ECKey.ECDSASignature>() {
                @Override
                public ECKey.ECDSASignature call() throws Exception {
                    return key.sign(hash);
                }
            }));
        }
        List<ECKey.ECDSASignature> sigs = Futures.allAsList(sigFutures).get();
        for (ECKey.ECDSASignature signature : sigs) {
            assertTrue(signature.isCanonical());
        }
        final ECDSASignature first = sigs.get(0);
        final ECKey.ECDSASignature duplicate = new ECKey.ECDSASignature(first.r, first.s);
        assertEquals(first, duplicate);
        assertEquals(first.hashCode(), duplicate.hashCode());

        final ECKey.ECDSASignature highS = new ECKey.ECDSASignature(first.r, ECKey.CURVE.getN().subtract(first.s));
        assertFalse(highS.isCanonical());
    }

    @Test
    public void testSignatures() throws Exception {
        // Test that we can construct an ECKey from a private key (deriving the public from the private), then signing
        // a message with it.
        BigInteger privkey = new BigInteger(1, HEX.decode("180cb41c7c600be951b5d3d0a7334acc7506173875834f7a6c4c786a28fcbb19"));
        ECKey key = ECKey.fromPrivate(privkey);
        byte[] output = key.sign(Sha256Hash.ZERO_HASH).encodeToDER();
        assertTrue(key.verify(Sha256Hash.ZERO_HASH.getBytes(), output));

        // Test interop with a signature from elsewhere.
        byte[] sig = HEX.decode(
                "3046022100dffbc26774fc841bbe1c1362fd643609c6e42dcb274763476d87af2c0597e89e022100c59e3c13b96b316cae9fa0ab0260612c7a133a6fe2b3445b6bf80b3123bf274d");
        assertTrue(key.verify(Sha256Hash.ZERO_HASH.getBytes(), sig));
    }

    @Test
    public void testASN1Roundtrip() throws Exception {
        byte[] privkeyASN1 = HEX.decode(
                "3082011302010104205c0b98e524ad188ddef35dc6abba13c34a351a05409e5d285403718b93336a4aa081a53081a2020101302c06072a8648ce3d0101022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f300604010004010704410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141020101a144034200042af7a2aafe8dafd7dc7f9cfb58ce09bda7dce28653ab229b98d1d3d759660c672dd0db18c8c2d76aa470448e876fc2089ab1354c01a6e72cefc50915f4a963ee");
        ECKey decodedKey = ECKey.fromASN1(privkeyASN1);

        // Now re-encode and decode the ASN.1 to see if it is equivalent (it does not produce the exact same byte
        // sequence, some integers are padded now).
        ECKey roundtripKey = ECKey.fromASN1(decodedKey.toASN1());

        assertArrayEquals(decodedKey.getPrivKeyBytes(), roundtripKey.getPrivKeyBytes());

        for (ECKey key : new ECKey[] {decodedKey, roundtripKey}) {
            byte[] message = reverseBytes(HEX.decode(
                    "11da3761e86431e4a54c176789e41f1651b324d240d599a7067bee23d328ec2a"));
            byte[] output = key.sign(Sha256Hash.wrap(message)).encodeToDER();
            assertTrue(key.verify(message, output));

            output = HEX.decode(
                    "304502206faa2ebc614bf4a0b31f0ce4ed9012eb193302ec2bcaccc7ae8bb40577f47549022100c73a1a1acc209f3f860bf9b9f5e13e9433db6f8b7bd527a088a0e0cd0a4c83e9");
            assertTrue(key.verify(message, output));
        }

        // Try to sign with one key and verify with the other.
        byte[] message = reverseBytes(HEX.decode(
            "11da3761e86431e4a54c176789e41f1651b324d240d599a7067bee23d328ec2a"));
        assertTrue(roundtripKey.verify(message, decodedKey.sign(Sha256Hash.wrap(message)).encodeToDER()));
        assertTrue(decodedKey.verify(message, roundtripKey.sign(Sha256Hash.wrap(message)).encodeToDER()));
    }

    @Test
    public void testKeyPairRoundtrip() throws Exception {
        byte[] privkeyASN1 = HEX.decode(
                "3082011302010104205c0b98e524ad188ddef35dc6abba13c34a351a05409e5d285403718b93336a4aa081a53081a2020101302c06072a8648ce3d0101022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f300604010004010704410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141020101a144034200042af7a2aafe8dafd7dc7f9cfb58ce09bda7dce28653ab229b98d1d3d759660c672dd0db18c8c2d76aa470448e876fc2089ab1354c01a6e72cefc50915f4a963ee");
        ECKey decodedKey = ECKey.fromASN1(privkeyASN1);

        // Now re-encode and decode the ASN.1 to see if it is equivalent (it does not produce the exact same byte
        // sequence, some integers are padded now).
        ECKey roundtripKey =
            ECKey.fromPrivateAndPrecalculatedPublic(decodedKey.getPrivKey(), decodedKey.getPubKeyPoint());

        for (ECKey key : new ECKey[] {decodedKey, roundtripKey}) {
            byte[] message = reverseBytes(HEX.decode(
                    "11da3761e86431e4a54c176789e41f1651b324d240d599a7067bee23d328ec2a"));
            byte[] output = key.sign(Sha256Hash.wrap(message)).encodeToDER();
            assertTrue(key.verify(message, output));

            output = HEX.decode(
                    "304502206faa2ebc614bf4a0b31f0ce4ed9012eb193302ec2bcaccc7ae8bb40577f47549022100c73a1a1acc209f3f860bf9b9f5e13e9433db6f8b7bd527a088a0e0cd0a4c83e9");
            assertTrue(key.verify(message, output));
        }

        // Try to sign with one key and verify with the other.
        byte[] message = reverseBytes(HEX.decode(
            "11da3761e86431e4a54c176789e41f1651b324d240d599a7067bee23d328ec2a"));
        assertTrue(roundtripKey.verify(message, decodedKey.sign(Sha256Hash.wrap(message)).encodeToDER()));
        assertTrue(decodedKey.verify(message, roundtripKey.sign(Sha256Hash.wrap(message)).encodeToDER()));

        // Verify bytewise equivalence of public keys (i.e. compression state is preserved)
        ECKey key = new ECKey();
        ECKey key2 = ECKey.fromASN1(key.toASN1());
        assertArrayEquals(key.getPubKey(), key2.getPubKey());
    }

    @Test
    public void base58Encoding() throws Exception {
        String addr = "mqAJmaxMcG5pPHHc3H3NtyXzY7kGbJLuMF";
        String privkey = "92shANodC6Y4evT5kFzjNFQAdjqTtHAnDTLzqBBq4BbKUPyx6CD";
        ECKey key = DumpedPrivateKey.fromBase58(TESTNET, privkey).getKey();
        assertEquals(privkey, key.getPrivateKeyEncoded(TESTNET).toString());
        assertEquals(addr, LegacyAddress.fromKey(TESTNET, key).toString());
    }

    @Test
    public void base58Encoding_leadingZero() throws Exception {
        String privkey = "91axuYLa8xK796DnBXXsMbjuc8pDYxYgJyQMvFzrZ6UfXaGYuqL";
        ECKey key = DumpedPrivateKey.fromBase58(TESTNET, privkey).getKey();
        assertEquals(privkey, key.getPrivateKeyEncoded(TESTNET).toString());
        assertEquals(0, key.getPrivKeyBytes()[0]);
    }

    @Test
    public void base58Encoding_stress() throws Exception {
        // Replace the loop bound with 1000 to get some keys with leading zero byte
        for (int i = 0 ; i < 20 ; i++) {
            ECKey key = new ECKey();
            ECKey key1 = DumpedPrivateKey.fromBase58(TESTNET,
                    key.getPrivateKeyEncoded(TESTNET).toString()).getKey();
            assertEquals(Utils.HEX.encode(key.getPrivKeyBytes()),
                    Utils.HEX.encode(key1.getPrivKeyBytes()));
        }
    }

    @Test
    public void signTextMessage() throws Exception {
        ECKey key = new ECKey();
        String message = "聡中本";
        String signatureBase64 = key.signMessage(message);
        log.info("Message signed with " + LegacyAddress.fromKey(MAINNET, key) + ": " + signatureBase64);
        // Should verify correctly.
        key.verifyMessage(message, signatureBase64);
        try {
            key.verifyMessage("Evil attacker says hello!", signatureBase64);
            fail();
        } catch (SignatureException e) {
            // OK.
        }
    }

    @Test
    public void verifyMessage() throws Exception {
        // Test vector generated by Bitcoin-Qt.
        String message = "hello";
        String sigBase64 = "HxNZdo6ggZ41hd3mM3gfJRqOQPZYcO8z8qdX2BwmpbF11CaOQV+QiZGGQxaYOncKoNW61oRuSMMF8udfK54XqI8=";
        Address expectedAddress = LegacyAddress.fromBase58(MAINNET, "14YPSNPi6NSXnUxtPAsyJSuw3pv7AU3Cag");
        ECKey key = ECKey.signedMessageToKey(message, sigBase64);
        Address gotAddress = LegacyAddress.fromKey(MAINNET, key);
        assertEquals(expectedAddress, gotAddress);
    }

    @Test
    public void findRecoveryId() {
        ECKey key = new ECKey();
        String message = "Hello World!";
        Sha256Hash hash = Sha256Hash.of(message.getBytes());
        ECKey.ECDSASignature sig = key.sign(hash);
        key = ECKey.fromPublicOnly(key.getPubKeyPoint());

        List<Byte> possibleRecIds = Lists.newArrayList((byte) 0, (byte) 1, (byte) 2, (byte) 3);
        byte recId = key.findRecoveryId(hash, sig);
        assertTrue(possibleRecIds.contains(recId));
    }

    @Test
    public void keyRecoveryTestVector() {
        // a test that exercises key recovery with findRecoveryId() on a test vector
        // test vector from https://crypto.stackexchange.com/a/41339
        ECKey key = ECKey.fromPrivate(
                new BigInteger("ebb2c082fd7727890a28ac82f6bdf97bad8de9f5d7c9028692de1a255cad3e0f", 16));
        String message = "Maarten Bodewes generated this test vector on 2016-11-08";
        Sha256Hash hash = Sha256Hash.of(message.getBytes());
        ECKey.ECDSASignature sig = key.sign(hash);
        key = ECKey.fromPublicOnly(key.getPubKeyPoint());

        byte recId = key.findRecoveryId(hash, sig);
        byte expectedRecId = 0;
        assertEquals(recId, expectedRecId);

        ECKey pubKey = ECKey.fromPublicOnly(key.getPubKeyPoint());
        ECKey recoveredKey = ECKey.recoverFromSignature(recId, sig, hash, true);
        assertEquals(recoveredKey, pubKey);
    }

    @Test
    public void keyRecoveryWithFindRecoveryId() throws Exception {
        ECKey key = new ECKey();
        String message = "Hello World!";
        Sha256Hash hash = Sha256Hash.of(message.getBytes());
        ECKey.ECDSASignature sig = key.sign(hash);

        byte recId = key.findRecoveryId(hash, sig);
        ECKey pubKey = ECKey.fromPublicOnly(key.getPubKeyPoint());
        ECKey recoveredKey = ECKey.recoverFromSignature(recId, sig, hash, true);
        assertEquals(recoveredKey, pubKey);
    }

    @Test
    public void keyRecovery() throws Exception {
        ECKey key = new ECKey();
        String message = "Hello World!";
        Sha256Hash hash = Sha256Hash.of(message.getBytes());
        ECKey.ECDSASignature sig = key.sign(hash);
        key = ECKey.fromPublicOnly(key.getPubKeyPoint());
        boolean found = false;
        for (int i = 0; i < 4; i++) {
            ECKey key2 = ECKey.recoverFromSignature(i, sig, hash, true);
            checkNotNull(key2);
            if (key.equals(key2)) {
                found = true;
                break;
            }
        }
        assertTrue(found);
    }

    @Test
    public void testUnencryptedCreate() throws Exception {
        Utils.setMockClock();
        ECKey key = new ECKey();
        long time = key.getCreationTimeSeconds();
        assertNotEquals(0, time);
        assertTrue(!key.isEncrypted());
        byte[] originalPrivateKeyBytes = key.getPrivKeyBytes();
        ECKey encryptedKey = key.encrypt(keyCrypter, keyCrypter.deriveKey(PASSWORD1));
        assertEquals(time, encryptedKey.getCreationTimeSeconds());
        assertTrue(encryptedKey.isEncrypted());
        assertNull(encryptedKey.getSecretBytes());
        key = encryptedKey.decrypt(keyCrypter.deriveKey(PASSWORD1));
        assertTrue(!key.isEncrypted());
        assertArrayEquals(originalPrivateKeyBytes, key.getPrivKeyBytes());
    }

    @Test
    public void testEncryptedCreate() throws Exception {
        ECKey unencryptedKey = new ECKey();
        byte[] originalPrivateKeyBytes = checkNotNull(unencryptedKey.getPrivKeyBytes());
        log.info("Original private key = " + Utils.HEX.encode(originalPrivateKeyBytes));
        EncryptedData encryptedPrivateKey = keyCrypter.encrypt(unencryptedKey.getPrivKeyBytes(), keyCrypter.deriveKey(PASSWORD1));
        ECKey encryptedKey = ECKey.fromEncrypted(encryptedPrivateKey, keyCrypter, unencryptedKey.getPubKey());
        assertTrue(encryptedKey.isEncrypted());
        assertNull(encryptedKey.getSecretBytes());
        ECKey rebornUnencryptedKey = encryptedKey.decrypt(keyCrypter.deriveKey(PASSWORD1));
        assertTrue(!rebornUnencryptedKey.isEncrypted());
        assertArrayEquals(originalPrivateKeyBytes, rebornUnencryptedKey.getPrivKeyBytes());
    }

    @Test
    public void testEncryptionIsReversible() throws Exception {
        ECKey originalUnencryptedKey = new ECKey();
        EncryptedData encryptedPrivateKey = keyCrypter.encrypt(originalUnencryptedKey.getPrivKeyBytes(), keyCrypter.deriveKey(PASSWORD1));
        ECKey encryptedKey = ECKey.fromEncrypted(encryptedPrivateKey, keyCrypter, originalUnencryptedKey.getPubKey());

        // The key should be encrypted
        assertTrue("Key not encrypted at start", encryptedKey.isEncrypted());

        // Check that the key can be successfully decrypted back to the original.
        assertTrue("Key encryption is not reversible but it should be", ECKey.encryptionIsReversible(originalUnencryptedKey, encryptedKey, keyCrypter, keyCrypter.deriveKey(PASSWORD1)));

        // Check that key encryption is not reversible if a password other than the original is used to generate the AES key.
        assertFalse("Key encryption is reversible with wrong password", ECKey.encryptionIsReversible(originalUnencryptedKey, encryptedKey, keyCrypter, keyCrypter.deriveKey(WRONG_PASSWORD)));

        // Change one of the encrypted key bytes (this is to simulate a faulty keyCrypter).
        // Encryption should not be reversible
        byte[] goodEncryptedPrivateKeyBytes = encryptedPrivateKey.encryptedBytes;

        // Break the encrypted private key and check it is broken.
        byte[] badEncryptedPrivateKeyBytes = new byte[goodEncryptedPrivateKeyBytes.length];
        encryptedPrivateKey = new EncryptedData(encryptedPrivateKey.initialisationVector, badEncryptedPrivateKeyBytes);
        ECKey badEncryptedKey = ECKey.fromEncrypted(encryptedPrivateKey, keyCrypter, originalUnencryptedKey.getPubKey());
        assertFalse("Key encryption is reversible with faulty encrypted bytes", ECKey.encryptionIsReversible(originalUnencryptedKey, badEncryptedKey, keyCrypter, keyCrypter.deriveKey(PASSWORD1)));
    }

    @Test
    public void testToString() throws Exception {
        ECKey key = ECKey.fromPrivate(BigInteger.TEN).decompress(); // An example private key.
        NetworkParameters params = MAINNET;
        assertEquals("ECKey{pub HEX=04a0434d9e47f3c86235477c7b1ae6ae5d3442d49b1943c2b752a68e2a47e247c7893aba425419bc27a3b6c7e693a24c696f794c2ed877a1593cbee53b037368d7, isEncrypted=false, isPubKeyOnly=false}", key.toString());
        assertEquals("ECKey{pub HEX=04a0434d9e47f3c86235477c7b1ae6ae5d3442d49b1943c2b752a68e2a47e247c7893aba425419bc27a3b6c7e693a24c696f794c2ed877a1593cbee53b037368d7, priv HEX=000000000000000000000000000000000000000000000000000000000000000a, priv WIF=5HpHagT65TZzG1PH3CSu63k8DbpvD8s5ip4nEB3kEsreBoNWTw6, isEncrypted=false, isPubKeyOnly=false}", key.toStringWithPrivate(null, params));
    }

    @Test
    public void testGetPrivateKeyAsHex() throws Exception {
        ECKey key = ECKey.fromPrivate(BigInteger.TEN).decompress(); // An example private key.
        assertEquals("000000000000000000000000000000000000000000000000000000000000000a", key.getPrivateKeyAsHex());
    }

    @Test
    public void testGetPublicKeyAsHex() throws Exception {
        ECKey key = ECKey.fromPrivate(BigInteger.TEN).decompress(); // An example private key.
        assertEquals("04a0434d9e47f3c86235477c7b1ae6ae5d3442d49b1943c2b752a68e2a47e247c7893aba425419bc27a3b6c7e693a24c696f794c2ed877a1593cbee53b037368d7", key.getPublicKeyAsHex());
    }

    @Test
    public void keyRecoveryWithEncryptedKey() throws Exception {
        ECKey unencryptedKey = new ECKey();
        KeyParameter aesKey =  keyCrypter.deriveKey(PASSWORD1);
        ECKey encryptedKey = unencryptedKey.encrypt(keyCrypter, aesKey);

        String message = "Goodbye Jupiter!";
        Sha256Hash hash = Sha256Hash.of(message.getBytes());
        ECKey.ECDSASignature sig = encryptedKey.sign(hash, aesKey);
        unencryptedKey = ECKey.fromPublicOnly(unencryptedKey.getPubKeyPoint());
        boolean found = false;
        for (int i = 0; i < 4; i++) {
            ECKey key2 = ECKey.recoverFromSignature(i, sig, hash, true);
            checkNotNull(key2);
            if (unencryptedKey.equals(key2)) {
                found = true;
                break;
            }
        }
        assertTrue(found);
    }

    @Test
    public void roundTripDumpedPrivKey() throws Exception {
        ECKey key = new ECKey();
        assertTrue(key.isCompressed());
        String base58 = key.getPrivateKeyEncoded(UNITTEST).toString();
        ECKey key2 = DumpedPrivateKey.fromBase58(UNITTEST, base58).getKey();
        assertTrue(key2.isCompressed());
        assertArrayEquals(key.getPrivKeyBytes(), key2.getPrivKeyBytes());
        assertArrayEquals(key.getPubKey(), key2.getPubKey());
    }

    @Test
    public void clear() throws Exception {
        ECKey unencryptedKey = new ECKey();
        ECKey encryptedKey = (new ECKey()).encrypt(keyCrypter, keyCrypter.deriveKey(PASSWORD1));

        checkSomeBytesAreNonZero(unencryptedKey.getPrivKeyBytes());

        // The encryptedPrivateKey should be null in an unencrypted ECKey anyhow but check all the same.
        assertTrue(unencryptedKey.getEncryptedPrivateKey() == null);

        checkSomeBytesAreNonZero(encryptedKey.getSecretBytes());
        checkSomeBytesAreNonZero(encryptedKey.getEncryptedPrivateKey().encryptedBytes);
        checkSomeBytesAreNonZero(encryptedKey.getEncryptedPrivateKey().initialisationVector);
    }

    @Test
    public void testCanonicalSigs() throws Exception {
        // Tests the canonical sigs from Bitcoin Core unit tests
        InputStream in = getClass().getResourceAsStream("sig_canonical.json");

        // Poor man's JSON parser (because pulling in a lib for this is overkill)
        while (in.available() > 0) {
            while (in.available() > 0 && in.read() != '"') ;
            if (in.available() < 1)
                break;

            StringBuilder sig = new StringBuilder();
            int c;
            while (in.available() > 0 && (c = in.read()) != '"')
                sig.append((char)c);

            assertTrue(TransactionSignature.isEncodingCanonical(HEX.decode(sig.toString())));
        }
        in.close();
    }

    @Test
    public void testNonCanonicalSigs() throws Exception {
        // Tests the noncanonical sigs from Bitcoin Core unit tests
        InputStream in = getClass().getResourceAsStream("sig_noncanonical.json");

        // Poor man's JSON parser (because pulling in a lib for this is overkill)
        while (in.available() > 0) {
            while (in.available() > 0 && in.read() != '"') ;
            if (in.available() < 1)
                break;

            StringBuilder sig = new StringBuilder();
            int c;
            while (in.available() > 0 && (c = in.read()) != '"')
                sig.append((char)c);

            try {
                final String sigStr = sig.toString();
                assertFalse(TransactionSignature.isEncodingCanonical(HEX.decode(sigStr)));
            } catch (IllegalArgumentException e) {
                // Expected for non-hex strings in the JSON that we should ignore
            }
        }
        in.close();
    }

    @Test
    public void testCreatedSigAndPubkeyAreCanonical() throws Exception {
        // Tests that we will not generate non-canonical pubkeys or signatures
        // We dump failed data to error log because this test is not expected to be deterministic
        ECKey key = new ECKey();
        if (!ECKey.isPubKeyCanonical(key.getPubKey())) {
            log.error(Utils.HEX.encode(key.getPubKey()));
            fail();
        }

        byte[] hash = new byte[32];
        new Random().nextBytes(hash);
        byte[] sigBytes = key.sign(Sha256Hash.wrap(hash)).encodeToDER();
        byte[] encodedSig = Arrays.copyOf(sigBytes, sigBytes.length + 1);
        encodedSig[sigBytes.length] = Transaction.SigHash.ALL.byteValue();
        if (!TransactionSignature.isEncodingCanonical(encodedSig)) {
            log.error(Utils.HEX.encode(sigBytes));
            fail();
        }
    }

    private static boolean checkSomeBytesAreNonZero(byte[] bytes) {
        if (bytes == null) return false;
        for (byte b : bytes) if (b != 0) return true;
        return false;
    }

    @Test
    public void testPublicKeysAreEqual() {
        ECKey key = new ECKey();
        ECKey pubKey1 = ECKey.fromPublicOnly(key.getPubKeyPoint());
        assertTrue(pubKey1.isCompressed());
        ECKey pubKey2 = pubKey1.decompress();
        assertEquals(pubKey1, pubKey2);
        assertEquals(pubKey1.hashCode(), pubKey2.hashCode());
    }

    @Test(expected = IllegalArgumentException.class)
    public void fromPrivate_exceedsSize() {
        final byte[] bytes = new byte[33];
        bytes[0] = 42;
        ECKey.fromPrivate(bytes);
    }
}


Developing a website for mobile devices, I hosted the site within IIS on my Windows 7 development machine. I wanted to give access to this site from another device on the LAN.
The culprit is Windows 7 Firewall. To enable HTTP access through Windows Firewall on Windows 7, execute the following procedure.
Left side menu: link for "Allow a program or feature through Windows Firewall"
Scroll the bottom of the list and enable "World Wide Web Services (HTTP)".


All parts of the world celebrate the harvest and so do the many gardeners who call DG their home. The County Fair is a longstanding agricultural and handicraft tradition that gives gardeners, farmers and artisans the opportunity to showcase their work to the community.
We are honoring this popular harvest tradition with our own virtual 6th annual County Fair happening here on Dave's Garden!
Who can enter? Any member or subscriber is eligible.
What pictures are eligible? Photos must be your own photos, not entered in any previous contest at Dave's Garden.
How many photos can I enter? You may enter two photos per category.
How do I enter recipes? Recipes can be entered in a designated thread in the cooking forum. As with the photo categories, you may submit 2 recipes.
What are the important dates? Enter between now and September 18. We'll start voting on September 19 and continue thru September 25.
Second place winners will receive a 6-month subscription and third place winners will receive a two-month subscription.
The voting is finished!! Congratulations to each of the winners. Click below to view the winners of each contest.


Throughout this week, SALT is offering a variety of ways to learn more about Technology Enhanced Learning and its innovative use for learning and teaching.
This is an online bulletin board that can be used to display information on any topic. Our TEL Padlet will display useful TEL links and resources that you can access from the one place.
Padlets are interactive, so we welcome questions and comments that we can then respond to.
TEL Padlet available from Monday 13th May from this page.
Becoming a Better Teacher – The Flipped Classroom, with Dr Nigel Francis, Medicine, Swansea University.
Wednesday 15th May 2019, 1-2pm, A019, The Bay Campus.
TEL Talks will take place Monday, Tuesday, Thursday and Friday, using Blackboard Collaborate, an online synchronous communication and webinar tool.
Experience the 'basics' of an online discussion in a live online learning environment, in an informal, friendly, introductory session with SALT Academic Developers.
Discuss the pedagogical benefits of TEL tools for learning and teaching on various themes, at the same time as developing your understanding of online discussions, webinar participation and virtual classrooms. Facilitated by SALT Academic Developers.
Click here to see our Adobe Spark page for more information on and the full programme of TEL Talks, including a link to reserve a place.
N.b. A Welsh version of the Spark page is available upon request.


text:
The Big Question: Will Synthetic Rhino Horns Save the Species or Kill it Off?
by Nathan Nicholson · Published February 19, 2016 · Updated September 3, 2018
Poaching is a major problem facing the world as a whole. Poachers kill and destroy certain animals, endangering their species.
One of such endangered species is the rhinoceros. Often abbreviated simply as rhino, the animal is mercilessly hunted and killed by poachers wherever it lives. When poachers kill it, they remove the horns; the lucrative reason for why poachers hunt them.
Rhino horns are very popular in Asia, especially in China, Vietnam and Thailand; for its use in traditional medicines. The horns are consumed in powder form with the belief that it can treat everything from hangovers to cancer. Intact horns are also carved into decorative items such as jewelry.
Rhino horns are very expensive. According to monitors of the trade, one kilogram of rhino horns costs around $65,000. Due to the price and the high demand, it has become very difficult for countries to fight poaching.
Particularly for Africa, poaching has devastated the continent, threatening other animals such as giraffes, lions, tigers, elephants, and rhinos amongst others.
In South Africa for example, the number of rhinos killed by poachers jumped from 262 in 2008, to 1,215 in 2014. Recently, in the Democratic Republic of the Congo in Central Africa, it was reported that there are only 38 giraffe remaining at one of the country's national parks, Garamba National Park.
Conservationists therefore, are calling for the ban of all products derived from endangered species. In the United States, the Endangered Species Act and the Rhinoceros and Tiger Conservation Act, make the commercial import, export, and interstate commerce of any products derived from rhinos, unlawful.
In light of these problems associated with poaching, a conservation-minded start-up company in the United States is growing rhino horns in the laboratory. The Seattle-based company, Pembient is one of the many companies in the United States developing synthetic rhino horns. The company said growing artificial horns in the laboratory, will discourage people from poaching.
According to the chief executive of Pembient, Matthew Markus, the company is growing the horns to drastically cut down the current market price. He said the idea is to bombard the market with fake rhino horns, which will drive down the price of a real horn, reducing the financial incentive for poachers to kill the animals. Markus also added that he hoped the synthetic horns would provide an outlet for consumers in the same way faux fur has done in the past.
But some environmental groups have disagreed with the work of Pembient and all other companies growing artificial rhino horns. They contended the synthetic version is not only illegal, but will also increase demand for real rhino horns.
To state their case officially, two environmental groups – the Center for Biological Diversity and WildAid – have filed a petition asking the United States Fish and Wildlife Service (FWS) to ban the import, export, and sale of 'cultured' rhinoceros horn.
"Pembient's cultured rhino horn is a 'product' of ESA-listed…rhinoceros. To produce its cultured horn, Pembient will insert the rhinoceros gene sequence that codes for rhino keratin into yeast, which then multiplies. Accordingly, because Pembient's synthetic rhino horn both is 'produced from' the rhinoceros genetic code and includes rhinoceros genetic material, and because the ESA prohibits the import, export, or sale of 'any . . . product' from an endangered animal, trade in cultured rhino horn is prohibited," the petition said.
Take Part reports that FWS spokesperson has declined to comment on the petition. But FWS deputy assistant director in charge of law enforcement, Edward Grace shared the concerns of the petitioners in an email to Take Part.
"Experience demonstrates that efforts to 'flood the market' for products produced from protected wildlife…often fail to achieve their stated goal. Such efforts often create more demand from consumers,"Grace wrote. He also added that FWS worries that synthetic products would make it harder for law enforcement to detect poached and trafficked wildlife products, and will allow criminals to disguise the source of illegal products by co-mingling them with these alternatives.
This article (The Big Question: Will Synthetic Rhino Horns Save the Species or Kill it Off?) is a free and open source. You have permission to republish this article under a Creative Commons license with attribution to the author and AnonHQ.com
New Study: Oceans To Have More Plastic Than Fish By 2050
Trump DOJ to Appeal Maryland Ruling Against Muslim Ban 2.0
Hillary Emails: NATO Destroyed Libya To Prevent Gold-Backed Dinar
by Nathan Nicholson · Published February 5, 2016 · Last modified September 3, 2018
Next story The NSA Actually Has A Program Called SKYNET — And It's Terrifying
Previous story Ecuador Set To Sell One Third Of Pristine Rainforest To Chinese Oil Companies

redpajama_set_name: RedPajamaCommonCrawl


Karan Thakur, a 17-year-old student of Chandigarh's DAV School, reportedly hanged himself in Panchkula, Haryana.
Thakur's mother claims he had taken up the deadly Blue Whale challenge on his cellphone.
She said he was addicted to the game and was taken to a psychiatrist but to no avail.
What is the Blue Whale suicide challenge?
The challenge supposedly originates from online social media groups, where the administrator sets out tasks for participants to complete.
The tasks range from self-mutilation to waking up at ungodly hours; and when the 50th day approaches, participants are brainwashed into committing suicide in order to complete the challenge.
The targets for these challenges are comprised of teenagers; some as young as 14.
The masterminds behind this "sick" game use pressure tactics when the participants try to get out of the game.
Threats come in the form of leaking personal information or harming people who are related to the participant.
The participant has to prove that he/she has completed the task by sending pictures and if one fails to do so, it would get them disqualified.
In May 2016, Russian citizens discovered this phenomenon and associated "death groups" after Novaya Gazeta, a newspaper, reported about a 12-year-old girl who had committed suicide.
Soon, it gained traction among Brazilian teenagers who are calling this online death trap 'Baleia Azul'.
The Blue Whale challenge has entered the UK as well, with Essex Police informing schools about the fatal nature of the game.
In May, 21-year-old Russian Philipp Budeikin, the alleged creator, was arrested for inciting at least 16 teenagers to kill themselves.
According to Budeikin, "(The victims) were dying happy. I was giving them what they didn't have in real life: warmth, understanding, connections."
He claimed he was "cleansing society" by ridding it of "biological waste".
Budeikin is currently held at Kresty Prison in St Petersburg.
The first death in India believed to be linked to the global Blue Whale was reported on July 29, when a 14-year-old boy allegedly jumped to his death from the fifth floor of a building in Mumbai.
On August 12 came the second alleged case: a Class X student in WB suffocated himself to death.
At least two other teenagers have been rescued.
Senator John McCain said he "cannot in good conscience" vote in favor of his fellow Republicans' latest efforts to repeal the Obamacare healthcare programme.
Russia's special envoy for Afghanistan Zamir Kabulov might visit India soon to discuss the security situation in Afghanistan.
PM Theresa May has proposed a transition period of "about" two years following Brexit in 2019, during which the UK would continue having unfettered access to the EU single market.


She became interested in journalistic writing after attending the "March for our Lives", a protest in support of stronger gun regulations last year in downtown Portland.
"It was completely new to me, at first I was resistant to just telling a story without inserting my opinion, but I ended up really enjoying it. I realized I could combine two things I really love: writing and discussing important issues," Rodriguez said.
Along with taking part in March for our Lives, Rodriguez has participated in several school walkouts as well as a meeting at Town Hall in Salem to discuss gun control.
As an aspiring journalist, she's not only excited about covering stories at West Linn High School, but also becoming a columnist on the teen page of the Clackamas Times. She'll be writing monthly content and hopes to use this opportunity to connect with local teens.
"Writing for the Clackamas Times will be a very new experience for me, but it's exciting," Rodriguez said. "I'm so lucky to start my exploration of journalism and I can't wait to see where it takes me."


text:
Defense Wins Championships: Except When You're The Columbus Blue Jackets
By Dan Dukart on December 12, 2019 at 1:45 pm @wowdangoodpoint
Eric Bolte-USA TODAY Sports
CBJ Analysis
Email this Article Share on Reddit Share on Twitter Share on Facebook
The Columbus Blue Jackets went into this season with a lot of question marks. But ultimately, those many questions can be boiled down to a few big ones:
Would they be able to replace their key UFAs on the offensive side of the puck?
Would Joonas Korpisalo and/or Elvis Merzlikins be able to make everyone forget about Sergei Bobrovsky?
Would their defense become/remain one of the top units in the league?
Now that we're at the 30-game poll, let's assess.
No, No, and Yes.
It's no secret that scoring has been a huge concern all year for the club - their 6.5% shooting percentage (5v5) ranks 30th in the NHL, besting only the (potentially historically bad) Detroit Red Wings (5.92%). The offense has been anemic for most of the year, and that's nothing new. But instead of beating a dead horse, let's turn to the defensive side of the puck for today; namely, let's discuss the battery that makes up the goaltenders and the defense corps in an attempt to help further explain their 12-14-4 record.
The Blue Jackets knew coming into the season that they would have to rely heavily on a deep and experienced group of defensemen. It was the one unit that had a surplus of quality players (when healthy), particularly with the emergence of Vladislav Gavrikov as a mainstay. Seth Jones, Zach Werenski, David Savard, Ryan Murray, and Markus Nutivaara, Dean Kukan and Scott Harrington round out one of the most formidable and complete defense corps in the NHL.
Even when the injury bug came and forced Werenski and Nutivaara out of the lineup, rookie Andrew Peeke earned a promotion and has shown well in his first stint in the NHL. The team's issues really don't pertain to the defense. Some evidence:
The Blue Jackets are among the best teams in the NHL at not gifting their opponents' quality looks. At 5v5, the club gives up just 29.33 shots on goal against per 60, eighth-best in the NHL, per NaturalStatTrick. But not all shots are created equal. To that end, the club ranks second in the NHL in high-danger chances-against/60, to the tune of allowing just 8.28 chances/game. At all strengths, their 2.24 expected goals against/60 minutes (xGA/60) is best in the NHL. And at 5v5, the Blue Jackets xGA/60 1.94 goals/game is tied for second-best, behind only the Pittsburgh Penguins.
Simply put, the Blue Jackets do not give up many chances, and when they do, they're not typically from the most dangerous areas on the ice.
Sounds like a recipe for success, right?
Well, yes, if your expected goals against match your actual goals given up, or you put the puck in the opposition's net with any sort of regularity. So to answer my own question: no.
Korpisalo and Merzlikins have been fine, but that's just it. Before the season started, I would venture to guess that most of you (and certainly I) would have been okay knowing that, at the 30-game mark, the Blue Jackets 5v5 save percentage ranks tied for 16th in the NHL. Is that great? No, but it's also kind of hard to say that the team is sub-.500 because of them, right? I mean, for those of us who have watched this struggle to score since day one, Korpisalo/Merzlikins have consistently been keeping the club in games, particularly as we've gotten deeper into the season.
This is where it gets tricky. Yes the offense has been invisible, but the Blue Jackets are giving up nearly a goal a game more than expected (all situations GA/60 = 3.04 (19th) vs. xGA/60 2.24 (1st)). Their all-situations save percentage is 24th. And even though their 5v5 save percentage (remember, ranked 16th) sounds fine, it's often the margin between winning and losing.
NaturalStatTrick isn't the only outfitter that has higher expectations for the Blue Jackets' goalie battery. Hockey-Reference utilizes a metric called Goals Saved Above Average (GSAA), which is exactly what it sounds like. Connor Hellebuyck, Winnipeg's star netminder, currently leads the league with a GSAA of 17.57. There are 62 qualifying goalies, and Merzlikins (-3.77, 43rd) and Korpisalo (-4.37 46) rank well outside of NHL starters. Put another way, Helebuyck has stopped 20+ pucks that Korpisalo/Merzlikins allowed, and the season is roughly 30 games old.
So while the Blue Jackets defense has been as advertised, or even better (even with sustained injuries), the inability to score with any consistency coupled with an average/below average goaltending tandem is the difference between being in the playoff chase and the lottery.
Note: All statistics courtesy of NaturalStatTrick unless stated otherwise.
With Joonas Korpisalo and Elvis Merzlikins Thriving In The NHL, The Blue Jackets Are Well Positioned Now And In The Future
Three Things: Playoff Thoughts In Central Ohio, Another Gritty Win, Elvis' Net
Log in or Sign up to Join the Discussion #CBJ
Who Has Been the Blue Jackets' MVP So Far This Season?
Pierre-Luc Dubois
Joonas Korpisalo


Is Your Chimney Cap Missing? Storm Damage Your Cap?
Keep Animals & Weather From Entering Your Chimney By Installing A Stainless Steel Chimney Cover Today!
We pride ourselves in providing all of Long Island with quality chimney cap installations for over 35 years. Fred's Chimney Magic is the chimney company you can count on in Long Island NY for a new chimney cap. Call us today to schedule your chimney cap installation or replacement at (800) 696- 7668.
Protect your home with a chimney cap and prevent animals and rain from coming in.
Caps come in all sizes and in different finishes. Some are custom and some standard. They all protect your chimney from obstructions like branches, animals, etc. and rain.
Every chimney should be capped! Maintaining your chimney crown and bricks will stop water damage and prevent staining.
Crowns, re-pointing, flashing and caps are just a few of the many services we provide. This type of repair and maintenance will help to prevent problems from occurring inside the chimney flues.
Fred's Chimney Magic promises hard work, ambition, safety and honesty in an effort to maintain a superior presence throughout Long Island NY. We work hard to keep our reputation at its best. Due to our high standards, we balance tasteful craftsmanship with reasonable pricing and timely completion to ensure your complete satisfaction on all chimney services and chimney repairs.


Start off your visit on the 13th (Wed): explore the world behind art at Palacio de Bellas Artes, appreciate the extensive heritage of Zocalo, then examine the collection at Frida Kahlo Museum, and finally see the interesting displays at National Museum of Anthropology.
For photos, maps, reviews, and tourist information, read our Mexico City trip builder tool .
If you are flying in from United States, the closest major airports are Licenciado Benito Juarez International Airport, Querétaro Intercontinental Airport and General Francisco J. Mujica International Airport. In February, plan for daily highs up to 75°F, and evening lows to 48°F. Wrap up your sightseeing on the 13th (Wed) to allow time to travel back home.


text:
Symptoms Of Liver Damage - 12 Signs of Liver Damage
thelifetoday.com/liverdamage/symptoms
Leam More About the 12 Common Signs & Symptoms of Liver Damage. While certainly a common enough symptom of liver damage, fatigue is a varied symptom .....
9 Signs Of Breast Cancer
Liver Cirrhosis Symptoms
Pancreatic Cancer Signs
10 Lung Cancer Symptoms
Heart Attack Symptoms
11 Signs Of Pancreatitis
5 Symptoms To Look Out For - 5 Early Warning Signs
healthprep.com/Liver-Failure
Discover the common symptoms of liver failure and liver damage to be aware of. Find out the early warning signs of liver failure and liver damage right now.
Types: Nutrition Information, Dieting Guidelines, Healthy Eating Tips
What Is Sinusitis?
Worst City For Allergies
Prevent Osteoporosis
10 Signs Of Liver Damage - DailyNaturalRemedies.com
www.DailyNaturalRemedies.com
Find Out These 10 Symptoms Of Liver Damage...You Won't Believe #9
12healthy.com/livercirrhosis/symptoms
Brain Tumor Warning Signs
10 Remedies Acid Reflux
10 Liver Disease Symptoms - Warning Signs & Early Symptoms
AllMedicineData.info/Liver-Diseases/Symptoms
10 Warning Signs & Symptoms of Liver Disease - Check Yourself!
What Are the Symptoms of Liver Damage?
The Mayo Clinic states that liver damage can be indicated by several symptoms related to liver disease. Sufferers of liver disease experience jaundice, abdominal pain and swelling, leg swelling, itchy skin, dark urine co...
www.reference.com/article/symptoms-liver-damage-ba7a493f75a80e0d
What Are Common Symptoms of Liver Damage From Tylenol?
Common symptoms of liver damage from Tylenol include nausea, vomiting, abdominal pain and loss of appetite, notes Tylenol. It may take time for the symptoms to occur or get severe. In some cases, the symptoms may be due ...
www.reference.com/article/common-symptoms-liver-damage-tylenol-8d44ea8445d68059
Is Liver Damage Reversible?
The liver is able to heal itself by replacing damaged tissue with new cells, according to the University of Iowa Hospitals and Clinics. In cases where scar tissue develops, a condition known as cirrhosis, complications m...
www.reference.com/article/liver-damage-reversible-607f407af2ab6029
Symptoms of Liver Damage
liver symptoms women over 50
Symptoms of Liver Damage from Alcohol
Liver Damage Symptoms
Liver Damage Cause by Drinking
10 signs of liver problems
Symptoms of Alcohol Liver Damage Hepatitis
Signs Symptoms of Liver Damage
Liver Damage Alcohol
Repairing Liver Damage
What Is NASH Liver Disease?
Nonalcoholic steatohepatitis liver disease refers to the inflammation and damage of the liver as a result of fat accumulation in the organ, according to WebMD. This condition hinders the normal functioning of the liver a...
www.reference.com/article/nash-liver-disease-3f4bb451b66a3dd0
What Is Sclerosis of the Liver?
Cirrhosis of the liver is the late stage of liver disease related to conditions such as hepatitis or chronic alcoholism, according to Mayo Clinic. Cirrhosis is scar tissue formed by the liver and a condition that is perm...
www.reference.com/article/sclerosis-liver-4dc83bbdc7544899
What Are the Symptoms of Liver Pain or Disease?
Common signs and symptoms of liver disease include jaundice, in which eyes and skin that take on a yellowish color, as well as abdominal pain, itchy skin, chronic fatigue, and swelling in the ankles and legs, according t...
www.reference.com/article/symptoms-liver-pain-disease-2a504a8d9e2a10fa
What Are the Most Common Symptoms of Liver Disease?
Typical symptoms of liver disease include swelling of the legs and ankles, abdominal pain, dark urine color and loss of appetite, explains Mayo Clinic. However, since liver disease occurs in different forms, symptoms are...
www.reference.com/article/common-symptoms-liver-disease-2a4e535158959cf4
first signs of liver disease
liver failure symptoms in women
early signs of liver damage from alcohol
early signs of liver damage
liver problem symptoms in men
Today's Top 10 Articles in health
What Does Salmonella Do to the Human Body?
What Is a Natural Thyroid Treatment?
What Limitations Does a Person With Progeria Have?
What Is a List of Protozoan Diseases?
Where Did Meningitis Come From?


It's incredible that the last entry in here is of Sal as a baby. He's a boy now, and we just put his crib away a couple of weeks ago in favor of a toddler-sized bed. And Enzo is in kindergarten now. Kacey's a full time mom, jewelry artist, business consultant and children's book rep (all from home), and me? Well…I guess I'm doing the same stuff I've always done. I'm still working for the same place, and still doing much the same things when I'm not there. Which as you might expect means that I need some new outlets for my energy after all this time.
I know that I'm going to try to review all the media I consume, so there are categories for music, books, and movies. I watch a lot of TV and play a lot of video games, too, so those will probably make it in here at times. I don't usually catch things right when they come out, so don't expect me to be timely, though.
This entry was posted on Monday, February 18th, 2008 at 10:56 am and is filed under Uncategorized.	You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.