edBytesToPoint function
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);
}