func TestBlockStat_01(t *testing.T) { bs := BlockStat{} bs.Init() _, seckey := cipher.GenerateKeyPair() hash := cipher.SumSHA256(secp256k1.RandByte(888)) sig := cipher.SignHash(hash, seckey) var r int = -1 r = bs.try_add_hash_and_sig(hash, cipher.Sig{}) if r != 4 { t.Log("BlockStat::try_add_hash_and_sig() failed to detect invalid signature.") t.Fail() } r = bs.try_add_hash_and_sig(cipher.SHA256{}, sig) if r != 4 { t.Log("BlockStat::try_add_hash_and_sig() failed to detect invalid hash and signature.") t.Fail() } r = bs.try_add_hash_and_sig(cipher.SHA256{}, cipher.Sig{}) if r != 4 { t.Log("BlockStat::try_add_hash_and_sig() failed to detect invalid hash and signature.") t.Fail() } //signer_pubkey, err := cipher.PubKeyFromSig(cipher.Sig{}, cipher.SHA256{}) //if err != nil { //fmt.Printf("Got pubkey='%s' from all-zero sig and all-zero hash.\n", signer_pubkey.Hex()) //} bs.frozen = true r2 := bs.try_add_hash_and_sig(hash, sig) if r2 != 3 { t.Log("BlockStat::try_add_hash_and_sig() failed to detect frozen.") t.Fail() } bs.frozen = false r3 := bs.try_add_hash_and_sig(hash, sig) if r3 != 0 { t.Log("BlockStat::try_add_hash_and_sig() failed to add.") t.Fail() } sig2 := cipher.SignHash(hash, seckey) // Redo signing. r4 := bs.try_add_hash_and_sig(hash, sig2) if r4 != 1 { t.Log("BlockStat::try_add_hash_and_sig() failed to detect duplicate (hash,pubkey).") t.Fail() } r5 := bs.try_add_hash_and_sig(hash, sig) if r5 != 1 { t.Log("BlockStat::try_add_hash_and_sig() failed to detect duplicate (hash,sig).") t.Fail() } }
//sign a block with seckey func (bc *BlockChain) SignBlock(seckey cipher.SecKey, block *Block) { //set signature if PubKeyHash(cipher.PubKeyFromSecKey(seckey)) != bc.Genesis().Head.PrevHash { log.Panic("NewBlock, invalid sec key") } block.Sig = cipher.SignHash(block.Head.Hash(), seckey) }
func createGenesisSignature(master wallet.WalletEntry) cipher.Sig { c := NewVisorConfig() bc := coin.NewBlockchain() gb := bc.CreateGenesisBlock(master.Address, c.GenesisTimestamp, c.GenesisCoinVolume) return cipher.SignHash(gb.HashHeader(), master.Secret) }
// Signs a block for master. Will panic if anything is invalid func (self *Visor) SignBlock(b coin.Block) SignedBlock { if !self.Config.IsMaster { log.Panic("Only master chain can sign blocks") } sig := cipher.SignHash(b.HashHeader(), self.Config.BlockchainSeckey) sb := SignedBlock{ Block: b, Sig: sig, } return sb }
// addBlockToBlockchain test helper function // Adds 2 blocks to the blockchain and return an unspent that has >0 coin hours func addBlockToBlockchain(t *testing.T, bc *Blockchain) (coin.Block, coin.UxOut) { // Split the genesis block into two transactions assert.Equal(t, len(bc.GetUnspent().Array()), 1) ux := bc.GetUnspent().Array()[0] assert.Equal(t, ux.Body.Address, genAddress) pub := cipher.PubKeyFromSecKey(genSecret) assert.Equal(t, genAddress, cipher.AddressFromPubKey(pub)) sig := cipher.SignHash(ux.Hash(), genSecret) assert.Nil(t, cipher.ChkSig(ux.Body.Address, ux.Hash(), sig)) tx, sec := makeTransactionForChainWithHoursFee(t, bc, ux, genSecret, 0, 0) b, err := bc.NewBlockFromTransactions(coin.Transactions{tx}, _incTime) assert.Nil(t, err) assertExecuteBlock(t, bc, b, tx) assert.Equal(t, len(bc.GetUnspent().Array()), 2) // Spend one of them // The other will have hours now ux = coin.UxOut{} for _, u := range bc.GetUnspent().Pool { if u.Body.Address != genAddress { ux = u break } } assert.NotEqual(t, ux.Body.Address, cipher.Address{}) assert.NotEqual(t, ux.Body.Address, genAddress) pub = cipher.PubKeyFromSecKey(sec) addr := cipher.AddressFromPubKey(pub) assert.Equal(t, ux.Body.Address, addr) tx, _ = makeTransactionForChainWithHoursFee(t, bc, ux, sec, 0, 0) b, err = bc.NewBlockFromTransactions(coin.Transactions{tx}, bc.Time()+_incTime) assert.Nil(t, err) assertExecuteBlock(t, bc, b, tx) assert.Equal(t, len(bc.GetUnspent().Array()), 2) // Check that the output in the 2nd block is owned by genesis, // and has coin hours for _, u := range bc.GetUnspent().Pool { if u.Body.Address == genAddress { ux = u break } } assert.Equal(t, ux.Body.Address, genAddress) assert.Equal(t, ux.Head.BkSeq, uint64(1)) assert.True(t, ux.CoinHours(bc.Time()) > 0) return b, ux }
func TestBlockStat_02(t *testing.T) { bs := BlockStat{} bs.Init() hash1 := cipher.SumSHA256(secp256k1.RandByte(888)) n1 := 3 for i := 0; i < n1; i++ { _, seckey := cipher.GenerateKeyPair() sig := cipher.SignHash(hash1, seckey) bs.try_add_hash_and_sig(hash1, sig) } hash2 := cipher.SumSHA256(secp256k1.RandByte(888)) n2 := 2 for i := 0; i < n2; i++ { _, seckey := cipher.GenerateKeyPair() sig := cipher.SignHash(hash2, seckey) bs.try_add_hash_and_sig(hash2, sig) } hash3 := cipher.SumSHA256(secp256k1.RandByte(888)) n3 := 1 for i := 0; i < n3; i++ { _, seckey := cipher.GenerateKeyPair() sig := cipher.SignHash(hash3, seckey) bs.try_add_hash_and_sig(hash3, sig) } best_hash, _, _ := bs.GetBestHashPubkeySig() if best_hash != hash1 { t.Log("BlockStat::try_add_hash_and_sig() or BlockStat::GetBestHashPubkeySig() issue.") t.Fail() } }
// Signs all inputs in the transaction func (self *Transaction) SignInputs(keys []cipher.SecKey) { if len(self.Head.Sigs) != 0 { log.Panic("Transaction has been signed") } if len(keys) != len(self.In) { log.Panic("Invalid number of keys") } if len(keys) > math.MaxUint16 { log.Panic("Too many key") } if len(keys) == 0 { log.Panic("No keys") } sigs := make([]cipher.Sig, len(self.In)) h := self.hashInner() for i, k := range keys { sigs[i] = cipher.SignHash(h, k) } self.Head.Sigs = sigs }
// Signs all inputs in the transaction func (self *Transaction) SignInputs(keys []cipher.SecKey) { self.InnerHash = self.HashInner() //update hash if len(self.Sigs) != 0 { log.Panic("Transaction has been signed") } if len(keys) != len(self.In) { log.Panic("Invalid number of keys") } if len(keys) > math.MaxUint16 { log.Panic("Too many key") } if len(keys) == 0 { log.Panic("No keys") } sigs := make([]cipher.Sig, len(self.In)) inner_hash := self.HashInner() for i, k := range keys { h := cipher.AddSHA256(inner_hash, self.In[i]) //hash to sign sigs[i] = cipher.SignHash(h, k) } self.Sigs = sigs }
//////////////////////////////////////////////////////////////////////////////// // Reasons for this function: 1st, we want to minimize exposure of // SecKey, even in same process space. 2nd, functions Sign and // SignHash already exist, so want keep search/browse/jump-to-tag // unambiguous. func (self *ConsensusParticipant) SignatureOf(hash cipher.SHA256) cipher.Sig { // PERFORMANCE: This is expensive when cipher.DebugLevel2 or // cipher.DebugLevel1 are true: return cipher.SignHash(hash, self.Seckey) }