JubJubAffineNativePoint.fromBytes constructor
JubJubAffineNativePoint.fromBytes(
- List<int> bytes, {
- bool zip216Enabled = false,
})
Implementation
factory JubJubAffineNativePoint.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 = JubJubNativeFq.fromBytes(b);
final v2 = v.square();
// u^2 = (v^2 - 1) / (1 + d*v^2)
final denominator = (JubJubNativeFq.one() + JubJubNativeFq.edwardsD() * v2);
JubJubNativeFq invDenominator =
denominator.invert() ?? JubJubNativeFq.zero();
final u2 = (v2 - JubJubNativeFq.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 = flipSign ? -u : u;
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 JubJubAffineNativePoint(u: finalU, v: v);
}