PHP WebShell
Текущая директория: /opt/BitGoJS/modules/sdk-lib-mpc/src/tss/ecdsa
Просмотр файла: paillierproof.ts
import { bitLength } from 'bigint-crypto-utils';
import { modInv, modPow } from 'bigint-mod-arith';
import { randomPositiveCoPrimeLessThan } from '../../util';
import { minModulusBitLength } from './index';
import { primesSmallerThan319567 } from './primes';
// Security parameters.
const k = 128;
// eprint.iacr.org/2018/057.pdf#page6 section 5
// https://github.com/BitGo/BitGoJS/pull/3502#discussion_r1203070392
export const alpha = 319567;
export const m = Math.ceil(k / Math.log2(alpha));
/**
* Generate a set of challenges $p$ for a given paillier public key modulus $n$.
* @param n - paillier public key modulus
* @returns {Promise<Array<bigint>>} - array of challenges $p_i$
*/
export async function generateP(n: bigint): Promise<Array<bigint>> {
if (bitLength(n) < minModulusBitLength) {
throw new Error(`modulus n must have a bit length larger than or equal to ${minModulusBitLength}`);
}
return Promise.all(
Array(m)
.fill(null)
.map(() => randomPositiveCoPrimeLessThan(n))
);
}
/**
* Generate a set of proofs $sigma$ for a given set of challenges $p$ using the paillier public key modulus $n$ and the private key $\lambda$.
* @param n - paillier public key modulus $n$
* @param lambda - private key $\lambda, which is the $\euler(N) = (p-1)(q-1)$
* @param p - array of challenges $p$
* @returns {Promise<Array<bigint>>} - array of proofs $\sigma$
*/
export function prove(n: bigint, lambda: bigint, p: Array<bigint>): bigint[] {
if (!p.every((p_i) => p_i > 0)) {
throw new Error('All paillier challenge values must be positive.');
}
const n_inv = modInv(n, lambda);
return p.map((p_i) => modPow(p_i, n_inv, n));
}
/**
* Verify a set of proofs $\sigma$ on the modulus $n$ using the challenges $p$ that were provided to the prover to generate the proofs.
* @param n - paillier public key modulus $n$
* @param p - array of challenges $p$
* @param sigma - array of proofs $\sigma$
*/
export function verify(n: bigint, p: Array<bigint>, sigma: Array<bigint>): boolean {
if (!p.every((p_i) => p_i > 0)) {
throw new Error('All paillier challenge values must be positive.');
}
if (!sigma.every((sigma_i) => sigma_i > 0)) {
throw new Error('All paillier challenge proof values must be positive.');
}
// a) Check that $N$ is a positive integer and is not divisible by all
// the primes less than $\alpha$.
if (n <= 0) {
return false;
}
if (alpha !== 319567) {
throw new Error('unsupported alpha value');
}
for (const prime of primesSmallerThan319567) {
if (n % BigInt(prime) === BigInt(0)) {
return false;
}
}
// b) Check that $\sigma_i$ is a positive integer $i = 1...m$.
if (sigma.length !== m) {
return false;
}
if (!sigma.every((sigma_i) => sigma_i > 0)) {
return false;
}
// c) Verify that $p_i = \sigma_i^N \mod N$ for $i = 1...m$.
for (let i = 0; i < m; i++) {
if (p[i] !== modPow(sigma[i], n, n)) {
return false;
}
}
return true;
}
Выполнить команду
Для локальной разработки. Не используйте в интернете!