From c25d20a2ce0ef15fa4abc6a01dbf3521bbf7b738 Mon Sep 17 00:00:00 2001 From: bsdevlin Date: Sat, 20 Jul 2019 23:33:34 +0800 Subject: [PATCH] Update Fp6 logic to use formulas --- ip_cores/ec/src/rtl/ec_fp6_arithmetic.sv | 539 ++++++++---------- zcash_fpga/src/rtl/bls12_381/bls12_381_pkg.sv | 50 +- 2 files changed, 263 insertions(+), 326 deletions(-) diff --git a/ip_cores/ec/src/rtl/ec_fp6_arithmetic.sv b/ip_cores/ec/src/rtl/ec_fp6_arithmetic.sv index cab929a..3293a05 100644 --- a/ip_cores/ec/src/rtl/ec_fp6_arithmetic.sv +++ b/ip_cores/ec/src/rtl/ec_fp6_arithmetic.sv @@ -52,6 +52,7 @@ module ec_fe6_arithmetic if_axi_stream.sink i_sub_fe6_if ); +localparam NUM_OVR_WRT_BIT = 5; if_axi_stream #(.DAT_BITS($bits(FE2_TYPE)), .CTL_BITS(CTL_BITS)) add_if_fe2_i [1:0] (i_clk); if_axi_stream #(.DAT_BITS(2*$bits(FE2_TYPE)), .CTL_BITS(CTL_BITS)) add_if_fe2_o [1:0] (i_clk); @@ -82,7 +83,7 @@ always_ff @ (posedge i_clk) begin add_if_fe2_o[0].copy_if({i_add_fe6_if.dat[$bits(FE6_TYPE) +: $bits(FE2_TYPE)], i_add_fe6_if.dat[0 +: $bits(FE2_TYPE)]}, i_add_fe6_if.val, 1, 1, i_add_fe6_if.err, i_add_fe6_if.mod, i_add_fe6_if.ctl); - add_if_fe2_o[0].ctl[OVR_WRT_BIT +: 2] <= add_cnt; + add_if_fe2_o[0].ctl[OVR_WRT_BIT +: NUM_OVR_WRT_BIT] <= add_cnt; if (i_add_fe6_if.val) add_cnt <= 1; end end @@ -91,7 +92,7 @@ always_ff @ (posedge i_clk) begin add_if_fe2_o[0].copy_if({i_add_fe6_if.dat[$bits(FE6_TYPE)+$bits(FE2_TYPE) +: $bits(FE2_TYPE)], i_add_fe6_if.dat[$bits(FE2_TYPE) +: $bits(FE2_TYPE)]}, i_add_fe6_if.val, 1, 1, i_add_fe6_if.err, i_add_fe6_if.mod, i_add_fe6_if.ctl); - add_if_fe2_o[0].ctl[OVR_WRT_BIT +: 2] <= add_cnt; + add_if_fe2_o[0].ctl[OVR_WRT_BIT +: NUM_OVR_WRT_BIT] <= add_cnt; if (i_add_fe6_if.val) add_cnt <= 2; end end @@ -100,7 +101,7 @@ always_ff @ (posedge i_clk) begin add_if_fe2_o[0].copy_if({i_add_fe6_if.dat[$bits(FE6_TYPE)+2*$bits(FE2_TYPE) +: $bits(FE2_TYPE)], i_add_fe6_if.dat[2*$bits(FE2_TYPE) +: $bits(FE2_TYPE)]}, i_add_fe6_if.val, 1, 1, i_add_fe6_if.err, i_add_fe6_if.mod, i_add_fe6_if.ctl); - add_if_fe2_o[0].ctl[OVR_WRT_BIT +: 2] <= add_cnt; + add_if_fe2_o[0].ctl[OVR_WRT_BIT +: NUM_OVR_WRT_BIT] <= add_cnt; if (i_add_fe6_if.val) add_cnt <= 0; end end @@ -109,11 +110,11 @@ always_ff @ (posedge i_clk) begin // One process to assign outputs if (~o_add_fe6_if.val || (o_add_fe6_if.val && o_add_fe6_if.rdy)) begin o_add_fe6_if.ctl <= add_if_fe2_i[0].ctl; - o_add_fe6_if.ctl[OVR_WRT_BIT +: 2] <= 0; - if (add_if_fe2_i[0].ctl[OVR_WRT_BIT +: 2] == 0) begin + o_add_fe6_if.ctl[OVR_WRT_BIT +: NUM_OVR_WRT_BIT] <= 0; + if (add_if_fe2_i[0].ctl[OVR_WRT_BIT +: NUM_OVR_WRT_BIT] == 0) begin if (add_if_fe2_i[0].val) o_add_fe6_if.dat[0 +: $bits(FE2_TYPE)] <= add_if_fe2_i[0].dat; - end else if (add_if_fe2_i[0].ctl[OVR_WRT_BIT +: 2] == 1) begin + end else if (add_if_fe2_i[0].ctl[OVR_WRT_BIT +: NUM_OVR_WRT_BIT] == 1) begin if (add_if_fe2_i[0].val) o_add_fe6_if.dat[$bits(FE2_TYPE) +: $bits(FE2_TYPE)] <= add_if_fe2_i[0].dat; end else begin @@ -150,7 +151,7 @@ always_ff @ (posedge i_clk) begin sub_if_fe2_o[0].copy_if({i_sub_fe6_if.dat[$bits(FE6_TYPE) +: $bits(FE2_TYPE)], i_sub_fe6_if.dat[0 +: $bits(FE2_TYPE)]}, i_sub_fe6_if.val, 1, 1, i_sub_fe6_if.err, i_sub_fe6_if.mod, i_sub_fe6_if.ctl); - sub_if_fe2_o[0].ctl[OVR_WRT_BIT +: 2] <= sub_cnt; + sub_if_fe2_o[0].ctl[OVR_WRT_BIT +: NUM_OVR_WRT_BIT] <= sub_cnt; if (i_sub_fe6_if.val) sub_cnt <= 1; end end @@ -159,7 +160,7 @@ always_ff @ (posedge i_clk) begin sub_if_fe2_o[0].copy_if({i_sub_fe6_if.dat[$bits(FE6_TYPE)+$bits(FE2_TYPE) +: $bits(FE2_TYPE)], i_sub_fe6_if.dat[$bits(FE2_TYPE) +: $bits(FE2_TYPE)]}, i_sub_fe6_if.val, 1, 1, i_sub_fe6_if.err, i_sub_fe6_if.mod, i_sub_fe6_if.ctl); - sub_if_fe2_o[0].ctl[OVR_WRT_BIT +: 2] <= sub_cnt; + sub_if_fe2_o[0].ctl[OVR_WRT_BIT +: NUM_OVR_WRT_BIT] <= sub_cnt; if (i_sub_fe6_if.val) sub_cnt <= 2; end end @@ -168,7 +169,7 @@ always_ff @ (posedge i_clk) begin sub_if_fe2_o[0].copy_if({i_sub_fe6_if.dat[$bits(FE6_TYPE)+2*$bits(FE2_TYPE) +: $bits(FE2_TYPE)], i_sub_fe6_if.dat[2*$bits(FE2_TYPE) +: $bits(FE2_TYPE)]}, i_sub_fe6_if.val, 1, 1, i_sub_fe6_if.err, i_sub_fe6_if.mod, i_sub_fe6_if.ctl); - sub_if_fe2_o[0].ctl[OVR_WRT_BIT +: 2] <= sub_cnt; + sub_if_fe2_o[0].ctl[OVR_WRT_BIT +: NUM_OVR_WRT_BIT] <= sub_cnt; if (i_sub_fe6_if.val) sub_cnt <= 0; end end @@ -176,337 +177,221 @@ always_ff @ (posedge i_clk) begin // One process to assign outputs if (~o_sub_fe6_if.val || (o_sub_fe6_if.val && o_sub_fe6_if.rdy)) begin - if (sub_if_fe2_i[0].ctl[OVR_WRT_BIT +: 2] == 0 && sub_if_fe2_i[0].val) begin + if (sub_if_fe2_i[0].ctl[OVR_WRT_BIT +: NUM_OVR_WRT_BIT] == 0 && sub_if_fe2_i[0].val) begin o_sub_fe6_if.dat[0 +: $bits(FE2_TYPE)] <= sub_if_fe2_i[0].dat; o_sub_fe6_if.ctl <= sub_if_fe2_i[0].ctl; - end else if (sub_if_fe2_i[0].ctl[OVR_WRT_BIT +: 2] == 1 && sub_if_fe2_i[0].val) begin + end else if (sub_if_fe2_i[0].ctl[OVR_WRT_BIT +: NUM_OVR_WRT_BIT] == 1 && sub_if_fe2_i[0].val) begin o_sub_fe6_if.dat[$bits(FE2_TYPE) +: $bits(FE2_TYPE)] <= sub_if_fe2_i[0].dat; - end else if (sub_if_fe2_i[0].ctl[OVR_WRT_BIT +: 2] == 2 && sub_if_fe2_i[0].val) begin + end else if (sub_if_fe2_i[0].ctl[OVR_WRT_BIT +: NUM_OVR_WRT_BIT] == 2 && sub_if_fe2_i[0].val) begin o_sub_fe6_if.dat[2*$bits(FE2_TYPE) +: $bits(FE2_TYPE)] <= sub_if_fe2_i[0].dat; o_sub_fe6_if.val <= 1; end end - o_sub_fe6_if.ctl[OVR_WRT_BIT +: 2] <= 0; + o_sub_fe6_if.ctl[OVR_WRT_BIT +: NUM_OVR_WRT_BIT] <= 0; end end // Multiplications are calculated using the formula in bls12_381.pkg::fe6_mul() +FE2_TYPE a_a, b_b, c_c, t; -logic [3:0] mul_cnt, add_mul_cnt, sub_mul_cnt, mnr_cnt; -logic [2:0] mul_val; -FE2_TYPE a_a, b_b, c_c; +logic [22:0] eq_val, eq_wait; +logic rdy_l; -always_comb begin - - case(i_mul_fe2_if.ctl[OVR_WRT_BIT +: 4]) inside - 0, 1, 2: i_mul_fe2_if.rdy = 1; - 3: i_mul_fe2_if.rdy = sub_mul_cnt == 0 && (~sub_if_fe2_o[1].val || (sub_if_fe2_o[1].val && sub_if_fe2_o[1].rdy)); - 4: i_mul_fe2_if.rdy = sub_mul_cnt == 2 && (~sub_if_fe2_o[1].val || (sub_if_fe2_o[1].val && sub_if_fe2_o[1].rdy)); - 5: i_mul_fe2_if.rdy = sub_mul_cnt == 3 && (~sub_if_fe2_o[1].val || (sub_if_fe2_o[1].val && sub_if_fe2_o[1].rdy)); - default: i_mul_fe2_if.rdy = 0; - endcase - - case(add_if_fe2_i[1].ctl[OVR_WRT_BIT +: 4]) inside - 0: add_if_fe2_i[1].rdy = mul_cnt == 3 && (~o_mul_fe2_if.val || (o_mul_fe2_if.val && o_mul_fe2_if.rdy)); - 1: add_if_fe2_i[1].rdy = mul_cnt == 3 && (~o_mul_fe2_if.val || (o_mul_fe2_if.val && o_mul_fe2_if.rdy)); - 2: add_if_fe2_i[1].rdy = mul_cnt == 4 && (~o_mul_fe2_if.val || (o_mul_fe2_if.val && o_mul_fe2_if.rdy)); - 3: add_if_fe2_i[1].rdy = mul_cnt == 4 && (~o_mul_fe2_if.val || (o_mul_fe2_if.val && o_mul_fe2_if.rdy)); - 4: add_if_fe2_i[1].rdy = mul_cnt == 5 && (~o_mul_fe2_if.val || (o_mul_fe2_if.val && o_mul_fe2_if.rdy)); - 5: add_if_fe2_i[1].rdy = mul_cnt == 5 && (~o_mul_fe2_if.val || (o_mul_fe2_if.val && o_mul_fe2_if.rdy)); - 6: add_if_fe2_i[1].rdy = sub_mul_cnt == 5 && (~sub_if_fe2_o[1].val || (sub_if_fe2_o[1].val && sub_if_fe2_o[1].rdy)); - 7, 8: add_if_fe2_i[1].rdy = ~o_mul_fe6_if.val || (o_mul_fe6_if.val && o_mul_fe6_if.rdy); - default: add_if_fe2_i[1].rdy = 0; - endcase - - case(sub_if_fe2_i[1].ctl[OVR_WRT_BIT +: 4]) inside - 0: sub_if_fe2_i[1].rdy = sub_mul_cnt == 1 && (~sub_if_fe2_o[1].val || (sub_if_fe2_o[1].val && sub_if_fe2_o[1].rdy)); - 1: sub_if_fe2_i[1].rdy = mnr_cnt == 0 && (~o_mnr_fe2_if.val || (o_mnr_fe2_if.val && o_mnr_fe2_if.rdy)); - 2: sub_if_fe2_i[1].rdy = add_mul_cnt == 6 && (~add_if_fe2_o[1].val || (add_if_fe2_o[1].val && add_if_fe2_o[1].rdy)); - 3: sub_if_fe2_i[1].rdy = sub_mul_cnt == 4 && (~sub_if_fe2_o[1].val || (sub_if_fe2_o[1].val && sub_if_fe2_o[1].rdy)); - 4: sub_if_fe2_i[1].rdy = add_mul_cnt == 8 && i_mnr_fe2_if.val && i_mnr_fe2_if.ctl[OVR_WRT_BIT +: 4] == 1 && (~add_if_fe2_o[1].val || (add_if_fe2_o[1].val && add_if_fe2_o[1].rdy)); - 5: sub_if_fe2_i[1].rdy = ~mul_val[2]; - default: sub_if_fe2_i[1].rdy = 0; - endcase - - case(i_mnr_fe2_if.ctl[OVR_WRT_BIT +: 4]) inside - 0: i_mnr_fe2_if.rdy = add_mul_cnt == 7 && (~add_if_fe2_o[1].val || (add_if_fe2_o[1].val && add_if_fe2_o[1].rdy)); - 1: i_mnr_fe2_if.rdy = add_mul_cnt == 8 && sub_if_fe2_i[1].val && sub_if_fe2_i[1].ctl[OVR_WRT_BIT +: 4] == 4 && (~add_if_fe2_o[1].val || (add_if_fe2_o[1].val && add_if_fe2_o[1].rdy)); - default: i_mnr_fe2_if.rdy = 0; - endcase - - o_mul_fe6_if.val <= &mul_val; -end - -logic output_done; always_ff @ (posedge i_clk) begin if (i_rst) begin - o_mul_fe6_if.ctl <= 0; - o_mul_fe6_if.mod <= 0; - o_mul_fe6_if.err <= 0; - o_mul_fe6_if.sop <= 1; - o_mul_fe6_if.eop <= 1; - o_mul_fe6_if.dat <= 0; + o_mul_fe6_if.copy_if(0, 0, 1, 1, 0, 0, 0); o_mnr_fe2_if.copy_if(0, 0, 1, 1, 0, 0, 0); - mul_cnt <= 0; - add_mul_cnt <= 0; - sub_mul_cnt <= 0; - mnr_cnt <= 0; o_mul_fe2_if.copy_if(0, 0, 1, 1, 0, 0, 0); sub_if_fe2_o[1].copy_if(0, 0, 1, 1, 0, 0, 0); add_if_fe2_o[1].copy_if(0, 0, 1, 1, 0, 0, 0); + i_mul_fe6_if.rdy <= 0; + i_mul_fe2_if.rdy <= 0; + sub_if_fe2_i[1].rdy <= 0; + add_if_fe2_i[1].rdy <= 0; + i_mnr_fe2_if.rdy <= 0; + eq_val <= 0; + eq_wait <= 0; + rdy_l <= 0; a_a <= 0; b_b <= 0; c_c <= 0; - i_mul_fe6_if.rdy <= 0; - mul_val <= 0; - output_done <= 1; + t <= 0; end else begin + i_mul_fe2_if.rdy <= 1; + sub_if_fe2_i[1].rdy <= 1; + add_if_fe2_i[1].rdy <= 1; + i_mnr_fe2_if.rdy <= 1; i_mul_fe6_if.rdy <= 0; + if (o_mul_fe6_if.rdy) o_mul_fe6_if.val <= 0; + if (o_mul_fe2_if.rdy) o_mul_fe2_if.val <= 0; + if (sub_if_fe2_o[1].rdy) sub_if_fe2_o[1].val <= 0; + if (add_if_fe2_o[1].rdy) add_if_fe2_o[1].val <= 0; + if (o_mnr_fe2_if.rdy) o_mnr_fe2_if.val <= 0; + + if (eq_val[22] && eq_val[20] && eq_val[19]) + o_mul_fe6_if.val <= 1; + if (o_mul_fe6_if.val && o_mul_fe6_if.rdy) begin - mul_val <= 0; - output_done <= 1; - end - if (o_mul_fe2_if.val && o_mul_fe2_if.rdy) o_mul_fe2_if.val <= 0; - if (sub_if_fe2_o[1].val && sub_if_fe2_o[1].rdy) sub_if_fe2_o[1].val <= 0; - if (add_if_fe2_o[1].val && add_if_fe2_o[1].rdy) add_if_fe2_o[1].val <= 0; - if (o_mnr_fe2_if.val && o_mnr_fe2_if.rdy) o_mnr_fe2_if.val <= 0; - - // Multiplications - if (~o_mul_fe2_if.val || (o_mul_fe2_if.val && o_mul_fe2_if.rdy)) begin - case(mul_cnt) - 0: begin - o_mul_fe2_if.copy_if({i_mul_fe6_if.dat[0 +: $bits(FE2_TYPE)], - i_mul_fe6_if.dat[$bits(FE6_TYPE) +: $bits(FE2_TYPE)]}, - i_mul_fe6_if.val && output_done, 1, 1, i_mul_fe6_if.err, i_mul_fe6_if.mod, i_mul_fe6_if.ctl); - if (i_mul_fe6_if.val && output_done) mul_cnt <= mul_cnt + 1; - end - 1: begin - o_mul_fe2_if.copy_if({i_mul_fe6_if.dat[$bits(FE2_TYPE) +: $bits(FE2_TYPE)], - i_mul_fe6_if.dat[$bits(FE6_TYPE) + $bits(FE2_TYPE) +: $bits(FE2_TYPE)]}, - 1, 1, 1, i_mul_fe6_if.err, i_mul_fe6_if.mod, i_mul_fe6_if.ctl); - mul_cnt <= mul_cnt + 1; - end - 2: begin - o_mul_fe2_if.copy_if({i_mul_fe6_if.dat[2*$bits(FE2_TYPE) +: $bits(FE2_TYPE)], - i_mul_fe6_if.dat[$bits(FE6_TYPE) + 2*$bits(FE2_TYPE) +: $bits(FE2_TYPE)]}, - 1, 1, 1, i_mul_fe6_if.err, i_mul_fe6_if.mod, i_mul_fe6_if.ctl); - mul_cnt <= mul_cnt + 1; - end - 3: begin - if (add_if_fe2_i[1].ctl[OVR_WRT_BIT +: 4] == 0 && add_if_fe2_i[1].val) - o_mul_fe2_if.dat[0 +: $bits(FE2_TYPE)] <= add_if_fe2_i[1].dat; - if (add_if_fe2_i[1].ctl[OVR_WRT_BIT +: 4] == 1 && add_if_fe2_i[1].val) begin - o_mul_fe2_if.dat[$bits(FE2_TYPE) +: $bits(FE2_TYPE)] <= add_if_fe2_i[1].dat; - o_mul_fe2_if.val <= 1; - mul_cnt <= mul_cnt + 1; - end - end - 4: begin - if (add_if_fe2_i[1].ctl[OVR_WRT_BIT +: 4] == 2 && add_if_fe2_i[1].val) - o_mul_fe2_if.dat[0 +: $bits(FE2_TYPE)] <= add_if_fe2_i[1].dat; - if (add_if_fe2_i[1].ctl[OVR_WRT_BIT +: 4] == 3 && add_if_fe2_i[1].val) begin - o_mul_fe2_if.dat[$bits(FE2_TYPE) +: $bits(FE2_TYPE)] <= add_if_fe2_i[1].dat; - o_mul_fe2_if.val <= 1; - mul_cnt <= mul_cnt + 1; - end - end - 5: begin - if (add_if_fe2_i[1].ctl[OVR_WRT_BIT +: 4] == 4 && add_if_fe2_i[1].val) - o_mul_fe2_if.dat[0 +: $bits(FE2_TYPE)] <= add_if_fe2_i[1].dat; - if (add_if_fe2_i[1].ctl[OVR_WRT_BIT +: 4] == 5 && add_if_fe2_i[1].val) begin - o_mul_fe2_if.dat[$bits(FE2_TYPE) +: $bits(FE2_TYPE)] <= add_if_fe2_i[1].dat; - o_mul_fe2_if.val <= 1; - mul_cnt <= 0; - end - end - endcase - o_mul_fe2_if.ctl[OVR_WRT_BIT +: 4] <= mul_cnt; - end - - // Additions - if (~add_if_fe2_o[1].val || (add_if_fe2_o[1].val && add_if_fe2_o[1].rdy)) begin - case (add_mul_cnt) - 0: begin - add_if_fe2_o[1].copy_if({i_mul_fe6_if.dat[$bits(FE2_TYPE) +: $bits(FE2_TYPE)], - i_mul_fe6_if.dat[2*$bits(FE2_TYPE) +: $bits(FE2_TYPE)]}, - i_mul_fe6_if.val && output_done, 1, 1, i_mul_fe6_if.err, i_mul_fe6_if.mod, i_mul_fe6_if.ctl); - if (i_mul_fe6_if.val && output_done) add_mul_cnt <= add_mul_cnt + 1; - end - 1: begin - add_if_fe2_o[1].copy_if({i_mul_fe6_if.dat[$bits(FE6_TYPE) + $bits(FE2_TYPE) +: $bits(FE2_TYPE)], - i_mul_fe6_if.dat[$bits(FE6_TYPE) + 2*$bits(FE2_TYPE) +: $bits(FE2_TYPE)]}, - 1, 1, 1, i_mul_fe6_if.err, i_mul_fe6_if.mod, i_mul_fe6_if.ctl); - add_mul_cnt <= add_mul_cnt + 1; - end - 2: begin - add_if_fe2_o[1].copy_if({i_mul_fe6_if.dat[$bits(FE6_TYPE) +: $bits(FE2_TYPE)], - i_mul_fe6_if.dat[$bits(FE6_TYPE) + 2*$bits(FE2_TYPE) +: $bits(FE2_TYPE)]}, - 1, 1, 1, i_mul_fe6_if.err, i_mul_fe6_if.mod, i_mul_fe6_if.ctl); - add_mul_cnt <= add_mul_cnt + 1; - end - 3: begin - add_if_fe2_o[1].copy_if({i_mul_fe6_if.dat[0 +: $bits(FE2_TYPE)], - i_mul_fe6_if.dat[2*$bits(FE2_TYPE) +: $bits(FE2_TYPE)]}, - 1, 1, 1, i_mul_fe6_if.err, i_mul_fe6_if.mod, i_mul_fe6_if.ctl); - add_mul_cnt <= add_mul_cnt + 1; - end - 4: begin - add_if_fe2_o[1].copy_if({i_mul_fe6_if.dat[$bits(FE6_TYPE) +: $bits(FE2_TYPE)], - i_mul_fe6_if.dat[$bits(FE6_TYPE) + $bits(FE2_TYPE) +: $bits(FE2_TYPE)]}, - 1, 1, 1, i_mul_fe6_if.err, i_mul_fe6_if.mod, i_mul_fe6_if.ctl); - add_mul_cnt <= add_mul_cnt + 1; - end - 5: begin - add_if_fe2_o[1].copy_if({i_mul_fe6_if.dat[0 +: $bits(FE2_TYPE)], - i_mul_fe6_if.dat[$bits(FE2_TYPE) +: $bits(FE2_TYPE)]}, - 1, 1, 1, i_mul_fe6_if.err, i_mul_fe6_if.mod, i_mul_fe6_if.ctl); - add_mul_cnt <= add_mul_cnt + 1; - i_mul_fe6_if.rdy <= 1; // Release input here - output_done <= 0; - end - 6: begin - add_if_fe2_o[1].dat[0 +: $bits(FE2_TYPE)] <= b_b; - if (sub_if_fe2_i[1].val) begin - add_if_fe2_o[1].dat[$bits(FE2_TYPE) +: $bits(FE2_TYPE)] <= sub_if_fe2_i[1].dat; - add_if_fe2_o[1].ctl <= sub_if_fe2_i[1].ctl; - end - if (sub_if_fe2_i[1].val && sub_if_fe2_i[1].ctl[OVR_WRT_BIT +: 4] == 2) begin - add_mul_cnt <= add_mul_cnt + 1; - add_if_fe2_o[1].val <= 1; - end - end - 7: begin - add_if_fe2_o[1].dat[0 +: $bits(FE2_TYPE)] <= a_a; - if (i_mnr_fe2_if.val) begin - add_if_fe2_o[1].dat[$bits(FE2_TYPE) +: $bits(FE2_TYPE)] <= i_mnr_fe2_if.dat; - add_if_fe2_o[1].ctl <= i_mnr_fe2_if.ctl; - end - if (i_mnr_fe2_if.val && i_mnr_fe2_if.ctl[OVR_WRT_BIT +: 4] == 0) begin - add_mul_cnt <= add_mul_cnt + 1; - add_if_fe2_o[1].val <= 1; - end - end - 8: begin - if (sub_if_fe2_i[1].val && sub_if_fe2_i[1].ctl[OVR_WRT_BIT +: 4] == 4 && - i_mnr_fe2_if.val && i_mnr_fe2_if.ctl[OVR_WRT_BIT +: 4] == 1) begin - add_if_fe2_o[1].dat[0 +: $bits(FE2_TYPE)] <= sub_if_fe2_i[1].dat; - add_if_fe2_o[1].ctl <= sub_if_fe2_i[1].ctl; - add_if_fe2_o[1].dat[$bits(FE2_TYPE) +: $bits(FE2_TYPE)] <= i_mnr_fe2_if.dat; - add_mul_cnt <= 0; - add_if_fe2_o[1].val <= 1; - end - end - endcase - add_if_fe2_o[1].ctl[OVR_WRT_BIT +: 4] <= add_mul_cnt; + eq_val <= 0; + eq_wait <= 0; + rdy_l <= 0; + a_a <= 0; + b_b <= 0; + c_c <= 0; + t <= 0; + o_mul_fe6_if.val <= 0; end - // Subtractions - if (~sub_if_fe2_o[1].val || (sub_if_fe2_o[1].val && sub_if_fe2_o[1].rdy)) begin - case (sub_mul_cnt) - 0: begin - if (i_mul_fe2_if.ctl[OVR_WRT_BIT +: 4] == 3) begin - sub_if_fe2_o[1].dat <= {b_b, i_mul_fe2_if.dat}; - sub_if_fe2_o[1].val <= i_mul_fe2_if.val; - sub_if_fe2_o[1].ctl <= i_mul_fe2_if.ctl; - if (i_mul_fe2_if.val) sub_mul_cnt <= sub_mul_cnt + 1; - end - end - 1: begin - if (sub_if_fe2_i[1].ctl[OVR_WRT_BIT +: 4] == 0) begin - sub_if_fe2_o[1].dat <= {c_c, sub_if_fe2_i[1].dat}; - sub_if_fe2_o[1].val <= sub_if_fe2_i[1].val; - sub_if_fe2_o[1].ctl <= sub_if_fe2_i[1].ctl; - if (sub_if_fe2_i[1].val) sub_mul_cnt <= sub_mul_cnt + 1; - end - end - 2: begin - if (i_mul_fe2_if.ctl[OVR_WRT_BIT +: 4] == 4) begin - sub_if_fe2_o[1].dat <= {a_a, i_mul_fe2_if.dat}; - sub_if_fe2_o[1].val <= i_mul_fe2_if.val; - sub_if_fe2_o[1].ctl <= i_mul_fe2_if.ctl; - if (i_mul_fe2_if.val) sub_mul_cnt <= sub_mul_cnt + 1; - end - end - 3: begin - if (i_mul_fe2_if.ctl[OVR_WRT_BIT +: 4] == 5) begin - sub_if_fe2_o[1].dat <= {a_a, i_mul_fe2_if.dat}; - sub_if_fe2_o[1].val <= i_mul_fe2_if.val; - sub_if_fe2_o[1].ctl <= i_mul_fe2_if.ctl; - if (i_mul_fe2_if.val) sub_mul_cnt <= sub_mul_cnt + 1; - end - end - 4: begin - if (sub_if_fe2_i[1].ctl[OVR_WRT_BIT +: 4] == 3) begin - sub_if_fe2_o[1].dat <= {b_b, sub_if_fe2_i[1].dat}; - sub_if_fe2_o[1].val <= sub_if_fe2_i[1].val; - sub_if_fe2_o[1].ctl <= sub_if_fe2_i[1].ctl; - if (sub_if_fe2_i[1].val) sub_mul_cnt <= sub_mul_cnt + 1; - end - end - 5: begin - if (add_if_fe2_i[1].ctl[OVR_WRT_BIT +: 4] == 6) begin - sub_if_fe2_o[1].dat <= {c_c, add_if_fe2_i[1].dat}; - sub_if_fe2_o[1].val <= add_if_fe2_i[1].val; - sub_if_fe2_o[1].ctl <= add_if_fe2_i[1].ctl; - if (add_if_fe2_i[1].val) sub_mul_cnt <= 0; - end - end - endcase - sub_if_fe2_o[1].ctl[OVR_WRT_BIT +: 4] <= sub_mul_cnt; + if (eq_wait[0] && eq_wait[1] && eq_wait[2] && eq_wait[13] && eq_wait[14] && ~rdy_l) begin + i_mul_fe6_if.rdy <= 1; + o_mul_fe6_if.ctl <= i_mul_fe6_if.ctl; + rdy_l <= 1; end - // Non-residue - if (~o_mnr_fe2_if.val || (o_mnr_fe2_if.val && o_mnr_fe2_if.rdy)) begin - case(mnr_cnt) - 0: begin - if (sub_if_fe2_i[1].ctl[OVR_WRT_BIT +: 4] == 1 && sub_if_fe2_i[1].val) begin - o_mnr_fe2_if.dat <= sub_if_fe2_i[1].dat; - o_mnr_fe2_if.val <= sub_if_fe2_i[1].val; - o_mnr_fe2_if.ctl <= 0; - o_mnr_fe2_if.ctl[OVR_WRT_BIT +: 4] <= mnr_cnt; - mnr_cnt <= mnr_cnt + 1; - end - end - 1: begin - o_mnr_fe2_if.dat <= c_c; - o_mnr_fe2_if.val <= 1; - o_mnr_fe2_if.ctl <= 0; - o_mnr_fe2_if.ctl[OVR_WRT_BIT +: 4] <= mnr_cnt; - mnr_cnt <= 0; - end - endcase - end - - // Take results from multiplications to save a_a, b_b, c_c + // Check any results from multiplier if (i_mul_fe2_if.val && i_mul_fe2_if.rdy) begin - case (i_mul_fe2_if.ctl[OVR_WRT_BIT +: 4]) - 0: a_a <= i_mul_fe2_if.dat; - 1: b_b <= i_mul_fe2_if.dat; - 2: c_c <= i_mul_fe2_if.dat; + eq_val[i_mul_fe2_if.ctl[OVR_WRT_BIT +: NUM_OVR_WRT_BIT]] <= 1; + case(i_mul_fe2_if.ctl[OVR_WRT_BIT +: NUM_OVR_WRT_BIT]) inside + 0: a_a <= i_mul_fe2_if.dat; + 1: b_b <= i_mul_fe2_if.dat; + 2: c_c <= i_mul_fe2_if.dat; + 5: o_mul_fe6_if.dat[0 +: $bits(FE2_TYPE)] <= i_mul_fe2_if.dat; + 10: o_mul_fe6_if.dat[2*$bits(FE2_TYPE) +: $bits(FE2_TYPE)] <= i_mul_fe2_if.dat; + 15: o_mul_fe6_if.dat[$bits(FE2_TYPE) +: $bits(FE2_TYPE)] <= i_mul_fe2_if.dat; + default: o_mul_fe6_if.err <= 1; endcase end - // Final output valid - if (sub_if_fe2_i[1].val && sub_if_fe2_i[1].ctl[OVR_WRT_BIT +: 4] == 5 && ~mul_val[2]) begin - o_mul_fe6_if.dat[2*$bits(FE2_TYPE) +: $bits(FE2_TYPE)] <= sub_if_fe2_i[1].dat; - o_mul_fe6_if.ctl <= sub_if_fe2_i[1].ctl; - mul_val[2] <= 1; + // Check any results from mnr + if (i_mnr_fe2_if.val && i_mnr_fe2_if.rdy) begin + eq_val[i_mnr_fe2_if.ctl[OVR_WRT_BIT +: NUM_OVR_WRT_BIT]] <= 1; + case(i_mnr_fe2_if.ctl[OVR_WRT_BIT +: NUM_OVR_WRT_BIT]) inside + 18: o_mul_fe6_if.dat[0 +: $bits(FE2_TYPE)] <= i_mnr_fe2_if.dat; + 21: c_c <= i_mnr_fe2_if.dat; + default: o_mul_fe6_if.err <= 1; + endcase end - if (add_if_fe2_i[1].val && add_if_fe2_i[1].ctl[OVR_WRT_BIT +: 4] == 8 && ~mul_val[1]) begin - o_mul_fe6_if.dat[$bits(FE2_TYPE) +: $bits(FE2_TYPE)] <= add_if_fe2_i[1].dat; - o_mul_fe6_if.ctl <= add_if_fe2_i[1].ctl; - mul_val[1] <= 1; + + // Check any results from sub + if (sub_if_fe2_i[1].val && sub_if_fe2_i[1].rdy) begin + eq_val[sub_if_fe2_i[1].ctl[OVR_WRT_BIT +: NUM_OVR_WRT_BIT]] <= 1; + case(sub_if_fe2_i[1].ctl[OVR_WRT_BIT +: NUM_OVR_WRT_BIT]) inside + 6: o_mul_fe6_if.dat[0 +: $bits(FE2_TYPE)] <= sub_if_fe2_i[1].dat; + 7: o_mul_fe6_if.dat[0 +: $bits(FE2_TYPE)] <= sub_if_fe2_i[1].dat; + 11: o_mul_fe6_if.dat[2*$bits(FE2_TYPE) +: $bits(FE2_TYPE)] <= sub_if_fe2_i[1].dat; + 16: o_mul_fe6_if.dat[$bits(FE2_TYPE) +: $bits(FE2_TYPE)] <= sub_if_fe2_i[1].dat; + 17: o_mul_fe6_if.dat[$bits(FE2_TYPE) +: $bits(FE2_TYPE)] <= sub_if_fe2_i[1].dat; + 20: o_mul_fe6_if.dat[2*$bits(FE2_TYPE) +: $bits(FE2_TYPE)] <= sub_if_fe2_i[1].dat; + default: o_mul_fe6_if.err <= 1; + endcase end - if (add_if_fe2_i[1].val && add_if_fe2_i[1].ctl[OVR_WRT_BIT +: 4] == 7 && ~mul_val[0]) begin - o_mul_fe6_if.dat[0 +: $bits(FE2_TYPE)] <= add_if_fe2_i[1].dat; - o_mul_fe6_if.ctl <= add_if_fe2_i[1].ctl; - mul_val[0] <= 1; + + // Check any results from add + if (add_if_fe2_i[1].val && add_if_fe2_i[1].rdy) begin + eq_val[add_if_fe2_i[1].ctl[OVR_WRT_BIT +: NUM_OVR_WRT_BIT]] <= 1; + case(add_if_fe2_i[1].ctl[OVR_WRT_BIT +: NUM_OVR_WRT_BIT]) inside + 3: o_mul_fe6_if.dat[0 +: $bits(FE2_TYPE)] <= add_if_fe2_i[1].dat; + 4: t <= add_if_fe2_i[1].dat; + 8: o_mul_fe6_if.dat[2*$bits(FE2_TYPE) +: $bits(FE2_TYPE)] <= add_if_fe2_i[1].dat; + 9: t <= add_if_fe2_i[1].dat; + 12: o_mul_fe6_if.dat[2*$bits(FE2_TYPE) +: $bits(FE2_TYPE)] <= add_if_fe2_i[1].dat; + 13: o_mul_fe6_if.dat[$bits(FE2_TYPE) +: $bits(FE2_TYPE)] <= add_if_fe2_i[1].dat; + 14: t <= add_if_fe2_i[1].dat; + 19: o_mul_fe6_if.dat[0 +: $bits(FE2_TYPE)] <= add_if_fe2_i[1].dat; + 22: begin + o_mul_fe6_if.dat[$bits(FE2_TYPE) +: $bits(FE2_TYPE)] <= add_if_fe2_i[1].dat; + end + default: o_mul_fe6_if.err <= 1; + endcase + end + + // Issue new multiplies + if (~eq_wait[0] && i_mul_fe6_if.val) begin // 0. a_a = fe2_mul(a[0], b[0]) + fe2_multiply(0, i_mul_fe6_if.dat[0 +: $bits(FE2_TYPE)], + i_mul_fe6_if.dat[$bits(FE6_TYPE) +: $bits(FE2_TYPE)]); + end else + if (~eq_wait[1] && i_mul_fe6_if.val) begin // 1. b_b = fe2_mul(a[1], b[1]) + fe2_multiply(1, i_mul_fe6_if.dat[$bits(FE2_TYPE) +: $bits(FE2_TYPE)], + i_mul_fe6_if.dat[$bits(FE6_TYPE) + $bits(FE2_TYPE) +: $bits(FE2_TYPE)]); + end else + if (~eq_wait[2] && i_mul_fe6_if.val) begin // 2. c_c = fe2_mul(a[2], b[2]) + fe2_multiply(2, i_mul_fe6_if.dat[2*$bits(FE2_TYPE) +: $bits(FE2_TYPE)], + i_mul_fe6_if.dat[$bits(FE6_TYPE) + 2*$bits(FE2_TYPE) +: $bits(FE2_TYPE)]); + end else + if (~eq_wait[5] && eq_val[3] && eq_val[4]) begin // 5. fe6_mul[0] = fe2_mul(fe6_mul[0], t) [3, 4] + fe2_multiply(5, o_mul_fe6_if.dat[0 +: $bits(FE2_TYPE)], t); + end else + if (~eq_wait[10] && eq_val[8] && eq_val[9]) begin // 10. fe6_mul[2] = fe2_mul(fe6_mul[2], t) [8, 9] + fe2_multiply(10, o_mul_fe6_if.dat[2*$bits(FE2_TYPE) +: $bits(FE2_TYPE)], t); + end else + if (~eq_wait[15] && eq_val[13] && eq_val[14]) begin // 15. fe6_mul[1] = fe2_mul(fe6_mul[1], t) [13, 14] + fe2_multiply(15, o_mul_fe6_if.dat[$bits(FE2_TYPE) +: $bits(FE2_TYPE)], t); + end + + // Issue new adds + if (~eq_wait[3] && i_mul_fe6_if.val) begin // 3. fe6_mul[0] = fe2_add(a[1], a[2]) + fe2_addition(3, i_mul_fe6_if.dat[$bits(FE2_TYPE) +: $bits(FE2_TYPE)], + i_mul_fe6_if.dat[2*$bits(FE2_TYPE) +: $bits(FE2_TYPE)]); + end else + if (~eq_wait[4] && i_mul_fe6_if.val) begin // 4. t = fe2_add(b[1], b[2]) + fe2_addition(4, i_mul_fe6_if.dat[$bits(FE6_TYPE) + $bits(FE2_TYPE) +: $bits(FE2_TYPE)], + i_mul_fe6_if.dat[$bits(FE6_TYPE) + 2*$bits(FE2_TYPE) +: $bits(FE2_TYPE)]); + end else + if (~eq_wait[8] && i_mul_fe6_if.val) begin // 8. fe6_mul[2] = fe2_add(b[0], b[2]) + fe2_addition(8, i_mul_fe6_if.dat[$bits(FE6_TYPE) +: $bits(FE2_TYPE)], + i_mul_fe6_if.dat[$bits(FE6_TYPE) + 2*$bits(FE2_TYPE) +: $bits(FE2_TYPE)]); + end else + if (~eq_wait[9] && eq_wait[5] && i_mul_fe6_if.val) begin // 9. t = fe2_add(a[0], a[2]) [wait 5] + fe2_addition(9, i_mul_fe6_if.dat[0 +: $bits(FE2_TYPE)], + i_mul_fe6_if.dat[2*$bits(FE2_TYPE) +: $bits(FE2_TYPE)]); + end else + if (~eq_wait[12] && eq_val[11] && eq_val[1]) begin // 12. fe6_mul[2] = fe2_add(fe6_mul[2], b_b) [11, 1] + fe2_addition(12, o_mul_fe6_if.dat[2*$bits(FE2_TYPE) +: $bits(FE2_TYPE)], b_b); + end else + if (~eq_wait[13] && i_mul_fe6_if.val) begin // 13. fe6_mul[1] = fe2_add(b[0], b[1]) + fe2_addition(13, i_mul_fe6_if.dat[$bits(FE6_TYPE) +: $bits(FE2_TYPE)], + i_mul_fe6_if.dat[$bits(FE6_TYPE) + $bits(FE2_TYPE) +: $bits(FE2_TYPE)]); + end else + if (~eq_wait[14] && eq_wait[10] && i_mul_fe6_if.val) begin // 14. t = fe2_add(a[0], a[1]) [wait 10] + fe2_addition(14, i_mul_fe6_if.dat[0 +: $bits(FE2_TYPE)], + i_mul_fe6_if.dat[$bits(FE2_TYPE) +: $bits(FE2_TYPE)]); + end else + if (~eq_wait[19] && eq_val[18] && eq_val[0]) begin // 19. fe6_mul[0] = fe2_add(fe6_mul[0], a_a) [18, 0] + fe2_addition(19, o_mul_fe6_if.dat[0 +: $bits(FE2_TYPE)], a_a); + end else + if (~eq_wait[22] && eq_val[17] && eq_val[21]) begin // 22. fe6_mul[1] = fe2_add(c_c, fe6_mul[1]) [17, 21] + fe2_addition(22, o_mul_fe6_if.dat[$bits(FE2_TYPE) +: $bits(FE2_TYPE)], c_c); + end + + // Issue new sub + if (~eq_wait[6] && eq_val[5] && eq_val[1]) begin // 6. fe6_mul[0] = fe2_sub(fe6_mul[0], b_b) [5, 1] + fe2_subtraction(6, o_mul_fe6_if.dat[0 +: $bits(FE2_TYPE)], b_b); + end else + if (~eq_wait[7] && eq_val[6] && eq_val[2]) begin // 7. fe6_mul[0] = fe2_sub(fe6_mul[0], c_c) [6, 2] + fe2_subtraction(7, o_mul_fe6_if.dat[0 +: $bits(FE2_TYPE)], c_c); + end else + if (~eq_wait[11] && eq_val[10] && eq_val[0]) begin // 11. fe6_mul[2] = fe2_sub(fe6_mul[2], a_a) [10, 0] + fe2_subtraction(11, o_mul_fe6_if.dat[2*$bits(FE2_TYPE) +: $bits(FE2_TYPE)], a_a); + end else + if (~eq_wait[16] && eq_val[15] && eq_val[0]) begin // 16. fe6_mul[1] = fe2_sub(fe6_mul[1], a_a) [15, 0] + fe2_subtraction(16, o_mul_fe6_if.dat[$bits(FE2_TYPE) +: $bits(FE2_TYPE)], a_a); + end else + if (~eq_wait[17] && eq_val[16] && eq_val[1]) begin // 17. fe6_mul[1] = fe2_sub(fe6_mul[1], b_b) [16, 1] + fe2_subtraction(17, o_mul_fe6_if.dat[$bits(FE2_TYPE) +: $bits(FE2_TYPE)], b_b); + end else + if (~eq_wait[20] && eq_val[12] && eq_val[2]) begin // 20. fe6_mul[2] = fe2_sub(fe6_mul[2], c_c) [12, 2] + fe2_subtraction(20, o_mul_fe6_if.dat[2*$bits(FE2_TYPE) +: $bits(FE2_TYPE)], c_c); + end + + // Issue new mnr + if (~eq_wait[18] && eq_val[7]) begin // 18. fe6_mul[0] = fe2_mul_by_nonresidue(fe6_mul[0]) [7] + fe2_mnr(18, o_mul_fe6_if.dat[0 +: $bits(FE2_TYPE)]); + end else + if (~eq_wait[21] && eq_wait[20]) begin // 21. c_c = fe2_mul_by_nonresidue(c_c) [20] + fe2_mnr(21, c_c); end - o_mul_fe6_if.ctl[OVR_WRT_BIT +: 4] <= 0; - - end end @@ -515,7 +400,7 @@ resource_share # ( .NUM_IN ( 2 ), .DAT_BITS ( 2*$bits(FE2_TYPE) ), .CTL_BITS ( CTL_BITS ), - .OVR_WRT_BIT ( OVR_WRT_BIT+4 ), + .OVR_WRT_BIT ( OVR_WRT_BIT+NUM_OVR_WRT_BIT ), .PIPELINE_IN ( 0 ), .PIPELINE_OUT ( 0 ) ) @@ -532,7 +417,7 @@ resource_share # ( .NUM_IN ( 2 ), .DAT_BITS ( 2*$bits(FE2_TYPE) ), .CTL_BITS ( CTL_BITS ), - .OVR_WRT_BIT ( OVR_WRT_BIT+4 ), + .OVR_WRT_BIT ( OVR_WRT_BIT+NUM_OVR_WRT_BIT ), .PIPELINE_IN ( 0 ), .PIPELINE_OUT ( 0 ) ) @@ -545,4 +430,50 @@ resource_share_add ( .o_axi ( add_if_fe2_i[1:0] ) ); +// Task for subtractions +task fe2_subtraction(input int unsigned ctl, input FE2_TYPE a, b); + if (~sub_if_fe2_o[1].val || (sub_if_fe2_o[1].val && sub_if_fe2_o[1].rdy)) begin + sub_if_fe2_o[1].val <= 1; + sub_if_fe2_o[1].dat[0 +: $bits(FE2_TYPE)] <= a; + sub_if_fe2_o[1].dat[$bits(FE2_TYPE) +: $bits(FE2_TYPE)] <= b; + sub_if_fe2_o[1].ctl[OVR_WRT_BIT +: NUM_OVR_WRT_BIT] <= ctl; + eq_wait[ctl] <= 1; + end +endtask + +// Task for addition +task fe2_addition(input int unsigned ctl, input FE2_TYPE a, b); + if (~add_if_fe2_o[1].val || (add_if_fe2_o[1].val && add_if_fe2_o[1].rdy)) begin + add_if_fe2_o[1].val <= 1; + add_if_fe2_o[1].dat[0 +: $bits(FE2_TYPE)] <= a; + add_if_fe2_o[1].dat[$bits(FE2_TYPE) +: $bits(FE2_TYPE)] <= b; + add_if_fe2_o[1].ctl[OVR_WRT_BIT +: NUM_OVR_WRT_BIT] <= ctl; + eq_wait[ctl] <= 1; + end +endtask + +// Task for using mult +task fe2_multiply(input int unsigned ctl, input FE2_TYPE a, b, input logic [1:0] en = 2'b11); + if (~o_mul_fe2_if.val || (o_mul_fe2_if.val && o_mul_fe2_if.rdy)) begin + o_mul_fe2_if.val <= 1; + if (en[0]) + o_mul_fe2_if.dat[0 +: $bits(FE2_TYPE)] <= a; + if (en[1]) + o_mul_fe2_if.dat[$bits(FE2_TYPE) +: $bits(FE2_TYPE)] <= b; + o_mul_fe2_if.ctl[OVR_WRT_BIT +: NUM_OVR_WRT_BIT] <= ctl; + eq_wait[ctl] <= 1; + end +endtask + +// Task for using mnr +task fe2_mnr(input int unsigned ctl, input FE2_TYPE a, input logic en = 1'b1); + if (~o_mnr_fe2_if.val || (o_mnr_fe2_if.val && o_mnr_fe2_if.rdy)) begin + o_mnr_fe2_if.val <= 1; + if (en) + o_mnr_fe2_if.dat <= a; + o_mnr_fe2_if.ctl[OVR_WRT_BIT +: NUM_OVR_WRT_BIT] <= ctl; + eq_wait[ctl] <= 1; + end +endtask + endmodule \ No newline at end of file diff --git a/zcash_fpga/src/rtl/bls12_381/bls12_381_pkg.sv b/zcash_fpga/src/rtl/bls12_381/bls12_381_pkg.sv index 52e27f2..14ea21f 100644 --- a/zcash_fpga/src/rtl/bls12_381/bls12_381_pkg.sv +++ b/zcash_fpga/src/rtl/bls12_381/bls12_381_pkg.sv @@ -417,32 +417,38 @@ package bls12_381_pkg; endfunction function fe6_t fe6_mul(fe6_t a, b); - fe2_t a_a, b_b, c_c; - a_a = fe2_mul(a[0], b[0]); - b_b = fe2_mul(a[1], b[1]); - c_c = fe2_mul(a[2], b[2]); + fe2_t a_a, b_b, c_c, t; + a_a = fe2_mul(a[0], b[0]); // 0. a_a = fe2_mul(a[0], b[0]) + b_b = fe2_mul(a[1], b[1]); // 1. b_b = fe2_mul(a[1], b[1]) + c_c = fe2_mul(a[2], b[2]); // 2. c_c = fe2_mul(a[2], b[2]) - fe6_mul[0] = fe2_mul(fe2_add(a[1], a[2]), fe2_add(b[1], b[2])); - fe6_mul[2] = fe2_mul(fe2_add(b[0], b[2]), fe2_add(a[0], a[2])); - fe6_mul[1] = fe2_mul(fe2_add(b[0], b[1]), fe2_add(a[0], a[1])); + fe6_mul[0] = fe2_add(a[1], a[2]); // 3. fe6_mul[0] = fe2_add(a[1], a[2]) + t = fe2_add(b[1], b[2]); // 4. t = fe2_add(b[1], b[2]) + fe6_mul[0] = fe2_mul(fe6_mul[0], t); // 5. fe6_mul[0] = fe2_mul(fe6_mul[0], t) [3, 4] + fe6_mul[0] = fe2_sub(fe6_mul[0], b_b); // 6. fe6_mul[0] = fe2_sub(fe6_mul[0], b_b) [5, 1] + fe6_mul[0] = fe2_sub(fe6_mul[0], c_c); // 7. fe6_mul[0] = fe2_sub(fe6_mul[0], c_c) [6, 2] - fe6_mul[0] = fe2_sub(fe6_mul[0], b_b); - fe6_mul[0] = fe2_sub(fe6_mul[0], c_c); + fe6_mul[2] = fe2_add(b[0], b[2]); // 8. fe6_mul[2] = fe2_add(b[0], b[2]) + t = fe2_add(a[0], a[2]); // 9. t = fe2_add(a[0], a[2]) [wait 5] + fe6_mul[2] = fe2_mul(fe6_mul[2], t); // 10. fe6_mul[2] = fe2_mul(fe6_mul[2], t) [8, 9] + fe6_mul[2] = fe2_sub(fe6_mul[2], a_a); // 11. fe6_mul[2] = fe2_sub(fe6_mul[2], a_a) [10, 0] + fe6_mul[2] = fe2_add(fe6_mul[2], b_b); // 12. fe6_mul[2] = fe2_add(fe6_mul[2], b_b) [11, 1] - fe6_mul[2] = fe2_sub(fe6_mul[2], a_a); - fe6_mul[2] = fe2_add(fe6_mul[2], b_b); + fe6_mul[1] = fe2_add(b[0], b[1]); // 13. fe6_mul[1] = fe2_add(b[0], b[1]) + t = fe2_add(a[0], a[1]); // 14. t = fe2_add(a[0], a[1]) [wait 10] - can release input here + fe6_mul[1] = fe2_mul(fe6_mul[1], t); // 15. fe6_mul[1] = fe2_mul(fe6_mul[1], t) [13, 14] + fe6_mul[1] = fe2_sub(fe6_mul[1], a_a); // 16. fe6_mul[1] = fe2_sub(fe6_mul[1], a_a) [15, 0] + fe6_mul[1] = fe2_sub(fe6_mul[1], b_b); // 17. fe6_mul[1] = fe2_sub(fe6_mul[1], b_b) [16, 1] - fe6_mul[1] = fe2_sub(fe6_mul[1], a_a); - fe6_mul[1] = fe2_sub(fe6_mul[1], b_b); + fe6_mul[0] = fe2_mul_by_nonresidue(fe6_mul[0]); // 18. fe6_mul[0] = fe2_mul_by_nonresidue(fe6_mul[0]) [7] + fe6_mul[0] = fe2_add(fe6_mul[0], a_a); // 19. fe6_mul[0] = fe2_add(fe6_mul[0], a_a) [18, 0] - fe6_mul[0] = fe2_mul_by_nonresidue(fe6_mul[0]); - fe6_mul[2] = fe2_sub(fe6_mul[2], c_c); - c_c = fe2_mul_by_nonresidue(c_c); + fe6_mul[2] = fe2_sub(fe6_mul[2], c_c); // 20. fe6_mul[2] = fe2_sub(fe6_mul[2], c_c) [12, 2] + c_c = fe2_mul_by_nonresidue(c_c); // 21. c_c = fe2_mul_by_nonresidue(c_c) [20] - fe6_mul[0] = fe2_add(fe6_mul[0], a_a); - fe6_mul[1] = fe2_add(c_c, fe6_mul[1]); + fe6_mul[1] = fe2_add(c_c, fe6_mul[1]); // 22. fe6_mul[1] = fe2_add(c_c, fe6_mul[1]) [17, 21] endfunction - + function fe12_t fe12_add(fe12_t a, b); for(int i = 0; i < 2; i++) fe12_add[i] = fe6_add(a[i], b[i]); @@ -457,14 +463,14 @@ package bls12_381_pkg; fe6_t aa, bb; aa = fe6_mul(a[0], b[0]); // 0. add_i0 = mul(a[0], b[0]) bb = fe6_mul(a[1], b[1]); // 1. bb = mul(a[1], b[1]) - + fe12_mul[1] = fe6_add(a[1], a[0]); // 2. fe6_mul[1] = add(a[1], a[0]) fe12_mul[0] = fe6_add(b[0], b[1]); // 3. fe6_mul[0] = add(b[0], b[1]) fe12_mul[1] = fe6_mul(fe12_mul[1], fe12_mul[0]); // 4. fe6_mul[1] = mul(fe6_mul[1], fe6_mul[0]) [2, 3] - fe12_mul[1] = fe6_sub(fe12_mul[1], aa); // 5. fe6_mul[1] = sub(fe6_mul[1], add_i0) [4, 0] + fe12_mul[1] = fe6_sub(fe12_mul[1], aa); // 5. fe6_mul[1] = sub(fe6_mul[1], add_i0) [4, 0] fe12_mul[1] = fe6_sub(fe12_mul[1], bb); // 6. fe6_mul[1] = sub(fe6_mul[1], bb) [5, 1] - + bb = fe6_mul_by_nonresidue(bb); // 7. bb = mnr(bb) [6] fe12_mul[0] = fe6_add(bb, aa); // 8. fe6_mul[0] = add(add_i0, bb) [0, 1, 7] endfunction