meck93/evote-crypto

View on GitHub
src/ff-elgamal/proofs/membership.ts

Summary

Maintainability
B
6 hrs
Test Coverage
/**
* Membership Proof
*
* ElGamal Finite Field Non-Interactive Zero-Knowledge Proof for Plaintext Membership
* Using the Disjunctive Chaum-Pedersen Proof
*
* Proof that one of two statements is true without revealing which one.
*
* - generate and verify proofs
*/
 
Missing semicolon
import BN = require('bn.js')
Missing semicolon
import { GlobalHelper } from '../../index'
Missing semicolon
import { Cipher, SystemParameters, isCipher, isSystemParameters } from '../index'
Missing semicolon
import { MembershipProof } from './models'
 
Missing semicolon
const web3 = require('web3')
Missing semicolon
const printConsole = false
 
// modulo operations
Identical blocks of code found in 2 locations. Consider refactoring.
Missing semicolon
const add = (a: BN, b: BN, sp: SystemParameters): BN => GlobalHelper.addBN(a, b, sp.q)
Similar blocks of code found in 4 locations. Consider refactoring.
Missing semicolon
const sub = (a: BN, b: BN, sp: SystemParameters): BN => GlobalHelper.subBN(a, b, sp.q)
Similar blocks of code found in 4 locations. Consider refactoring.
Missing semicolon
const mul = (a: BN, b: BN, sp: SystemParameters): BN => GlobalHelper.mulBN(a, b, sp.p)
Similar blocks of code found in 4 locations. Consider refactoring.
Missing semicolon
const div = (a: BN, b: BN, sp: SystemParameters): BN => GlobalHelper.divBN(a, b, sp.p)
Identical blocks of code found in 2 locations. Consider refactoring.
Missing semicolon
const pow = (a: BN, b: BN, sp: SystemParameters): BN => GlobalHelper.powBN(a, b, sp.p)
 
TODO found
// TODO: check paper https://eprint.iacr.org/2016/771.pdf why we should not hash a and b
Similar blocks of code found in 2 locations. Consider refactoring.
const generateChallenge = (
q: BN,
uniqueID: string,
a: BN,
b: BN,
a0: BN,
b0: BN,
a1: BN,
b1: BN
): BN => {
Missing semicolon
let c = web3.utils.soliditySha3(uniqueID, a, b, a0, b0, a1, b1)
Missing semicolon
c = web3.utils.toBN(c)
Missing semicolon
c = c.mod(q)
 
Missing semicolon
return c
Missing semicolon
}
 
// generate a proof for an encrypted yes vote
// given:
// - cipher (a,b) = (g^r, h^r*g^m)
// - random value r used to encrypt the message
// steps:
// 1. generate fake values c0,f0 for m=0 (random values in Z_q)
// 2. compute fake (a0,b0) = (g^f0 / a^c0, h^f0 / b^c0)
// 3. generate proof for m=1
// 3.1 generate a random value x in Z_q
// 3.2 compute (a1,b1) = (g^x, h^x)
// 4. generate the challenge c
// 5. compute c1 = c - c0
// 6. compute f1 = x + c1 * r (NOTE: mod q!)
export const generateYesProof = (
cipher: Cipher,
sp: SystemParameters,
pk: BN,
uniqueID: string
): MembershipProof => {
Missing semicolon
isCipher(cipher)
Missing semicolon
isSystemParameters(sp)
 
Missing semicolon
const { a, b, r } = cipher
 
Missing semicolon
const c0 = GlobalHelper.getSecureRandomValue(sp.q)
Missing semicolon
const f0 = GlobalHelper.getSecureRandomValue(sp.q)
 
Missing semicolon
const a0 = div(pow(sp.g, f0, sp), pow(a, c0, sp), sp)
Missing semicolon
const b0 = div(pow(pk, f0, sp), pow(b, c0, sp), sp)
 
Missing semicolon
const x = GlobalHelper.getSecureRandomValue(sp.q)
Missing semicolon
const a1 = pow(sp.g, x, sp)
Missing semicolon
const b1 = pow(pk, x, sp)
 
Missing semicolon
const c = generateChallenge(sp.q, uniqueID, a, b, a0, b0, a1, b1)
Missing semicolon
const c1 = add(sp.q, sub(c, c0, sp), sp)
 
Missing semicolon
const f1 = add(x, c1.mul(r as BN).mod(sp.q), sp)
 
unused expression, expected an assignment or function call
Missing semicolon
printConsole && console.log('c0\t\t\t', c0.toNumber())
unused expression, expected an assignment or function call
Missing semicolon
printConsole && console.log('f0\t\t\t', f0.toNumber())
unused expression, expected an assignment or function call
Missing semicolon
printConsole && console.log('a0\t\t\t', a0.toNumber())
unused expression, expected an assignment or function call
Missing semicolon
printConsole && console.log('b0\t\t\t', b0.toNumber())
unused expression, expected an assignment or function call
Missing semicolon
printConsole && console.log('x\t\t\t', x.toNumber())
unused expression, expected an assignment or function call
Missing semicolon
printConsole && console.log('a1\t\t\t', a1.toNumber())
unused expression, expected an assignment or function call
Missing semicolon
printConsole && console.log('b1\t\t\t', b1.toNumber())
unused expression, expected an assignment or function call
Missing semicolon
printConsole && console.log('c\t\t', c.toNumber())
unused expression, expected an assignment or function call
Missing semicolon
printConsole && console.log('c1 = (q + (c - c0) % q) % q\t', c1.toNumber())
unused expression, expected an assignment or function call
Missing semicolon
printConsole && console.log('f1 = x + c1*r\t\t', f1.toNumber())
unused expression, expected an assignment or function call
Missing semicolon
printConsole && console.log()
 
TODO found
// TODO: proof is only c0,c1 f0,f1 (recompute a0,a1 and b0,b1 during the verification)
Missing semicolon
return { a0, a1, b0, b1, c0, c1, f0, f1 }
Missing semicolon
}
 
// generate a proof for an encrypted no vote
// given:
// - cipher (a,b) = (g^r, h^r*g^m)
// - random value r used to encrypt the message
// steps:
// 1. generate fake values c1,f1 for m=1 (random values in Z_q)
// 2. compute fake b_ = b/g
// 3. compute fake (a1,b1) = (g^f1 / a^c1, h^f1 / (b/g)^c1)
// 4. generate proof for m=0
// 4.1 generate a random value x in Z_q
// 4.2 compute (a0,b0) = (g^x, h^x)
// 5. generate the challenge c
// 6. compute c0 = c - c1
// 7. compute f0 = x + c0 * r (NOTE: mod q! = mod n!)
Function `generateNoProof` has 26 lines of code (exceeds 25 allowed). Consider refactoring.
export const generateNoProof = (
cipher: Cipher,
sp: SystemParameters,
pk: BN,
uniqueID: string
): MembershipProof => {
Missing semicolon
isCipher(cipher)
Missing semicolon
isSystemParameters(sp)
 
Missing semicolon
const { a, b, r } = cipher
 
Missing semicolon
const c1 = GlobalHelper.getSecureRandomValue(sp.q)
Missing semicolon
const f1 = GlobalHelper.getSecureRandomValue(sp.q)
 
Missing semicolon
const b_ = div(b, sp.g, sp)
 
Missing semicolon
const a1 = div(pow(sp.g, f1, sp), pow(a, c1, sp), sp)
Missing semicolon
const b1 = div(pow(pk, f1, sp), pow(b_, c1, sp), sp)
 
Missing semicolon
const x = GlobalHelper.getSecureRandomValue(sp.q)
Missing semicolon
const a0 = pow(sp.g, x, sp)
Missing semicolon
const b0 = pow(pk, x, sp)
 
Missing semicolon
const c = generateChallenge(sp.q, uniqueID, a, b, a0, b0, a1, b1)
Missing semicolon
const c0 = add(sp.q, sub(c, c1, sp), sp)
 
Missing semicolon
const f0 = add(x, c0.mul(r as BN).mod(sp.q), sp)
 
unused expression, expected an assignment or function call
Missing semicolon
printConsole && console.log('c0\t\t\t', c0.toNumber())
unused expression, expected an assignment or function call
Missing semicolon
printConsole && console.log('f0\t\t\t', f0.toNumber())
unused expression, expected an assignment or function call
Missing semicolon
printConsole && console.log('a0\t\t\t', a0.toNumber())
unused expression, expected an assignment or function call
Missing semicolon
printConsole && console.log('b0\t\t\t', b0.toNumber())
unused expression, expected an assignment or function call
Missing semicolon
printConsole && console.log('x\t\t\t', x.toNumber())
Missing semicolon
unused expression, expected an assignment or function call
printConsole && console.log('a1\t\t\t', a1.toNumber())
unused expression, expected an assignment or function call
Missing semicolon
printConsole && console.log('b1\t\t\t', b1.toNumber())
unused expression, expected an assignment or function call
Missing semicolon
printConsole && console.log('c\t\t', c.toNumber())
unused expression, expected an assignment or function call
Missing semicolon
printConsole && console.log('c1 = (q + (c - c0) % q) % q\t', c1.toNumber())
unused expression, expected an assignment or function call
Missing semicolon
printConsole && console.log('f1 = x + c1*r\t\t', f1.toNumber())
unused expression, expected an assignment or function call
Missing semicolon
printConsole && console.log()
 
Missing semicolon
return { a0, a1, b0, b1, c0, c1, f0, f1 }
Missing semicolon
}
 
// verification g^f0 == a0*a^c0
// verification g^f1 == a1*a^c1
// verification h^f0 == b0 * b^c0
// verification h^f1 == b1 * (b/g)^c1
// recompute the hash and verify
export const verify = (
cipher: Cipher,
proof: MembershipProof,
sp: SystemParameters,
pk: BN,
uniqueID: string
): boolean => {
Missing semicolon
isCipher(cipher)
Missing semicolon
isSystemParameters(sp)
 
Missing semicolon
const { a, b } = cipher
Identical blocks of code found in 2 locations. Consider refactoring.
Missing semicolon
const { a0, a1, b0, b1, c0, c1, f0, f1 } = proof
 
Missing semicolon
const v1 = GlobalHelper.timingSafeEqualBN(pow(sp.g, f0, sp), mul(a0, pow(a, c0, sp), sp))
Missing semicolon
const v2 = GlobalHelper.timingSafeEqualBN(pow(sp.g, f1, sp), mul(a1, pow(a, c1, sp), sp))
Missing semicolon
const v3 = GlobalHelper.timingSafeEqualBN(pow(pk, f0, sp), mul(b0, pow(b, c0, sp), sp))
const v4 = GlobalHelper.timingSafeEqualBN(
pow(pk, f1, sp),
mul(b1, pow(div(b, sp.g, sp), c1, sp), sp)
Missing semicolon
)
const v5 = GlobalHelper.timingSafeEqualBN(
c1.add(c0).mod(sp.q),
generateChallenge(sp.q, uniqueID, a, b, a0, b0, a1, b1)
Missing semicolon
)
 
unused expression, expected an assignment or function call
Missing semicolon
printConsole && console.log('g^f0 == a0*a^c0:\t', v1)
unused expression, expected an assignment or function call
Missing semicolon
printConsole && console.log('g^f1 == a1*a^c1\t', v2)
unused expression, expected an assignment or function call
Missing semicolon
printConsole && console.log('h^f0 == b0*b^c0\t\t', v3)
Missing semicolon
unused expression, expected an assignment or function call
printConsole && console.log('h^f1 == b1*(b/g)^c1\t', v4)
unused expression, expected an assignment or function call
Missing semicolon
printConsole && console.log('c == c1 + c0\t\t', v5)
unused expression, expected an assignment or function call
Missing semicolon
printConsole && console.log()
 
Missing semicolon
return v1 && v2 && v3 && v4 && v5
Missing semicolon
}