| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409 |
- constant edwards_d 0x2a9318e74bfa2b48f5fd9207e6bd7fd4292d7f6d37579d2601065fd6d6343eb1
- constant one 0x0000000000000000000000000000000000000000000000000000000000000001
- constant zero 0x0000000000000000000000000000000000000000000000000000000000000000
- constant G_VCR_u 0x6800f4fa0f001cfc7ff6826ad58004b4d1d8da41af03744e3bce3b7793664337
- constant G_VCR_v 0x6d81d3a9cb45dedbe6fb2a6e1e22ab50ad46f1b0473b803b3caefab9380b6a8b
- constant G_VCV_u 0x273f910d9ecc1615d8618ed1d15fef4e9472c89ac043042d36183b2cb4d7ef51
- constant G_VCV_v 0x466a7e3a82f67ab1d32294fd89774ad6bc3332d0fa1ccd18a77a81f50667c8d7
- {% macro square(x2, x) %}
- ########################################################
- # square({{x2}}, {{x}})
- ########################################################
- private {{x2}}
- set {{x2}} {{x}}
- mul {{x2}} {{x}}
- lc0_add {{x}}
- lc1_add {{x}}
- lc2_add {{x2}}
- enforce
- {% endmacro %}
- {% macro jubjub_witness(p, u, v) %}
- ########################################################
- # jubjub_witness({{p}}, {{u}}, {{v}})
- ########################################################
- # -u^2 + v^2 = 1 + du^2v^2
- {{ square(p + "_u2", u) }}
- {{ square(p + "_v2", v) }}
- private {{p}}_u2v2
- set {{p}}_u2v2 {{p + "_u2"}}
- mul {{p}}_u2v2 {{p + "_v2"}}
- # on curve check
- lc0_sub {{p + "_u2"}}
- lc0_add {{p + "_v2"}}
- lc1_add_one
- lc2_add_one
- lc2_add_coeff edwards_d {{p}}_u2v2
- enforce
- {% endmacro %}
- {% macro jubjub_double(p, u, v) %}
- ########################################################
- # jubjub_double({{p}}, {{u}}, {{v}})
- ########################################################
- # Compute T = (u + v) * (v - EDWARDS_A*u)
- # = (u + v) * (u + v)
- private {{p}}_t
- set {{p}}_t {{u}}
- add {{p}}_t {{v}}
- local {{p}}_t1
- set {{p}}_t1 {{u}}
- add {{p}}_t1 {{v}}
- mul {{p}}_t {{p}}_t1
- lc0_add {{u}}
- lc0_add {{v}}
- lc1_add {{u}}
- lc1_add {{v}}
- lc2_add {{p}}_t
- enforce
- # Compute A = u * v
- private {{p}}_A
- set {{p}}_A {{u}}
- mul {{p}}_A {{v}}
- # Compute C = d*A*A
- private {{p}}_C
- load {{p}}_C edwards_d
- mul {{p}}_C {{p}}_A
- mul {{p}}_C {{p}}_A
- lc0_add_coeff edwards_d {{p}}_A
- lc1_add {{p}}_A
- lc2_add {{p}}_C
- enforce
- # Compute u3 = (2.A) / (1 + C)
- private {{p}}_u
- set {{p}}_u {{p}}_A
- add {{p}}_u {{p}}_A
- local {{p}}_u3_t1
- load {{p}}_u3_t1 one
- add {{p}}_u3_t1 {{p}}_C
- divide {{p}}_u {{p}}_u3_t1
- lc0_add_one
- lc0_add {{p}}_C
- lc1_add {{p}}_u
- lc2_add {{p}}_A
- lc2_add {{p}}_A
- enforce
- # Compute v3 = (T + (EDWARDS_A-1)*A) / (1 - C)
- # = (T - 2.A) / (1 - C)
- private {{p}}_v
- set {{p}}_v {{p}}_t
- local {{p}}_2A
- set {{p}}_2A {{p}}_A
- add {{p}}_2A {{p}}_A
- sub {{p}}_v {{p}}_2A
- local {{p}}_v3_t1
- load {{p}}_v3_t1 one
- sub {{p}}_v3_t1 {{p}}_C
- divide {{p}}_v {{p}}_v3_t1
- lc0_add_one
- lc0_sub {{p}}_C
- lc1_add {{p}}_v
- lc2_add {{p}}_t
- lc2_sub {{p}}_A
- lc2_sub {{p}}_A
- enforce
- {% endmacro %}
- {% macro jubjub_assert_not_small_order(p, u, v) %}
- ########################################################
- # jubjub_assert_not_small_order({{p}}, {{u}}, {{v}})
- ########################################################
- # First doubling
- {{ jubjub_double(p + "1", u, v) }}
- # Second doubling
- {{ jubjub_double(p + "2", p + "1_u", p + "1_v") }}
- # Third doubling
- {{ jubjub_double(p + "3", p + "2_u", p + "2_v") }}
- # (0, -1) is a small order point, but won't ever appear here
- # because cofactor is 2^3, and we performed three doublings.
- # (0, 1) is the neutral element, so checking if u is nonzero
- # is sufficient to prevent small order points here.
- # Check u != 0
- # Constrain a * inv = 1, which is only valid
- # iff a has a multiplicative inverse, untrue
- # for zero.
- private {{p}}_u3_inv
- set {{p}}_u3_inv {{p}}3_u
- invert {{p}}_u3_inv
- lc0_add {{p}}3_u
- lc1_add {{p}}_u3_inv
- lc2_add_one
- enforce
- {% endmacro %}
- {% macro jubjub_add(P, x1, y1, x2, y2) %}
- ########################################################
- # jubjub_add({{P}}, {{x1}}, {{y1}}, {{x2}}, {{y2}})
- ########################################################
- # Compute U = (x1 + y1) * (y2 - EDWARDS_A*x2)
- # = (x1 + y1) * (x2 + y2)
- private {{P}}_U
- set {{P}}_U {{ x1 }}
- add {{P}}_U {{ y1 }}
- local {{P}}_tmp
- set {{P}}_tmp {{ x2 }}
- add {{P}}_tmp {{ y2 }}
- mul {{P}}_U {{P}}_tmp
- # assert (x1 + y1) * (x2 + y2) == U
- lc0_add {{ x1 }}
- lc0_add {{ y1 }}
- lc1_add {{ x2 }}
- lc1_add {{ y2 }}
- lc2_add {{P}}_U
- enforce
- # Compute A = y2 * x1
- private {{P}}_A
- set {{P}}_A {{ y2 }}
- mul {{P}}_A {{ x1 }}
- # Compute B = x2 * y1
- private {{P}}_B
- set {{P}}_B {{ x2 }}
- mul {{P}}_B {{ y1 }}
- # Compute C = d*A*B
- private {{P}}_C
- load {{P}}_C edwards_d
- mul {{P}}_C {{P}}_A
- mul {{P}}_C {{P}}_B
- # assert (d * A) * (B) == C
- lc0_add_coeff edwards_d {{P}}_A
- lc1_add {{P}}_B
- lc2_add {{P}}_C
- enforce
- # Compute P.x = (A + B) / (1 + C)
- private {{P}}_u
- set {{P}}_u {{P}}_A
- add {{P}}_u {{P}}_B
- local {{P}}_u_denom
- load {{P}}_u_denom one
- add {{P}}_u_denom {{P}}_C
- divide {{P}}_u {{P}}_u_denom
- lc0_add_one
- lc0_add {{P}}_C
- lc1_add {{P}}_u
- lc2_add {{P}}_A
- lc2_add {{P}}_B
- enforce
- # Compute P.y = (U - A - B) / (1 - C)
- private {{P}}_v
- set {{P}}_v {{P}}_U
- sub {{P}}_v {{P}}_A
- sub {{P}}_v {{P}}_B
- local {{P}}_v_denom
- load {{P}}_v_denom one
- sub {{P}}_v_denom {{P}}_C
- divide {{P}}_v {{P}}_v_denom
- lc0_add_one
- lc0_sub {{P}}_C
- lc1_add {{P}}_v
- lc2_add {{P}}_U
- lc2_sub {{P}}_A
- lc2_sub {{P}}_B
- enforce
- {% endmacro %}
- {% macro jubjub_conditionally_select(p, u, v, condition) %}
- ########################################################
- # jubjub_conditionally_select({{p}}, {{u}}, {{v}}, {{condition}})
- ########################################################
- # Compute u' = self.u if condition, and 0 otherwise
- private {{p}}_u
- set {{p}}_u {{u}}
- mul {{p}}_u {{condition}}
- # condition * u = u'
- # if condition is 0, u' must be 0
- # if condition is 1, u' must be u
- lc0_add {{u}}
- lc1_add {{condition}}
- lc2_add {{p}}_u
- enforce
- # Compute v' = self.v if condition, and 1 otherwise
- # v' = condition * v + 1 - condition
- private {{p}}_v
- set {{p}}_v {{v}}
- mul {{p}}_v {{condition}}
- local {{p}}_one
- load {{p}}_one one
- add {{p}}_v {{p}}_one
- sub {{p}}_v {{condition}}
- # condition * v = v' - (1 - condition)
- # if condition is 0, v' must be 1
- # if condition is 1, v' must be v
- lc0_add {{v}}
- lc1_add {{condition}}
- lc2_add {{p}}_v
- lc2_sub_one
- lc2_add {{condition}}
- enforce
- {% endmacro %}
- {% macro jubjub_mul(p, u, v, x, n) %}
- ########################################################
- # jubjub_mul({{p}}, {{u}}, {{v}}, {{x}}, {{n}})
- ########################################################
- # Performs a scalar multiplication of this twisted Edwards
- # point by a scalar represented as a sequence of booleans
- # in little-endian bit order.
-
- {% for i in range(n) %}
- {% if i == 0 %}
- {{ jubjub_conditionally_select(
- p + "_this_base_" + i|string,
- u,
- v,
- x + "_" + i|string
- ) }}
- debug {{x + "_" + i|string}}
- debug {{p + "_this_base_" + i|string}}_u
- debug {{p + "_this_base_" + i|string}}_v
- {% else %}
- {{ jubjub_conditionally_select(
- p + "_this_base_" + i|string,
- p + "_currbase_" + i|string + "_u",
- p + "_currbase_" + i|string + "_v",
- x + "_" + i|string
- ) }}
- debug {{x + "_" + i|string}}
- debug {{p + "_this_base_" + i|string}}_u
- debug {{p + "_this_base_" + i|string}}_v
- {% endif %}
- {% if i == 0 %}
- # Do nothing on first round
- {% elif i == 1 %}
- {{ jubjub_add(
- p + "_result_2",
- p + "_this_base_1_u",
- p + "_this_base_1_v",
- p + "_this_base_0_u",
- p + "_this_base_0_v"
- ) }}
- debug {{p + "_result_" + (i + 1)|string}}_u
- debug {{p + "_result_" + (i + 1)|string}}_v
- {% elif i == (n - 1) %}
- {{ jubjub_add(
- p,
- p + "_this_base_" + i|string + "_u",
- p + "_this_base_" + i|string + "_v",
- p + "_result_" + i|string + "_u",
- p + "_result_" + i|string + "_v",
- ) }}
- debug {{p}}_u
- debug {{p}}_v
- {% else %}
- {{ jubjub_add(
- p + "_result_" + (i + 1)|string,
- p + "_this_base_" + i|string + "_u",
- p + "_this_base_" + i|string + "_v",
- p + "_result_" + i|string + "_u",
- p + "_result_" + i|string + "_v",
- ) }}
- debug {{p + "_result_" + (i + 1)|string}}_u
- debug {{p + "_result_" + (i + 1)|string}}_v
- {% endif %}
- {% if i == 0 %}
- {{ jubjub_double(
- p + "_currbase_" + (i + 1)|string,
- u,
- v
- ) }}
- {% else %}
- {{ jubjub_double(
- p + "_currbase_" + (i + 1)|string,
- p + "_currbase_" + i|string + "_u",
- p + "_currbase_" + i|string + "_v"
- ) }}
- {% endif %}
- {% endfor %}
- {% endmacro %}
- contract mint_contract
- param public_u
- param public_v
- {{ jubjub_witness("public", "public_u", "public_v") }}
- {{ jubjub_assert_not_small_order("not_small", "public_u", "public_v") }}
- {% for i in range(256) %}
- param vc_randomness_{{i}}
- lc0_add vc_randomness_{{i}}
- enforce
- {% endfor %}
- private g_vcr_u
- private g_vcr_v
- load g_vcr_u G_VCR_u
- load g_vcr_v G_VCR_v
- {{ jubjub_mul("rcv", "g_vcr_u", "g_vcr_v", "vc_randomness", 256) }}
- public rcvu
- set rcvu rcv_u
- lc0_add rcvu
- lc1_add_one
- lc2_add rcv_u
- enforce
- public rcvv
- set rcvv rcv_v
- lc0_add rcvv
- lc1_add_one
- lc2_add rcv_v
- enforce
- #############
- {#
- {{ jubjub_double("pub_dbl_pre", "public_u", "public_v") }}
- private condition
- load condition zero
- {{ jubjub_conditionally_select("pub_dbl", "pub_dbl_pre_u", "pub_dbl_pre_v", "condition") }}
- # Use this code for testing point doubling
- public dbl_u
- set dbl_u pub_dbl_u
- lc0_add dbl_u
- lc1_add_one
- lc2_add pub_dbl_u
- enforce
- public dbl_v
- set dbl_v pub_dbl_v
- lc0_add dbl_v
- lc1_add_one
- lc2_add pub_dbl_v
- enforce
- #}
- end
|