-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Value Sealing and Encryption #15
Comments
Of potential interest is some ability to apply homomorphic encryption, or at least a weaker ability to specify transformations for a sealed value without actually unsealing it (and without sharing the seal or unseal capabilities). I can think of a few potential approaches to represent this. It may be worth leaving a 'hole' in the design for such extensions, even if I don't get around to it for some time. |
For secure sealer/unsealer pairs, an ECC public key mechanism might work pretty well. It can allow much smaller key sizes compared to RSA (e.g. 384 bits, same size as a resource ID). I'll just need to beware of the dubious algorithms promoted by the NSA, e.g. looking instead into those used by Bitcoin and Namecoin. |
Need to remember: sealed values must use a block type, to preserve substructural properties. Maybe model a sealed value as a block to which you pass the key?
Internally, the block could use cipher-text and a common decryption capability. A key could itself be modeled as a special, sealed value that can only be provided by an unsealer capability (i.e. not just arbitrary text). For debugging purposes, we might want to further indicate this is a sealed value with some sort of 'brand' or 'hint' provided by the developer. For key-chain purposes, a developer may also wish to explicitly couple sealer or unsealer capabilities with other metadata. But having a block at the very bottom seems 'right' for modeling sealed values. |
I can't directly use a block, e.g. But I do need a block, still, to at least attribute the affine and relevance properties, and it does seem reasonable to wrap the cipher text within the block to make it a little more opaque. I could perhaps simply use |
Okay, last night I came up with a satisfying design for secure value sealing, using symbol '$' for secure sealers:
Serializations:
Here, the cipherText is basically the same as an ABC resource - compressed and encrypted, though the encryption in this case depends on the format. To regenerate the value, we'll decrypt and decompress the cipherText, then run it. It will have type The cipher text is wrapped in a block mostly so we can preserve substructural types of the sealed values: affine, relevant, etc. It is then marked as sealed with The format might be something like 'ecc.secp256k1' (to indicate the same, weak Elliptic curve cryptography used in Bitcoin). The default format string would be left blank. Most likely, we'll settle on just one common, default format. Elliptic curve cryptography is promising in general because it allows asymmetric encryption with relatively small keys (twice the size compared to symmetric key encryption). However, it seems that a lot of ECC curves are 'weak', including secp256k1, and it seems difficult to know whether a curve is intentionally weak as a honeypot. Using Bitcoin's exact curve is tempting, though, because I'd at least hear about it if broken. But there are other suggestions. Cf. safe curves |
In case of ECC encryption, it may be useful to apply 'point compression' on the public key. This takes a bit more time to recover the key, but less time to serialize it. And the key would be easily cached. OTOH, might be better just to send the whole key, if the savings would be marginal. |
At the moment, I have {:u} as type
a → Sealed :u a
for discretionary sealers, which serves a role similar tonewtype
in Haskell languages (i.e. you cannot accidentally use the value without correctly unsealing it, and we can test this at typecheck time typecheck this).But long term, I plan to have an secure API for acquiring fresh sealer/unsealer pairs. I need to progress further on this, though the need isn't pressing at the moment (it can wait until I'm really moving forward on distributed programming).
I must protect ABC's spatial idempotence property. Thus, I'll need either to linearize the sealer/unsealer pair generator, or to pass a linear 'uniqueness source' as an argument. I can still make a few decisions here, and I should review my ideas for source-stable uniqueness, i.e. 'splitting' the generator should involve a uniquely named child to ensure stable outputs.
Anyhow, my idea is that sealed values are not encrypted until serialization, i.e. such that if we seal then unseal a value without leaving a local machine we also never go through the encryption step. Also, 'discretionary sealed' values are never encrypted (i.e. they'll be quoted as
#42[{:foo}]$
or similar, even when sending the block to a remote system.The encrypted values will have a format something closer to:
"binaryCipherText\n~[{$!hint}]
(cf. #12 for binary encoding). I must to decide on a standard naming convention, slightly different from true sealers, but$
isn't a bad prefix. We could use$:
for the sealer,$.
for the unsealer, and$!
for the sealed encrypted value.What is the cipher text? In this case, it should simply be a representation of more ABC, likely compressed using the exact same algorithm as ABC resources, of type 1→Value. So the unsealer will decrypt this, then compute the value.
The text was updated successfully, but these errors were encountered: