# Poly1305 one-time authenticator This unit implements the Poly1305 universal hash family which is mainly used as a one-time authenticator, that is, it can verify the authenticity of a message given a shared secret key. This mainly allows the creation of authenticated encryption. This solves the issue of knowing whether a received encrypted message has been tampered with. To use Poly1305, one initializes it with a key. A key is always 32-bytes long. Then after updating the structure a number of time, the Poly1305 is finished and returns a Message Authentication Code. This MAC is always 16-bytes long. A MAC, also called tag, is proved to be unique for a message-key pair. ## Security considerations This implementation hasn't been reviewed nor audited by any competent authority. It is provided purely as a best effort basis and the port of a C implementation made to be as portable as possible. As it is a *one-time* authenticator, a key should be used to identify a *single* message. This key must remain secret and shared between involved parties only. Reusing the same key for two different messages make it very easy for an attacker to forge messages. In order to minimize the choices for the user, Poly1305 is often be embedded in a structure which takes care of this aspect. ## API ### Struct struct Poly1305 { [uchar,BLKSZ] pbuffer ; [uint,5] _tmp polyr polyh ; [uint,10] polyd ; [uint,8] polypad ; uint leftover highbit ; } ### Words newPoly1305 ( a -- poly1305 ) Initialize a new Poly1305 for authentication from the given key located at address "a". A key is always 32-bytes long. Poly1305$ ( a poly1305 -- ) Reinitialize a potentially finished Poly1305 structure so it can be reused. "poly1305" is an address which must be *aligned to 4 bytes*. "a" is the address of the 32-bytes long key. update ( a u poly1305 -- ) This is the main word used to authenticate messages. This "update" method is akin to a streaming API where a message can be progressively accumulated to be authenticated. In order to get maximum performance from this implementation, "a" should be aligned to 4 bytes and "u" should be a multiple of 16. finish ( poly1305 -- a ) Finish the authentication of the given message and return a 16-bytes long Message Authentication Code. This can then be compared against another MAC to known whether a message comes from the right sender. verify ( a a -- f ) Checks whether two MACs are the same. This helper word works similar to "c[]=" for MACs. This verification is implemented in constant time in order to avoid side-channel attacks. ## See also This unit is a port of poly1305-donna to HAL, the logic comes from there. * https://github.com/floodyberry/poly1305-donna * The Poly1305-AES message-authentication code, Daniel J. Bernstein * RFC 8439