You are here

public static function ParagonIE_Sodium_Core_X25519::crypto_scalarmult_curve25519_ref10 in Automatic Updates 7

Same name and namespace in other branches
  1. 8 vendor/paragonie/sodium_compat/src/Core/X25519.php \ParagonIE_Sodium_Core_X25519::crypto_scalarmult_curve25519_ref10()

@internal You should not use this directly from another application

Inline comments preceded by # are from libsodium's ref10 code.

Parameters

string $n:

string $p:

Return value

string

Throws

SodiumException

TypeError

1 call to ParagonIE_Sodium_Core_X25519::crypto_scalarmult_curve25519_ref10()
ParagonIE_Sodium_Crypto::scalarmult in vendor/paragonie/sodium_compat/src/Crypto.php
ECDH over Curve25519

File

vendor/paragonie/sodium_compat/src/Core/X25519.php, line 161

Class

ParagonIE_Sodium_Core_X25519
Class ParagonIE_Sodium_Core_X25519

Code

public static function crypto_scalarmult_curve25519_ref10($n, $p) {

  # for (i = 0;i < 32;++i) e[i] = n[i];
  $e = '' . $n;

  # e[0] &= 248;
  $e[0] = self::intToChr(self::chrToInt($e[0]) & 248);

  # e[31] &= 127;

  # e[31] |= 64;
  $e[31] = self::intToChr(self::chrToInt($e[31]) & 127 | 64);

  # fe_frombytes(x1,p);
  $x1 = self::fe_frombytes($p);

  # fe_1(x2);
  $x2 = self::fe_1();

  # fe_0(z2);
  $z2 = self::fe_0();

  # fe_copy(x3,x1);
  $x3 = self::fe_copy($x1);

  # fe_1(z3);
  $z3 = self::fe_1();

  # swap = 0;

  /** @var int $swap */
  $swap = 0;

  # for (pos = 254;pos >= 0;--pos) {
  for ($pos = 254; $pos >= 0; --$pos) {

    # b = e[pos / 8] >> (pos & 7);

    /** @var int $b */
    $b = self::chrToInt($e[(int) floor($pos / 8)]) >> ($pos & 7);

    # b &= 1;
    $b &= 1;

    # swap ^= b;
    $swap ^= $b;

    # fe_cswap(x2,x3,swap);
    self::fe_cswap($x2, $x3, $swap);

    # fe_cswap(z2,z3,swap);
    self::fe_cswap($z2, $z3, $swap);

    # swap = b;
    $swap = $b;

    # fe_sub(tmp0,x3,z3);
    $tmp0 = self::fe_sub($x3, $z3);

    # fe_sub(tmp1,x2,z2);
    $tmp1 = self::fe_sub($x2, $z2);

    # fe_add(x2,x2,z2);
    $x2 = self::fe_add($x2, $z2);

    # fe_add(z2,x3,z3);
    $z2 = self::fe_add($x3, $z3);

    # fe_mul(z3,tmp0,x2);
    $z3 = self::fe_mul($tmp0, $x2);

    # fe_mul(z2,z2,tmp1);
    $z2 = self::fe_mul($z2, $tmp1);

    # fe_sq(tmp0,tmp1);
    $tmp0 = self::fe_sq($tmp1);

    # fe_sq(tmp1,x2);
    $tmp1 = self::fe_sq($x2);

    # fe_add(x3,z3,z2);
    $x3 = self::fe_add($z3, $z2);

    # fe_sub(z2,z3,z2);
    $z2 = self::fe_sub($z3, $z2);

    # fe_mul(x2,tmp1,tmp0);
    $x2 = self::fe_mul($tmp1, $tmp0);

    # fe_sub(tmp1,tmp1,tmp0);
    $tmp1 = self::fe_sub($tmp1, $tmp0);

    # fe_sq(z2,z2);
    $z2 = self::fe_sq($z2);

    # fe_mul121666(z3,tmp1);
    $z3 = self::fe_mul121666($tmp1);

    # fe_sq(x3,x3);
    $x3 = self::fe_sq($x3);

    # fe_add(tmp0,tmp0,z3);
    $tmp0 = self::fe_add($tmp0, $z3);

    # fe_mul(z3,x1,z2);
    $z3 = self::fe_mul($x1, $z2);

    # fe_mul(z2,tmp1,tmp0);
    $z2 = self::fe_mul($tmp1, $tmp0);
  }

  # fe_cswap(x2,x3,swap);
  self::fe_cswap($x2, $x3, $swap);

  # fe_cswap(z2,z3,swap);
  self::fe_cswap($z2, $z3, $swap);

  # fe_invert(z2,z2);
  $z2 = self::fe_invert($z2);

  # fe_mul(x2,x2,z2);
  $x2 = self::fe_mul($x2, $z2);

  # fe_tobytes(q,x2);
  return self::fe_tobytes($x2);
}