summaryrefslogtreecommitdiff
path: root/doc/effective_go.html
diff options
context:
space:
mode:
authorRob Pike <r@golang.org>2011-11-09 14:40:49 -0800
committerRob Pike <r@golang.org>2011-11-09 14:40:49 -0800
commit2529bbb82254c17271516edac4df18a0e9c6ba72 (patch)
treed84df2a821daabc7d20eb5c149157ab46aa81d6c /doc/effective_go.html
parent56fbb7d4b6d9012c4ba2a328e648de370b458d9c (diff)
downloadgo-2529bbb82254c17271516edac4df18a0e9c6ba72.tar.gz
effective_go: fix up the description of cipher blocks and streams
R=golang-dev, r, agl, dsymonds CC=golang-dev http://codereview.appspot.com/5374046
Diffstat (limited to 'doc/effective_go.html')
-rw-r--r--doc/effective_go.html56
1 files changed, 33 insertions, 23 deletions
diff --git a/doc/effective_go.html b/doc/effective_go.html
index 41c7206b8..bec95e5fb 100644
--- a/doc/effective_go.html
+++ b/doc/effective_go.html
@@ -1915,42 +1915,53 @@ the rest of the code is unaffected by the change of algorithm.
</p>
<p>
A similar approach allows the streaming cipher algorithms
-in the <code>crypto/block</code> package to be
+in the various <code>crypto</code> packages to be
separated from the block ciphers they chain together.
-By analogy with the <code>bufio</code> package,
-they wrap a <code>Cipher</code> interface
-and return <code>hash.Hash</code>,
-<code>io.Reader</code>, or <code>io.Writer</code>
-interface values, not specific implementations.
+The <code>Block</code> interface
+in the <code>crypto/cipher</code>package specifies the
+behavior of a block cipher, which provides encryption
+of a single block of data.
+Then, by analogy with the <code>bufio</code> package,
+cipher packages that implement this interface
+can be used to construct streaming ciphers, represented
+by the <code>Stream</code> interface, without
+knowing the details of the block encryption.
</p>
<p>
-The interface to <code>crypto/block</code> includes:
+The <code>crypto/cipher</code> interfaces look like this:
</p>
<pre>
-type Cipher interface {
+type Block interface {
BlockSize() int
Encrypt(src, dst []byte)
Decrypt(src, dst []byte)
}
-// NewECBDecrypter returns a reader that reads data
-// from r and decrypts it using c in electronic codebook (ECB) mode.
-func NewECBDecrypter(c Cipher, r io.Reader) io.Reader
+type Stream interface {
+ XORKeyStream(dst, src []byte)
+}
+</pre>
+
+<p>
+Here's the definition of the counter mode (CTR) stream,
+which turns a block cipher into a streaming cipher; notice
+that the block cipher's details are abstracted away:
+</p>
-// NewCBCDecrypter returns a reader that reads data
-// from r and decrypts it using c in cipher block chaining (CBC) mode
-// with the initialization vector iv.
-func NewCBCDecrypter(c Cipher, iv []byte, r io.Reader) io.Reader
+<pre>
+// NewCTR returns a Stream that encrypts/decrypts using the given Block in
+// counter mode. The length of iv must be the same as the Block's block size.
+func NewCTR(block Block, iv []byte) Stream
</pre>
<p>
-<code>NewECBDecrypter</code> and <code>NewCBCReader</code> apply not
+<code>NewCTR</code> applies not
just to one specific encryption algorithm and data source but to any
-implementation of the <code>Cipher</code> interface and any
-<code>io.Reader</code>. Because they return <code>io.Reader</code>
-interface values, replacing ECB
-encryption with CBC encryption is a localized change. The constructor
+implementation of the <code>Block</code> interface and any
+<code>Stream</code>. Because they return
+interface values, replacing CTR
+encryption with other encryption modes is a localized change. The constructor
calls must be edited, but because the surrounding code must treat the result only
-as an <code>io.Reader</code>, it won't notice the difference.
+as a <code>Stream</code>, it won't notice the difference.
</p>
<h3 id="interface_methods">Interfaces and methods</h3>
@@ -2930,8 +2941,7 @@ import (
&#34;text/template&#34;
)
-var // Q=17, R=18
-addr = flag.String(&#34;addr&#34;, &#34;:1718&#34;, &#34;http service address&#34;)
+var addr = flag.String(&#34;addr&#34;, &#34;:1718&#34;, &#34;http service address&#34;) // Q=17, R=18
var templ = template.Must(template.New(&#34;qr&#34;).Parse(templateStr))