edBytesToPoint function

EdPoint edBytesToPoint(
  1. Uint8List bytes
)

Implementation

EdPoint edBytesToPoint(Uint8List bytes) {
  if (bytes.length != 32) {
    throw ArgumentError('Invalid encoded point length (${bytes.length} bytes)');
  }

  final sign = (bytes[31] >> 7) & 1;
  final yBytes = Uint8List.fromList(bytes);
  yBytes[31] &= 0x7F;
  final y = edBytesToBigInt(yBytes);

  if (y >= ed25519P) {
    throw ArgumentError('Invalid point: y >= p');
  }

  final y2 = (y * y) % ed25519P;
  final u = (y2 - BigInt.one + ed25519P) % ed25519P;
  final v = (ed25519D * y2 + BigInt.one) % ed25519P;

  final v3 = (v * v % ed25519P * v) % ed25519P;
  final v7 = (v3 * v3 % ed25519P * v) % ed25519P;
  final uv7 = (u * v7) % ed25519P;

  final exp = (ed25519P - BigInt.from(5)) >> 3;
  var x = (u * v3 % ed25519P * uv7.modPow(exp, ed25519P)) % ed25519P;

  final vx2 = (v * x % ed25519P * x) % ed25519P;
  if (vx2 == u) {
    // x is correct
  } else if (vx2 == (ed25519P - u) % ed25519P) {
    x = (x * ed25519I) % ed25519P;
  } else {
    throw ArgumentError('Invalid point: no square root exists');
  }

  if (x == BigInt.zero && sign == 1) {
    throw ArgumentError('Invalid point: x is zero but sign bit is set');
  }

  if ((x.isOdd ? 1 : 0) != sign) {
    x = ed25519P - x;
  }

  return EdPoint(x, y);
}