factomdid

package module
v0.0.0-...-35d6fc8 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 13, 2021 License: MIT Imports: 18 Imported by: 0

README

Factom DID (Decentralized Identities) Golang Lib

The first W3C compatible Golang lib for Factom DID (Decentralized Identities).
Overall overview of this library design: https://docs.google.com/document/d/19JvrOyVKk6hHTtUuWoH1HS3vGQAu1MjbwsPgj33tIFo/edit

What this lib can do

  • Generate DID (DID keys, Management keys, Services)
  • Update DID and calculate difference between initial and updated DID documents for on-chain update
    • Add/revoke DID keys
    • Add/revoke Management keys
    • Add/revoke Services
  • Deactivate DID
  • Generate *factom.Entry{} for DIDManagement, DIDUpdate, DIDDeactivation (fully compatible with Factom Golang Lib)
  • Advanced DID validation
    • Full validation of DID, DIDKey, ManagementKey, Service structs before generating on-chain entry
    • At least one DIDkey and one ManagementKey required for DID creation
    • At least one ManagementKey with priority = 0 required for DID creation
    • At least one ManagementKey with priority = 0 required to remain after DID update
    • DID Deactivation only using ManagementKey with priority = 0 required
    • Check for no duplicates of aliases among DID and Management keys
    • Check for no duplicates of services aliases
    • Dynamic calculation of max required priority for DID Update and comparing if signing Management Key is equal or lower than the required priority
    • Max Factom Entry size (10KB) validation
  • Sign and Verify
    • Signing and verifying any messages with DID keys and Management Keys
    • Built-in automatic signing of generated DIDUpdate, DIDDeactivation entries
    • Supported signatures: ECDSASecp256k1, Ed25519, RSA
  • Automatic public keys conversion into on-chain format (Base58 for ECDSASecp256k1 and Ed25519, PEM for RSA)

Functions

  • DID
    • NewDID()
    • String()
    • GetChainID()
    • SetMainnet()
    • SetTestnet()
    • AddDIDKey(key *DIDKEY)
    • AddManagementKey(key *ManagementKey)
    • AddService(service *Service)
    • RevokeDIDKey(alias string)
    • RevokeManagementKey(alias string)
    • RevokeService(alias string)
    • Create()
    • Update(update *DID, signingKeyAlias string)
    • Deactivate(signingKeyAlias string)
    • Validate()
    • Copy()
  • DIDKey
    • NewDIDKey(alias string, keyType string)
    • AddPurpose(purpose string)
    • SetPriorityRequirement(i int)
    • Sign(message []byte)
    • Verify(message []byte, signature []byte)
  • ManagementKey
    • NewManagementKey(alias string, keyType string, priority int)
    • SetPriorityRequirement(i int)
    • Sign(message []byte)
    • Verify(message []byte, signature []byte)
  • Service
    • NewService(alias string, serviceType string, endpoint string)
    • SetPriorityRequirement(i int)

Enums

// DID Factom Entry Type enum

// EntryTypeCreate is ExtID "DIDManagement" used in the first entry of DID chain
EntryTypeCreate = "DIDManagement"
// EntryTypeDeactivation is ExtID "DIDDeactivation" used in deactivation entry
EntryTypeDeactivation = "DIDDeactivation"
// EntryTypeUpdate is ExtID "DIDUpdate" used in update entry
EntryTypeUpdate = "DIDUpdate"
// EntryTypeVersionUpgrade is ExtID "DIDMethodVersionUpgrade" used in version upgrade entry
EntryTypeVersionUpgrade = "DIDMethodVersionUpgrade"

// DID Network enum

// NetworkMainnet is "mainnet"
NetworkMainnet = "mainnet"
// NetworkTestnet is "testnet"
NetworkTestnet = "testnet"
// NetworkUnspecified is empty string
NetworkUnspecified = ""

// DIDMethodName is method name for Factom DID, used in DID Document
DIDMethodName = "did:factom"
// MaxEntrySize is maximum size of Factom Entry
MaxEntrySize = 10240

// Versions

// EntrySchemaV100 is version 1.0.0 of entry schema
EntrySchemaV100 = "1.0.0"
// DIDMethodSpecV020 is version 0.2.0 of DID specification
DIDMethodSpecV020 = "0.2.0"

// Latest versions

// LatestEntrySchema is latest available entry schema
LatestEntrySchema = EntrySchemaV100
// LatestDIDMethodSpec is latest available DID specification version
LatestDIDMethodSpec = DIDMethodSpecV020

// KeyTypeECDSA is a constant for "ECDSASecp256k1VerificationKey"
KeyTypeECDSA = "ECDSASecp256k1VerificationKey"
// KeyTypeEdDSA is a constant for "Ed25519VerificationKey"
KeyTypeEdDSA = "Ed25519VerificationKey"
// KeyTypeRSA is a constant for "RSAVerificationKey"
KeyTypeRSA = "RSAVerificationKey"

Example

Create new DID document
// Generate blank DID document
// factom.ExtIDs with nonce are automatically generated in did.ExtIDs
did := factomdid.NewDID()

// Generate DID key
// NewDIDKey(alias, keyType)
didKey, err := factomdid.NewDIDKey("did-key-alias", factomdid.KeyTypeECDSA)
if err != nil {
  // handle error
}
didKey.AddPurpose(KeyPurposePublicKey)
didKey.SetPriorityRequirement(0)
did.AddDIDKey(didKey)

// Generate Management Key
// NewManagementKey(alias, keyType, priority)
mgmtKey, err := factomdid.NewManagementKey("mgmt-key-alias", factomdid.KeyTypeRSA, 0)
if err != nil {
  // handle error
}
did.AddManagementKey(mgmtKey)

// Generate Service
// NewService(alias, serviceType, endpoint)
service, err := factomdid.NewService("service-alias", "KYC", "https://kyc.example.com")
if err != nil {
  // handle error
}
service.SetPriorityRequirement(0)
did.AddService(service)

// Generate DIDManagement factom.Entry
entry, err := did.Create()
if err != nil {
  // handle error
}

// publish entry (*factom.Entry) on-chain using Factom Golang lib or Factom Open API
wallet.CommitRevealEntry(entry)
Update existing DID document
...
// continuation of the code above
// make a copy of DID document for updating it
// we need a copy to calculate difference between 2 DID documents later
update := did.Copy()

// revoke DID key
update.RevokeDIDKey("did-key-alias")

// add second Management key
mgmtKey2, err := factomdid.NewManagementKey("second-mgmt-key-alias", factomdid.KeyTypeEdDSA, 1)
if err != nil {
  // handle error
}
update.AddManagementKey(mgmtKey)

// Generate DIDUpdate Factom entry, signed with Management Key "mgmt-key-alias"
// DID.Update(updatedDIDDocument, signingKeyAlias)
entry, err := did.Update(update, "mgmt-key-alias")

// publish entry (*factom.Entry) on-chain using Factom Golang lib or Factom Open API
wallet.CommitRevealEntry(entry)
Deactivate DID document
...
// continuation of the code above
// Generate DIDDeactivation Factom entry, signed with Management Key "mgmt-key-alias"
// DID.Deactivate(signingKeyAlias)
entry, err := did.Deactivate("did-key-alias")

// publish entry (*factom.Entry) on-chain using Factom Golang lib or Factom Open API
wallet.CommitRevealEntry(entry)

Documentation

Index

Constants

View Source
const (
	// KeyTypeECDSA is a constant for "ECDSASecp256k1VerificationKey"
	KeyTypeECDSA = "ECDSASecp256k1VerificationKey"
	// KeyTypeEdDSA is a constant for "Ed25519VerificationKey"
	KeyTypeEdDSA = "Ed25519VerificationKey"
	// KeyTypeRSA is a constant for "RSAVerificationKey"
	KeyTypeRSA = "RSAVerificationKey"
)
View Source
const (

	// EntryTypeCreate is ExtID "DIDManagement" used in the first entry of DID chain
	EntryTypeCreate = "DIDManagement"
	// EntryTypeDeactivation is ExtID "DIDDeactivation" used in deactivation entry
	EntryTypeDeactivation = "DIDDeactivation"
	// EntryTypeUpdate is ExtID "DIDUpdate" used in update entry
	EntryTypeUpdate = "DIDUpdate"
	// EntryTypeVersionUpgrade is ExtID "DIDMethodVersionUpgrade" used in version upgrade entry
	EntryTypeVersionUpgrade = "DIDMethodVersionUpgrade"

	// NetworkMainnet is "mainnet"
	NetworkMainnet = "mainnet"
	// NetworkTestnet is "testnet"
	NetworkTestnet = "testnet"
	// NetworkUnspecified is empty string
	NetworkUnspecified = ""

	// DIDMethodName is method name for Factom DID, used in DID Document
	DIDMethodName = "did:factom"
	// MaxEntrySize is maximum size of Factom Entry
	MaxEntrySize = 10240

	// EntrySchemaV100 is version 1.0.0 of entry schema
	EntrySchemaV100 = "1.0.0"
	// DIDMethodSpecV020 is version 0.2.0 of DID specification
	DIDMethodSpecV020 = "0.2.0"

	// LatestEntrySchema is latest available entry schema
	LatestEntrySchema = EntrySchemaV100
	// LatestDIDMethodSpec is latest available DID specification version
	LatestDIDMethodSpec = DIDMethodSpecV020
)
View Source
const (
	// KeyPurposeAuthentication is authentication purpose
	KeyPurposeAuthentication = "authentication"
	// KeyPurposePublic is publicKey purpose
	KeyPurposePublic = "publicKey"
	// OnChainPubKeyName is name of public key on-chain
	OnChainPubKeyName = "publicKeyBase58"
)

Variables

This section is empty.

Functions

This section is empty.

Types

type AbstractKey

type AbstractKey struct {
	Alias               string `json:"alias" form:"alias" query:"alias" validate:"required"`
	KeyType             string `` /* 143-byte string literal not displayed */
	Controller          string `json:"controller" form:"controller" query:"controller" validate:"required"`
	PriorityRequirement *int   `json:"priorityRequirement" form:"priorityRequirement" query:"omitempty,priorityRequirement"`
	PublicKey           []byte `json:"publicKey" form:"publicKey" query:"publicKey" validate:"required"`
	PrivateKey          []byte `json:"privateKey" form:"privateKey" query:"privateKey" validate:"required"`
}

AbstractKey represents the common fields and functionality in a ManagementKey and a DIDKey.

func (*AbstractKey) SetPriorityRequirement

func (key *AbstractKey) SetPriorityRequirement(i int) *AbstractKey

SetPriorityRequirement sets PriorityRequirement for AbstractKey

func (*AbstractKey) Sign

func (key *AbstractKey) Sign(message []byte) ([]byte, error)

Sign a message with the existing private key and signature type The message is hashed (SHA-256) before being signed

func (*AbstractKey) Verify

func (key *AbstractKey) Verify(message []byte, signature []byte) (bool, error)

Verify the signature of the given message. The message is hashed (SHA-256) before being verified

type DID

type DID struct {
	ID             string           `json:"id" form:"id" query:"id" validate:"required"`
	Network        string           `json:"network" form:"network" query:"network"`
	ManagementKeys []*ManagementKey `json:"managementKeys" form:"managementKeys" query:"managementKeys" validate:"required"`
	DIDKeys        []*DIDKey        `json:"didKeys" form:"didKeys" query:"didKeys" validate:"required"`
	Services       []*Service       `json:"services" form:"services" query:"services"`
	ExtIDs         [][]byte         `json:"extIDs" form:"extIDs" query:"extIDs"`
}

DID describes DID document

func NewDID

func NewDID() *DID

NewDID generates new blank DID document. DID.ExtIDs is a helper field that stores ExtIDs to be written on-chain to get expected ChainID for new DID chain. DID.ExtIDs is not a part of DID Document (JSON)

func (*DID) AddDIDKey

func (did *DID) AddDIDKey(key *DIDKey) (*DID, error)

AddDIDKey adds a DID key to the DID object

func (*DID) AddManagementKey

func (did *DID) AddManagementKey(key *ManagementKey) (*DID, error)

AddManagementKey adds a new Management key to the DID object

func (*DID) AddService

func (did *DID) AddService(service *Service) (*DID, error)

AddService adds a new Service to the DID object

func (*DID) Copy

func (did *DID) Copy() *DID

Copy makes a copy of DID Document for update

func (*DID) Create

func (did *DID) Create() (*factom.Entry, error)

Create generates DIDManagement Factom Entry from DID document

func (*DID) Deactivate

func (did *DID) Deactivate(signingKeyAlias string) (*factom.Entry, error)

Deactivate generates DIDDeactivation Factom Entry signed with ManagementKey (priority=0 key required)

func (*DID) GetChainID

func (did *DID) GetChainID() string

GetChainID gets ChainID from DID string

func (*DID) RevokeDIDKey

func (did *DID) RevokeDIDKey(alias string) (*DID, error)

RevokeDIDKey revokes DID Key from DID object

func (*DID) RevokeManagementKey

func (did *DID) RevokeManagementKey(alias string) (*DID, error)

RevokeManagementKey revokes Management Key from DID object

func (*DID) RevokeService

func (did *DID) RevokeService(alias string) (*DID, error)

RevokeService revokes Service from DID object

func (*DID) SetMainnet

func (did *DID) SetMainnet() *DID

SetMainnet sets the DID network to mainnet

func (*DID) SetTestnet

func (did *DID) SetTestnet() *DID

SetTestnet sets the DID network to testnet

func (*DID) String

func (did *DID) String() string

The decentralized identifier, a 32 byte hexadecimal string

func (*DID) Update

func (did *DID) Update(updatedDID *DID, signingKeyAlias string) (*factom.Entry, error)

Update compares existing and updated DID documents and generates DIDUpdate Factom Entry signed with ManagementKey

func (*DID) Validate

func (did *DID) Validate() error

Validate validates DID document

type DIDDeactivationEntrySchema

type DIDDeactivationEntrySchema struct{}

type DIDKey

type DIDKey struct {
	AbstractKey
	Purpose []DIDKeyPurpose `json:"purpose" form:"purpose" query:"purpose" validate:"len=1|len=2,unique,required,dive"`
}

DIDKey is a key used to sign updates for an existing DID DIDKey.Purpose may be publicKey, authentication or both

func NewDIDKey

func NewDIDKey(alias string, keyType string) (*DIDKey, error)

NewDIDKey generates new DIDKey with alias and keyType

func (*DIDKey) AddPurpose

func (didkey *DIDKey) AddPurpose(purpose string) (*DIDKey, error)

AddPurpose adds purpose into DIDKey

type DIDKeyPurpose

type DIDKeyPurpose struct {
	Purpose string `json:"purpose" form:"purpose" query:"purpose" validate:"required,oneof=publicKey authentication"`
}

DIDKeyPurpose shows what purpose(s) the key serves

type DIDKeySchema

type DIDKeySchema struct {
	Controller          string   `json:"controller" form:"controller" query:"controller"`
	ID                  string   `json:"id" form:"id" query:"id"`
	PublicKeyBase58     string   `json:"publicKeyBase58,omitempty" form:"publicKeyBase58" query:"publicKeyBase58"`
	PublicKeyPem        string   `json:"publicKeyPem,omitempty" form:"publicKeyPem" query:"publicKeyPem"`
	Purpose             []string `json:"purpose" form:"purpose" query:"purpose"`
	Type                string   `json:"type" form:"type" query:"type"`
	PriorityRequirement *int     `json:"priorityRequirement,omitempty" form:"priorityRequirement" query:"priorityRequirement"`
	BIP44               string   `json:"bip44,omitempty" form:"bip44" query:"bip44"`
}

type DIDManagementEntrySchema

type DIDManagementEntrySchema struct {
	DIDKey           []*DIDKeySchema        `json:"didKey" form:"didKey" query:"didKey"`
	DIDMethodVersion string                 `json:"didMethodVersion" form:"didMethodVersion" query:"didMethodVersion"`
	ManagementKey    []*ManagementKeySchema `json:"managementKey" form:"managementKey" query:"managementKey"`
	Service          []*ServiceSchema       `json:"service,omitempty" form:"service" query:"service"`
}

type DIDUpdateEntrySchema

type DIDUpdateEntrySchema struct {
	Add struct {
		DIDKey        []*DIDKeySchema        `json:"didKey,omitempty" form:"didKey" query:"didKey"`
		ManagementKey []*ManagementKeySchema `json:"managementKey,omitempty" form:"managementKey" query:"managementKey"`
		Service       []*ServiceSchema       `json:"service,omitempty" form:"service" query:"service"`
	}
	Revoke struct {
		DIDKey        []*RevokeIDSchema `json:"didKey,omitempty" form:"didKey" query:"didKey"`
		ManagementKey []*RevokeIDSchema `json:"managementKey,omitempty" form:"managementKey" query:"managementKey"`
		Service       []*RevokeIDSchema `json:"service,omitempty" form:"service" query:"service"`
	}
}

type ManagementKey

type ManagementKey struct {
	AbstractKey
	Priority int `json:"priority" form:"priority" query:"priority" validate:"min=0"`
}

ManagementKey is a key used to sign updates for an existing DID

func NewManagementKey

func NewManagementKey(alias string, keyType string, priority int) (*ManagementKey, error)

NewManagementKey generates new ManagementKey with alias and keyType

type ManagementKeySchema

type ManagementKeySchema struct {
	Controller          string `json:"controller" form:"controller" query:"controller"`
	ID                  string `json:"id" form:"id" query:"id"`
	PublicKeyBase58     string `json:"publicKeyBase58,omitempty" form:"publicKeyBase58" query:"publicKeyBase58"`
	PublicKeyPem        string `json:"publicKeyPem,omitempty" form:"publicKeyPem" query:"publicKeyPem"`
	Type                string `json:"type" form:"type" query:"type"`
	Priority            int    `json:"priority" form:"priority" query:"priority"`
	PriorityRequirement *int   `json:"priorityRequirement,omitempty" form:"priorityRequirement" query:"priorityRequirement"`
	BIP44               string `json:"bip44,omitempty" form:"bip44" query:"bip44"`
}

type RevokeIDSchema

type RevokeIDSchema struct {
	ID string `json:"id" form:"id" query:"id"`
}

type Service

type Service struct {
	Alias               string `json:"alias" form:"alias" query:"alias" validate:"required"`
	ServiceType         string `json:"serviceType" form:"serviceType" query:"serviceType" validate:"required"`
	Endpoint            string `json:"endpoint" form:"endpoint" query:"endpoint" validate:"required,url"`
	PriorityRequirement *int   `json:"priorityRequirement" form:"priorityRequirement" query:"priorityRequirement" validate:"omitempty,min=0"`
	CustomField         []byte `json:"customFields" form:"customFields" query:"customFields"`
}

Service represents a service associated with a DID. A service is an end-point, which can be used to communicate with the DID or to carry out different tasks on behalf of the DID (such as signatures, e.g.)

func NewService

func NewService(alias string, serviceType string, endpoint string) (*Service, error)

NewService creates new Service

func (*Service) SetPriorityRequirement

func (service *Service) SetPriorityRequirement(i int) *Service

SetPriorityRequirement sets PriorityRequirement for Service

type ServiceSchema

type ServiceSchema struct {
	ID                  string `json:"id" form:"id" query:"id"`
	Type                string `json:"type" form:"type" query:"type"`
	ServiceEndpoint     string `json:"serviceEndpoint" form:"serviceEndpoint" query:"serviceEndpoint"`
	PriorityRequirement *int   `json:"priorityRequirement,omitempty" form:"priorityRequirement" query:"priorityRequirement"`
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL