github.com/turingchain2020/turingchain@v1.1.21/wallet/bipwallet/btcutilecc/blind_requester.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  	"math/big"
    11  )
    12  
    13  // BlindRequesterState State
    14  type BlindRequesterState struct {
    15  	// secret stuff
    16  	a, b, bInv, c *big.Int
    17  
    18  	// shareable stuff
    19  	F    *ecdsa.PublicKey
    20  	X0   *big.Int //
    21  	Mhat *big.Int // called m̂ in the paper
    22  }
    23  
    24  // BlindMessage Calculates a blinded version of message m
    25  func BlindMessage(rState *BlindRequesterState, Q, R *ecdsa.PublicKey, m *big.Int) *big.Int {
    26  	crv := Secp256k1().Params()
    27  
    28  	// generate F which is not equal to O (§4.2)
    29  	var err error
    30  	F := new(ecdsa.PublicKey)
    31  	for F.X == nil && F.Y == nil {
    32  		// requester's three blinding factors (§4.2)
    33  		rState.a, err = RandFieldElement(rand.Reader)
    34  		maybePanic(err)
    35  		rState.b, err = RandFieldElement(rand.Reader)
    36  		maybePanic(err)
    37  		rState.c, err = RandFieldElement(rand.Reader)
    38  		maybePanic(err)
    39  		rState.bInv = new(big.Int).ModInverse(rState.b, crv.N)
    40  
    41  		// requester calculates point F (§4.2)
    42  		abInv := new(big.Int).Mul(rState.a, rState.bInv)
    43  		abInv.Mod(abInv, crv.N)
    44  		bInvR := ScalarMult(rState.bInv, R)
    45  		abInvQ := ScalarMult(abInv, Q)
    46  		cG := ScalarBaseMult(rState.c)
    47  		F = Add(bInvR, abInvQ)
    48  		F = Add(F, cG)
    49  	}
    50  	rState.F = F
    51  
    52  	// calculate r and m̂
    53  	r := new(big.Int).Mod(F.X, crv.N)
    54  	mHat := new(big.Int).Mul(rState.b, r)
    55  	mHat.Mul(mHat, m)
    56  	mHat.Add(mHat, rState.a)
    57  	mHat.Mod(mHat, crv.N)
    58  	rState.Mhat = mHat
    59  
    60  	return rState.Mhat
    61  }
    62  
    63  // BlindExtract Extract true signature from the blind signature
    64  func BlindExtract(rState *BlindRequesterState, sHat *big.Int) *BlindSignature {
    65  	crv := Secp256k1().Params()
    66  
    67  	// requester extracts the real signature (§4.4)
    68  	s := new(big.Int).Mul(rState.bInv, sHat)
    69  	s.Add(s, rState.c)
    70  	s.Mod(s, crv.N)
    71  	sig := &BlindSignature{S: s, F: rState.F}
    72  	return sig
    73  }
    74  
    75  func maybePanic(err error) {
    76  	if err != nil {
    77  		panic(err)
    78  	}
    79  }