Files
varsig/constant.go

155 lines
4.5 KiB
Go

package varsig
import (
"encoding/binary"
"fmt"
)
// Prefix is the value for the varsig's varuint prefix byte.
const Prefix = uint64(0x34)
// Hash is the value that specifies the hash algorithm
// that's used to reduce the signed content
type Hash uint64
// Constant values that allow Varsig implementations to specify how
// the payload content is hashed before the signature is generated.
const (
HashUnspecified Hash = 0x00
HashSha2_224 = Hash(0x1013)
HashSha2_256 = Hash(0x12)
HashSha2_384 = Hash(0x20)
HashSha2_512 = Hash(0x13)
HashSha3_224 = Hash(0x17)
HashSha3_256 = Hash(0x16)
HashSha3_384 = Hash(0x15)
HashSha3_512 = Hash(0x14)
HashSha512_224 = Hash(0x1014)
HashSha512_256 = Hash(0x1015)
HashBlake2s_256 = Hash(0xb260)
HashBlake2b_256 = Hash(0xb220)
HashBlake2b_384 = Hash(0xb230)
HashBlake2b_512 = Hash(0xb240)
HashShake_256 = Hash(0x19)
HashKeccak256 = Hash(0x1b)
HashKeccak512 = Hash(0x1d)
)
// DecodeHashAlgorithm reads and validates the expected hash algorithm
// (for varsig types include a variable hash algorithm.)
func DecodeHashAlgorithm(r BytesReader) (Hash, error) {
u, err := binary.ReadUvarint(r)
if err != nil {
return HashUnspecified, fmt.Errorf("%w: %w", ErrUnknownHash, err)
}
h := Hash(u)
switch h {
case HashSha2_224,
HashSha2_256,
HashSha2_384,
HashSha2_512,
HashSha3_224,
HashSha3_256,
HashSha3_384,
HashSha3_512,
HashSha512_224,
HashSha512_256,
HashBlake2s_256,
HashBlake2b_256,
HashBlake2b_384,
HashBlake2b_512,
HashShake_256,
HashKeccak256,
HashKeccak512:
return h, nil
default:
return HashUnspecified, fmt.Errorf("%w: %x", ErrUnknownHash, h)
}
}
// PayloadEncoding specifies the encoding of the data being (hashed and)
// signed. A canonical representation of the data is required to produce
// consistent hashes and signatures.
type PayloadEncoding uint64
// Constant values that allow Varsig implementations to specify how the
// payload content is encoded before being hashed.
// In varsig >= v1, only canonical encoding is allowed.
const (
PayloadEncodingUnspecified PayloadEncoding = 0x00
PayloadEncodingVerbatim PayloadEncoding = 0x5f
PayloadEncodingDAGPB = PayloadEncoding(0x70)
PayloadEncodingDAGCBOR = PayloadEncoding(0x71)
PayloadEncodingDAGJSON = PayloadEncoding(0x0129)
PayloadEncodingEIP191 = PayloadEncoding(0xd191)
PayloadEncodingJWT PayloadEncoding = 0x6a77
)
// DecodePayloadEncoding reads and validates the expected canonical payload
// encoding of the data to be signed.
func DecodePayloadEncoding(r BytesReader, vers Version) (PayloadEncoding, error) {
u, err := binary.ReadUvarint(r)
if err != nil {
return PayloadEncodingUnspecified, fmt.Errorf("%w: %w", ErrUnsupportedPayloadEncoding, err)
}
payEnc := PayloadEncoding(u)
switch vers {
case Version0:
return decodeEncodingInfoV0(payEnc)
case Version1:
return decodeEncodingInfoV1(payEnc)
default:
return 0, ErrUnsupportedVersion
}
}
// https://github.com/ChainAgnostic/varsig#4-payload-encoding
func decodeEncodingInfoV0(payEnc PayloadEncoding) (PayloadEncoding, error) {
switch payEnc {
case PayloadEncodingVerbatim,
PayloadEncodingDAGPB,
PayloadEncodingDAGCBOR,
PayloadEncodingDAGJSON,
PayloadEncodingJWT,
PayloadEncodingEIP191:
return payEnc, nil
default:
return PayloadEncodingUnspecified, fmt.Errorf("%w: version=%d, encoding=%x", ErrUnsupportedPayloadEncoding, Version0, payEnc)
}
}
// https://github.com/expede/varsig/blob/main/README.md#payload-encoding
func decodeEncodingInfoV1(payEnc PayloadEncoding) (PayloadEncoding, error) {
switch payEnc {
case PayloadEncodingVerbatim,
PayloadEncodingDAGCBOR,
PayloadEncodingDAGJSON,
PayloadEncodingEIP191:
return payEnc, nil
default:
return PayloadEncodingUnspecified, fmt.Errorf("%w: version=%d, encoding=%x", ErrUnsupportedPayloadEncoding, Version1, payEnc)
}
}
// Discriminator is (usually) the value representing the public key type of
// the algorithm used to create the signature.
//
// There is not set list of constants here, nor is there a decode function
// as the author of an implementation should include the constant with the
// implementation, and the decoding is handled by the Handler, which uses
// the Discriminator to choose the correct implementation. Also note that
// some of the Discriminator values for a specific implementation have
// changed between varsig v0 and v1, so it's possible to have more than one
// constant defined per implementation.
type Discriminator uint64