Re: [Cfrg] Feedback on: draft-irtf-cfrg-chacha20-poly1305-01

"Parkinson, Sean" <> Sun, 12 October 2014 22:50 UTC

Return-Path: <>
Received: from localhost ( []) by (Postfix) with ESMTP id BD3BE1A9125 for <>; Sun, 12 Oct 2014 15:50:34 -0700 (PDT)
X-Virus-Scanned: amavisd-new at
X-Spam-Flag: NO
X-Spam-Score: -1
X-Spam-Status: No, score=-1 tagged_above=-999 required=5 tests=[BAYES_50=0.8, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HTML_MESSAGE=0.001, J_CHICKENPOX_46=0.6, RCVD_IN_DNSWL_MED=-2.3, SPF_PASS=-0.001] autolearn=ham
Received: from ([]) by localhost ( []) (amavisd-new, port 10024) with ESMTP id z3lv2GXZ2EKi for <>; Sun, 12 Oct 2014 15:50:30 -0700 (PDT)
Received: from ( []) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by (Postfix) with ESMTPS id 508081A9128 for <>; Sun, 12 Oct 2014 15:50:30 -0700 (PDT)
Received: from ( []) by (Sentrion-MTA-4.3.0/Sentrion-MTA-4.3.0) with ESMTP id s9CMoRbI017656 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Sun, 12 Oct 2014 18:50:27 -0400
X-DKIM: OpenDKIM Filter v2.4.3 s9CMoRbI017656
DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed;; s=jan2013; t=1413154228; bh=PQNN/f7XWfd7Ikm1WDofCSo1pyY=; h=From:To:CC:Date:Subject:Message-ID:References:In-Reply-To: Content-Type:MIME-Version; b=mWpXiFx0iFyc2Gchhl9jzwhmu0iNp3kqHR1KW1I6QwNsQBJNhoVraX1MBaiAu11bI eXHo4f2IBCQEr7vFp8OYc29O9347SWDBmx7wD+eaPlxs3VDdeZJSNwf1F+i10BM1/k 4mS/dQCzflD+aa2rw8JDt1CuuWD8ZnAKNPuzRDVs=
X-DKIM: OpenDKIM Filter v2.4.3 s9CMoRbI017656
Received: from ( []) by (RSA Interceptor); Sun, 12 Oct 2014 18:49:58 -0400
Received: from ( []) by (Sentrion-MTA-4.3.0/Sentrion-MTA-4.3.0) with ESMTP id s9CMo7Lc030213 (version=TLSv1/SSLv3 cipher=AES128-SHA bits=128 verify=FAIL); Sun, 12 Oct 2014 18:50:08 -0400
Received: from ([]) by ([]) with mapi; Sun, 12 Oct 2014 18:50:07 -0400
From: "Parkinson, Sean" <>
To: Yoav Nir <>
Date: Sun, 12 Oct 2014 18:50:04 -0400
Thread-Topic: Feedback on: draft-irtf-cfrg-chacha20-poly1305-01
Thread-Index: Ac/mLayTjrBjTuD2QyiFE9j68lZxywAP8kRw
Message-ID: <>
References: <> <>
In-Reply-To: <>
Accept-Language: en-US
Content-Language: en-US
acceptlanguage: en-US
Content-Type: multipart/alternative; boundary="_000_2FBC676C3BBFBB4AA82945763B361DE60A76B074MX17Acorpemccom_"
MIME-Version: 1.0
X-RSA-Classifications: public
Cc: "" <>
Subject: Re: [Cfrg] Feedback on: draft-irtf-cfrg-chacha20-poly1305-01
X-Mailman-Version: 2.1.15
Precedence: list
List-Id: Crypto Forum Research Group <>
List-Unsubscribe: <>, <>
List-Archive: <>
List-Post: <>
List-Help: <>
List-Subscribe: <>, <>
X-List-Received-Date: Sun, 12 Oct 2014 22:50:34 -0000

Hi Yoav,

I was intrigued by the idea of using these algorithms and thought I would have a go at implementing them based on the draft.
Here are some comments I have that could help clarify the descriptions for implementers.

First of all I would like to say that I was able to quickly implement the algorithms so I think all of the details are there. What I'm going to suggest are things  that will make it a simpler for an implementer to pick out what they need to do and make it easier to verify the implementation.
1.            The ChaCha quarter round description (2.1) is not really C code. It is a mathematical description. The steps are ordered and therefore should be numbered. The worked example is good for clarity and should use values that show up edge cases: b=0xffeeddcc, a=0x77777777. Rotate by 7 rather than 16 and it is clearer that you have rotated the correct direction.
2.            In the worked example in 2.2.1 it might be helpful to highlight the modified values using, say, a bold font if possible.
3.            In section 2.3, the state and the block are mixed in together. How about separating the 'inner block' (where the quarter rounds are performed) out into its own section?
4.            In section 2.3, putting the adding of the original input words into an algorithm description would help implementers 'tick-off' that they have got all the parts done. Something like:
chacha20_block(key, counter, nonce):
state = key | counter | nonce
working_state = state
for i=1 upto 10
state += working_state
5.            In section 2.3, saying there are 20 rounds but combining the two rounds into one step is confusing. Saying there are 10 rounds of the following 8 steps explicitly could remove the confusion.
6.            In section 2.3, the whole endian thing is very confusing. Thankfully the worked example makes this clear.
7.            In section 2.4, an algorithmic representation of the block counter incrementing would be helpful. Something like:
chacha20_encrypt(key, counter, nonce, plaintext):
for counter=1 upto ceil(length of plaintext in bytes / 64)
     key_stream = chacha20_block(key, counter, nonce)
     encrypted_message += plaintext[((counter-1)*64)..(counter*64-1)] ^ key_stream
8.            In section 2.4, say that a key-stream block can be XOR-ed with a plaintext block before proceeding. Implementation detail should, I think, be kept for a later section.
9.            In section 2.4, a minor quibble but, copying the plaintext and ciphertext into test code is a little difficult.
10.          In section 2.5, a proper algorithmic description would be nice. Something like:
clamp(r): r &= 0x0fffff0c0ffffffc0ffffffcffffffff
poly1305_mac(msg, tag, key):
r = clamp(le_bytes_to_num(tag))
s = le_num(key)
accumulator = 0
p = (1<<130)-5
for i=1 upto ceil(msg length in bytes / 16)
     n = le_bytes_to_num([0x01] | msg[((i-1)*16)..(i*16)])
     a += n
     a = (r * a) % p
a += s
11.          In section 2.6, an algorithmic description would be good too:
poly1305_key_gen(key, iv, constant):
counter = 0
chacha20_block(key, counter, constant | iv)[0..31]
12.          In section 2.8 there is a lot of text and an algorithmic description would be better. Something like:
chacha20_aead_encrypt(aad, key, iv, constant, plaintext):
k = poly1305_key_gen(key, iv, constant)
ciphertext = chacha_encrypt(key, 1, constant | iv, plaintext)
mac_data = aad | [0]*((16 - (aad.length & 15)) & 15)
mac_data |= ciphertext | [0]*((16 - (ciphertext.length & 15)) & 15)
mac_data |= num_to_4_le_bytes(aad.length)
mac_data |= num_to_4_le_bytes(ciphertext.length)
tag = poly1305_mac(mac_data, k[0..15], k[16..31])
(ciphertext, tag)

Hope this is helpful,
Sean Parkinson | Consultant Software Engineer | RSA, The Security Division of EMC
Office +61 7 3032 5232 | Fax +61 7 3032 5299<>