/// <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; }
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); }
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())); }