// NewChainID generates a ChainID from an entry. ChainID = primitives.Sha(Sha(ExtIDs[0]) + // Sha(ExtIDs[1] + ... + Sha(ExtIDs[n])) func NewChainID(e interfaces.IEBEntry) interfaces.IHash { id := new(primitives.Hash) sum := sha256.New() for _, v := range e.ExternalIDs() { x := sha256.Sum256(v) sum.Write(x[:]) } id.SetBytes(sum.Sum(nil)) return id }
func (st *State) UpdateAuthorityFromABEntry(entry interfaces.IABEntry) error { var AuthorityIndex int data, err := entry.MarshalBinary() if err != nil { return err } switch entry.Type() { case constants.TYPE_REVEAL_MATRYOSHKA: r := new(adminBlock.RevealMatryoshkaHash) err := r.UnmarshalBinary(data) if err != nil { return err } // Does nothing for authority right now case constants.TYPE_ADD_MATRYOSHKA: m := new(adminBlock.AddReplaceMatryoshkaHash) err := m.UnmarshalBinary(data) if err != nil { return err } AuthorityIndex = st.AddAuthorityFromChainID(m.IdentityChainID) st.Authorities[AuthorityIndex].MatryoshkaHash = m.MHash case constants.TYPE_ADD_SERVER_COUNT: s := new(adminBlock.IncreaseServerCount) err := s.UnmarshalBinary(data) if err != nil { return err } st.AuthorityServerCount = st.AuthorityServerCount + int(s.Amount) case constants.TYPE_ADD_FED_SERVER: f := new(adminBlock.AddFederatedServer) err := f.UnmarshalBinary(data) if err != nil { return err } err = st.AddIdentityFromChainID(f.IdentityChainID) if err != nil { //fmt.Println("Error when Making Identity,", err) } AuthorityIndex = st.AddAuthorityFromChainID(f.IdentityChainID) st.Authorities[AuthorityIndex].Status = constants.IDENTITY_FEDERATED_SERVER // check Identity status UpdateIdentityStatus(f.IdentityChainID, constants.IDENTITY_FEDERATED_SERVER, st) case constants.TYPE_ADD_AUDIT_SERVER: a := new(adminBlock.AddAuditServer) err := a.UnmarshalBinary(data) if err != nil { return err } err = st.AddIdentityFromChainID(a.IdentityChainID) if err != nil { //fmt.Println("Error when Making Identity,", err) } AuthorityIndex = st.AddAuthorityFromChainID(a.IdentityChainID) st.Authorities[AuthorityIndex].Status = constants.IDENTITY_AUDIT_SERVER // check Identity status UpdateIdentityStatus(a.IdentityChainID, constants.IDENTITY_AUDIT_SERVER, st) case constants.TYPE_REMOVE_FED_SERVER: f := new(adminBlock.RemoveFederatedServer) err := f.UnmarshalBinary(data) if err != nil { return err } AuthorityIndex = st.isAuthorityChain(f.IdentityChainID) if AuthorityIndex == -1 { log.Println(f.IdentityChainID.String() + " Cannot be removed. Not in Authorities List.") } else { st.RemoveAuthority(f.IdentityChainID) IdentityIndex := st.isIdentityChain(f.IdentityChainID) if IdentityIndex != -1 && IdentityIndex < len(st.Identities) { if st.Identities[IdentityIndex].IdentityChainID.IsSameAs(st.IdentityChainID) { st.Identities[IdentityIndex].Status = constants.IDENTITY_SELF } else { st.removeIdentity(IdentityIndex) } } } case constants.TYPE_ADD_FED_SERVER_KEY: f := new(adminBlock.AddFederatedServerSigningKey) err := f.UnmarshalBinary(data) if err != nil { return err } keyBytes, err := f.PublicKey.MarshalBinary() if err != nil { return err } key := new(primitives.Hash) err = key.SetBytes(keyBytes) if err != nil { return err } addServerSigningKey(f.IdentityChainID, key, f.DBHeight, st) case constants.TYPE_ADD_BTC_ANCHOR_KEY: b := new(adminBlock.AddFederatedServerBitcoinAnchorKey) err := b.UnmarshalBinary(data) if err != nil { return err } pubKey, err := b.ECDSAPublicKey.MarshalBinary() if err != nil { return err } registerAuthAnchor(b.IdentityChainID, pubKey, b.KeyType, b.KeyPriority, st, "BTC") } return nil }
func toHash(txHash *wire.ShaHash) *primitives.Hash { h := new(primitives.Hash) h.SetBytes(txHash.Bytes()) return h }
func registerAnchorSigningKey(entry interfaces.IEBEntry, initial bool, height uint32, st *State, BlockChain string) error { extIDs := entry.ExternalIDs() if bytes.Compare([]byte{0x00}, extIDs[0]) != 0 || !CheckExternalIDsLength(extIDs, []int{1, 15, 32, 1, 1, 20, 8, 33, 64}) { return errors.New("Identity Error Anchor Key: Invalid external ID length") } subChainID := entry.GetChainID() chainID := new(primitives.Hash) chainID.SetBytes(extIDs[2][:32]) IdentityIndex := st.isIdentityChain(chainID) if IdentityIndex == -1 { return errors.New("Identity Error: This cannot happen. New Bitcoin Key to nonexistent identity") } if !st.Identities[IdentityIndex].ManagementChainID.IsSameAs(subChainID) { return errors.New("Identity Error: Entry was not placed in the correct management chain") } var ask []AnchorSigningKey var newAsk []AnchorSigningKey var oneAsk AnchorSigningKey ask = st.Identities[IdentityIndex].AnchorKeys newAsk = make([]AnchorSigningKey, len(ask)+1) oneAsk.BlockChain = BlockChain oneAsk.KeyLevel = extIDs[3][0] oneAsk.KeyType = extIDs[4][0] oneAsk.SigningKey = extIDs[5] contains := false for i := 0; i < len(ask); i++ { if ask[i].KeyLevel == oneAsk.KeyLevel && strings.Compare(ask[i].BlockChain, oneAsk.BlockChain) == 0 { contains = true ask[i] = oneAsk } else { newAsk[i] = ask[i] } } newAsk[len(ask)] = oneAsk sigmsg, err := AppendExtIDs(extIDs, 0, 6) if err != nil { return err } else { // Verify Signature idKey := st.Identities[IdentityIndex].Key1 if CheckSig(idKey, extIDs[7][1:33], sigmsg, extIDs[8]) { var key [20]byte if len(extIDs[5]) != 20 { return errors.New("New Anchor key for identity [" + chainID.String()[:10] + "] is invalid length") } dbase := st.GetAndLockDB() dblk, err := dbase.FetchDBlockByHeight(height) st.UnlockDB() if err == nil && dblk != nil && dblk.GetHeader().GetTimestamp().GetTimeSeconds() != 0 { if !CheckTimestamp(extIDs[6], dblk.GetHeader().GetTimestamp().GetTimeSeconds()) { return errors.New("New Anchor key for identity [" + chainID.String()[:10] + "] timestamp is too old") } } else { if !CheckTimestamp(extIDs[6], st.GetTimestamp().GetTimeSeconds()) { return errors.New("New Anchor key for identity [" + chainID.String()[:10] + "] timestamp is too old") } } if contains { st.Identities[IdentityIndex].AnchorKeys = ask } else { st.Identities[IdentityIndex].AnchorKeys = newAsk } // Add to admin block status := st.Identities[IdentityIndex].Status if !initial && statusIsFedOrAudit(status) && st.GetLeaderVM() == st.ComputeVMIndex(entry.GetChainID().Bytes()) { copy(key[:20], extIDs[5][:20]) extIDs[5] = append(extIDs[5], []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}...) key := primitives.NewHash(extIDs[5]) msg := messages.NewChangeServerKeyMsg(st, chainID, constants.TYPE_ADD_BTC_ANCHOR_KEY, extIDs[3][0], extIDs[4][0], key) err := msg.(*messages.ChangeServerKeyMsg).Sign(st.serverPrivKey) if err != nil { return errors.New("New Block Signing key for identity [" + chainID.String()[:10] + "] Error: cannot sign msg") } st.InMsgQueue() <- msg } } else { return errors.New("New Anchor key for identity [" + chainID.String()[:10] + "] is invalid. Bad signiture") } } return nil }
func updateMatryoshkaHash(entry interfaces.IEBEntry, initial bool, height uint32, st *State) error { extIDs := entry.ExternalIDs() if len(extIDs) == 0 { return errors.New("Identity Error MHash: Invalid external ID length") } if bytes.Compare([]byte{0x00}, extIDs[0]) != 0 || // Version !CheckExternalIDsLength(extIDs, []int{1, 19, 32, 32, 8, 33, 64}) { // Signiture return errors.New("Identity Error MHash: Invalid external ID length") } chainID := new(primitives.Hash) chainID.SetBytes(extIDs[2][:32]) subChainID := entry.GetChainID() IdentityIndex := st.isIdentityChain(chainID) if IdentityIndex == -1 { return errors.New("Identity Error: This cannot happen. New Matryoshka Hash to nonexistent identity") } if !st.Identities[IdentityIndex].ManagementChainID.IsSameAs(subChainID) { return errors.New("Identity Error: Entry was not placed in the correct management chain") } sigmsg, err := AppendExtIDs(extIDs, 0, 4) if err != nil { //log.Printfln("Identity Error:", err) return nil } else { // Verify Signature idKey := st.Identities[IdentityIndex].Key1 if CheckSig(idKey, extIDs[5][1:33], sigmsg, extIDs[6]) { // Check MHash length if len(extIDs[3]) != 32 { return errors.New("New Matryoshka Hash for identity [" + chainID.String()[:10] + "] is invalid length") } dbase := st.GetAndLockDB() dblk, err := dbase.FetchDBlockByHeight(height) st.UnlockDB() if err == nil && dblk != nil && dblk.GetHeader().GetTimestamp().GetTimeSeconds() != 0 { if !CheckTimestamp(extIDs[4], dblk.GetHeader().GetTimestamp().GetTimeSeconds()) { return errors.New("New Matryoshka Hash for identity [" + chainID.String()[:10] + "] timestamp is too old") } } else { if !CheckTimestamp(extIDs[4], st.GetTimestamp().GetTimeSeconds()) { return errors.New("New Matryoshka Hash for identity [" + chainID.String()[:10] + "] timestamp is too old") } } mhash := primitives.NewHash(extIDs[3]) st.Identities[IdentityIndex].MatryoshkaHash = mhash // Add to admin block status := st.Identities[IdentityIndex].Status if !initial && statusIsFedOrAudit(status) && st.GetLeaderVM() == st.ComputeVMIndex(entry.GetChainID().Bytes()) { //if st.LeaderPL.VMIndexFor(constants.ADMIN_CHAINID) == st.GetLeaderVM() { msg := messages.NewChangeServerKeyMsg(st, chainID, constants.TYPE_ADD_MATRYOSHKA, 0, 0, mhash) err := msg.(*messages.ChangeServerKeyMsg).Sign(st.serverPrivKey) if err != nil { return errors.New("New Block Signing key for identity [" + chainID.String()[:10] + "] Error: cannot sign msg") } //log.Printfln("DEBUG: MHash ChangeServer Message Sent") st.InMsgQueue() <- msg //} } } else { return errors.New("New Matryoshka Hash for identity [" + chainID.String()[:10] + "] is invalid. Bad signiture") } } return nil }
func registerBlockSigningKey(entry interfaces.IEBEntry, initial bool, height uint32, st *State) error { extIDs := entry.ExternalIDs() if len(extIDs) == 0 { return errors.New("Identity Error Block Signing Key: Invalid external ID length") } if bytes.Compare([]byte{0x00}, extIDs[0]) != 0 || // Version !CheckExternalIDsLength(extIDs, []int{1, 21, 32, 32, 8, 33, 64}) { return errors.New("Identity Error Block Signing Key: Invalid external ID length") } subChainID := entry.GetChainID() chainID := new(primitives.Hash) chainID.SetBytes(extIDs[2][:32]) IdentityIndex := st.isIdentityChain(chainID) if IdentityIndex == -1 { return errors.New("Identity Error: This cannot happen. New block signing key to nonexistent identity") } if !st.Identities[IdentityIndex].ManagementChainID.IsSameAs(subChainID) { return errors.New("Identity Error: Entry was not placed in the correct management chain") } sigmsg, err := AppendExtIDs(extIDs, 0, 4) if err != nil { return err } else { //verify Signature idKey := st.Identities[IdentityIndex].Key1 if CheckSig(idKey, extIDs[5][1:33], sigmsg, extIDs[6]) { // Check block key length if len(extIDs[3]) != 32 { return errors.New("New Block Signing key for identity [" + chainID.String()[:10] + "] is invalid length") } dbase := st.GetAndLockDB() dblk, err := dbase.FetchDBlockByHeight(height) st.UnlockDB() if err == nil && dblk != nil && dblk.GetHeader().GetTimestamp().GetTimeSeconds() != 0 { if !CheckTimestamp(extIDs[4], dblk.GetHeader().GetTimestamp().GetTimeSeconds()) { return errors.New("New Block Signing key for identity [" + chainID.String()[:10] + "] timestamp is too old") } } else { if !CheckTimestamp(extIDs[4], st.GetTimestamp().GetTimeSeconds()) { return errors.New("New Block Signing key for identity [" + chainID.String()[:10] + "] timestamp is too old") } } st.Identities[IdentityIndex].SigningKey = primitives.NewHash(extIDs[3]) // Add to admin block status := st.Identities[IdentityIndex].Status if !initial && statusIsFedOrAudit(status) && st.GetLeaderVM() == st.ComputeVMIndex(entry.GetChainID().Bytes()) { key := primitives.NewHash(extIDs[3]) msg := messages.NewChangeServerKeyMsg(st, chainID, constants.TYPE_ADD_FED_SERVER_KEY, 0, 0, key) err := msg.(*messages.ChangeServerKeyMsg).Sign(st.serverPrivKey) if err != nil { return errors.New("New Block Signing key for identity [" + chainID.String()[:10] + "] Error: cannot sign msg") } st.InMsgQueue() <- msg } } else { return errors.New("New Block Signing key for identity [" + chainID.String()[:10] + "] is invalid. Bad signiture") } } return nil }