-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathschnorr.js
More file actions
117 lines (97 loc) · 3.93 KB
/
Copy pathschnorr.js
File metadata and controls
117 lines (97 loc) · 3.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
/**
* Schnorr module
* @module
*/
const Prover = require('./modules/prover');
const Verifier = require('./modules/verifier');
const bigInteger = require('big-integer');
const debug = require('debug');
const ElGamal = require('basic_simple_elgamal');
/**
* @typedef {Object} Proof - The NIZK Schnorr proof.
* @property {bigInteger.BigInteger|string} commitment - The commitment which is made randomly
* by prover.
* @property {bigInteger.BigInteger|string} response - The response which contains the secret
* knowledge r and is used to prove the knowledge of secret.
*/
const log = debug('app::NIZKP::Schnorr');
/**
* The class which integrate the prover and verifier both together and give you
* the schnorr module at once.
* Though this module works upon ElGamal engine but don't worry! if you use discrete logarithm
* and you want to prove the secret, you can use this module too. As matter of fact you even don't
* need to know what is ElGamal and how it works.
* Also you should note that this module just works upon Multiplicative group!
*/
class Schnorr{
/**
* Initialize the prover and verifier with multiplicative group which you use in your
* computations. you can initialize schnorr by passing an instance of you ElGamal engine if
* you have one or initialize with the Modulus and generator separately
* @param {ElGamal|string|bigInteger.BigInteger} p - The ElGamal engine or the modulus of the
* multiplicative group, if you pass ElGamal engine then you can leave the g as undefined.
* @param {string|bigInteger.BigInteger} [g] - The generator of the underlying multiplicative group.
* @throws Will throw an error if wrong type of arguments is passed.
*/
constructor(p, g){
let generator = undefined;
let modulus = undefined;
if(p instanceof ElGamal){
generator = p.generator;
modulus = p.modulus;
}else if(typeof p === 'string')
modulus = bigInteger(p);
else if(p instanceof bigInteger)
modulus = p;
else
throw new Error('Wrong type of modulus is passed!');
if(generator === undefined){
if(typeof g === 'string')
generator = bigInteger(g);
else if(g instanceof bigInteger)
generator = g;
else
throw new Error('Wrong type of generator is passed!');
}
/**
* @property {Prover} prover - The underlying prover class.
*/
this.prover = new Prover({
p: modulus,
g: generator
});
/**
* @property {Verifier} verifier - The underlying verifier class.
*/
this.verifier = new Verifier({
p: modulus,
g: generator
});
}
/**
* Prove the secret "r" to verifier, to be more accurate, you prove that x = g^r without
* revealing the secret "r".
* @param {bigInteger.BigInteger|string} r - The secret knowledge which you want to prove.
* @param {bigInteger.BigInteger|string} [x] - The public info which is g^r
* @returns {Promise<Proof>} - the resulted schnorr proof.
* @throws Will throw an error if given secret knowledge is not type of string nor big integer.
*/
async prove(r, x){
return this.prover.prove(r, x)
}
/**
* Verify knowledge of 'r' which is used in producing of 'x': x = g^{r}
* @param {bigInteger.BigInteger|string} x - The argument which the prover should prove
* he knows its secret knowledge and how it's produced.
* @param {Proof} proof - The Schnorr proof which is resulted by calling prove() method and
* you use it to verify prover's knowledge of secret.
* @returns {boolean} Returns true if NIZK Schnorr proof verified and false otherwise
*/
verify(x, proof){
return this.verifier.verify(x, proof);
}
}
/**
* Schnorr class
*/
module.exports = Schnorr;