Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MuSig2: Catch up to 0.4.0 #1865

Merged
merged 11 commits into from Aug 11, 2022
15 changes: 15 additions & 0 deletions btcec/btcec.go
Expand Up @@ -39,3 +39,18 @@ type CurveParams = secp.CurveParams
func Params() *CurveParams {
return secp.Params()
}

// Generator returns the public key at the Generator Point.
func Generator() *PublicKey {
sputn1ck marked this conversation as resolved.
Show resolved Hide resolved
var (
result JacobianPoint
k secp.ModNScalar
)

k.SetInt(1)
ScalarBaseMultNonConst(&k, &result)
sputn1ck marked this conversation as resolved.
Show resolved Hide resolved

result.ToAffine()

return NewPublicKey(&result.X, &result.Y)
}
52 changes: 52 additions & 0 deletions btcec/curve.go
Expand Up @@ -4,13 +4,18 @@
package btcec

import (
"fmt"

secp "github.com/decred/dcrd/dcrec/secp256k1/v4"
)

// JacobianPoint is an element of the group formed by the secp256k1 curve in
// Jacobian projective coordinates and thus represents a point on the curve.
type JacobianPoint = secp.JacobianPoint

// infinityPoint is the jacobian representation of the point at infinity.
var infinityPoint JacobianPoint

// MakeJacobianPoint returns a Jacobian point with the provided X, Y, and Z
// coordinates.
func MakeJacobianPoint(x, y, z *FieldVal) JacobianPoint {
Expand Down Expand Up @@ -61,3 +66,50 @@ func ScalarBaseMultNonConst(k *ModNScalar, result *JacobianPoint) {
func ScalarMultNonConst(k *ModNScalar, point, result *JacobianPoint) {
secp.ScalarMultNonConst(k, point, result)
}

// ParseJacobian parses a byte slice point as a secp.Publickey and returns the
// pubkey as a JacobianPoint. If the nonce is a zero slice, the infinityPoint
// is returned.
func ParseJacobian(point []byte) (JacobianPoint, error) {
var result JacobianPoint

if len(point) != 33 {
str := fmt.Sprintf("invalid nonce: invalid length: %v",
len(point))
sputn1ck marked this conversation as resolved.
Show resolved Hide resolved
return JacobianPoint{}, makeError(secp.ErrPubKeyInvalidLen, str)
}

if point[0] == 0x00 {
return infinityPoint, nil
}

noncePk, err := secp.ParsePubKey(point)
if err != nil {
return JacobianPoint{}, err
}
noncePk.AsJacobian(&result)

return result, nil
}

// JacobianToByteSlice converts the passed JacobianPoint to a Pubkey
// and serializes that to a byte slice. If the JacobianPoint is the infinity
// point, a zero slice is returned.
func JacobianToByteSlice(point JacobianPoint) []byte {
if point.X == infinityPoint.X && point.Y == infinityPoint.Y {
return make([]byte, 33)
}

point.ToAffine()

return NewPublicKey(
&point.X, &point.Y,
).SerializeCompressed()
}

// GeneratorJacobian sets the passed JacobianPoint to the Generator Point.
func GeneratorJacobian(jacobian *JacobianPoint) {
var k ModNScalar
k.SetInt(1)
ScalarBaseMultNonConst(&k, jacobian)
}
5 changes: 5 additions & 0 deletions btcec/error.go
Expand Up @@ -17,3 +17,8 @@ type Error = secp.Error
// errors.As, so the caller can directly check against an error kind when
// determining the reason for an error.
type ErrorKind = secp.ErrorKind

// makeError creates an secp.Error given a set of arguments.
func makeError(kind ErrorKind, desc string) Error {
return Error{Err: kind, Description: desc}
}
9 changes: 8 additions & 1 deletion btcec/schnorr/musig2/keys.go
Expand Up @@ -26,6 +26,10 @@ var (
// ErrTweakedKeyIsInfinity is returned if while tweaking a key, we end
// up with the point at infinity.
ErrTweakedKeyIsInfinity = fmt.Errorf("tweaked key is infinity point")

// ErrTweakedKeyOverflows is returned if a tweaking key is larger than
// 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141.
ErrTweakedKeyOverflows = fmt.Errorf("tweaked key is to large")
)

// sortableKeys defines a type of slice of public keys that implements the sort
Expand Down Expand Up @@ -286,7 +290,10 @@ func tweakKey(keyJ btcec.JacobianPoint, parityAcc btcec.ModNScalar, tweak [32]by
// Next, map the tweak into a mod n integer so we can use it for
// manipulations below.
tweakInt := new(btcec.ModNScalar)
tweakInt.SetBytes(&tweak)
overflows := tweakInt.SetBytes(&tweak)
if overflows == 1 {
return keyJ, parityAcc, tweakAcc, ErrTweakedKeyOverflows
}
Roasbeef marked this conversation as resolved.
Show resolved Hide resolved

// Next, we'll compute: Q_i = g*Q + t*G, where g is our parityFactor and t
// is the tweakInt above. We'll space things out a bit to make it easier to
Expand Down