diff --git a/icicle/include/icicle/curves/params/bls12_377.h b/icicle/include/icicle/curves/params/bls12_377.h index da19ab2bd..6ad767e5f 100644 --- a/icicle/include/icicle/curves/params/bls12_377.h +++ b/icicle/include/icicle/curves/params/bls12_377.h @@ -25,6 +25,9 @@ namespace bls12_377 { static constexpr point_field_t weierstrass_b = {0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}; + + static constexpr bool is_b_u32 = true; + static constexpr bool is_b_neg = false; }; // G1 struct G2 { @@ -47,6 +50,11 @@ namespace bls12_377 { 0x3c6bf800, 0x129207b6, 0xcd5fd889, 0xdc7b4f91, 0x7460c589, 0x43bd0373, 0xdb0fd6f3, 0x010222f6}; + static constexpr bool is_b_u32_g2_re = true; + static constexpr bool is_b_neg_g2_re = false; + static constexpr bool is_b_u32_g2_im = false; + static constexpr bool is_b_neg_g2_im = false; + static constexpr g2_point_field_t gen_x = {g2_gen_x_re, g2_gen_x_im}; static constexpr g2_point_field_t gen_y = {g2_gen_y_re, g2_gen_y_im}; static constexpr g2_point_field_t weierstrass_b = {weierstrass_b_g2_re, weierstrass_b_g2_im}; diff --git a/icicle/include/icicle/curves/params/bls12_381.h b/icicle/include/icicle/curves/params/bls12_381.h index 7457bd49c..18fbf9749 100644 --- a/icicle/include/icicle/curves/params/bls12_381.h +++ b/icicle/include/icicle/curves/params/bls12_381.h @@ -25,6 +25,9 @@ namespace bls12_381 { static constexpr point_field_t weierstrass_b = {0x00000004, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}; + + static constexpr bool is_b_u32 = true; + static constexpr bool is_b_neg = false; }; struct G2 { @@ -48,6 +51,11 @@ namespace bls12_381 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}; + static constexpr bool is_b_u32_g2_re = true; + static constexpr bool is_b_neg_g2_re = false; + static constexpr bool is_b_u32_g2_im = true; + static constexpr bool is_b_neg_g2_im = false; + static constexpr g2_point_field_t gen_x = {g2_gen_x_re, g2_gen_x_im}; static constexpr g2_point_field_t gen_y = {g2_gen_y_re, g2_gen_y_im}; static constexpr g2_point_field_t weierstrass_b = {weierstrass_b_g2_re, weierstrass_b_g2_im}; diff --git a/icicle/include/icicle/curves/params/bn254.h b/icicle/include/icicle/curves/params/bn254.h index b8095b53f..0a628afcb 100644 --- a/icicle/include/icicle/curves/params/bn254.h +++ b/icicle/include/icicle/curves/params/bn254.h @@ -24,6 +24,9 @@ namespace bn254 { 0x00000000, 0x00000000, 0x00000000, 0x00000000}; static constexpr point_field_t weierstrass_b = {0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}; + + static constexpr bool is_b_u32 = true; + static constexpr bool is_b_neg = false; }; // G1 struct G2 { @@ -40,6 +43,11 @@ namespace bn254 { static constexpr point_field_t weierstrass_b_g2_im = {0x85c315d2, 0xe4a2bd06, 0xe52d1852, 0xa74fa084, 0xeed8fdf4, 0xcd2cafad, 0x3af0fed4, 0x009713b0}; + static constexpr bool is_b_u32_g2_re = false; + static constexpr bool is_b_neg_g2_re = false; + static constexpr bool is_b_u32_g2_im = false; + static constexpr bool is_b_neg_g2_im = false; + static constexpr g2_point_field_t gen_x = {g2_gen_x_re, g2_gen_x_im}; static constexpr g2_point_field_t gen_y = {g2_gen_y_re, g2_gen_y_im}; static constexpr g2_point_field_t weierstrass_b = {weierstrass_b_g2_re, weierstrass_b_g2_im}; diff --git a/icicle/include/icicle/curves/params/bw6_761.h b/icicle/include/icicle/curves/params/bw6_761.h index c0a1fcf5e..7760c2023 100644 --- a/icicle/include/icicle/curves/params/bw6_761.h +++ b/icicle/include/icicle/curves/params/bw6_761.h @@ -25,10 +25,18 @@ namespace bw6_761 { 0xb3053253, 0x9f9df141, 0x6fc2cdd4, 0xbe3fb90b, 0x717a4c55, 0xcc685d31, 0x71b5b806, 0xc5b8fa17, 0xaf7e0dba, 0x265909f1, 0xa2e573a3, 0x1a7348d2, 0x884c9ec6, 0x0f952589, 0x45cc2a42, 0xe6fd637b, 0x0a6fc574, 0x0058b84e}; + // actual value: + // static constexpr point_field_t weierstrass_b = { + // 0x0000008a, 0xf49d0000, 0x70000082, 0xe6913e68, 0xeaf0a437, 0x160cf8ae, 0x5667a8f8, 0x98a116c2, + // 0x73ebff2e, 0x71dcd3dc, 0x12f9fd90, 0x8689c8ed, 0x25b42304, 0x03cebaff, 0xe584e919, 0x707ba638, + // 0x8087be41, 0x528275ef, 0x81d14688, 0xb926186a, 0x04faff3e, 0xd187c940, 0xfb83ce0a, 0x0122e824}; static constexpr point_field_t weierstrass_b = { - 0x0000008a, 0xf49d0000, 0x70000082, 0xe6913e68, 0xeaf0a437, 0x160cf8ae, 0x5667a8f8, 0x98a116c2, - 0x73ebff2e, 0x71dcd3dc, 0x12f9fd90, 0x8689c8ed, 0x25b42304, 0x03cebaff, 0xe584e919, 0x707ba638, - 0x8087be41, 0x528275ef, 0x81d14688, 0xb926186a, 0x04faff3e, 0xd187c940, 0xfb83ce0a, 0x0122e824}; + 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}; + + static constexpr bool is_b_u32 = true; + static constexpr bool is_b_neg = true; }; struct G2 { @@ -44,5 +52,8 @@ namespace bw6_761 { 0x00000004, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}; + + static constexpr bool is_b_u32 = true; + static constexpr bool is_b_neg = false; }; } // namespace bw6_761 diff --git a/icicle/include/icicle/curves/params/grumpkin.h b/icicle/include/icicle/curves/params/grumpkin.h index a468fd911..d09390bcc 100644 --- a/icicle/include/icicle/curves/params/grumpkin.h +++ b/icicle/include/icicle/curves/params/grumpkin.h @@ -16,7 +16,13 @@ namespace grumpkin { static constexpr point_field_t gen_y = {0x823f272c, 0x833fc48d, 0xf1181294, 0x2d270d45, 0x6a45d63, 0xcf135e75, 0x00000002, 0x00000000}; - static constexpr point_field_t weierstrass_b = {0xeffffff0, 0x43e1f593, 0x79b97091, 0x2833e848, - 0x8181585d, 0xb85045b6, 0xe131a029, 0x30644e72}; + // actual value: + // static constexpr point_field_t weierstrass_b = {0xeffffff0, 0x43e1f593, 0x79b97091, 0x2833e848, + // 0x8181585d, 0xb85045b6, 0xe131a029, 0x30644e72}; + static constexpr point_field_t weierstrass_b = {0x00000011, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000}; + + static constexpr bool is_b_u32 = true; + static constexpr bool is_b_neg = true; }; // G1 } // namespace grumpkin diff --git a/icicle/include/icicle/curves/projective.h b/icicle/include/icicle/curves/projective.h index 87fe0ab23..17cf9329c 100644 --- a/icicle/include/icicle/curves/projective.h +++ b/icicle/include/icicle/curves/projective.h @@ -58,70 +58,68 @@ class Projective const FF Z = point.z; // TODO: Change to efficient dbl once implemented for field.cuh - FF t0 = FF::sqr(Y); // 1. t0 ← Y · Y - FF Z3 = t0 + t0; // 2. Z3 ← t0 + t0 - Z3 = Z3 + Z3; // 3. Z3 ← Z3 + Z3 - Z3 = Z3 + Z3; // 4. Z3 ← Z3 + Z3 - FF t1 = Y * Z; // 5. t1 ← Y · Z - FF t2 = FF::sqr(Z); // 6. t2 ← Z · Z - t2 = FF::template mul_unsigned<3>(FF::template mul_const(t2)); // 7. t2 ← b3 · t2 - FF X3 = t2 * Z3; // 8. X3 ← t2 · Z3 - FF Y3 = t0 + t2; // 9. Y3 ← t0 + t2 - Z3 = t1 * Z3; // 10. Z3 ← t1 · Z3 - t1 = t2 + t2; // 11. t1 ← t2 + t2 - t2 = t1 + t2; // 12. t2 ← t1 + t2 - t0 = t0 - t2; // 13. t0 ← t0 − t2 - Y3 = t0 * Y3; // 14. Y3 ← t0 · Y3 - Y3 = X3 + Y3; // 15. Y3 ← X3 + Y3 - t1 = X * Y; // 16. t1 ← X · Y - X3 = t0 * t1; // 17. X3 ← t0 · t1 - X3 = X3 + X3; // 18. X3 ← X3 + X3 + FF t0 = FF::sqr(Y); // 1. t0 ← Y · Y + FF Z3 = t0 + t0; // 2. Z3 ← t0 + t0 + Z3 = Z3 + Z3; // 3. Z3 ← Z3 + Z3 + Z3 = Z3 + Z3; // 4. Z3 ← Z3 + Z3 + FF t1 = Y * Z; // 5. t1 ← Y · Z + FF t2 = FF::sqr(Z); // 6. t2 ← Z · Z + t2 = FF::template mul_weierstrass_b(t2); // 7. t2 ← b3 · t2 + FF X3 = t2 * Z3; // 8. X3 ← t2 · Z3 + FF Y3 = t0 + t2; // 9. Y3 ← t0 + t2 + Z3 = t1 * Z3; // 10. Z3 ← t1 · Z3 + t1 = t2 + t2; // 11. t1 ← t2 + t2 + t2 = t1 + t2; // 12. t2 ← t1 + t2 + t0 = t0 - t2; // 13. t0 ← t0 − t2 + Y3 = t0 * Y3; // 14. Y3 ← t0 · Y3 + Y3 = X3 + Y3; // 15. Y3 ← X3 + Y3 + t1 = X * Y; // 16. t1 ← X · Y + X3 = t0 * t1; // 17. X3 ← t0 · t1 + X3 = X3 + X3; // 18. X3 ← X3 + X3 return {X3, Y3, Z3}; } friend HOST_DEVICE Projective operator+(Projective p1, const Projective& p2) { - const FF X1 = p1.x; // < 2 - const FF Y1 = p1.y; // < 2 - const FF Z1 = p1.z; // < 2 - const FF X2 = p2.x; // < 2 - const FF Y2 = p2.y; // < 2 - const FF Z2 = p2.z; // < 2 - const FF t00 = X1 * X2; // t00 ← X1 · X2 < 2 - const FF t01 = Y1 * Y2; // t01 ← Y1 · Y2 < 2 - const FF t02 = Z1 * Z2; // t02 ← Z1 · Z2 < 2 - const FF t03 = X1 + Y1; // t03 ← X1 + Y1 < 4 - const FF t04 = X2 + Y2; // t04 ← X2 + Y2 < 4 - const FF t05 = t03 * t04; // t03 ← t03 · t04 < 3 - const FF t06 = t00 + t01; // t06 ← t00 + t01 < 4 - const FF t07 = t05 - t06; // t05 ← t05 − t06 < 2 - const FF t08 = Y1 + Z1; // t08 ← Y1 + Z1 < 4 - const FF t09 = Y2 + Z2; // t09 ← Y2 + Z2 < 4 - const FF t10 = t08 * t09; // t10 ← t08 · t09 < 3 - const FF t11 = t01 + t02; // t11 ← t01 + t02 < 4 - const FF t12 = t10 - t11; // t12 ← t10 − t11 < 2 - const FF t13 = X1 + Z1; // t13 ← X1 + Z1 < 4 - const FF t14 = X2 + Z2; // t14 ← X2 + Z2 < 4 - const FF t15 = t13 * t14; // t15 ← t13 · t14 < 3 - const FF t16 = t00 + t02; // t16 ← t00 + t02 < 4 - const FF t17 = t15 - t16; // t17 ← t15 − t16 < 2 - const FF t18 = t00 + t00; // t18 ← t00 + t00 < 2 - const FF t19 = t18 + t00; // t19 ← t18 + t00 < 2 - const FF t20 = - FF::template mul_unsigned<3>(FF::template mul_const(t02)); // t20 ← b3 · t02 < 2 - const FF t21 = t01 + t20; // t21 ← t01 + t20 < 2 - const FF t22 = t01 - t20; // t22 ← t01 − t20 < 2 - const FF t23 = - FF::template mul_unsigned<3>(FF::template mul_const(t17)); // t23 ← b3 · t17 < 2 - const auto t24 = FF::mul_wide(t12, t23); // t24 ← t12 · t23 < 2 - const auto t25 = FF::mul_wide(t07, t22); // t25 ← t07 · t22 < 2 - const FF X3 = FF::reduce(t25 - t24); // X3 ← t25 − t24 < 2 - const auto t27 = FF::mul_wide(t23, t19); // t27 ← t23 · t19 < 2 - const auto t28 = FF::mul_wide(t22, t21); // t28 ← t22 · t21 < 2 - const FF Y3 = FF::reduce(t28 + t27); // Y3 ← t28 + t27 < 2 - const auto t30 = FF::mul_wide(t19, t07); // t30 ← t19 · t07 < 2 - const auto t31 = FF::mul_wide(t21, t12); // t31 ← t21 · t12 < 2 - const FF Z3 = FF::reduce(t31 + t30); // Z3 ← t31 + t30 < 2 + const FF X1 = p1.x; // < 2 + const FF Y1 = p1.y; // < 2 + const FF Z1 = p1.z; // < 2 + const FF X2 = p2.x; // < 2 + const FF Y2 = p2.y; // < 2 + const FF Z2 = p2.z; // < 2 + const FF t00 = X1 * X2; // t00 ← X1 · X2 < 2 + const FF t01 = Y1 * Y2; // t01 ← Y1 · Y2 < 2 + const FF t02 = Z1 * Z2; // t02 ← Z1 · Z2 < 2 + const FF t03 = X1 + Y1; // t03 ← X1 + Y1 < 4 + const FF t04 = X2 + Y2; // t04 ← X2 + Y2 < 4 + const FF t05 = t03 * t04; // t03 ← t03 · t04 < 3 + const FF t06 = t00 + t01; // t06 ← t00 + t01 < 4 + const FF t07 = t05 - t06; // t05 ← t05 − t06 < 2 + const FF t08 = Y1 + Z1; // t08 ← Y1 + Z1 < 4 + const FF t09 = Y2 + Z2; // t09 ← Y2 + Z2 < 4 + const FF t10 = t08 * t09; // t10 ← t08 · t09 < 3 + const FF t11 = t01 + t02; // t11 ← t01 + t02 < 4 + const FF t12 = t10 - t11; // t12 ← t10 − t11 < 2 + const FF t13 = X1 + Z1; // t13 ← X1 + Z1 < 4 + const FF t14 = X2 + Z2; // t14 ← X2 + Z2 < 4 + const FF t15 = t13 * t14; // t15 ← t13 · t14 < 3 + const FF t16 = t00 + t02; // t16 ← t00 + t02 < 4 + const FF t17 = t15 - t16; // t17 ← t15 − t16 < 2 + const FF t18 = t00 + t00; // t18 ← t00 + t00 < 2 + const FF t19 = t18 + t00; // t19 ← t18 + t00 < 2 + const FF t20 = FF::template mul_weierstrass_b(t02); // t20 ← b3 · t02 < 2 + const FF t21 = t01 + t20; // t21 ← t01 + t20 < 2 + const FF t22 = t01 - t20; // t22 ← t01 − t20 < 2 + const FF t23 = FF::template mul_weierstrass_b(t17); // t23 ← b3 · t17 < 2 + const auto t24 = FF::mul_wide(t12, t23); // t24 ← t12 · t23 < 2 + const auto t25 = FF::mul_wide(t07, t22); // t25 ← t07 · t22 < 2 + const FF X3 = FF::reduce(t25 - t24); // X3 ← t25 − t24 < 2 + const auto t27 = FF::mul_wide(t23, t19); // t27 ← t23 · t19 < 2 + const auto t28 = FF::mul_wide(t22, t21); // t28 ← t22 · t21 < 2 + const FF Y3 = FF::reduce(t28 + t27); // Y3 ← t28 + t27 < 2 + const auto t30 = FF::mul_wide(t19, t07); // t30 ← t19 · t07 < 2 + const auto t31 = FF::mul_wide(t21, t12); // t31 ← t21 · t12 < 2 + const FF Z3 = FF::reduce(t31 + t30); // Z3 ← t31 + t30 < 2 return {X3, Y3, Z3}; } @@ -129,46 +127,44 @@ class Projective friend HOST_DEVICE Projective operator+(Projective p1, const Affine& p2) { - const FF X1 = p1.x; // < 2 - const FF Y1 = p1.y; // < 2 - const FF Z1 = p1.z; // < 2 - const FF X2 = p2.x; // < 2 - const FF Y2 = p2.y; // < 2 - const FF t00 = X1 * X2; // t00 ← X1 · X2 < 2 - const FF t01 = Y1 * Y2; // t01 ← Y1 · Y2 < 2 - const FF t02 = Z1; // t02 ← Z1 < 2 - const FF t03 = X1 + Y1; // t03 ← X1 + Y1 < 4 - const FF t04 = X2 + Y2; // t04 ← X2 + Y2 < 4 - const FF t05 = t03 * t04; // t03 ← t03 · t04 < 3 - const FF t06 = t00 + t01; // t06 ← t00 + t01 < 4 - const FF t07 = t05 - t06; // t05 ← t05 − t06 < 2 - const FF t08 = Y1 + Z1; // t08 ← Y1 + Z1 < 4 - const FF t09 = Y2 + FF::one(); // t09 ← Y2 + 1 < 4 - const FF t10 = t08 * t09; // t10 ← t08 · t09 < 3 - const FF t11 = t01 + t02; // t11 ← t01 + t02 < 4 - const FF t12 = t10 - t11; // t12 ← t10 − t11 < 2 - const FF t13 = X1 + Z1; // t13 ← X1 + Z1 < 4 - const FF t14 = X2 + FF::one(); // t14 ← X2 + 1 < 4 - const FF t15 = t13 * t14; // t15 ← t13 · t14 < 3 - const FF t16 = t00 + t02; // t16 ← t00 + t02 < 4 - const FF t17 = t15 - t16; // t17 ← t15 − t16 < 2 - const FF t18 = t00 + t00; // t18 ← t00 + t00 < 2 - const FF t19 = t18 + t00; // t19 ← t18 + t00 < 2 - const FF t20 = - FF::template mul_unsigned<3>(FF::template mul_const(t02)); // t20 ← b3 · t02 < 2 - const FF t21 = t01 + t20; // t21 ← t01 + t20 < 2 - const FF t22 = t01 - t20; // t22 ← t01 − t20 < 2 - const FF t23 = - FF::template mul_unsigned<3>(FF::template mul_const(t17)); // t23 ← b3 · t17 < 2 - const auto t24 = FF::mul_wide(t12, t23); // t24 ← t12 · t23 < 2 - const auto t25 = FF::mul_wide(t07, t22); // t25 ← t07 · t22 < 2 - const FF X3 = FF::reduce(t25 - t24); // X3 ← t25 − t24 < 2 - const auto t27 = FF::mul_wide(t23, t19); // t27 ← t23 · t19 < 2 - const auto t28 = FF::mul_wide(t22, t21); // t28 ← t22 · t21 < 2 - const FF Y3 = FF::reduce(t28 + t27); // Y3 ← t28 + t27 < 2 - const auto t30 = FF::mul_wide(t19, t07); // t30 ← t19 · t07 < 2 - const auto t31 = FF::mul_wide(t21, t12); // t31 ← t21 · t12 < 2 - const FF Z3 = FF::reduce(t31 + t30); // Z3 ← t31 + t30 < 2 + const FF X1 = p1.x; // < 2 + const FF Y1 = p1.y; // < 2 + const FF Z1 = p1.z; // < 2 + const FF X2 = p2.x; // < 2 + const FF Y2 = p2.y; // < 2 + const FF t00 = X1 * X2; // t00 ← X1 · X2 < 2 + const FF t01 = Y1 * Y2; // t01 ← Y1 · Y2 < 2 + const FF t02 = Z1; // t02 ← Z1 < 2 + const FF t03 = X1 + Y1; // t03 ← X1 + Y1 < 4 + const FF t04 = X2 + Y2; // t04 ← X2 + Y2 < 4 + const FF t05 = t03 * t04; // t03 ← t03 · t04 < 3 + const FF t06 = t00 + t01; // t06 ← t00 + t01 < 4 + const FF t07 = t05 - t06; // t05 ← t05 − t06 < 2 + const FF t08 = Y1 + Z1; // t08 ← Y1 + Z1 < 4 + const FF t09 = Y2 + FF::one(); // t09 ← Y2 + 1 < 4 + const FF t10 = t08 * t09; // t10 ← t08 · t09 < 3 + const FF t11 = t01 + t02; // t11 ← t01 + t02 < 4 + const FF t12 = t10 - t11; // t12 ← t10 − t11 < 2 + const FF t13 = X1 + Z1; // t13 ← X1 + Z1 < 4 + const FF t14 = X2 + FF::one(); // t14 ← X2 + 1 < 4 + const FF t15 = t13 * t14; // t15 ← t13 · t14 < 3 + const FF t16 = t00 + t02; // t16 ← t00 + t02 < 4 + const FF t17 = t15 - t16; // t17 ← t15 − t16 < 2 + const FF t18 = t00 + t00; // t18 ← t00 + t00 < 2 + const FF t19 = t18 + t00; // t19 ← t18 + t00 < 2 + const FF t20 = FF::template mul_weierstrass_b(t02); // t20 ← b3 · t02 < 2 + const FF t21 = t01 + t20; // t21 ← t01 + t20 < 2 + const FF t22 = t01 - t20; // t22 ← t01 − t20 < 2 + const FF t23 = FF::template mul_weierstrass_b(t17); // t23 ← b3 · t17 < 2 + const auto t24 = FF::mul_wide(t12, t23); // t24 ← t12 · t23 < 2 + const auto t25 = FF::mul_wide(t07, t22); // t25 ← t07 · t22 < 2 + const FF X3 = FF::reduce(t25 - t24); // X3 ← t25 − t24 < 2 + const auto t27 = FF::mul_wide(t23, t19); // t27 ← t23 · t19 < 2 + const auto t28 = FF::mul_wide(t22, t21); // t28 ← t22 · t21 < 2 + const FF Y3 = FF::reduce(t28 + t27); // Y3 ← t28 + t27 < 2 + const auto t30 = FF::mul_wide(t19, t07); // t30 ← t19 · t07 < 2 + const auto t31 = FF::mul_wide(t21, t12); // t31 ← t21 · t12 < 2 + const FF Z3 = FF::reduce(t31 + t30); // Z3 ← t31 + t30 < 2 return {X3, Y3, Z3}; } @@ -235,7 +231,7 @@ class Projective { if (is_zero(point)) return true; bool eq_holds = - (FF::template mul_const(FF::sqr(point.z) * point.z) + FF::sqr(point.x) * point.x == + (FF::template mul_weierstrass_b(FF::sqr(point.z) * point.z) + FF::sqr(point.x) * point.x == point.z * FF::sqr(point.y)); return point.z != FF::zero() && eq_holds; } diff --git a/icicle/include/icicle/fields/complex_extension.h b/icicle/include/icicle/fields/complex_extension.h index 42740859f..c65ad37ec 100644 --- a/icicle/include/icicle/fields/complex_extension.h +++ b/icicle/include/icicle/fields/complex_extension.h @@ -158,6 +158,90 @@ class ComplexExtensionField return !(xs == ys); } + template + static HOST_DEVICE_INLINE FF mul_weierstrass_b_real(const FF& xs) + { + FF r = {}; + constexpr FF b_mult = []() { + FF b_mult = FF{Gen::weierstrass_b_g2_re}; + if constexpr (!IS_3B) return b_mult; + typename FF::ff_storage temp = {}; + typename FF::ff_storage modulus = FF::get_modulus(); + host_math::template add_sub_limbs( + b_mult.limbs_storage, b_mult.limbs_storage, b_mult.limbs_storage); + b_mult.limbs_storage = + host_math::template add_sub_limbs(b_mult.limbs_storage, modulus, temp) + ? b_mult.limbs_storage + : temp; + host_math::template add_sub_limbs( + b_mult.limbs_storage, FF{Gen::weierstrass_b_g2_re}.limbs_storage, b_mult.limbs_storage); + b_mult.limbs_storage = + host_math::template add_sub_limbs(b_mult.limbs_storage, modulus, temp) + ? b_mult.limbs_storage + : temp; + return b_mult; + }(); + if constexpr (Gen::is_b_u32_g2_re) { + r = FF::template mul_unsigned(xs); + if constexpr (Gen::is_b_neg_g2_re) + return FF::neg(r); + else { + return r; + } + } else { + return b_mult * xs; + } + } + + template + static HOST_DEVICE_INLINE FF mul_weierstrass_b_imag(const FF& xs) + { + FF r = {}; + constexpr FF b_mult = []() { + FF b_mult = FF{Gen::weierstrass_b_g2_im}; + if constexpr (!IS_3B) return b_mult; + typename FF::ff_storage temp = {}; + typename FF::ff_storage modulus = FF::get_modulus(); + host_math::template add_sub_limbs( + b_mult.limbs_storage, b_mult.limbs_storage, b_mult.limbs_storage); + b_mult.limbs_storage = + host_math::template add_sub_limbs(b_mult.limbs_storage, modulus, temp) + ? b_mult.limbs_storage + : temp; + host_math::template add_sub_limbs( + b_mult.limbs_storage, FF{Gen::weierstrass_b_g2_im}.limbs_storage, b_mult.limbs_storage); + b_mult.limbs_storage = + host_math::template add_sub_limbs(b_mult.limbs_storage, modulus, temp) + ? b_mult.limbs_storage + : temp; + return b_mult; + }(); + if constexpr (Gen::is_b_u32_g2_im) { + r = FF::template mul_unsigned(xs); + if constexpr (Gen::is_b_neg_g2_im) + return FF::neg(r); + else { + return r; + } + } else { + return b_mult * xs; + } + } + + template + static HOST_DEVICE_INLINE ComplexExtensionField mul_weierstrass_b(const ComplexExtensionField& xs) + { + const FF xs_real = xs.real; + const FF xs_imaginary = xs.imaginary; + FF real_prod = mul_weierstrass_b_real(xs_real); + FF imaginary_prod = mul_weierstrass_b_imag(xs_imaginary); + FF re_im = mul_weierstrass_b_real(xs_imaginary); + FF im_re = mul_weierstrass_b_imag(xs_real); + FF nonresidue_times_im = FF::template mul_unsigned(imaginary_prod); + nonresidue_times_im = CONFIG::nonresidue_is_negative ? FF::neg(nonresidue_times_im) : nonresidue_times_im; + return ComplexExtensionField{real_prod + nonresidue_times_im, re_im + im_re}; + } + template static HOST_DEVICE_INLINE ComplexExtensionField mul_const(const ComplexExtensionField& xs) { diff --git a/icicle/include/icicle/fields/field.h b/icicle/include/icicle/fields/field.h index 80c4b4178..3563424c0 100644 --- a/icicle/include/icicle/fields/field.h +++ b/icicle/include/icicle/fields/field.h @@ -875,6 +875,42 @@ class Field friend HOST_DEVICE bool operator!=(const Field& xs, const Field& ys) { return !(xs == ys); } + template + static HOST_DEVICE_INLINE Field mul_weierstrass_b(const Field& xs) + { + Field r = {}; + constexpr Field b_mult = []() { + Field b_mult = Field{Gen::weierstrass_b}; + if constexpr (!IS_3B) return b_mult; + ff_storage temp = {}; + ff_storage modulus = get_modulus<>(); + host_math::template add_sub_limbs( + b_mult.limbs_storage, b_mult.limbs_storage, b_mult.limbs_storage); + b_mult.limbs_storage = + host_math::template add_sub_limbs(b_mult.limbs_storage, modulus, temp) + ? b_mult.limbs_storage + : temp; + host_math::template add_sub_limbs( + b_mult.limbs_storage, Field{Gen::weierstrass_b}.limbs_storage, b_mult.limbs_storage); + b_mult.limbs_storage = + host_math::template add_sub_limbs(b_mult.limbs_storage, modulus, temp) + ? b_mult.limbs_storage + : temp; + return b_mult; + }(); + + if constexpr (Gen::is_b_u32) { // assumes that 3b is also u32 + r = mul_unsigned(xs); + if constexpr (Gen::is_b_neg) + return neg(r); + else { + return r; + } + } else { + return b_mult * xs; + } + } + template static HOST_DEVICE_INLINE Field mul_const(const Field& xs) {