miller in rust

This commit is contained in:
Dmitry Vagner 2022-12-27 14:16:22 -08:00
parent f2787a06a0
commit ef824110fd
2 changed files with 105 additions and 29 deletions

View File

@ -115,6 +115,27 @@ fn neg_fp(x: Fp) -> Fp {
(BN_BASE - x) % BN_BASE
}
fn exp_fp(x: Fp, e: U256) -> Fp {
let mut current = x;
let mut product = U256::one();
for j in 0..256 {
if e.bit(j) {
product = U256::try_from(product.full_mul(current) % BN_BASE).unwrap();
}
current = U256::try_from(current.full_mul(current) % BN_BASE).unwrap();
}
product
}
fn inv_fp(x: Fp) -> Fp {
exp_fp(x, BN_BASE - 2)
}
fn div_fp(x: Fp, y: Fp) -> Fp {
mul_fp(x, inv_fp(y))
}
fn conj_fp2(a: Fp2) -> Fp2 {
let [a, a_] = a;
[a, neg_fp(a_)]
@ -246,23 +267,6 @@ pub fn frob_fp12(n: usize, f: Fp12) -> Fp12 {
[frob_fp6(n, f0), mul_fp6(scale, frob_fp6(n, f1))]
}
fn exp_fp(x: Fp, e: U256) -> Fp {
let mut current = x;
let mut product = U256::one();
for j in 0..256 {
if e.bit(j) {
product = U256::try_from(product.full_mul(current) % BN_BASE).unwrap();
}
current = U256::try_from(current.full_mul(current) % BN_BASE).unwrap();
}
product
}
fn inv_fp(x: Fp) -> Fp {
exp_fp(x, BN_BASE - 2)
}
// fn inv_fp2(a: Fp2) -> Fp2 {
// let [a0, a1] = a;
// let norm = inv_fp(mul_fp(a0, a0) + mul_fp(a1, a1));
@ -655,3 +659,69 @@ pub fn cord(p1: Curve, p2: Curve, q: TwistedCurve) -> Fp12 {
mul_fp2(embed_fp2(cy), qy),
)
}
fn tangent_slope(p: Curve) -> Fp {
let [px, py] = p;
let num = mul_fp(mul_fp(px, px), U256::from(3));
let denom = mul_fp(py, U256::from(2));
div_fp(num, denom)
}
fn cord_slope(p: Curve, q: Curve) -> Fp {
let [px, py] = p;
let [qx, qy] = q;
let num = sub_fp(qy, py);
let denom = sub_fp(qx, px);
div_fp(num, denom)
}
fn third_point(m: Fp, p: Curve, q: Curve) -> Curve {
let [px, py] = p;
let [qx, _] = q;
let ox = sub_fp(mul_fp(m, m), add_fp(px, qx));
let oy = sub_fp(mul_fp(m, sub_fp(px, ox)), py);
[ox, oy]
}
fn curve_add(p: Curve, q: Curve) -> Curve {
if p == q {
curve_double(p)
}
else {
third_point(cord_slope(p, q), p, q)
}
}
fn curve_double(p: Curve) -> Curve {
third_point(tangent_slope(p), p, p)
}
const EXP: [usize; 253] = [
1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1,
0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1,
1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0,
0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1,
0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1,
1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0,
0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
];
pub fn miller_loop(p: Curve, q: TwistedCurve) -> Fp12 {
let mut o = p;
let mut acc = embed_fp12(U256::one());
let mut line;
for i in EXP {
acc = mul_fp12(acc, acc);
line = tangent(o, q);
acc = mul_fp12(line, acc);
o = curve_double(o);
if i != 0 {
line = cord(p, o, q);
acc = mul_fp12(line, acc);
o = curve_add(p, o);
}
}
acc
}

View File

@ -126,6 +126,12 @@ miller_zero_final:
/// out = mul_fp12_sparse(out, line)
/// O += O
global test_mul_tan:
// stack: out, f, retdest, 0xnm, times, O, P, Q, out
%store_fp12
// stack: retdest, 0xnm, times, O, P, Q, out
%jump(mul_tangent)
mul_tangent:
// stack: retdest, 0xnm, times, O, P, Q, out
PUSH mul_tangent_2 DUP13 PUSH mul_tangent_1
@ -154,7 +160,13 @@ mul_tangent_2:
after_double:
// stack: 2*O, retdest, 0xnm, times, O, P, Q, out {100: line}
SWAP5 POP SWAP5 POP
// stack: retdest, 0xnm, times, 2*O, P, Q, out {100: line}
%pop3 %pop2 %pop2 %pop4
%load_fp12
%jump(0xdeadbeef)
JUMP
@ -163,6 +175,12 @@ after_double:
/// out = mul_fp12_sparse(out, line)
/// O += P
global test_mul_cord:
// stack: out, f, 0xnm, times, O, P, Q, out
%store_fp12
// stack: 0xnm, times, O, P, Q, out
%jump(mul_cord)
mul_cord:
// stack: 0xnm, times, O, P, Q, out
PUSH mul_cord_1
@ -196,12 +214,6 @@ after_add:
%jump(miller_one)
global test_cord:
// stack: p1x , p1y, p2x , p2y, qx, qx_, qy, qy_
%cord
// stack:
%check(100)
/// def cord(p1x, p1y, p2x, p2y, qx, qy):
/// return sparse_store(
/// p1y*p2x - p2y*p1x,
@ -249,12 +261,6 @@ global test_cord:
%endmacro
global test_tangent:
// stack: px, py, qx, qx_, qy, qy_
%tangent
// stack:
%check(100)
/// def tangent(px, py, qx, qy):
/// return sparse_store(
/// py**2 - 9,