<div dir="ltr"><div class="gmail_default" style="font-size:small">I have been working on an end to end encrypted Web site using Proxy Re-Encryption 'recryption'. The basic idea is that Alice is the administrator, she creates a keypair for 'Group W' and published the public part. Anyone who wants to can publish material encrypted under this key.</div><div class="gmail_default" style="font-size:small"><br></div><div class="gmail_default" style="font-size:small">For each person Alice adds to the group, she creates a recryption keypair [recrypt, decrypt], the first key is sent to the online recryption service chosen by Alice. The second is encrypted under Bob's public key and uploaded to the recryption service.</div><div class="gmail_default" style="font-size:small"><br></div><div class="gmail_default" style="font-size:small">The net effect is that it is impossible for any party to decrypt the content on the site unless they have either:</div><div class="gmail_default" style="font-size:small"><br></div><div class="gmail_default" style="font-size:small">* The private key held by Alice</div><div class="gmail_default" style="font-size:small">* The private key of one of the group members and at least an oracle that will preform the recryption step.</div><div class="gmail_default" style="font-size:small"><br></div><div class="gmail_default" style="font-size:small">This is true end to end encryption. An attacker can breach both the cloud services and the material is still confidential.</div><div class="gmail_default" style="font-size:small"><br></div><div class="gmail_default" style="font-size:small"><br></div><div class="gmail_default" style="font-size:small">So to implement this I need an API. OK so first off, I need an API for DH key agreement:</div><div class="gmail_default" style="font-size:small"><br></div><div class="gmail_default"><div class="gmail_default">            var AliceKeyPair = new DiffeHellmanPrivate();</div><div class="gmail_default">            var BobKeyPair = new DiffeHellmanPrivate();</div><div class="gmail_default"><br></div><div class="gmail_default">            var AlicePublic = AliceKeyPair.DiffeHellmanPublic;</div><div class="gmail_default">            var BobPublic = BobKeyPair.DiffeHellmanPublic;</div><div class="gmail_default"><br></div><div class="gmail_default">            var AliceAgree = AliceKeyPair.Agreement(BobPublic);</div><div class="gmail_default">            var BobAgree = BobKeyPair.Agreement(AlicePublic);</div><div class="gmail_default"><br></div><div class="gmail_default"><div class="gmail_default">            if (AliceAgree!=BobAgree) {</div><div class="gmail_default">                Console.WriteLine("Fail");</div><div class="gmail_default">                }</div></div><div class="gmail_default"><br></div><div class="gmail_default">[This is of course eliding all the code that would move the data between Alice and Bob]</div><div class="gmail_default"><br></div><div class="gmail_default">This looks nice and symmetric. AliceAgree  is currently returned as a BigInteger. This should obviously be fed into a hash function in some fashion to derive a key. But that would be part of DH-SHA2-512 or the like which would wrap this class.</div><div class="gmail_default"><br></div><div class="gmail_default">OK so what does a recryption scheme look like?</div><div class="gmail_default"><br></div><div class="gmail_default"><div class="gmail_default">            var GroupKeyPair = new DiffeHellmanPrivate();</div><div class="gmail_default">            var GroupKeyPublic = GroupKeyPair.DiffeHellmanPublic;</div><div class="gmail_default"><br></div><div class="gmail_default">            var BobSplit = GroupKeyPair.MakeRecryption(2);</div><div class="gmail_default">            var BobRecryption = BobSplit[0];</div><div class="gmail_default">            var BobDecryption = BobSplit[1];</div><div class="gmail_default"><br></div><div class="gmail_default">            var AliceAgreeW = AliceKeyPair.Agreement(GroupKeyPublic);</div><div class="gmail_default"><br></div><div class="gmail_default">            var ServerAgreeW = BobRecryption.Agreement(AlicePublic);</div><div class="gmail_default">            var BobAgreeW = BobDecryption.Agreement(AlicePublic, ServerAgreeW);</div><div class="gmail_default"><br></div><div class="gmail_default"><br></div><div class="gmail_default">            if (AliceAgreeW != BobAgreeW) {</div><div class="gmail_default">                Console.WriteLine("Fail");</div><div class="gmail_default">                }</div></div><div class="gmail_default"><br></div><div class="gmail_default">This is pretty similar to the previous verison. The only changes are making the recryption set (MakeRecryption) and there are now two agreement operations instead of one. The first is exactly the same as before and the second requires the output of the first as a 'carry'.</div><div class="gmail_default"><br></div><div class="gmail_default">One thing I don't much like about this approach is that it enforces sequential processing. That is pretty much inevitable with two parties. But with more parties you might well want to perform the agreement steps in one place and then the combination elsewhere.</div><div class="gmail_default"><br></div><div class="gmail_default"><div class="gmail_default"><div class="gmail_default">            var ServerRecrypt = BobRecryption.Agreement(AlicePublic);</div><div class="gmail_default">            var BobRecrypt = BobDecryption.Agreement(AlicePublic);</div><div class="gmail_default"><br></div><div class="gmail_default">            var Recrypts = new BigInteger[] { ServerRecrypt, BobRecrypt };</div><div class="gmail_default">            var BobAgreeW = BobDecryption.Agreement(Recrypts);</div></div><div><br></div><div>Does this make sense?</div><div><br></div><div>Here is the code that implements the methods:</div><div><br></div><div><div>        public BigInteger Agreement(DiffeHellmanPublic Public) {</div><div>            Verify(Public);</div><div>            return BigInteger.ModPow(Public.Public, Private, Modulus);</div><div>            }</div></div><div><div><br></div><div>        public BigInteger Agreement(DiffeHellmanPublic Public, BigInteger Carry) {</div><div>            Verify(Public);</div><div>            var Partial = Agreement(Public);</div><div>            return (Partial * Carry) % Modulus;</div><div>            }</div></div><div><br></div><div>If the basic framework is right, it should be possible to implement this for the curve-x algorithms. If I can work out what the functions corresponding to ModPow and * are from DJB's code.</div><div><br></div><div><br></div><div><br></div></div><div class="gmail_default"><br></div></div></div>