From e4a586011774a1db990c88ef3b0f37f7547ea913 Mon Sep 17 00:00:00 2001 From: Jordi Baylina Date: Sun, 11 Nov 2018 20:58:36 +0100 Subject: [PATCH] Select points in subgroup and calculate x from y --- calcpedersenbases/calcpedersenbases.js | 72 +++++++++++++++++++++----- 1 file changed, 59 insertions(+), 13 deletions(-) diff --git a/calcpedersenbases/calcpedersenbases.js b/calcpedersenbases/calcpedersenbases.js index be9617c..a6bd290 100644 --- a/calcpedersenbases/calcpedersenbases.js +++ b/calcpedersenbases/calcpedersenbases.js @@ -3,6 +3,32 @@ const bigInt = require("snarkjs").bigInt; const createBlakeHash = require("blake-hash"); const assert = require("assert"); +function addPoint(a,b, q) { + const cta = bigInt("168700"); + const d = bigInt("168696"); + + const res = []; + res[0] = bigInt((a[0]*b[1] + b[0]*a[1]) * bigInt(bigInt("1") + d*a[0]*b[0]*a[1]*b[1]).inverse(q)).affine(q); + res[1] = bigInt((a[1]*b[1] - cta*a[0]*b[0]) * bigInt(bigInt("1") - d*a[0]*b[0]*a[1]*b[1]).inverse(q)).affine(q); + return res; +} + +function mulPointEscalar(base, e, q) { + let res = [bigInt("0"),bigInt("1")]; + let rem = bigInt(e); + let exp = base; + + while (! rem.isZero()) { + if (rem.isOdd()) { + res = addPoint(res, exp, q); + } + exp = addPoint(exp, exp, q); + rem = rem.shr(1); + } + + return res; +} + function getPoint(S) { const F = bn128.Fr; const h = createBlakeHash("blake256").update(S).digest(); @@ -15,26 +41,30 @@ function getPoint(S) { sign = true; } - let x = bigInt(0); + let y = bigInt(0); for (let i=0; i<32; i++) { - x = x.shl(8); - x = x.add(bigInt(h[i])); + y = y.shl(8); + y = y.add(bigInt(h[i])); } const a = bigInt("168700"); const d = bigInt("168696"); - const x2 = F.square(x); + const y2 = F.square(y); + + let x = F.sqrt(F.div( + F.sub(F.one, y2), + F.sub(a, F.mul(d, y2)))); + + if (x == null) return null; - let y = F.sqrt(F.div( - F.sub(F.one, F.mul(a, x2)), - F.sub(F.one, F.mul(d, x2)))); + if (sign) x = F.neg(x); - if (y == null) return null; + const p = [bn128.Fr.affine(x), bn128.Fr.affine(y)]; - if (sign) y = F.neg(y); + const p8 =mulPointEscalar(p, 8, q); - return [bn128.Fr.affine(x), bn128.Fr.affine(y)]; + return p8; } @@ -47,10 +77,21 @@ function generatePoint(S) { p = getPoint(S+"_"+sidx); idx++; } - assert(inCurve(p)); + assert(inCurve(p), "Point not in curve"); return p; } + + + + +const q = bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617"); +const r = bigInt("21888242871839275222246405745257275088614511777268538073601725287587578984328").shr(3); +function isLowGrade(p, q) { + const res= mulPointEscalar(p, r, q); + return (res[0].equals(bigInt(0))) && (res[1].equals(bigInt(1))); +} + function inCurve(p) { const F = bn128.Fr; @@ -60,15 +101,20 @@ function inCurve(p) { const x2 = F.square(p[0]); const y2 = F.square(p[1]); - return F.equals( + if (!F.equals( F.add(F.mul(a, x2), y2), - F.add(F.one, F.mul(F.mul(x2, y2), d))); + F.add(F.one, F.mul(F.mul(x2, y2), d)))) return false; + + if (!isLowGrade(p, q)) return false; + + return true; } const g = [ bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"), bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475")]; + if (!inCurve(g)) { throw new Error("Generator not In curve -> Some thing goes wrong..."); }