A stab at the sealer in E

Mark S. Miller markm@caplet.com
Tue, 02 Nov 1999 17:39:18 -0800


At 04:57 PM 11/2/99 , Ka-Ping Yee wrote:

>Notes:
>     1.  This is personal, but it seems surprising that "==" means
>         object identity here, and i can imagine a novice asking
>         "Why can't i get the contents of just any envelope with
>         envelope getContents([])?"  I'm very hooked on Python's
>         "is" and "is not" operators.

You'll have to remind me about Python's equality semantics.  Not knowing
which is Python's object identity operation, or what the other means, I did
not get the point of your comment.

>     2.  I wandered through the E language documentation to find the
>         proper syntax for throwing an exception, and at first
>         thought that the lack of a "throw expression" section on
>         the grammar page was an omission.  Now i realize that
>         "throw" must be a function object provided by the big bang,
>         but you might want to make this more explicit on the
>         grammar page.  In general it was tricky to find the info
>         i needed to throw the right kind of exception (no sealer
>         documentation yet, throw signature not mentioned on grammar
>         page, no UnsealingException signature until i went to the
>         Java docs).

You are correct.  The state of documentation on the E language still sucks.
I believe I (or MarcS?) once asked you to hold off contributing writings
during a time when I was doing more writing.  I believe we made a mistake.
Documentation contributions would be most welcome from everyone!  I will, of
course, act as editor before posting any docs on the erights site.

>     3.  In the above i am using the convention of a leading _ for
>         private variables, often seen in C++.  Perhaps this could
>         be another useful sanity check: variables whose names
>         begin with _ are never intended to escape outside the
>         scope in which they were defined.

I like the idea of having such a convention.  In fact, I like it a lot!!  My
immediate reaction is that I hate leading "_" as a convention, but maybe I
would get used to it.

>     4.  The above is not tested in E.  I just wrote it in a text
>         editor (which happens to be vim with E highlighting :) ).
>
>Does this work?

Here is the subset of your code with the problems:

>     define BrandMaker make(name) {
>         define _key := []
>         define EnvelopeMaker make(contents) {
>             define Envelope {
>                 to getContents(key) : any {
>                     if (key == _key) {
>                         contents
>                     }
>                 }
>             }
>         }
>         define unsealer {
>             to unseal(envelope) : any {
>                 envelope getContents(_key)
>             }
>         }

Actually, this code contains two problems, one trivial and one interesting.

The trivial one:

"[]" evaluates to a ConstList.  ConstLists are PassByCopy and hence without
object identity.  "==" on two ConstLists compares contents rather than
identity.  Were this not the case, it would not be semantics-preserving to
copy them when passed over the network.  This problem is easily fixed by
saying either "[] diverge" or "define _ {}" instead, in order to trivially
create fresh objects with object identity.

The interesting one:

Let's say your code was being used by the mint in our MintMaker example,
and, of course, that Alice and Bob know this.  Without trusting Alice,
Bob wishes to deposit a payment from Alice and only dispense some service or
whatever if he's actually been paid.  The mint, of course, trusts neither
Alice nor Bob, and must preserve the integrity of money despite their
possible misbehavior.  Here's how a dishonest Alice can create a BadPurse
that fools Bob and violates conservation of the mint's currency.

     ? define keyStash := null
     ? define BadPurse {
     >     to getDecr : any {
     >         define BadEnvelope {
     >             to getContents(key) : any {
     >                 keyStash := key
     >                 define BadDecr(amount) {
     >                     # do nothing silently
     >                 }
     >             }
     >         }
     >     }
     > }

The problem is that the unsealer is giving the alleged envelope the key it
is supposed to keep secret.  In fact, you could have caught this security
breach using your own suggested convention!  The line
"envelope getContents(_key)" visibly passes out a variable that starts with
an underbar.

Alice's BadPurse, when asked for an envelope encapsulating the decr
function, hands back a BadEnvelope.  Bob's purse then gives Alice's
BadEnvelope the key to the mint!  The BadEnvelope then puts or send this
somewhere where Alice can then use it to engage in further mischief.
Finally, Alice's BadDecr function does not decrement anything but claims to
succeed, by returning without throwing an exception, fooling Bob's Purse
into incrementing its balance and reporting success to Bob.


         Cheers,
         --MarkM