[cap-talk] Mailkey works! (correction)

David Hopwood david.hopwood at industrial-designers.co.uk
Thu Jun 7 16:59:25 EDT 2007


David Hopwood wrote:
[...]
> # To remove the assumption of a universally trusted comparer, we have each domain
> # do comparison for its own objects. A domain can be any unit of distribution.
> #
> # For simplicity, this code is written to use immediate calls, even though it
> # really only makes sense in a distributed setting. In practice this functionality
> # would probably be built-in to the distribution protocol, making use of vats'
> # public/private keys instead of [domainSigner, domainVerifier].
> 
> def distributedCase {
>    to makeDomain(name :String) {
>       # Sealer/unsealer pairs can be used either with the unsealer private, for
>       # encryption, or with the sealer private, for authentication. Here we are
>       # using them for authentication.
>       def [domainSigner, domainVerifier] := makeBrand(name)
> 
>       # Same as the non-distributed case.
>       def [siblingSealer, siblingUnsealer] := makeBrand(`$name sibling`)
> 
>       def domain {
>          to getVerifier() :any { return domainVerifier }
> 
>          to makeAddressAndRevoker(var target) :[any, Thunk] {
>             def address {
>                # If we seal [x, y] using domainSigner, we are asserting that x and y
>                # both belong to this domain and are (forever) weakly equal.
> 
>                # I'm sure there is probably a simpler way of doing this.
> 
>                to getProofOfDomain() :any {
>                   return [domainVerifier, domainSigner.seal([address, address])]
>                }
>                to getProofOfWeakEqualityTo(other) :any {
>                   def [otherVerifier, otherProof] := other.getProofOfDomain()
> 
>                   try {
>                      if (otherVerifier != domainVerifier ||
>                          otherVerifier.unseal(otherProof) != other ||
>                          siblingUnsealer.unseal(address.getSealedTarget()) !=
>                            siblingUnsealer.unseal(other.getSealedTarget())) {
>                         return null
>                      }
>                      return [domainVerifier, domainSigner.seal([address, other])]
> 
>                   } catch _ {  # FIXME: more specific catch
>                      return null
>                   }
>                }
>                to getSealedTarget() :any { return siblingSealer.seal(target) }
> 
>                match [verb, args] { return E.call(target, verb, args) }
>             }
>             def revoker() { target := null }
> 
>             return [address, revoker]
>          }
>       }
>       return domain
>    }
> 
>    to weakEq(a, b) :boolean {
>       try {
>          def [aVerifier, aProof] := a.getProofOfDomain()
>          def [bVerifier, bProof] := b.getProofOfWeakEqualityTo(a)
> 
>          return aVerifier == bVerifier &&
>                 aVerifier.unseal(aProof) == [a, a] &&
>                 bVerifier.unseal(bProof) == [b, a]
> 
>       } catch _ {  # FIXME: more specific catch
>          return false
>       }
>    }
> 
>    to getDomainVerifier(a) :any {
>       def [aVerifier, aProof] := a.getProofOfDomain()
>       if (aVerifier.unseal(aProof) != a) {
                                        ^ should be [a, a]

(I originally had getProofOfDomain returning just
[domainVerifier, domainSigner.seal(address)], but was concerned about
"chosen protocol" attacks. Generally it's safer for all signatures performed
with a given signing key to be of things that have a common format and meaning.)

>          throw `$a failed to prove membership of $aVerifier`
>       }
>       return aVerifier
>    }
> }

-- 
David Hopwood <david.hopwood at industrial-designers.co.uk>



More information about the cap-talk mailing list