Jesse and I think we have found the problem. Here is the patch to fix it. 
This has been confirmed to work and we were able to encrypt in CryptoPP and 
decrypt in Bouncy Castle.

On Thursday, April 11, 2013 9:32:16 AM UTC-7, Jesse Wilson wrote:
>
> Cryptopp folks,
>
> I'm attempting to interop ECIES encryption between bouncy castle and 
> cryptopp. Unfortunately, I've run into a problem and I think it's a bug in 
> cryptopp.
>
> When cryptopp creates the digest for ECIES, it sends the payload, followed 
> by the encoding parameters, followed by the encoding parameters' size in 
> bytes as an 8-byte value. For example, if the encoding parameter is 4 bytes 
> long, it writes the length as 00 00 00 00 00 00 00 04. If its 32 bytes 
> long it writes00 00 00 00 00 00 00 20.
>
> This is driven by code in 
> gfpcrypt.h<http://cryptopp.svn.sourceforge.net/viewvc/cryptopp/trunk/c5/gfpcrypt.h?revision=535&view=markup>
> :
>
>         mac.Update(encodingParameters.begin(), encodingParameters.size());
>         if (DHAES_MODE)
>         {
>             byte L[8] = {0,0,0,0};
>             PutWord(false, BIG_ENDIAN_ORDER, L+4, 
> word32(encodingParameters.size()));
>             mac.Update(L, 8);
>         }
>
> Bouncy castle writes the encoding parameter size in bits as a 4-byte 
> value. For example, if the encoding parameter is 4 bytes long it writes 00 
> 00 00 20. If its 32 bytes long, bouncy castle writes 00 00 01 00.
>
> This is driven by code in 
> IESEngine.java<http://www.bouncycastle.org/viewcvs/viewcvs.cgi/java/crypto/src/org/bouncycastle/crypto/engines/IESEngine.java?revision=1.10&view=markup>
> :
>
>         byte[] L2 = new byte[4];
>
>         if (V.length != 0)
>         {
>             if (P2 != null)
>             {
>                 Pack.intToBigEndian(P2.length * 8, L2, 0);
>             }
>             else
>             {
>                 Pack.intToBigEndian(0, L2, 0);
>             }
>         }
>
>         ...
>
>         if (V.length != 0)
>
>         {
>             mac.update(L2, 0, L2.length);
>         }
>
> I cross 
> posted<http://bouncy-castle.1462172.n4.nabble.com/Problem-with-the-way-IESEngine-HMAC-s-the-encoding-parameters-length-td4655770.html>this
>  message to the bouncy castle list, and David Hook replied with a quote 
> from Victor Shoup's paper <http://www.shoup.net/papers/iso-2_1.pdf>:
>
> In particular, we multiply |L| by 8 so as to encode the length of L in 
> bits, rather than bytes, since the IEEE P1363a version of ECIES allows 
> (in theory, but not really in practice) messages and labels that are bit 
> strings rather than byte strings.
>
> Is it a bug?
>
> Thanks!
>

-- 
-- 
You received this message because you are subscribed to the "Crypto++ Users" 
Google Group.
To unsubscribe, send an email to [email protected].
More information about Crypto++ and this group is available at 
http://www.cryptopp.com.
--- 
You received this message because you are subscribed to the Google Groups 
"Crypto++ Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.


>From 8e168b09d4e3e5f132049601152e8271cb8a5c29 Mon Sep 17 00:00:00 2001
From: Daniele Perito and Jesse Wilson <[email protected]>
Date: Thu, 11 Apr 2013 09:59:12 -0700
Subject: [PATCH] Patch CryptoPP's ECIES padding to work nicely with BC.

---
 src/cryptopp/gfpcrypt.h | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/src/cryptopp/gfpcrypt.h b/src/cryptopp/gfpcrypt.h
index 7af993f..f25eeaa 100644
--- a/src/cryptopp/gfpcrypt.h
+++ b/src/cryptopp/gfpcrypt.h
@@ -442,9 +442,9 @@ public:
 		mac.Update(encodingParameters.begin(), encodingParameters.size());
 		if (DHAES_MODE)
 		{
-			byte L[8] = {0,0,0,0};
-			PutWord(false, BIG_ENDIAN_ORDER, L+4, word32(encodingParameters.size()));
-			mac.Update(L, 8);
+			byte L[4];
+			PutWord(false, BIG_ENDIAN_ORDER, L, word32(8 * encodingParameters.size()));
+			mac.Update(L, 4);
 		}
 		mac.Final(ciphertext + plaintextLength);
 	}
@@ -471,9 +471,9 @@ public:
 		mac.Update(encodingParameters.begin(), encodingParameters.size());
 		if (DHAES_MODE)
 		{
-			byte L[8] = {0,0,0,0};
-			PutWord(false, BIG_ENDIAN_ORDER, L+4, word32(encodingParameters.size()));
-			mac.Update(L, 8);
+			byte L[4];
+			PutWord(false, BIG_ENDIAN_ORDER, L, word32(8 * encodingParameters.size()));
+			mac.Update(L, 4);
 		}
 		if (!mac.Verify(ciphertext + plaintextLength))
 			return DecodingResult();
-- 
1.7.12.1

Reply via email to