|
1 | 1 | use crate::bn254::fp254impl::Fp254Impl; |
2 | 2 | use crate::bn254::fq::Fq; |
| 3 | +use crate::bn254::fq12::Fq12; |
3 | 4 | use crate::bn254::fq2::Fq2; |
4 | 5 | use crate::treepp::{script, Script}; |
5 | 6 | use crate::bn254::utils::Hint; |
6 | | -use ark_ff::{Field, Fp6Config}; |
| 7 | +use ark_ff::{AdditiveGroup, Field, Fp6Config}; |
7 | 8 | use num_bigint::BigUint; |
8 | 9 |
|
9 | 10 | pub struct Fq6; |
@@ -41,6 +42,22 @@ impl Fq6 { |
41 | 42 | } |
42 | 43 | } |
43 | 44 |
|
| 45 | + pub fn is_zero() -> Script { |
| 46 | + script! ( |
| 47 | + for _ in 0..6 { |
| 48 | + {Fq::push(ark_bn254::Fq::ZERO)} |
| 49 | + {Fq::equal(1, 0)} |
| 50 | + OP_TOALTSTACK |
| 51 | + } |
| 52 | + {1} |
| 53 | + for _ in 0..6 { |
| 54 | + OP_FROMALTSTACK |
| 55 | + OP_BOOLAND |
| 56 | + } |
| 57 | + ) |
| 58 | + // Fq6::ZERO -> {1} else {0} |
| 59 | + } |
| 60 | + |
44 | 61 | pub fn fromaltstack() -> Script { |
45 | 62 | script! { |
46 | 63 | { Fq2::fromaltstack() } |
@@ -131,7 +148,105 @@ impl Fq6 { |
131 | 148 | } |
132 | 149 | } |
133 | 150 |
|
134 | | - pub fn hinted_mul(mut a_depth: u32, mut a: ark_bn254::Fq6, mut b_depth: u32, mut b: ark_bn254::Fq6) -> (Script, Vec<Hint>) { |
| 151 | + pub fn hinted_square(a: ark_bn254::Fq6) -> (Script, Vec<Hint>) { |
| 152 | + let mut hints = Vec::new(); |
| 153 | + |
| 154 | + let (hinted_script1, hints1) = Fq2::hinted_square(a.c0); |
| 155 | + let (hinted_script2, hints2) = Fq2::hinted_square(a.c0 + a.c1 + a.c2); |
| 156 | + let (hinted_script3, hints3) = Fq2::hinted_square(a.c0 - a.c1 + a.c2); |
| 157 | + let (hinted_script4, hints4) = Fq2::hinted_mul(2, a.c1,0, a.c2); |
| 158 | + let (hinted_script5, hints5) = Fq2::hinted_square(a.c2); |
| 159 | + |
| 160 | + let mut script = script! {}; |
| 161 | + let script_lines = [ |
| 162 | + // compute s_0 = a_0 ^ 2 |
| 163 | + Fq2::copy(4), |
| 164 | + hinted_script1, |
| 165 | + |
| 166 | + // compute a_0 + a_2 |
| 167 | + Fq2::roll(6), |
| 168 | + Fq2::copy(4), |
| 169 | + Fq2::add(2, 0), |
| 170 | + |
| 171 | + // compute s_1 = (a_0 + a_1 + a_2) ^ 2 |
| 172 | + Fq2::copy(0), |
| 173 | + Fq2::copy(8), |
| 174 | + Fq2::add(2, 0), |
| 175 | + hinted_script2, |
| 176 | + |
| 177 | + // compute s_2 = (a_0 - a_1 + a_2) ^ 2 |
| 178 | + Fq2::copy(8), |
| 179 | + Fq2::sub(4, 0), |
| 180 | + hinted_script3, |
| 181 | + |
| 182 | + // compute s_3 = 2a_1a_2 |
| 183 | + Fq2::roll(8), |
| 184 | + Fq2::copy(8), |
| 185 | + hinted_script4, |
| 186 | + Fq2::double(0), |
| 187 | + |
| 188 | + // compute s_4 = a_2 ^ 2 |
| 189 | + Fq2::roll(8), |
| 190 | + hinted_script5, |
| 191 | + |
| 192 | + // compute t_1 = (s_1 + s_2) / 2 |
| 193 | + Fq2::copy(6), |
| 194 | + Fq2::roll(6), |
| 195 | + Fq2::add(2, 0), |
| 196 | + Fq2::div2(), |
| 197 | + |
| 198 | + // at this point, we have s_0, s_1, s_3, s_4, t_1 |
| 199 | + |
| 200 | + // compute c_0 = s_0 + \beta s_3 |
| 201 | + Fq2::copy(4), |
| 202 | + Fq6::mul_fq2_by_nonresidue(), |
| 203 | + Fq2::copy(10), |
| 204 | + Fq2::add(2, 0), |
| 205 | + |
| 206 | + // compute c_1 = s_1 - s_3 - t_1 + \beta s_4 |
| 207 | + Fq2::copy(4), |
| 208 | + Fq6::mul_fq2_by_nonresidue(), |
| 209 | + Fq2::copy(4), |
| 210 | + Fq2::add(10, 0), |
| 211 | + Fq2::sub(10, 0), |
| 212 | + Fq2::add(2, 0), |
| 213 | + |
| 214 | + // compute c_2 = t_1 - s_0 - s_4 |
| 215 | + Fq2::add(8, 6), |
| 216 | + Fq2::sub(6, 0), |
| 217 | + ]; |
| 218 | + for script_line in script_lines { |
| 219 | + script = script.push_script(script_line.compile()); |
| 220 | + } |
| 221 | + |
| 222 | + hints.extend(hints1); |
| 223 | + hints.extend(hints2); |
| 224 | + hints.extend(hints3); |
| 225 | + hints.extend(hints4); |
| 226 | + hints.extend(hints5); |
| 227 | + |
| 228 | + (script, hints) |
| 229 | + } |
| 230 | + |
| 231 | + // Input: [A, B] |
| 232 | + // Output: [C] where C = A x B |
| 233 | + pub fn hinted_mul(a_depth: u32, a: ark_bn254::Fq6, b_depth: u32, b: ark_bn254::Fq6) -> (Script, Vec<Hint>) { |
| 234 | + Self::hinted_mul_core(a_depth, a, b_depth, b, script!{}) |
| 235 | + } |
| 236 | + |
| 237 | + // Input: [A, B] |
| 238 | + // Output: [A, B, C] where C = A x B |
| 239 | + pub fn hinted_mul_keep_elements(a_depth: u32, a: ark_bn254::Fq6, b_depth: u32, b: ark_bn254::Fq6) -> (Script, Vec<Hint>) { |
| 240 | + let preserve_scr = script!{ |
| 241 | + {Fq6::toaltstack()} |
| 242 | + {Fq12::copy(0)} |
| 243 | + {Fq6::fromaltstack()} |
| 244 | + }; |
| 245 | + |
| 246 | + Self::hinted_mul_core(a_depth, a, b_depth, b, preserve_scr) |
| 247 | + } |
| 248 | + |
| 249 | + fn hinted_mul_core(mut a_depth: u32, mut a: ark_bn254::Fq6, mut b_depth: u32, mut b: ark_bn254::Fq6, keep_elements_scr: Script) -> (Script, Vec<Hint>) { |
135 | 250 | // The degree-6 extension on BN254 Fq2 is under the polynomial y^3 - x - 9 |
136 | 251 | // Toom-Cook-3 from https://eprint.iacr.org/2006/471.pdf |
137 | 252 | if a_depth < b_depth { |
@@ -184,6 +299,8 @@ impl Fq6 { |
184 | 299 | // compute (a-b+c)(d-e+f) = P(-1) |
185 | 300 | { hinted_script3 } |
186 | 301 |
|
| 302 | + { keep_elements_scr } |
| 303 | + |
187 | 304 | // compute 2b |
188 | 305 | { Fq2::roll(a_depth + 8) } |
189 | 306 | { Fq2::double(0) } |
|
0 commit comments