# 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
