Skip to content
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

New abstract.Cipher interface #11

Closed
wants to merge 31 commits into from
Closed

New abstract.Cipher interface #11

wants to merge 31 commits into from

Conversation

bford
Copy link
Contributor

@bford bford commented Jan 12, 2015

This branch represents a significant batch of changes that I hope to merge in the next day or two, but would like to seek comment on first if anyone has feedback.

The main change is to create a new interface 'abstract.Cipher' representing a generic "all-purpose symmetric cipher" abstraction that can subsume block/stream ciphers, hash functions, authenticated encryption functionality, and in effect basically all the useful symmetric cipher functionality we know of. The current main implementation of abstract.Cipher, also in this set of changes, is based on the SHA3 or "Keccak" sponge function, which slightly contrary to the "SHA3" name is far more general than just a hash function. For background on the amazingly awesome coolness of cryptographic sponge functions, see for example: http://sponge.noekeon.org

The main impact of this change that will directly impact other code is probably just that you'll now have to call 'suite.Cipher()' instead of 'suite.Stream()' to get one of these general Cipher instances from the cipher suite. The new Cipher interface is backward-compatible with the old cipher.Stream interface, however, so an instance of Cipher will work fine wherever a cipher.Stream was used before. (I haven't decided whether or not to retain this backward-compatibility provision in the long term, but it isn't very cumbersome to do so I'm inclined to.)

But the more significant impact is the expressiveness and ease with which I believe this new interface allows us to do a lot of common things we need to do with symmetric ciphers. Here's one quick example of how it simplified authenticated-encryption, from anon/enc.go:

OLD anon/enc:
@@ -148,21 +145,18 @@ func Encrypt(suite abstract.Suite, rand cipher.Stream, message []byte,
anonymitySet Set, hide bool) []byte {

    xb,hdr := encryptKey(suite, rand, anonymitySet, hide)

    // We now know the ciphertext layout
  •   hdrlen := len(hdr)
    
  •   msglen := len(message)
    
  •   maclen := suite.KeyLen()
    
  •   ciphertext := make([]byte, hdrlen+msglen+maclen)
    copy(ciphertext,hdr)
    
    // Now encrypt and MAC the message based on the master secret
    
  •   stream := abstract.HashStream(suite, xb, nil)
    
  •   mackey := random.Bytes(maclen, stream)
    
  •   mac := hmac.New(suite.Hash, mackey)
    
  •   stream.XORKeyStream(ciphertext[hdrlen:hdrlen+msglen], message)
    
  •   mac.Write(ciphertext[:hdrlen+msglen])
    
  •   ciphertext = mac.Sum(ciphertext[:hdrlen+msglen])[:hdrlen+msglen+maclen]
    return ciphertext
    
    }

NEW anon/enc.go:
anonymitySet Set, hide bool) []byte {

    xb,hdr := encryptKey(suite, rand, anonymitySet, hide)
  •   cipher := suite.Cipher(xb, abstract.Encrypt)
    
    // We now know the ciphertext layout
    
  •   hdrhi := 0 + len(hdr)
    
  •   msghi := hdrhi + len(message)
    
  •   machi := msghi + cipher.KeySize()
    
  •   ciphertext := make([]byte, machi)
    copy(ciphertext,hdr)
    
    // Now encrypt and MAC the message based on the master secret
    
  •   cipher.Crypt(ciphertext[hdrhi:msghi], message)
    
  •   cipher.Crypt(ciphertext[msghi:machi], nil) // MAC
    return ciphertext
    
    }

I believe this general-purpose Cipher interface may be at least marginally useful and interesting from a research perspective, as a possible high-level "narrow-waist" or "hourglass-interface" abstraction for symmetric-key crypto in general. I've started a sketch of a write-up on this idea in the papers/net/cipher directory of the papers repo for anyone interested, but it's still just a skeleton and probably not very readable yet. Anyone wanting to work on fleshing this out and exploring it further, feel free to volunteer.

In any case, I have NOT yet updated all the higher-level crypto functionality throughout the library to take advantage of the features of the new Cipher interface; there are still lingering uses of hash functions and HMACs in which code could probably simplified (and perhaps made more efficient) by making it use the Cipher interface. We can do these cleanups and simplifications incrementally as we get to them.

Thanks
Bryan

still very experimental universal cipher API...
Conflicts:
	sponge/aead.go
	sponge/block.go
	sponge/stream.go
and benchmark it against the cleaner and more state-of-the-art SHA3.
Verdict: SHA3 kicks ass.
version dated Sun Jun 8 21:21:28 2014 +0200,
commit 17f7f8363875a67487ec2d7d4177b98e91517e1a
update all current ciphersuites to provide a SHA3 SHAKE-based Cipher.
in part because it's trivial and the I/O interface is pervasive in Go,
and partly so that abstract.Read() can be given a Cipher
in order to construct objects pseudorandomly.
and provide generic implementations that "do the right thing"
including when decoding from cryptographic randomness (Stream or Cipher).
This simplifies and cleans up the generic object Read and Write code.
replace all uses with the new general Cipher constructor instead.
As a result, all uses of the stream Cipher have transitioned
from AES-CTR-128 to SHAKE128.
and considerably simplified a number of the high-level crypto packages
by migrating them to the new general Cipher interface.
by moving encoding/decoding helper functions to separate group package
since all current and pausible uses only deal with
complete Capacity-size (or perhaps in the future State-size)
sponge input/output buffers anyway.
@bford
Copy link
Contributor Author

bford commented Jan 12, 2015

Closing this in favor of an inter-branch pull in the same repo as suggested by Danny (#12 (comment)).

@bford bford closed this Jan 12, 2015
samanklesaria pushed a commit to samanklesaria/crypto that referenced this pull request Mar 24, 2015
Evaluation Branch -- code for evaluation and the refactoring and changes needed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants