title: ECIES with Inferno: Signing with ECDSA
body: <p>I'm trying to sign a text file encrypted with ECIES, using Inferno. The encryption and key exchange parts work well but I'm left with a few questions regarding ECDSA.</p>
  
  <p>1- I guess that the ECDSA signature must be stored in the sent file, so that receiver can use it to verify data integrity, right?</p>
  
  <p>2- I have read many times that signing should be performed on hashed data, yet the data sent with ECIES is encrypted, not hashed else how can receiver retrieve it?</p>
  
  <p>3- Where in the following code example should the signing take place? The current attempt does not work since although the signature is accepted upon decryption, an empty string is returned(instead of decrypted text).</p>
  
  <pre><code>    internal static void EncryptText(string text, Keyring k, string file, bool forSender)
      {
          // never mind the Keyring class, it has no methods and only exposes
          // a few properties to store the session keys conveniently
  
          SharedEphemeralBundle ephemeralBundle;
          if (forSender) ephemeralBundle = k.SenderDHM.GetSharedEphemeralDhmSecret();
          else ephemeralBundle = k.ReceiverDHM.GetSharedEphemeralDhmSecret();
  
          var ephemeralPublic = ephemeralBundle.EphemeralDhmPublicKeyBlob;
          var ephemeralSymmetric = ephemeralBundle.SharedSecret;
          var textBytes = Utils.SafeUTF8.GetBytes(text);
  
          byte[] signature;            
          using (var ecdsa = new ECDsaCng(k.SenderDSA) { HashAlgorithm = CngAlgorithm.Sha384 })
              signature = ecdsa.SignData(textBytes);
  
          using (FileStream fs = new FileStream(file, FileMode.Create, FileAccess.Write))
          {
              fs.Write(signature, 0, signature.Length);
              fs.Write(ephemeralPublic, 0, ephemeralPublic.Length);
  
              EtM_EncryptTransform etm = new EtM_EncryptTransform(ephemeralSymmetric);
              using (CryptoStream cs = new CryptoStream(fs, etm, CryptoStreamMode.Write))                
                  cs.Write(textBytes, 0, textBytes.Length);                                   
          }            
      }
  
      internal static string DecryptText(string file, Keyring k)
      {
          string decrypted = null;            
          var ephemeralPublic = new byte[104];
          var signature = new byte[96];            
  
          using (FileStream fs = new FileStream(file, FileMode.Open, FileAccess.Read))
          {
              fs.Read(signature, 0, 96);
              fs.Read(ephemeralPublic, 0, 104);
  
              var ephemeralSymmetric = k.SenderDHM.GetSharedDhmSecret(ephemeralPublic.ToPublicKeyFromBlob());
              EtM_DecryptTransform etm = new EtM_DecryptTransform(ephemeralSymmetric);
              using (CryptoStream cs = new CryptoStream(fs, etm, CryptoStreamMode.Read))
              {
                  byte[] decrypt = new byte[fs.Length - 200];
                  cs.Read(decrypt, 0, decrypt.Length);
                  using (var ecdsa = new ECDsaCng(k.SenderDSA))
                  {
                      // signature is accepted but returns an empty string!?
                      if (ecdsa.VerifyData(decrypt, signature))
                          decrypted = Utils.SafeUTF8.GetString(decrypt);                        
                  }                        
              }                                                                                       
          }
          return decrypted;
      }
  </code></pre>