crypto

package
v0.0.0-...-1e6caf6 Latest Latest
Warning

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

Go to latest
Published: Dec 17, 2023 License: BSD-3-Clause Imports: 18 Imported by: 0

README

Cryptography Implementations

Contents:

  • types.go: type declarations with descriptions for all the files below.
  • bls.go: implementation of k-of-n threshold signatures using a BLS library.
  • rsa.go: Creates slightly simplified+application specific RSA functions from go's "crypto/rsa" library.
  • hash.go: functions for hashing of data using a variety of schemes.
  • generate_crypto.go: Given security constraints/requirements and the names of each entity in the network, generate BLS and RSA keys, and create and store CryptoConfig files for each entity.

crypto_config.go:

  • CryptoConfig is an object that contains all the cryptographic information for an entity to use
    • e.x: Mappings to public keys, Private keys, signature schemes being utilized, etc.
  • For convenience, methods are defined for this object which use the information stored within the config to Hash, Sign, and Verify signatures.
  • Thus, all cryptographic actions are condensed to a single object.

Signature Object Format:

  • RSASig, ThresholdSig, and SigFragment are objects of signatures bundled with the signing entity. (BLS for the latter two).
  • While this information is typically contained within a gossip object's Signer Field, there currently isn't a way to store multiple signers of data in a gossip object. Thus, this implementation is integral to the ThresholdSig Type.

cyrpto_test.go

The following tests are included:

  1. Hash function test
  2. K-of-n BLS key generation + signing/verifying with different subsets
  3. IO function tests: Writes and then reads a cryptoconfig and verifies functionality

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func GenerateDataBlocks

func GenerateDataBlocks(certs []x509.Certificate) (dataBlocks []merkletree.DataBlock)

func GenerateMD5

func GenerateMD5(data []byte) ([]byte, error)

Generates the MD5 hash for the given bits.

func GenerateMerkleTree

func GenerateMerkleTree(blocks []merkletree.DataBlock) (tree *merkletree.MerkleTree, error error)

func GeneratePOI

func GeneratePOI(tree *merkletree.MerkleTree) (proofs []*merkletree.Proof)

func GenerateRootHash

func GenerateRootHash(tree *merkletree.MerkleTree) (rootHash []byte)

func GenerateSHA256

func GenerateSHA256(data []byte) ([]byte, error)

Generates the SHA256 hash for the given bits.

func GenerateThresholdKeypairs

func GenerateThresholdKeypairs(entities []CTngID, threshold int) ([]bls.ID, BlsPublicMap, BlsPrivateMap, error)

Generate mappings of IDs to Private Keys and Public Keys Based on a config's parameters

func Generatedummycertlist

func Generatedummycertlist(size int) (certs []x509.Certificate)

func GetPublicKey

func GetPublicKey(privateKey *rsa.PrivateKey) (*rsa.PublicKey, error)

func NewRSAPrivateKey

func NewRSAPrivateKey() (*rsa.PrivateKey, error)

func RSAVerify

func RSAVerify(msg []byte, signature RSASig, pub *rsa.PublicKey) error

func SaveCryptoFiles

func SaveCryptoFiles(directory string, configs []CryptoConfig) error

Saves a list of cryptoconfigs to files in a directory. Each file is named the ID of the corresponding entity.

func VerifyPOI

func VerifyPOI(rootHash []byte, poi *merkletree.Proof, cert x509.Certificate) (ok bool, err error)

Types

type BLSThresholdSignatures

type BLSThresholdSignatures interface {
	GenerateThresholdKeypairs([]CTngID, int) ([]bls.ID, BlsPublicMap, BlsPrivateMap, error)
	ThresholdSign(msg string, secret bls.SecretKey) (SigFragment, error)
	ThresholdAggregate([]SigFragment, int) (ThresholdSig, error)
	VerifyAggregate(msg string, fragments []SigFragment, config *CryptoConfig) error
}
Threshold signatures will use the BLS12-381 signature scheme, which also happens to be used by Ethereum 2.0.

/* The "k of n" Threshold signature scheme which we rely on is described here:

https://github.com/herumi/bls/blob/master/sample/minsample.c#L20
View The Go function translations here:
https://github.com/herumi/bls-go-binary/blob/master/bls/bls.go

type BasicCryptoConfig

type BasicCryptoConfig struct {
	HashScheme HashAlgorithm
	SignScheme string // "rsa" is the only valid value currently.
	//entityIDs          []CTngID      // id of each entity (DNS string), should really exist outside of this struct.
	SelfID             CTngID         // id of the current entity
	SignaturePublicMap RSAPublicMap   // map of entityID to RSA public key
	RSAPrivateKey      rsa.PrivateKey // RSA private key
}

without threshold scheme

type BlsPrivateMap

type BlsPrivateMap map[CTngID]bls.SecretKey

This privatekey map is returned by the key generator. Individual private keys should be stored in the crypto configuration file of each entity.

type BlsPublicMap

type BlsPublicMap map[CTngID]bls.PublicKey

func (*BlsPublicMap) Deserialize

func (p *BlsPublicMap) Deserialize(serialized map[string][]byte) error

Deserialize takes the serialized version of the public map, deserializes it, and puts it in p. p should be allocated space for the BLSPublicMap to be stored.

func (*BlsPublicMap) Serialize

func (p *BlsPublicMap) Serialize() map[string][]byte

Serialization of these fields for transportation. Note that this is an inconvenience of this specific BLS library. Normally, we would be able to just Marshal/Unmarshal a mapping. This is likely an inconvenience of using the C implementation of BLS.

type CTngID

type CTngID string

Generic Ids are URLS.

func CTngIDfromBlsID

func CTngIDfromBlsID(blsid *bls.ID) (CTngID, error)

The reverse of CTngID.BlsID().

func (CTngID) BlsID

func (id CTngID) BlsID() *bls.ID

BLS IDs should be derived directly from the CTngID. This essentially maps every CTngID to a unique BLS ID.

func (CTngID) String

func (id CTngID) String() string

type CTngIDs

type CTngIDs []CTngID

Implemented functions for sorting The following types are neccessary for the sorting of CTng IDs. We sort CTngIds in aggregated signatures for consistency when transporting. Otherwise, payloads which contain the CTng IDs may not be consistent.

func (CTngIDs) Len

func (ids CTngIDs) Len() int

func (CTngIDs) Less

func (ids CTngIDs) Less(i, j int) bool

func (CTngIDs) Swap

func (ids CTngIDs) Swap(i, j int)

type CertPool

type CertPool struct {
	// contains filtered or unexported fields
}

CertPool is a set of certificates.

func NewCertPool

func NewCertPool() *CertPool

NewCertPool returns a new, empty CertPool.

func (*CertPool) AddCert

func (s *CertPool) AddCert(cert *x509.Certificate)

AddCert adds a certificate to a pool.

func (*CertPool) AppendCertsFromPEM

func (s *CertPool) AppendCertsFromPEM(pemCerts []byte) (ok bool)

AppendCertsFromPEM attempts to parse a series of PEM encoded certificates. It appends any certificates found to s and reports whether any certificates were successfully parsed.

On many Linux systems, /etc/ssl/cert.pem will contain the system wide set of root CAs in a format suitable for this function.

func (*CertPool) GetCertBySubjectKeyID

func (s *CertPool) GetCertBySubjectKeyID(subjectKeyId string) *x509.Certificate

Get a Cerificate from the pool by its subjectkeyid

func (*CertPool) GetCertList

func (c *CertPool) GetCertList() []*x509.Certificate

func (*CertPool) GetCerts

func (c *CertPool) GetCerts() []x509.Certificate

func (*CertPool) GetLength

func (c *CertPool) GetLength() int

func (*CertPool) Subjects

func (s *CertPool) Subjects() [][]byte

Subjects returns a list of the DER-encoded subjects of all of the certificates in the pool.

func (*CertPool) UpdateCertBySubjectKeyID

func (s *CertPool) UpdateCertBySubjectKeyID(subjectKeyId string, cert *x509.Certificate)

Update one certificate in the pool by its subjectkeyid

type Certblock

type Certblock struct {
	Content x509.Certificate
}

func (*Certblock) Serialize

func (c *Certblock) Serialize() ([]byte, error)

type CryptoConfig

type CryptoConfig struct {
	Threshold       int //f+1 is the threshold for signing
	N               int //n is the number of participants
	HashScheme      HashAlgorithm
	SignScheme      string // "rsa" is the only valid value currently.
	ThresholdScheme string // "bls" is the only valid value currently.
	//entityIDs          []CTngID      // id of each entity (DNS string), should really exist outside of this struct.
	SelfID             CTngID         // id of the current entity
	SignPublicMap      RSAPublicMap   // map of entityID to RSA public key
	SignSecretKey      rsa.PrivateKey // RSA private key
	ThresholdPublicMap BlsPublicMap   // mapping of BLS IDs to public keys
	ThresholdSecretKey bls.SecretKey  // secret key for the current entity
}

func GenerateEntityCryptoConfigs

func GenerateEntityCryptoConfigs(entityIDs []CTngID, threshold int) ([]CryptoConfig, error)

Generate a list of cryptoconfigs from a list of entity names. The threshold determines the k value in "k-of-n" threshold signing.

func NewBasicCryptoConfig

func NewBasicCryptoConfig(scc *StoredCryptoConfig) (*CryptoConfig, error)

Creates a cryptoconfig from a stored one. This is used for reading a stored file cryptoconfig. Returns a pointer to the new config.

func NewCryptoConfig

func NewCryptoConfig(scc *StoredCryptoConfig) (*CryptoConfig, error)

Creates a cryptoconfig from a stored one. This is used for reading a stored file cryptoconfig. Returns a pointer to the new config.

func NewVerifyOnlyCryptoConfig

func NewVerifyOnlyCryptoConfig(scc *StoredCryptoConfig) (*CryptoConfig, error)

func ReadBasicCryptoConfig

func ReadBasicCryptoConfig(file string) (*CryptoConfig, error)

Read a stored basic crypto config from a file, convert it to a basiccryptoconfig and return a pointer to it.

func ReadCryptoConfig

func ReadCryptoConfig(file string) (*CryptoConfig, error)

Read a storedcryptoconfig from a file, convert it to a cryptoconfig and return a pointer to it.

func ReadVerifyOnlyCryptoConfig

func ReadVerifyOnlyCryptoConfig(file string) (*CryptoConfig, error)

func (*CryptoConfig) FragmentVerify

func (c *CryptoConfig) FragmentVerify(msg string, sig SigFragment) error

Verify the validity of a single signature fragment using the configured "threshold signature" scheme. Uses the keys stored in the CryptoConfig struct to verify the signature.

func (*CryptoConfig) Hash

func (c *CryptoConfig) Hash(msg []byte) ([]byte, error)

Hash a message using the configured hash scheme.

func (*CryptoConfig) Sign

func (c *CryptoConfig) Sign(msg []byte) (RSASig, error)

Sign a message using the configured "normal signature" scheme. Note: This is not a threshold signature/threshold signature fragment.

func (*CryptoConfig) ThresholdAggregate

func (c *CryptoConfig) ThresholdAggregate(sigs []SigFragment) (ThresholdSig, error)

Aggregate a list of threshold signature fragments to make a threshold signature.

func (*CryptoConfig) ThresholdSign

func (c *CryptoConfig) ThresholdSign(msg string) (SigFragment, error)

Sign a message to make a keyfragment using the configured "threshold signature" scheme.

func (*CryptoConfig) ThresholdVerify

func (c *CryptoConfig) ThresholdVerify(msg string, sig ThresholdSig) error

Verify a threshold signature using the configured "threshold signature" scheme, and the stored public keys. Uses the keys stored in the CryptoConfig struct to verify the signature.

func (*CryptoConfig) Verify

func (c *CryptoConfig) Verify(msg []byte, sig RSASig) error

Verify a message using the configured "normal signature" scheme, and the stored public keys.

type CryptoConfigInterface

type CryptoConfigInterface interface {
	Hash([]byte) ([]byte, error)
	Sign([]byte) (RSASig, error)
	Verify([]byte, RSASig) error
	ThresholdSign(string) (SigFragment, error)
	ThresholdAggregate([]SigFragment) (ThresholdSig, error)
	ThresholdVerify(string, ThresholdSig) error
	FragmentVerify(string, SigFragment) error
}

type CryptoStorage

type CryptoStorage interface {
	GenerateCryptoCryptoConfigs([]CTngID, int) error
	SaveCryptoFiles(string, []CryptoConfig) error
	ReadCryptoConfig(file string) (*CryptoConfig, error)
}

type Enum

type Enum uint64

Enum is an unsigned integer.

type HashAlgorithm

type HashAlgorithm Enum

HashAlgorithm enum from RFC 5246 s7.4.1.4.1.

const (
	None   HashAlgorithm = 0
	MD5    HashAlgorithm = 1
	SHA1   HashAlgorithm = 2
	SHA224 HashAlgorithm = 3
	SHA256 HashAlgorithm = 4
	SHA384 HashAlgorithm = 5
	SHA512 HashAlgorithm = 6
)

HashAlgorithm constants from RFC 5246 s7.4.1.4.1.

func (HashAlgorithm) String

func (h HashAlgorithm) String() string

type HashInterface

type HashInterface interface {
	GenerateMD5(msg []byte) ([]byte, error)
	GenerateSHA256(msg []byte) ([]byte, error)
}

type POI_for_transmission

type POI_for_transmission struct {
	Poi          *merkletree.Proof `json:"poi,omitempty"`
	SubjectKeyId []byte            `json:"subjectKeyId,omitempty"`
	Issuer       string            `json:"issuer,omitempty"`
	LoggerID     string            `json:"loggerID,omitempty"`
}

type RSAPublicMap

type RSAPublicMap map[CTngID]rsa.PublicKey

Public key maps for the configuration files. Follows the security assumption that "All public keys are known to all parties."

type RSASig

type RSASig struct {
	Sig []byte
	ID  CTngID
}

RSASig contains the ID of the signer and the rsa signature.

func RSASigFromString

func RSASigFromString(str string) (RSASig, error)

RSASig -> String conversion

func RSASign

func RSASign(msg []byte, privateKey *rsa.PrivateKey, id CTngID) (RSASig, error)

func (RSASig) String

func (s RSASig) String() string

String -> RSASig conversion

type RsaSignatures

type RsaSignatures interface {
	NewRSAPrivateKey() (*rsa.PrivateKey, error)
	GetPublicKey(privateKey *rsa.PrivateKey) (*rsa.PublicKey, error)
	Sign(msg []byte, privateKey *rsa.PrivateKey) ([]byte, error)
	//Verify returns an error if the signature couldnt be verified.
	Verify(msg []byte, signature []byte, publicKey []byte, config *CryptoConfig) error
}

type SigFragment

type SigFragment struct {
	Sign *bls.Sign
	ID   CTngID
}

Signature Fragments store the signer and the signature. This information can safely be sent, as it does not contain the private key. This information may be too much here: the gossiper should be able to deduce the signer(s) from the gossip object, as opposed to having it stored in the signature. Two possible refactors: remove the ID field altogether, or change it to a CTngID.

func SigFragmentFromString

func SigFragmentFromString(str string) (SigFragment, error)

Returns a signature fragment generated from a string.

func ThresholdSign

func ThresholdSign(msg string, sec *bls.SecretKey, SelfID CTngID) SigFragment

ThresholdSign will generate a signature fragment for the given message.

func (SigFragment) String

func (s SigFragment) String() string

Convert a SigFragment to a string. Signatures need to be turned into strings to be stored in Gossip Objects. To convert back, use SigFragmentFromString().

func (SigFragment) Verify

func (f SigFragment) Verify(msg string, pubs *BlsPublicMap) bool

Given a message and a public key mapping, verify the signature runs.

type StoredCryptoConfig

type StoredCryptoConfig struct {
	SelfID          CTngID // id of the current entity
	Threshold       int    //f+1 is the threshold for signing
	N               int    //n is the number of participants
	HashScheme      int
	SignScheme      string // "rsa" is the only valid value currently.
	ThresholdScheme string // "bls" is the only valid value currently.
	//entityIDs          []CTngID      // id of each entity (DNS string), should really exist outside of this struct.
	SignPublicMap      RSAPublicMap      // map of entityID to RSA public key
	SignSecretKey      rsa.PrivateKey    // RSA private key
	ThresholdPublicMap map[string][]byte // mapping of BLS IDs to public keys
	ThresholdSecretKey []byte
}

This is the serialized version of CryptoConfig. Again, this is required because we're using the bls C implementation which can't be stored without serialization.

func NewStoredCryptoConfig

func NewStoredCryptoConfig(c *CryptoConfig) *StoredCryptoConfig

Converts a CryptoConfig to a marshal-able format.

type ThresholdSig

type ThresholdSig struct {
	IDs  []CTngID // Users must know the list of IDs that created the theshold signature to verify.
	Sign *bls.Sign
}

func ThresholdAggregate

func ThresholdAggregate(sigs []SigFragment, threshold int) (ThresholdSig, error)

Aggregate signature Fragments into a ThresholdSig.

func ThresholdSigFromString

func ThresholdSigFromString(str string) (ThresholdSig, error)

func (ThresholdSig) String

func (t ThresholdSig) String() (string, error)

func (ThresholdSig) Verify

func (sig ThresholdSig) Verify(msg string, pubs *BlsPublicMap) bool

Verify an aggregated threshold signature against the message and the public keys

Jump to

Keyboard shortcuts

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