JubJubAffinePoint.fromBytes constructor
JubJubAffinePoint.fromBytes(
- List<int> bytes, {
- bool zip216Enabled = false,
})
Implementation
factory JubJubAffinePoint.fromBytes(
List<int> bytes, {
bool zip216Enabled = false,
}) {
final b =
bytes
.exc(
length: 32,
operation: "fromBytes",
reason: "Invalid point encoding bytes length.",
)
.clone();
// Grab the sign bit
final sign = (b[31] >> 7).toU8;
// Mask away the sign bit
b[31] &= 0x7F;
// Interpret remaining bytes as v-coordinate
final v = JubJubFq.fromBytes(b);
final v2 = v.square();
// u^2 = (v^2 - 1) / (1 + d*v^2)
final denominator = JubJubFq.one() + JubJubFq.edwardsD() * v2;
JubJubFq invDenominator = denominator.invert() ?? JubJubFq.zero();
final u2 = (v2 - JubJubFq.one()) * invDenominator;
final u = u2.sqrt().sqrtOrNull();
if (u == null) {
throw ArgumentException.invalidOperationArguments(
"JubJubAffinePoint",
reason: "Invalid point encoding bytes.",
);
}
// Fix the sign of u if necessary
final flipSign = ((u.toBytes()[0] ^ sign) & 1) == 1;
final finalU = JubJubFq.conditionalSelect(u, -u, flipSign);
final uIsZero = u.isZero();
// ZIP 216 check: reject encoding if enabled and u == 0 and flipSign == true
final isValid = !(zip216Enabled && uIsZero && flipSign);
if (!isValid) {
throw ArgumentException.invalidOperationArguments(
"JubJubAffinePoint",
reason: "Invalid point encoding bytes.",
);
}
return JubJubAffinePoint(u: finalU, v: v);
}