You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I have been working on a circuit for a proof of ownership of a private key.
The circuit computes the public key given the input private key and matches the computed public key with the input public key.
package gnark
import (
"github.com/consensys/gnark/frontend"
"github.com/consensys/gnark/std/algebra/twistededwards"
"github.com/consensys/gnark/std/signature/eddsa"
"github.com/consensys/gurvy"
)
// OwnershipSkCircuit defines circuit for proof of ownership of sk
type OwnershipSkCircuit struct {
Pk eddsa.PublicKey `gnark:",public"`
Sk frontend.Variable
}
// Define declares the circuit's constraints
func (circuit *OwnershipSkCircuit) Define(curveID gurvy.ID, cs *frontend.ConstraintSystem) error {
params, err := twistededwards.NewEdCurve(curveID)
if err != nil {
return err
}
circuit.Pk.Curve = params
computedPk := twistededwards.Point{}
computedPk.ScalarMulFixedBase(cs, circuit.Pk.Curve.BaseX, circuit.Pk.Curve.BaseY, circuit.Sk, circuit.Pk.Curve)
computedPk.MustBeOnCurve(cs, circuit.Pk.Curve)
cs.AssertIsEqual(circuit.Pk.A.X, computedPk.X)
cs.AssertIsEqual(circuit.Pk.A.Y, computedPk.Y)
return nil
}
I wrote tests for the circuit similar to the tests of the std lib eddsa tests here, see below.
To my surprise, the tests pass for curve bn256 and bls381 but fail for bls377 and bw761.
Cannot find the issue in the circuit and tests, any suggestion would be greatly appreciated.
witness.Sk.Assign(privkeyScalar) --> under the hood, privkeyScalar is reduced modulo r (the size of the field in which the variables of the SNARK circuit live, equal to the size of the r-torsion of the pairing curve, eg bn256, bls381, etc)
During the key generation in eddsa (see signature/eddsa/bn256/eddsa.go, the function GenerateKey for instance), privkeyScalar is taken modulo the cardinality of the twisted Edwards curve.
Both reductions yield 2 different results, hence the discrepancy between what is computed by the circuit and what is computed by the eddsa signature lib. In fact it's deterministic here due to the lack of randomness (source=0), and the scalar is such that there is no reduction in bn256 and bls381, so the test passes.
To correct this, you need to write privkeyScalar in 2 chunks of say 128 bits each, assign each chunk as a 2 different private inputs, and in the circuit you need to do something like
I have been working on a circuit for a proof of ownership of a private key.
The circuit computes the public key given the input private key and matches the computed public key with the input public key.
I wrote tests for the circuit similar to the tests of the std lib eddsa tests here, see below.
To my surprise, the tests pass for curve bn256 and bls381 but fail for bls377 and bw761.
Cannot find the issue in the circuit and tests, any suggestion would be greatly appreciated.
gnark version: v0.3.9-0.20210121051139-4078ebfe99fc
gurvy version: v0.3.8-0.20210118135515-02bca07c2b11
The text was updated successfully, but these errors were encountered: