schnor in go

package main

import (
    "crypto/ecdsa"
    "crypto/elliptic"
    "crypto/rand"
    "crypto/sha256"
    "fmt"
    "math/big"
)

func main() {
    privateKeyAlice, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
    publicKeyAlice := &privateKeyAlice.PublicKey

    privateKeyBob, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
    publicKeyBob := &privateKeyBob.PublicKey

    message := "Hello, Schnorr!"

    // Alice's side
    r, s, err := schnorrSign(privateKeyAlice, message)
    if err != nil {
        fmt.Println("Error signing:", err)
        return
    }

    // Bob's side
    valid := schnorrVerify(publicKeyAlice, message, r, s)
    if valid {
        fmt.Println("Signature is valid.")
    } else {
        fmt.Println("Signature is invalid.")
    }
}

func schnorrSign(privateKey ecdsa.PrivateKey, message string) (big.Int, *big.Int, error) {
    // Step 1: Choose a random nonce
    k, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
    if err != nil {
        return nil, nil, err
    }
    nonce := k.D

    // Step 2: Compute the public nonce point
    Rx, Ry := elliptic.P256().ScalarBaseMult(nonce.Bytes())

    // Step 3: Compute the challenge
    e := computeChallenge(Rx, Ry, privateKey.PublicKey.X, privateKey.PublicKey.Y, message)

    // Step 4: Compute the response
    s := new(big.Int).Mul(privateKey.D, e)
    s.Add(s, nonce)
    s.Mod(s, elliptic.P256().Params().N)

    // Step 5: Construct the signature (Rx, s)
    return Rx, s, nil
}

func schnorrVerify(publicKey ecdsa.PublicKey, message string, Rx, s big.Int) bool {
    // Step 1: Compute the challenge
    e := computeChallenge(Rx, nil, publicKey.X, publicKey.Y, message)

    // Step 2: Compute the public nonce point
    Rx, Ry := elliptic.P256().ScalarBaseMult(s.Bytes())

    // Step 3: Compute the response point
    Px, Py := elliptic.P256().Add(Rx, nil, publicKey.X, publicKey.Y)

    // Step 4: Verify that Rx is equal to Px
    return Rx.Cmp(Px) == 0 && e.Cmp(new(big.Int).SetBytes(hashR(Rx.Bytes(), Py.Bytes(), message))) == 0
}

func computeChallenge(Rx, Ry, Px, Py big.Int, message string) big.Int {
    // Step 1: Compute the hash of (Rx || Ry || Px || Py || message)
    hash := hashR(Rx.Bytes(), Ry.Bytes(), Px.Bytes(), Py.Bytes(), []byte(message))

    // Step 2: Convert the hash to a big.Int
    return new(big.Int).SetBytes(hash)
}

func hashR(args ...[]byte) []byte {
    hash := sha256.New()
    for _, arg := range args {
        hash.Write(arg)
    }
    return hash.Sum(nil)
}