musig2 0.1.1 → 0.1.2
raw patch · 9 files changed
+78/−61 lines, 9 filesdep ~ppad-secp256k1
Dependency ranges changed: ppad-secp256k1
Files
- CHANGELOG +4/−0
- lib/Crypto/Curve/Secp256k1/MuSig2.hs +22/−22
- lib/Crypto/Curve/Secp256k1/MuSig2/Internal.hs +13/−3
- musig2.cabal +2/−2
- test/AggPartialsProperty.hs +7/−7
- test/NonceGenProperty.hs +4/−4
- test/SignVerifyProperty.hs +7/−6
- test/SignVerifyTweakProperty.hs +10/−9
- test/Util.hs +9/−8
CHANGELOG view
@@ -1,5 +1,9 @@ # Changelog +## 0.1.2 (2025-12-30)++* Fix Hackage build failure by implementing `modQ` locally to support `ppad-secp256k1` 0.5.0+.+ ## 0.1.1 (2025-12-22) * Bump `ppad-secp256k1` to 0.5.0. More efficient and faster EC operations.
lib/Crypto/Curve/Secp256k1/MuSig2.hs view
@@ -105,7 +105,7 @@ ) where import Control.Exception (ErrorCall (..), evaluate, throwIO, try)-import Crypto.Curve.Secp256k1 (Projective, Pub, add, derive_pub, modQ, mul, neg, serialize_point, _CURVE_G, _CURVE_Q, _CURVE_ZERO)+import Crypto.Curve.Secp256k1 (Projective, Pub, add, derive_pub, mul, neg, serialize_point, _CURVE_G, _CURVE_ZERO) import Crypto.Curve.Secp256k1.MuSig2.Internal import Data.Binary.Put ( putWord32be,@@ -145,7 +145,7 @@ taccVal = maybe 0 getTweak $ tacc keyCtx gaccVal = gacc keyCtx -- BIP 327: Let g = 1 if has_even_y(Q), otherwise let g = -1 mod n- g = if isEvenPub aggPk then 1 else _CURVE_Q - 1+ g = if isEvenPub aggPk then 1 else curveOrder - 1 -- Apply accumulated parity factor g' = modQ (g * gaccVal) sSum = modQ $ sum partials@@ -187,8 +187,8 @@ -- `d` is negated if exactly one of the parity accumulator OR the aggregated pubkey has odd parity. -- gaccVal == 1 means no negation, gaccVal == n-1 means negation parityFromGacc = gaccVal /= 1- d = if parityFromGacc /= oddAggPk then _CURVE_Q - d' else d'- p = fromMaybe (error "musig2 (sign): failed to derive public key") $ derive_pub d' -- Use original secret key for public key derivation+ d = if parityFromGacc /= oddAggPk then curveOrder - d' else d'+ p = fromMaybe (error "musig2 (sign): failed to derive public key") $ derive_pub (fromInteger d') -- Use original secret key for public key derivation a = computeKeyAggCoef p publicKeys -- if has_even_Y(R): -- k = k1 + b*k2@@ -196,10 +196,10 @@ -- k = (n-k1) + b(n-k2) -- = n - (k1 + b*k2) b = getSigningNonceCoeff ctx- k = if isEvenPub nonce then k1 + b * k2 else _CURVE_Q - (k1 + b * k2)+ k = if isEvenPub nonce then k1 + b * k2 else curveOrder - (k1 + b * k2) s = modQ (k + e * a * d)- r1' = fromMaybe (error "musig2 (sign): failed to compute r1") $ mul _CURVE_G secnonce.k1- r2' = fromMaybe (error "musig2 (sign): failed to compute r2") $ mul _CURVE_G secnonce.k2+ r1' = fromMaybe (error "musig2 (sign): failed to compute r1") $ mul _CURVE_G (fromInteger secnonce.k1)+ r2' = fromMaybe (error "musig2 (sign): failed to compute r2") $ mul _CURVE_G (fromInteger secnonce.k2) pubNonce' = PubNonce r1' r2' in if partialSigVerifyInternal s pubNonce' p ctx then s else error "musig2 (sign): could not verify partial signature against public nonce, public key and session context"@@ -264,19 +264,19 @@ r2' = pubnonce.r2 b = getSigningNonceCoeff ctx finalNonce = getSigningNonce ctx -- This is the final aggregate nonce used for evenness check- s = if partial < 0 || partial >= _CURVE_Q then error "musig2 (partialSigVerifyInternal): partial signature must be within curve order." else partial+ s = if partial < 0 || partial >= curveOrder then error "musig2 (partialSigVerifyInternal): partial signature must be within curve order." else partial -- Reconstruct the individual's effective nonce: R_s1 + b * R_s2- r2b = fromMaybe (error "musig2 (partialSigVerifyInternal): failed to compute r2 * b") $ mul r2' b+ r2b = fromMaybe (error "musig2 (partialSigVerifyInternal): failed to compute r2 * b") $ mul r2' (fromInteger b) re' = add r1' r2b -- Negate individual nonce if final aggregate nonce has odd Y re = if isEvenPub finalNonce then re' else neg re' a = computeKeyAggCoef pk publicKeys -- Calculate g factor: 1 if aggregate pubkey has even Y, n-1 if odd- g = if oddAggPk then _CURVE_Q - 1 else 1+ g = if oddAggPk then curveOrder - 1 else 1 -- Apply parity accumulator: gacc is accumulated parity factor g' = modQ (g * gaccVal)- sG = fromMaybe (error "musig2 (partialSigVerifyInternal): failed to compute s * G") $ mul _CURVE_G s- pkMul = fromMaybe (error "musig2 (partialSigVerifyInternal): failed to compute pk multiplication") $ mul pk (modQ (e * a * g'))+ sG = fromMaybe (error "musig2 (partialSigVerifyInternal): failed to compute s * G") $ mul _CURVE_G (fromInteger s)+ pkMul = fromMaybe (error "musig2 (partialSigVerifyInternal): failed to compute pk multiplication") $ mul pk (fromInteger (modQ (e * a * g'))) sG' = re `add` pkMul in sG == sG'@@ -327,7 +327,7 @@ | Seq.length pks' > fromIntegral (maxBound :: Word32) = error "musig2 (mkKeyAggContext): too many public keys (max 2^32 - 1)" | _CURVE_ZERO `elem` pks' = error "musig2 (mkKeyAggContext): public key at point of infinity" | maybe False ((< 0) . getTweak) mTweak = error "musig2 (mkKeyAggContext): tweak must be non-negative"- | maybe False ((>= _CURVE_Q) . getTweak) mTweak = error "musig2 (mkKeyAggContext): tweak must be less than curve order"+ | maybe False ((>= curveOrder) . getTweak) mTweak = error "musig2 (mkKeyAggContext): tweak must be less than curve order" | otherwise = case aggPublicKeys pks' of Nothing -> error "musig2 (mkKeyAggContext): failed to aggregate public keys" Just aggPk@@ -395,7 +395,7 @@ pks' = Seq.fromList (toList pks) tweaks' = Seq.fromList (toList tweaks) checkNeg = (< 0) . getTweak- checkOrder = (>= _CURVE_Q) . getTweak+ checkOrder = (>= curveOrder) . getTweak {- | Gets the signing nonce as a 'Projective' following [BIP-0327 algorithm and recommendations](https://github.com/bitcoin/bips/blob/master/bip-0327.mediawiki#dealing-with-infinity-in-nonce-aggregation).@@ -406,7 +406,7 @@ b = getSigningNonceCoeff ctx aggNonce = ctx.aggNonce aggNonce' = if aggNonce.r1 == _CURVE_ZERO then PubNonce _CURVE_G aggNonce.r2 else aggNonce- r2b = fromMaybe (error "musig2 (getSigningNonce): failed to compute r2 * b") $ mul aggNonce'.r2 b+ r2b = fromMaybe (error "musig2 (getSigningNonce): failed to compute r2 * b") $ mul aggNonce'.r2 (fromInteger b) finalNonce = add aggNonce'.r1 r2b in if finalNonce == _CURVE_ZERO then _CURVE_G else finalNonce@@ -484,8 +484,8 @@ PlainTweak t -> -- Plain tweak: g = 1, Q' = g*Q + t*G, tacc' = t + g*tacc, gacc' = g*gacc let g = 1- pubkeyMul = fromMaybe (error "musig2 (applyTweak): failed to compute pubkey * g") $ mul pubkey g- tG = fromMaybe (error "musig2 (applyTweak): failed to compute t * G") $ mul _CURVE_G t+ pubkeyMul = fromMaybe (error "musig2 (applyTweak): failed to compute pubkey * g") $ mul pubkey (fromInteger g)+ tG = fromMaybe (error "musig2 (applyTweak): failed to compute t * G") $ mul _CURVE_G (fromInteger t) tweakedPk = add pubkeyMul tG newAccTweak = modQ (t + (g * accTweakVal)) newGacc = modQ (g * gaccIn)@@ -494,9 +494,9 @@ else ctx{q = tweakedPk, tacc = Just (PlainTweak newAccTweak), gacc = newGacc} XOnlyTweak t -> -- X-only tweak: g = 1 if even Y, g = n-1 if odd Y, tacc' = t + g*tacc- let g = if isEvenPub pubkey then 1 else _CURVE_Q - 1- pubkeyMul = fromMaybe (error "musig2 (applyTweak): failed to compute pubkey * g") $ mul pubkey g- tG = fromMaybe (error "musig2 (applyTweak): failed to compute t * G") $ mul _CURVE_G t+ let g = if isEvenPub pubkey then 1 else curveOrder - 1+ pubkeyMul = fromMaybe (error "musig2 (applyTweak): failed to compute pubkey * g") $ mul pubkey (fromInteger g)+ tG = fromMaybe (error "musig2 (applyTweak): failed to compute t * G") $ mul _CURVE_G (fromInteger t) tweakedPk = add pubkeyMul tG newAccTweak = modQ (t + (g * accTweakVal)) newGacc = modQ (g * gaccIn)@@ -685,8 +685,8 @@ -- | Generates a 'PubNonce' from a 'SecNonce'. publicNonce :: SecNonce -> PubNonce publicNonce secNonce =- let r1' = fromMaybe (error "musig2 (publicNonce): failed to compute r1") $ mul _CURVE_G (k1 secNonce)- r2' = fromMaybe (error "musig2 (publicNonce): failed to compute r2") $ mul _CURVE_G (k2 secNonce)+ let r1' = fromMaybe (error "musig2 (publicNonce): failed to compute r1") $ mul _CURVE_G (fromInteger (k1 secNonce))+ r2' = fromMaybe (error "musig2 (publicNonce): failed to compute r2") $ mul _CURVE_G (fromInteger (k2 secNonce)) in PubNonce r1' r2' -- | 'Data.Semigroup' implementation of 'PubNonce' for algebraic sound combination of public nonces.
lib/Crypto/Curve/Secp256k1/MuSig2/Internal.hs view
@@ -27,9 +27,11 @@ hashTag, hashTagModQ, hashProjectivesTag,+ modQ,+ curveOrder, ) where -import Crypto.Curve.Secp256k1 (Projective, Pub, add, modQ, mul, serialize_point, _CURVE_ZERO)+import Crypto.Curve.Secp256k1 (Projective, Pub, add, mul, serialize_point, _CURVE_ZERO) import Crypto.Hash.SHA256 (hash) import Data.Bits (shiftR, xor, (.&.)) import Data.ByteString (ByteString)@@ -68,8 +70,8 @@ pure $ fold1WithDefault _CURVE_ZERO mulResults where pksSeq = Seq.fromList (toList pks)- coefs = fmap (`computeKeyAggCoef` pksSeq) pksSeq- aggPk i p = mul p i -- mul takes first point then scalar+ coefs = fmap (fromInteger . (`computeKeyAggCoef` pksSeq)) pksSeq+ aggPk i p = mul p i -- mul takes first point then scalar (i is now Wider) -- Safe fold1 that handles empty sequences fold1WithDefault def xs = case Seq.viewl xs of Seq.EmptyL -> def@@ -152,3 +154,11 @@ -- | Gets the X-coordinate from a 'Pub'lic key as 'ByteString' xBytes :: Pub -> ByteString xBytes pk = BS.drop 1 $ serialize_point pk++-- | The secp256k1 curve order (a mathematical constant).+curveOrder :: Integer+curveOrder = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141++-- | Modular reduction by the curve order.+modQ :: Integer -> Integer+modQ x = x `mod` curveOrder
musig2.cabal view
@@ -1,6 +1,6 @@ cabal-version: 3.0 name: musig2-version: 0.1.1+version: 0.1.2 synopsis: MuSig2 library license: MIT license-file: LICENSE@@ -31,7 +31,7 @@ , bytestring >=0.9 && <0.13 , containers >=0.6 && <0.9 , entropy >=0.4 && <0.5- , ppad-secp256k1 >=0.3 && <0.6+ , ppad-secp256k1 >=0.5 && <0.6 , ppad-sha256 >=0.2 && <0.3.0 test-suite musig2-tests
test/AggPartialsProperty.hs view
@@ -24,8 +24,8 @@ -- | Property: Aggregating valid partial signatures produces a consistent result prop_aggValidPartials :: SecNonce -> SecKey -> SecNonce -> SecKey -> ByteString -> Property prop_aggValidPartials secNonce1 secKey1 secNonce2 secKey2 msg =- let pubkey1 = fromMaybe (error "Failed to derive pubkey1") $ derive_pub (case secKey1 of SecKey sk -> sk)- pubkey2 = fromMaybe (error "Failed to derive pubkey2") $ derive_pub (case secKey2 of SecKey sk -> sk)+ let pubkey1 = fromMaybe (error "Failed to derive pubkey1") $ derive_pub (fromInteger (case secKey1 of SecKey sk -> sk))+ pubkey2 = fromMaybe (error "Failed to derive pubkey2") $ derive_pub (fromInteger (case secKey2 of SecKey sk -> sk)) pubkeys = [pubkey1, pubkey2] pubNonces = [publicNonce secNonce1, publicNonce secNonce2] aggNonce = fromJust $ aggNonces pubNonces@@ -38,8 +38,8 @@ -- | Property: Aggregation is deterministic - same inputs produce same output prop_aggDeterministic :: SecNonce -> SecKey -> SecNonce -> SecKey -> ByteString -> Property prop_aggDeterministic secNonce1 secKey1 secNonce2 secKey2 msg =- let pubkey1 = fromMaybe (error "Failed to derive pubkey1") $ derive_pub (case secKey1 of SecKey sk -> sk)- pubkey2 = fromMaybe (error "Failed to derive pubkey2") $ derive_pub (case secKey2 of SecKey sk -> sk)+ let pubkey1 = fromMaybe (error "Failed to derive pubkey1") $ derive_pub (fromInteger (case secKey1 of SecKey sk -> sk))+ pubkey2 = fromMaybe (error "Failed to derive pubkey2") $ derive_pub (fromInteger (case secKey2 of SecKey sk -> sk)) pubkeys = [pubkey1, pubkey2] pubNonces = [publicNonce secNonce1, publicNonce secNonce2] aggNonce = fromJust $ aggNonces pubNonces@@ -54,8 +54,8 @@ -- | Property: All partial signatures should verify individually before aggregation prop_partialsVerifyBeforeAgg :: SecNonce -> SecKey -> SecNonce -> SecKey -> ByteString -> Property prop_partialsVerifyBeforeAgg secNonce1 secKey1 secNonce2 secKey2 msg =- let pubkey1 = fromMaybe (error "Failed to derive pubkey1") $ derive_pub (case secKey1 of SecKey sk -> sk)- pubkey2 = fromMaybe (error "Failed to derive pubkey2") $ derive_pub (case secKey2 of SecKey sk -> sk)+ let pubkey1 = fromMaybe (error "Failed to derive pubkey1") $ derive_pub (fromInteger (case secKey1 of SecKey sk -> sk))+ pubkey2 = fromMaybe (error "Failed to derive pubkey2") $ derive_pub (fromInteger (case secKey2 of SecKey sk -> sk)) pubkeys = [pubkey1, pubkey2] pubNonces = [publicNonce secNonce1, publicNonce secNonce2] aggNonce = fromJust $ aggNonces pubNonces@@ -69,7 +69,7 @@ -- | Property: For a single signer, aggregation should work correctly prop_singleSignerAgg :: SecNonce -> SecKey -> ByteString -> Property prop_singleSignerAgg secNonce secKey@(SecKey sk) msg =- let pubkey = fromMaybe (error "Failed to derive pubkey") $ derive_pub sk+ let pubkey = fromMaybe (error "Failed to derive pubkey") $ derive_pub (fromInteger sk) pubNonce = publicNonce secNonce pubNonces = [pubNonce] pubkeys = [pubkey]
test/NonceGenProperty.hs view
@@ -3,9 +3,9 @@ module NonceGenProperty (propertyNonceGen) where -import Crypto.Curve.Secp256k1 (mul, _CURVE_G, _CURVE_Q)+import Crypto.Curve.Secp256k1 (mul, _CURVE_G) import Crypto.Curve.Secp256k1.MuSig2 (PubNonce (..), SecKey (..), SecNonce (..), SecNonceGenParams (..), publicNonce, secNonceGenWithRand)-import Crypto.Curve.Secp256k1.MuSig2.Internal (hashTag, integerToBytes32, xorByteStrings)+import Crypto.Curve.Secp256k1.MuSig2.Internal (curveOrder, hashTag, integerToBytes32, xorByteStrings) import Data.ByteString () import Data.Maybe (fromMaybe) import Test.Tasty@@ -25,14 +25,14 @@ prop_validRange :: Rand32 -> SecNonceGenParams -> Property prop_validRange (Rand32 rand) params = let SecNonce{..} = secNonceGenWithRand rand params- in (1 <= k1 && k1 < _CURVE_Q) .&&. (1 <= k2 && k2 < _CURVE_Q)+ in (1 <= k1 && k1 < curveOrder) .&&. (1 <= k2 && k2 < curveOrder) -- | Property: The public nonce points correspond to G multiplied by k1 and k2 prop_correctPubNonce :: Rand32 -> SecNonceGenParams -> Property prop_correctPubNonce (Rand32 rand) params = let sn@SecNonce{..} = secNonceGenWithRand rand params PubNonce r1 r2 = publicNonce sn- in r1 === fromMaybe (error "Failed to multiply scalar by generator") (mul _CURVE_G k1) .&&. r2 === fromMaybe (error "Failed to multiply scalar by generator") (mul _CURVE_G k2)+ in r1 === fromMaybe (error "Failed to multiply scalar by generator") (mul _CURVE_G (fromInteger k1)) .&&. r2 === fromMaybe (error "Failed to multiply scalar by generator") (mul _CURVE_G (fromInteger k2)) -- | Property: Generating with sk provided is equivalent to XORing rand with the aux hash and generating without sk prop_skConsistency :: Rand32 -> SecNonceGenParams -> Scalar -> Property
test/SignVerifyProperty.hs view
@@ -2,8 +2,9 @@ module SignVerifyProperty (propertySignVerify) where -import Crypto.Curve.Secp256k1 (derive_pub, _CURVE_Q)+import Crypto.Curve.Secp256k1 (derive_pub) import Crypto.Curve.Secp256k1.MuSig2 (SecKey (..), SecNonce (..), aggNonces, mkSessionContext, partialSigVerify, publicNonce, sign)+import Crypto.Curve.Secp256k1.MuSig2.Internal (curveOrder) import Data.ByteString (ByteString) import Data.Maybe (fromJust, fromMaybe) import Test.Tasty@@ -23,19 +24,19 @@ -- | Property: Generated signatures are in the valid range \([0, Q-1]\). prop_validSignatureRange :: SecNonce -> SecKey -> ByteString -> Property prop_validSignatureRange secNonce secKey@(SecKey sk) msg =- let pubkey = fromMaybe (error "Failed to derive pubkey") $ derive_pub sk+ let pubkey = fromMaybe (error "Failed to derive pubkey") $ derive_pub (fromInteger sk) pubNonce = publicNonce secNonce pubNonces = [pubNonce] pubkeys = [pubkey] aggNonce = fromJust $ aggNonces pubNonces ctx = mkSessionContext aggNonce pubkeys [] msg sig = sign secNonce secKey ctx- in (sig >= 0) .&&. (sig < _CURVE_Q)+ in (sig >= 0) .&&. (sig < curveOrder) -- | Property: A signature created with sign verifies with 'partialSigVerify'. prop_signVerifyRoundtrip :: SecNonce -> SecKey -> ByteString -> Property prop_signVerifyRoundtrip secNonce secKey@(SecKey sk) msg =- let pubkey = fromMaybe (error "Failed to derive pubkey") $ derive_pub sk+ let pubkey = fromMaybe (error "Failed to derive pubkey") $ derive_pub (fromInteger sk) pubNonce = publicNonce secNonce pubNonces = [pubNonce] pubkeys = [pubkey]@@ -49,7 +50,7 @@ -- | Property: Signing the same message with the same parameters produces the same signature. prop_signatureDeterminism :: SecNonce -> SecKey -> ByteString -> Property prop_signatureDeterminism secNonce secKey@(SecKey sk) msg =- let pubkey = fromMaybe (error "Failed to derive pubkey") $ derive_pub sk+ let pubkey = fromMaybe (error "Failed to derive pubkey") $ derive_pub (fromInteger sk) pubNonce = publicNonce secNonce pubNonces = [pubNonce] pubkeys = [pubkey]@@ -62,7 +63,7 @@ -- | Property: Using an invalid signer index should fail verification. prop_invalidSignerIndex :: SecNonce -> SecKey -> ByteString -> Property prop_invalidSignerIndex secNonce secKey@(SecKey sk) msg =- let pubkey = fromMaybe (error "Failed to derive pubkey") $ derive_pub sk+ let pubkey = fromMaybe (error "Failed to derive pubkey") $ derive_pub (fromInteger sk) pubNonce = publicNonce secNonce pubNonces = [pubNonce] pubkeys = [pubkey]
test/SignVerifyTweakProperty.hs view
@@ -2,8 +2,9 @@ module SignVerifyTweakProperty (propertySignVerifyTweak) where -import Crypto.Curve.Secp256k1 (derive_pub, _CURVE_Q)+import Crypto.Curve.Secp256k1 (derive_pub) import Crypto.Curve.Secp256k1.MuSig2 (SecKey (..), SecNonce (..), Tweak (..), aggNonces, mkSessionContext, partialSigVerify, publicNonce, sign)+import Crypto.Curve.Secp256k1.MuSig2.Internal (curveOrder) import Data.ByteString (ByteString) import Data.Maybe (fromJust, fromMaybe) import Test.Tasty@@ -26,21 +27,21 @@ prop_validSignatureRangeWithTweaks secNonce secKey@(SecKey sk) = forAll (resize 5 $ listOf arbitrary) $ \tweaks -> forAll arbitrary $ \msg ->- let pubkey = fromMaybe (error "Failed to derive pubkey") $ derive_pub sk+ let pubkey = fromMaybe (error "Failed to derive pubkey") $ derive_pub (fromInteger sk) pubNonce = publicNonce secNonce pubNonces = [pubNonce] pubkeys = [pubkey] aggNonce = fromJust $ aggNonces pubNonces ctx = mkSessionContext aggNonce pubkeys tweaks msg sig = sign secNonce secKey ctx- in (sig >= 0) .&&. (sig < _CURVE_Q)+ in (sig >= 0) .&&. (sig < curveOrder) -- | Property: A signature created with tweaks verifies with 'partialSigVerify'. prop_signVerifyRoundtripWithTweaks :: SecNonce -> SecKey -> Property prop_signVerifyRoundtripWithTweaks secNonce secKey@(SecKey sk) = forAll (resize 5 $ listOf arbitrary) $ \tweaks -> forAll arbitrary $ \msg ->- let pubkey = fromMaybe (error "Failed to derive pubkey") $ derive_pub sk+ let pubkey = fromMaybe (error "Failed to derive pubkey") $ derive_pub (fromInteger sk) pubNonce = publicNonce secNonce pubNonces = [pubNonce] pubkeys = [pubkey]@@ -56,7 +57,7 @@ prop_signatureDeterminismWithTweaks secNonce secKey@(SecKey sk) = forAll (resize 5 $ listOf arbitrary) $ \tweaks -> forAll arbitrary $ \msg ->- let pubkey = fromMaybe (error "Failed to derive pubkey") $ derive_pub sk+ let pubkey = fromMaybe (error "Failed to derive pubkey") $ derive_pub (fromInteger sk) pubNonce = publicNonce secNonce pubNonces = [pubNonce] pubkeys = [pubkey]@@ -69,7 +70,7 @@ -- | Property: Empty tweaks should produce the same result as no tweaks. prop_emptyTweaksEqualsNoTweaks :: SecNonce -> SecKey -> ByteString -> Property prop_emptyTweaksEqualsNoTweaks secNonce secKey@(SecKey sk) msg =- let pubkey = fromMaybe (error "Failed to derive pubkey") $ derive_pub sk+ let pubkey = fromMaybe (error "Failed to derive pubkey") $ derive_pub (fromInteger sk) pubNonce = publicNonce secNonce pubNonces = [pubNonce] pubkeys = [pubkey]@@ -88,12 +89,12 @@ prop_plainTweaksCommutative :: SecNonce -> SecKey -> Integer -> Integer -> ByteString -> Property prop_plainTweaksCommutative secNonce secKey@(SecKey sk) t1 t2 msg = t1 > 0- && t1 < _CURVE_Q+ && t1 < curveOrder && t2 > 0- && t2 < _CURVE_Q+ && t2 < curveOrder && t1 /= t2- ==> let pubkey = fromMaybe (error "Failed to derive pubkey") $ derive_pub sk+ ==> let pubkey = fromMaybe (error "Failed to derive pubkey") $ derive_pub (fromInteger sk) pubNonce = publicNonce secNonce pubNonces = [pubNonce] pubkeys = [pubkey]
test/Util.hs view
@@ -5,8 +5,9 @@ module Util (parsePoint, parseScalar, parsePubNonce, extractXOnly, decodeHex, Rand32 (..), Scalar (..)) where -import Crypto.Curve.Secp256k1 (Projective, Pub, mul, parse_point, serialize_point, _CURVE_G, _CURVE_Q, _CURVE_ZERO)+import Crypto.Curve.Secp256k1 (Projective, Pub, mul, parse_point, serialize_point, _CURVE_G, _CURVE_ZERO) import Crypto.Curve.Secp256k1.MuSig2 (PubNonce (..), SecKey (..), SecNonce (..), SecNonceGenParams (..), Tweak (..))+import Crypto.Curve.Secp256k1.MuSig2.Internal (curveOrder) import Data.ByteString (ByteString) import qualified Data.ByteString as BS import qualified Data.ByteString.Base16 as B16@@ -50,8 +51,8 @@ , ( 99 , do- scalar <- choose (0, _CURVE_Q)- return (fromMaybe (error "Failed to multiply scalar by generator") $ mul _CURVE_G scalar)+ scalar <- choose (0, curveOrder)+ return (fromMaybe (error "Failed to multiply scalar by generator") $ mul _CURVE_G (fromInteger scalar)) ) ] @@ -70,7 +71,7 @@ -- | 'Arbitrary' instance for 'Scalar' to be within curve order. instance Arbitrary Scalar where- arbitrary = Scalar <$> choose (1, _CURVE_Q - 1)+ arbitrary = Scalar <$> choose (1, curveOrder - 1) -- | 32-byte 'ByteString' for testing hashes. newtype Rand32 = Rand32 ByteString deriving (Show, Eq)@@ -132,8 +133,8 @@ -- | 'Arbitrary' instace of 'SecNonce'. instance Arbitrary SecNonce where arbitrary = do- k1 <- choose (1, _CURVE_Q - 1) -- Ensure non-zero- k2 <- choose (1, _CURVE_Q - 1) -- Ensure non-zero+ k1 <- choose (1, curveOrder - 1) -- Ensure non-zero+ k2 <- choose (1, curveOrder - 1) -- Ensure non-zero return SecNonce{k1 = k1, k2 = k2} {- | 'Show' instance for 'SecNonce'.@@ -147,7 +148,7 @@ -- | 'Arbitrary' instace of 'SecKey'. instance Arbitrary SecKey where arbitrary = do- sk <- choose (1, _CURVE_Q - 1) -- Ensure non-zero+ sk <- choose (1, curveOrder - 1) -- Ensure non-zero return (SecKey sk) {- | 'Show' instance for 'SecKey'.@@ -160,7 +161,7 @@ -- | 'Arbitrary' instance for 'Tweak'. instance Arbitrary Tweak where arbitrary = do- tweakValue <- choose (1, _CURVE_Q - 1) -- Ensure valid tweak value+ tweakValue <- choose (1, curveOrder - 1) -- Ensure valid tweak value isXOnly <- arbitrary return $ if isXOnly then XOnlyTweak tweakValue else PlainTweak tweakValue