github.com/dusk-network/dusk-crypto@v0.1.3/mlsag/dualkey.go (about) 1 package mlsag 2 3 import ( 4 "errors" 5 6 ristretto "github.com/bwesterb/go-ristretto" 7 ) 8 9 // DualKey is a specific instantiation of mlsag where the second key is 10 // a commitment to zero 11 type DualKey struct { 12 Proof 13 dualkeys []ristretto.Scalar 14 } 15 16 func NewDualKey() *DualKey { 17 return &DualKey{ 18 Proof: Proof{}, 19 dualkeys: make([]ristretto.Scalar, 2), 20 } 21 } 22 23 func (d *DualKey) SetPrimaryKey(key ristretto.Scalar) ristretto.Point { 24 d.dualkeys[0] = key 25 return privKeyToPubKey(key) 26 } 27 28 func (d *DualKey) SetCommToZero(key ristretto.Scalar) ristretto.Point { 29 d.dualkeys[1] = key 30 return privKeyToPubKey(key) 31 } 32 33 func (d *DualKey) SetMsg(msg []byte) { 34 d.Proof.msg = msg 35 } 36 37 // SubCommToZero subtracts p from every point from the second public key 38 // in the matrix of decoy pubkeys 39 func (d *DualKey) SubCommToZero(p ristretto.Point) { 40 for i := range d.pubKeysMatrix { 41 commToZero := &d.pubKeysMatrix[i].keys[1] 42 commToZero.Sub(commToZero, &p) 43 } 44 } 45 46 func (d *DualKey) Prove() (*Signature, ristretto.Point, error) { 47 48 if (d.dualkeys[0].IsNonZeroI() == 0) || (d.dualkeys[1].IsNonZeroI() == 0) { 49 return nil, ristretto.Point{}, errors.New("primary key or commitment to zero cannot be zero") 50 } 51 52 d.AddSecret(d.dualkeys[0]) 53 d.AddSecret(d.dualkeys[1]) 54 55 sig, keyimage, err := d.prove(true) 56 if err != nil { 57 return nil, ristretto.Point{}, err 58 } 59 if len(keyimage) != 1 { 60 return nil, ristretto.Point{}, errors.New("dual key mlsag must only contain one key image") 61 } 62 return sig, keyimage[0], err 63 }