/// <summary>
        ///     Create a RadixAddress from a Elliptic Curve Public Key
        /// </summary>
        /// <param name="magic"></param>
        /// <param name="publicKey"></param>
        public RadixAddress(int magic, ECPublicKey publicKey)
        {
            if (publicKey == null)
            {
                throw new ArgumentNullException(nameof(publicKey));
            }

            if (publicKey.Length() != 33)
            {
                throw new ArgumentException($"publickey must be 33 in lenghth but was : {publicKey.Length()}");
            }

            byte[] addressBytes = new byte[1 + publicKey.Length() + 4];
            // Universe magic byte
            addressBytes[0] = (byte)(magic & 0xff);
            publicKey.CopyPublicKey(addressBytes, 1);

            // Checksum
            byte[] check = RadixHash.Of(addressBytes, 0, publicKey.Length() + 1).ToByteArray();
            Array.Copy(check, 0, addressBytes, publicKey.Length() + 1, 4);

            //_addressBase58 = Base58.ToBase58(addressBytes);
            _addressBase58 = Base58Encoding.Encode(addressBytes);
            _pubKey        = publicKey;
        }
Example #2
0
        public virtual byte[] Decrypt(ECPrivateKey privateKey, byte[] data)
        {
            using (var stream = new MemoryStream(data))
            {
                //  read the IV
                byte[] iv = new byte[16];
                stream.Read(iv, 0, iv.Length);

                //  read the publickey
                var    pubkeysize = stream.ReadByte();
                byte[] pubkeyraw  = new byte[pubkeysize];
                stream.Read(pubkeyraw, 0, pubkeyraw.Length);
                var pubkey = new ECPublicKey(pubkeyraw);

                //  Do an EC point multiply with this.getPrivateKey() and ephemeral public key. This gives you a point M.
                var m = GetECPoint(pubkey).Multiply(new BigInteger(1, privateKey.Base64Array)).Normalize();

                //  Use the X component of point M and calculate the SHA512 hash H.
                byte[] h = RadixHash.Sha512Of(m.XCoord.GetEncoded()).ToByteArray();

                //  The first 32 bytes of H are called key_e and the last 32 bytes are called key_m.
                byte[] keyE = Arrays.CopyOfRange(h, 0, 32);
                byte[] keyM = Arrays.CopyOfRange(h, 32, 64);

                //  Read encrypted data
                var size = new byte[4];
                stream.Read(size, 0, size.Length);
                byte[] encrypted = new byte[BitConverter.ToInt32(size, 0)];
                stream.Read(encrypted, 0, encrypted.Length);

                //  Read MAC
                byte[] mac = new byte[32];
                stream.Read(mac, 0, mac.Length);

                //  Compare MAC with MAC'. If not equal, decryption will fail.
                byte[] pkMac = CalculateMAC(keyM, iv, pubkey, encrypted);
                if (pkMac.Equals(mac))
                {
                    throw new ApplicationException
                              ($"Decryption failed, mac mismatch , {Convert.ToBase64String(pkMac)} <> {Convert.ToBase64String(mac)}");
                }

                //  Decrypt the cipher text with AES-256-CBC, using IV as initialization vector, key_e as decryption key,
                //  and the cipher text as payload. The output is the padded input text.
                return(Crypt(false, encrypted, iv, keyE));
            }
        }
        /// <summary>
        ///     Create a RadixAddres from a base58 string
        /// </summary>
        /// <param name="addressBase58"></param>
        public RadixAddress(string addressBase58)
        {
            byte[]    raw   = Base58Encoding.Decode(addressBase58);
            RadixHash check = RadixHash.Of(raw, 0, raw.Length - 4);

            for (int i = 0; i < 4; ++i)
            {
                if (check.Get(i) != raw[raw.Length - 4 + i])
                {
                    throw new ArgumentException("Address " + addressBase58 + " checksum mismatch");
                }
            }

            byte[] publicKey = new byte[raw.Length - 5];
            Array.Copy(raw, 1, publicKey, 0, raw.Length - 5);

            _addressBase58 = addressBase58;
            _pubKey        = new ECPublicKey(publicKey);
        }
Example #4
0
        public virtual byte[] Encrypt(ECPublicKey publicKey, byte[] data)
        {
            Random rand = new SecureRandom();

            byte[] iv = new byte[16];
            // 2. Generate 16 random bytes using a secure random number generator. Call them IV
            rand.NextBytes(iv);

            var randomKeyPair = GetRandomKeyPair();

            //  Do an EC point multiply with publicKey and random keypair. This gives you a point M.
            var m = GetECPoint(publicKey).Multiply(new BigInteger(1, randomKeyPair.PrivateKey.Base64Array)).Normalize();

            //  Use the X component of point M and calculate the SHA512 hash H.
            byte[] h = RadixHash.Sha512Of(m.AffineXCoord.GetEncoded()).ToByteArray();

            //  The first 32 bytes of H are called key_e and the last 32 bytes are called key_m.
            byte[] keyE      = Arrays.CopyOfRange(h, 0, 32);
            byte[] keyM      = Arrays.CopyOfRange(h, 32, 64);
            byte[] encrypted = Crypt(true, data, iv, keyE);

            //  Calculate a 32 byte MAC with HMACSHA256, using key_m as salt and
            //  IV + ephemeral.pub + cipher text as data. Call the output MAC.
            byte[] mac = CalculateMAC(keyM, iv, randomKeyPair.PublicKey, encrypted);

            //  Write out the encryption result IV +ephemeral.pub + encrypted + MAC
            using (var memstr = new MemoryStream())
            {
                memstr.Write(iv, 0, iv.Length);
                memstr.WriteByte((byte)randomKeyPair.PublicKey.Length());
                memstr.Write(randomKeyPair.PublicKey.Base64Array, 0, randomKeyPair.PublicKey.Length());
                memstr.Write(BitConverter.GetBytes(encrypted.Length), 0, 4);
                memstr.Write(encrypted, 0, encrypted.Length);
                memstr.Write(mac, 0, mac.Length);

                return(memstr.ToArray());
            }
        }
 public virtual EUID GetEUID(ECPublicKey pubkey)
 {
     return(GetEUID(RadixHash.Of(pubkey.Base64Array).ToByteArray()));
 }