github.com/turingchain2020/turingchain@v1.1.21/wallet/bipwallet/btcutilecc/blind_signer.go (about)

     1  // Copyright Turing Corp. 2018 All Rights Reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package btcutil
     6  
     7  import (
     8  	"crypto/ecdsa"
     9  	"crypto/rand"
    10  	"fmt"
    11  	"math/big"
    12  )
    13  
    14  // BlindSignerState blind signer state
    15  type BlindSignerState struct {
    16  	// secret stuff
    17  	d, k *big.Int
    18  
    19  	// shareable stuff
    20  	Q *ecdsa.PublicKey
    21  }
    22  
    23  // BlindSession Request that the signer start a blind signature protocol.  Returns
    24  // the signer's public key and an EC point named R.
    25  func BlindSession(sState *BlindSignerState) (*ecdsa.PublicKey, *ecdsa.PublicKey) {
    26  
    27  	// generate signer's private & public key pair
    28  	if sState.Q == nil {
    29  		keys, err := GenerateKey(rand.Reader)
    30  		maybePanic(err)
    31  		sState.d = keys.D
    32  		sState.Q = &keys.PublicKey
    33  		fmt.Printf("Signer:\t%x\n\t%x\n", sState.d, sState.Q.X)
    34  	}
    35  
    36  	// generate k and R for each user request (§4.2)
    37  	request, err := GenerateKey(rand.Reader)
    38  	maybePanic(err)
    39  	sState.k = request.D
    40  	R := &request.PublicKey
    41  
    42  	return sState.Q, R
    43  }
    44  
    45  // BlindSign Signs a blinded message
    46  func BlindSign(sState *BlindSignerState, R *ecdsa.PublicKey, mHat *big.Int) *big.Int {
    47  	crv := Secp256k1().Params()
    48  
    49  	// verify that R matches our secret k
    50  	RSM := ScalarBaseMult(sState.k)
    51  	if !KeysEqual(R, RSM) {
    52  		panic("unknown R")
    53  	}
    54  
    55  	// signer generates signature (§4.3)
    56  	sHat := new(big.Int).Mul(sState.d, mHat)
    57  	sHat.Add(sHat, sState.k)
    58  	sHat.Mod(sHat, crv.N)
    59  
    60  	return sHat
    61  }