Source
pub const Endormorphism = struct {
const lambda: u256 = 37718080363155996902926221483475020450927657555482586988616620542887997980018;
const beta: u256 = 55594575648329892869085402983802832744385952214688224221778511981742606582254;
const lambda_s = s: {
var buf: [32]u8 = undefined;
mem.writeInt(u256, &buf, Endormorphism.lambda, .little);
break :s buf;
};
pub const SplitScalar = struct {
r1: [32]u8,
r2: [32]u8,
};
/// Compute r1 and r2 so that k = r1 + r2*lambda (mod L).
pub fn splitScalar(s: [32]u8, endian: std.builtin.Endian) NonCanonicalError!SplitScalar {
const b1_neg_s = comptime s: {
var buf: [32]u8 = undefined;
mem.writeInt(u256, &buf, 303414439467246543595250775667605759171, .little);
break :s buf;
};
const b2_neg_s = comptime s: {
var buf: [32]u8 = undefined;
mem.writeInt(u256, &buf, scalar.field_order - 64502973549206556628585045361533709077, .little);
break :s buf;
};
const k = mem.readInt(u256, &s, endian);
const t1 = math.mulWide(u256, k, 21949224512762693861512883645436906316123769664773102907882521278123970637873);
const t2 = math.mulWide(u256, k, 103246583619904461035481197785446227098457807945486720222659797044629401272177);
const c1 = @as(u128, @truncate(t1 >> 384)) + @as(u1, @truncate(t1 >> 383));
const c2 = @as(u128, @truncate(t2 >> 384)) + @as(u1, @truncate(t2 >> 383));
var buf: [32]u8 = undefined;
mem.writeInt(u256, &buf, c1, .little);
const c1x = try scalar.mul(buf, b1_neg_s, .little);
mem.writeInt(u256, &buf, c2, .little);
const c2x = try scalar.mul(buf, b2_neg_s, .little);
const r2 = try scalar.add(c1x, c2x, .little);
var r1 = try scalar.mul(r2, lambda_s, .little);
r1 = try scalar.sub(s, r1, .little);
return SplitScalar{ .r1 = r1, .r2 = r2 };
}
}