@@ -72,30 +72,52 @@ func SampleQn(random io.Reader, N *big.Int) (*big.Int, error) {
7272func Prove (random io.Reader , x , g , gx , h , hx , N * big.Int , secParam uint ) (* Proof , error ) {
7373 rSizeBits := uint (N .BitLen ()) + 2 * secParam
7474 rSizeBytes := (rSizeBits + 7 ) / 8
75-
7675 rBytes := make ([]byte , rSizeBytes )
77- _ , err := io .ReadFull (random , rBytes )
78- if err != nil {
79- return nil , err
80- }
81- r := new (big.Int ).SetBytes (rBytes )
8276
83- gP := new (big.Int ).Exp (g , r , N )
84- hP := new (big.Int ).Exp (h , r , N )
77+ ONE := big .NewInt (1 )
78+ NUM_TRIES := 10
79+ var r , gP , hP , gc , hc big.Int
80+ for i := 0 ; i < NUM_TRIES ; i ++ {
81+ _ , err := io .ReadFull (random , rBytes )
82+ if err != nil {
83+ return nil , err
84+ }
8585
86- c , err := doChallenge (g , gx , h , hx , gP , hP , N , secParam )
87- if err != nil {
88- return nil , err
89- }
86+ r .SetBytes (rBytes )
87+ gP .Exp (g , & r , N )
88+ hP .Exp (h , & r , N )
9089
91- z := new (big.Int )
92- z .Mul (c , x ).Add (z , r )
90+ c , err := doChallenge (g , gx , h , hx , & gP , & hP , N , secParam )
91+ if err != nil {
92+ return nil , err
93+ }
9394
94- return & Proof {z , c , secParam }, nil
95+ // Challenge must not be congruent to zero.
96+ // c != 0 mod m, where m = (p-1)(q-1)/4, and N = p*q.
97+ // Check this by doing an Exp because m is unknown.
98+ gc .Exp (g , c , N )
99+ hc .Exp (h , c , N )
100+ if gc .Cmp (ONE ) != 0 && hc .Cmp (ONE ) != 0 {
101+ z := new (big.Int ).Mul (c , x )
102+ z .Add (z , & r )
103+ return & Proof {z , c , secParam }, nil
104+ }
105+ }
106+
107+ return nil , ErrProve
95108}
96109
97110// Verify checks whether x = Log_g(g^x) = Log_h(h^x).
98111func (p Proof ) Verify (g , gx , h , hx , N * big.Int ) bool {
112+ // Check c != 0 (mod m), where m = (p-1)(q-1)/4,
113+ // by doing an Exp as m is unknown.
114+ ONE := big .NewInt (1 )
115+ gc := new (big.Int ).Exp (g , p .c , N )
116+ hc := new (big.Int ).Exp (h , p .c , N )
117+ if gc .Cmp (ONE ) == 0 || hc .Cmp (ONE ) == 0 {
118+ return false
119+ }
120+
99121 gPNum := new (big.Int ).Exp (g , p .z , N )
100122 gPDen := new (big.Int ).Exp (gx , p .c , N )
101123 ok := gPDen .ModInverse (gPDen , N )
@@ -193,4 +215,6 @@ var (
193215 ErrSecParam = errors .New ("zk/qndleq: the security parameter must be greater than 128" )
194216 // ErrBounds is returned when a value is not in the range 0 to N.
195217 ErrBounds = errors .New ("zk/qndleq: input must be greater than 0 and less than N" )
218+ // ErrProve is returned when Prove cannot produce a proof.
219+ ErrProve = errors .New ("zk/qndleq: Prove cannot produce a proof" )
196220)
0 commit comments