structstd.crypto.pcurves.secp256k1.Secp256k1.Endormorphism[src]

Functions

FunctionsplitScalar[src]

pub fn splitScalar(s: [32]u8, endian: std.builtin.Endian) NonCanonicalError!SplitScalar

Compute r1 and r2 so that k = r1 + r2*lambda (mod L).

Parameters

s: [32]u8

Source Code

Source code
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 };
}

Source Code

Source code
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 };
    }
}