functionalscript
Version:
FunctionalScript is a purely functional subset of JavaScript
137 lines (136 loc) • 4.37 kB
JavaScript
import { prime_field } from "../prime_field/module.f.js";
import { curve, secp256k1, secp192r1, secp256r1, eq, secp384r1, secp521r1 } from "./module.f.js";
const poker = (param) => () => {
// (c ^ x) ^ y = c ^ (x * y)
// c ^ ((x * y) * (1/x * 1/y)) = c
const { g, n } = param;
const { mul, y } = curve(param);
const f = (m) => (pList) => pList.map(i => mul(i)(m));
//
const pf = prime_field(n);
// 0 1 2 3 4 5 6 7
const sA = 0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdefn % n;
const sB = 0xfedcba98fedcba98fedcba98fedcba98fedcba98fedcba98fedcba98fedcba98n % n;
// "22d3ad011aec6aabdb3d3d47636f3e2859de02298c87a496"
// "2b359de5cfb5937a5610d565dceaef2a760ceeaec96e68140757f0c8371534e0"
// "1359162ede91207ccaea1de94afc63c1db5a967c1e6e21f91ef9f077f20a46b6"
const rA = pf.reciprocal(sA);
// "e1e768c7427cf5bafd58756df9b54b9ec2558201f129f4ab"
// "edaf7ede285c3da723c54fcdaa3b631f626681f884d8f41fae55c4f552bb551e"
// "6ca248e88c124478975b57c4c3ca682bd8be0f0d9f11593d01273d9ceebdb735"
const rB = pf.reciprocal(sB);
//
let d = [];
for (let i = 0n; i < 52n; ++i) {
let nonce = 0n; // can be a random number in a range [`0`, `p >> 6n`).
let x = 0n;
let yi;
while (true) {
x = i | (nonce << 6n);
yi = y(x);
if (yi !== null) {
break;
}
++nonce;
}
d = [...d, [x, yi]];
}
//
const dA = f(sA)(d);
const dAB = f(sB)(dA);
const dB = f(rA)(dAB);
const dN = f(rB)(dB);
//
let m = 0n;
for (const p of dN) {
if (p === null) {
throw 'null';
}
const x = p[0] & 0x3fn;
if (x !== m) {
throw [p[0], x, m];
}
++m;
}
};
export default {
example: () => {
const curveParams = {
p: 23n,
a: [0n, 1n],
g: [1n, 1n],
n: 19n
};
const c = curve(curveParams);
// Access curve operations
const point = c.add([1n, 1n])([2n, 5n]); // Add two points
const negPoint = c.neg([1n, 1n]); // Negate a point
const mulPoint = c.mul([1n, 1n])(3n); // Multiply a point by 3
},
test: () => {
const test_curve = c => {
const { g } = c;
const { mul, neg, pf: { abs }, y: yf, nf: { p: n } } = curve(c);
const point_check = (p) => {
if (p === null) {
throw 'p === null';
}
const [x, y] = p;
const ye = yf(x);
if (ye === null) {
throw 'ye === null';
}
if (abs(ye) !== abs(y)) {
throw 'ye';
}
};
point_check(g);
point_check(neg(g));
const test_mul = (p) => {
if (mul(p)(0n) !== null) {
throw 'O';
}
if (mul(p)(1n) !== p) {
throw 'p';
}
if (mul(p)(n) !== null) {
throw 'n';
}
const pn = neg(p);
if (!eq(mul(p)(n - 1n))(pn)) {
throw 'n - 1';
}
const f = s => {
const r = mul(p)(s);
point_check(r);
const rn = mul(pn)(s);
point_check(rn);
if (!eq(r)(neg(rn))) {
throw 'r != -rn';
}
};
f(2n);
f(3n);
f(4n << 128n);
f((5n << 128n) + 6n);
f(7n << 128n);
f((8n << 128n) + 9n);
};
test_mul(g);
test_mul(neg(g));
};
test_curve(secp256k1);
test_curve(secp192r1);
test_curve(secp256r1);
test_curve(secp384r1);
test_curve(secp521r1);
},
poker: () => {
const c = {
secp192r1,
//secp256k1,
//secp256r1,
};
return Object.fromEntries(Object.entries(c).map(([k, v]) => [k, poker(v)]));
}
};