~/bend-docscommunity

spec/crypto/poly1305.bend checks

raw source on the hub · import 0xd9a2fae439ac7ff9e21e0853948f94fe/spec/crypto/poly1305.bend as Poly1305

2 imports
import Base
import ../lib/common.bend as C

Definitions

def p source · line 24 · raw

Nat

p = 2^130 - 5

def fold source · line 29 · raw

@+x:Nat -> Nat

x = lo + 2^130 hi is congruent to lo + 5 hi mod p (2^130 = p + 5); the fold strictly decreases x while hi > 0, so x folds bring x below 2^130.

def folds source · line 32 · raw

@n:Nat -> @x:Nat -> Nat

def pick source · line 37 · raw

@b:Bool -> @x:Nat -> @y:Nat -> Nat

def canon source · line 43 · raw

@+y:Nat -> Nat

y < 2^130: y itself when y < p, else y - p = (y + 5) - 2^130.

def modp source · line 49 · raw

@+x:Nat -> Nat

x mod p

def le_num source · line 53 · raw

@bytes:List<&2, U32> -> Nat

le_bytes_to_num

def le_bytes source · line 59 · raw

@n:Nat -> @+x:Nat -> List<&2, U32>

num_to_n_le_bytes: the low n bytes of x.

def prefix source · line 64 · raw

@n:Nat -> @xs:List<&2, U32> -> List<&2, U32>

def suffix source · line 70 · raw

@n:Nat -> @xs:List<&2, U32> -> List<&2, U32>

def clamp_mask source · line 78 · raw

@i:Nat -> U32

clamp(r): r &= 0x0ffffffc0ffffffc0ffffffc0fffffff, i.e. r[3], r[7], r[11] and r[15] keep their low four bits, r[4], r[8] and r[12] lose their low two.

def clamp_from source · line 89 · raw

@r:List<&2, U32> -> @+i:Nat -> List<&2, U32>

def clamp source · line 94 · raw

@r:List<&2, U32> -> List<&2, U32>

def blocks source · line 99 · raw

@fuel:Nat -> @+msg:List<&2, U32> -> List<&2, List<&2, U32>>

The message cut into 16-byte blocks, the last one possibly shorter; fuel bounds the number of blocks (the length of the message is enough).

def absorb source · line 106 · raw

@bs:List<&2, List<&2, U32>> -> @+r:Nat -> @a:Nat -> Nat

for each block: n = le_bytes_to_num(block | [0x01]); a += n; a = (r * a) % p

def poly1305_mac source · line 115 · raw

@+key:List<&2, U32> -> @+msg:List<&2, U32> -> List<&2, U32>

poly1305_mac(msg, key): r = clamp(key[0..16]), s = key[16..32]; a = 0, absorb every block, a += s; the tag is num_to_16_le_bytes(a).

def mac source · line 122 · raw

@+key:List<&2, U32> -> @+msg:List<&2, U32> -> List<&2, U32>

The same function, split on the message first so that a proof about an unknown message does not unfold it.

def coeff source · line 136 · raw

@b:List<&2, U32> -> Nat

RFC 8439 2.5 describes the accumulator as the evaluation, at r and modulo p, of the polynomial whose coefficients are the blocks (each with its 0x01 byte): with q blocks n_1 .. n_q, poly(r) = n_1 r^q + n_2 r^(q-1) + ... + n_q r (as Spec.Poly1305 in HACL* and the field statements of Mathlib's ZMod p). Clause absorb_poly (proofs/crypto/poly1305/poly.bend) proves absorb(blocks, r, 0) == poly(blocks, r) mod (2^130 - 5).

def poly source · line 139 · raw

@+bs:List<&2, List<&2, U32>> -> @+r:Nat -> Nat