pssht  latest
SSH server library written in PHP
Poly1305.php
1 <?php
2 
3 /*
4 * This file is part of pssht.
5 *
6 * (c) François Poirotte <clicky@erebot.net>
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11 
13 
22 class Poly1305
23 {
25  protected $r;
26 
28  protected $s;
29 
30  public function __construct($key)
31  {
32  if (strlen($key) !== 32) {
33  throw new \InvalidArgumentException();
34  }
35 
36  $r = substr($key, 0, 16);
37  $s = substr($key, 16);
38  $t1 = "\x0F";
39  $t2 = "\xFC";
40  $r[ 3] = $r[ 3] & $t1;
41  $r[ 4] = $r[ 4] & $t2;
42  $r[ 7] = $r[ 7] & $t1;
43  $r[ 8] = $r[ 8] & $t2;
44  $r[11] = $r[11] & $t1;
45  $r[12] = $r[12] & $t2;
46  $r[15] = $r[15] & $t1;
47  $this->s = gmp_init(bin2hex(strrev($s)), 16);
48  $this->r = gmp_init(bin2hex(strrev($r)), 16);
49  }
50 
51  public function mac($message)
52  {
53  $res = gmp_init(0);
54  if ($message !== '') {
55  $chunks = str_split($message, 16);
56  $q = count($chunks);
57  foreach ($chunks as $i => $chunk) {
58  $t = gmp_init(bin2hex(strrev($chunk . "\x01")), 16);
59  $res = gmp_add($res, gmp_mul($t, gmp_pow($this->r, $q - $i)));
60  }
61  $res = gmp_mod($res, gmp_sub(gmp_pow(2, 130), 5));
62  }
63 
64  $res = gmp_mod(gmp_add($res, $this->s), gmp_pow(2, 128));
65  return strrev(pack('H*', str_pad(gmp_strval($res, 16), 32, '0', STR_PAD_LEFT)));
66  }
67 }
$r
First half of the secret key (second half in the spec. due to endianness).
Definition: Poly1305.php:25
$s
Second half of the secret key.
Definition: Poly1305.php:28